プロが教える店舗&オフィスのセキュリティ対策術

どなたかご教授の方よろしくお願いします。。

現在セレクトボックスを二つ実装して、施設(コンビニA店)と複数物件情報を含んだ市町村(○○市)を選択した後、ボタンクリックで施設とコンビニの距離?を実装するところまで来ました。質問・回答して欲しい箇所は以下の通りです。

1,距離を計算した後にランキング形式で表示したい。
2,セレクトボックスを増やしても計算できる実装にしたい。
3,よりHTMLっぽいGUIにしたい。
4,表示された物件名によって、画像表示が変わるようにしたい。
(物件1ならa.jpg、物件2ならb.jpg等表示順の変更(ランキング表示形式の場合))

参考になるように、コード貼っておきます。
使用言語はHTML,CSS,javascriptです。
ご回答待っています。よろしくお願いします。

ソースコード
<div id="page-1">
<select id="shop">
<option value="a">コンビニA店</option>
<option value="b">コンビニB店</option>
<option value="c">コンビニC店</option>
</select>
<select id="city">
<option value="icity">い市</option>
<option value="rocity">ろ市</option>
<option value="hacity">は市</option>
</select>
<button id="btn" >ボタン</button>
</div>
<div id="page-2">
</div>
<script>
// 施設データ
const conveni = {
a: {x: 99, y: 121},
b: {x: 134, y: 153},
c: {x: 98, y: 150},
}
// 物件データ
const data = {
icity: [
{name: '物件1', x: 123, y: 111},
{name: '物件2', x: 95, y: 191},
{name: '物件3', x: 133, y: 81},
],
rocity: [
{name: '物件4', x: 81, y: 111},
{name: '物件5', x: 95, y: 123},
{name: '物件6', x: 133, y: 123},
],
hacity: [
{name: '物件7', x: 191, y: 161},
{name: '物件8', x: 95, y: 191},
{name: '物件9', x: 143, y: 81},
]};

document.getElementById('btn').addEventListener('click',()=>{
document.getElementById('page-1').style.display = 'none';
const conv = conveni[document.getElementById('shop').value];
const city = data[document.getElementById('city').value]
.map(b => {
b.len = (b.x - conv.x) ** 2 + (b.y - conv.y) ** 2;
return b;
})
.sort((a, b) => a.len - b.len);

document.getElementById('page-2')
.appendChild(Object.assign(document.createElement('ol'),{
innerHTML: city.map(c => `<li>${c.name}</li>`).join('')
}));
},false);

</script>

A 回答 (2件)

こんにちは



最終的にどのようなものになさりたいのかわかりませんけれど、ご提示の方式のままでやるのであれば・・・
(=データ数に限度があるでしょうし、また、selectで選択できる程度の数という意味)

1.)
何のランキングなのか不明ですが、ランキングのためのデータを物件データに加えておいて、そちらの値で現状と同様にソートすれば、ランキング順に表示することは可能ではないでしょうか。
(ご提示の「距離?」も一種のランキングと言えば言えますよね?)

2.)
>セレクトボックスを増やしても計算できる
言葉通り「セレクトボックスの数を増やす」意味なのか、「オプションの数を増やす」のかによります。

「オプションの数が増える」だけなら、初期表示時にセレクトのオプションをデータに基づいて作成するような仕組みにしておけば宜しいでしょう。
いずれにしろ、名前や位置のデータは事前に用意されているのでしょうから。
具体的には、ロード時に各データのkeyをそのままオプションとして設定すれば済むものと思います。
現状のデータのままだと、a、b、cやicity、rocity、hacityがそのまま表示値になってしまうので、名称データを追加しておくか、あるいは、表示名とデータを一致させておくかでしょうか。

「セレクトボックスの数が増える」場合は、どのような内容のボックスで、それをどのように処理に反映するのかによって仕組みは変わってくるものと思います。
内容によっては、スクリプトそのものを変える必要も出てくるでしょうから。
セレクトボックスに対応するような形で処理をモジュール化できるのであれば、メインの処理構造を「存在するセレクトボックスに応じて処理を呼び出す」ような形式にしておくことで、モジュールを追加するだけで処理がされるようにすることも不可能ではないと思いますけれど・・・

3.)
目指しているものが何なのか不明なので、なんとも言えませんけれど・・・
位置情報が主体なのなら、地図上に表示するとかでしょうか?
例えば、某有名MapのAPIを利用することで、地図上の2点を指定したら、2点間の直線距離や道路経路の距離を計算/表示することは可能ですし、その経路を地図上に表示することなども可能です。

4.)
物件データに、対応する画像データのURLを追加しておくことで、比較的簡単に実現できると思われます。
img要素を生成して追加すれば良いだけなので。
    • good
    • 1
この回答へのお礼

ご回答ありがとうございます。
自分がまだまだ初学者なものでして、回答者様の意見を
コードで実装する段階までが困難なため、質問いたしました。

ですが、とても詳しく考え方をご教授いただきまして大変勉強になりました!
こんな私の分かりづらい質問にも関わらず真摯に対応していただきまして、
誠にありがとうございました。

お礼日時:2021/12/27 18:32

1 と 4 の実装例です



const RG = {
1:"gold.png",
2:"silv.png",
3:"bron.png",
0:"iron.png"
};
var list = 物件列.map(距離を計算).sort(距離の昇順);

list.forEach((b,i)=>{
var n = i+1;
if (i != 0) {
var c = list[i-1];
if (b.len == c.len) n = c.rank; // 同率の考慮
}
b.rank = n; // 順位
b.img = RG[n]?? RG[0]; // 順位によって画像を変える
});

var html = list.map(c=>`
<li>
<img src="${c.img}"><span>${c.rank}位</span>
<em>${c.name}</em>
<small>(距離=${c.len}km)</small>
</li>
`).join("");
    • good
    • 1
この回答へのお礼

ご回答ありがとうございます。
自分の実装に組み込んでみた結果、Googlemapで調べてみた結果通りに
ランキング表示されました!!

大変助かりましたので、この回答をベストアンサーとさせていただきます。
自分の実装したい理想に近づけました。ありがとうございます。

お礼日時:2021/12/27 18:28

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!