Taco Radar: San Diego — 地図上でレストランを選んで半径内のライバルを比較するVizを作った話

今週のお題
MakeoverMonday 2026 Week 18 のお題は “Best Tacos in San Diego”。サンディエゴのタコス店のGoogleレビューデータをもとに、スコア・緯度経度・レビュー文(スニペット)が含まれるCSVが提供されました。
「ランキングを棒グラフで並べるだけ」では面白みがないテーマです。そこで 「どの店から探すか」 を起点にした、地理的なレーダー可視化に仕上げました。
作成したダッシュボード
→ https://is.gd/ZJ8LCu
タイトルは 『Taco Radar: San Diego — Explore top taco spots around your selected restaurant』。地図上でレストランをクリックすると、その店を中心に設定した半径バッファ内にある競合店が絞り込まれ、スコアと距離で一斉にランキング表示されます。さらに、選んだ店のクチコミに登場する単語をワードクラウドで表示し、任意のキーワードをクリックすると該当レビューだけに絞り込める仕組みです。
工夫した点・こだわり
1. 「今自分がいる店の周辺を知りたい」という自然な問いを設計の起点にした
マップ上のすべての店を同時に見ても、どこから意思決定すればいいか分からない。「自分が今いる店(または気になる店)を選び、その周辺を見る」というユーザーストーリーを軸にしたことで、バッファ・ランキング・クチコミの3パーツが自然につながりました。
2. バッファ半径をパラメータで可変にした
p.buffer_r というパラメータで半径(km)をスライダー調整できます。デフォルト20km、狭くすれば市街地の競合のみ、広げれば郊外まで比較対象に入ります。
3. クチコミのトークンを「フィルター兼インサイト」として活用
レビュー文を形態素(トークン)に分解したword_count.csvを別途用意し、頻出ワードをワードクラウドで表示しています。トークンをクリックすると p.token パラメータが更新され、そのキーワードが含まれるレビューだけにランキングが絞り込まれます。「tortillas」を選べば「生地にこだわる店」だけが浮かび上がる、という使い方ができます。
使ったTableauの技術・Tips
① BUFFER() + INTERSECTS() で空間フィルタを実現
Tableauの空間関数を使い、選択された店の座標を中心に円形バッファを生成し、バッファ内に入る他店舗を抽出しています。
// バッファ生成(c.buffer)
buffer(
makepoint([p.latitude], [p.longitude]),
[p.buffer_r],
"km"
)
// バッファ内判定(f.intersects)
INTERSECTS([c.buffer], makepoint([latitude], [longitude]))
ポイントは、パラメータが未設定(0.0)のとき全店舗の平均座標を中心にフォールバックする条件分岐を入れている点です。「何も選んでいない状態」でも地図がクラッシュしません。
② FIXED LOD で選択店舗の座標をスカラーとして取り出す
選択店舗との距離を計算するには、その店の緯度経度を「1つの値」として取り出す必要があります。FIXED LODで実装しています。
// 選択店舗の緯度(c.Latitude(selected shop))
{max(iif([c.selected shop?], [latitude], null))}
// 選択店舗との距離(c.distance)
distance(
makepoint([c.Latitude(selected shop)], [c.Longitude(selected shop)]),
makepoint([latitude], [longitude]),
'km'
)
iif で「選択外の店はnull」にしてから max を取ることで、選ばれた1店のスカラー値になります。
③ Edit Parameter Action でマップクリックを座標入力に変換
地図上の店舗ドットをクリックすると、p.Restaurant Name・p.latitude・p.longitude の3つのパラメータが同時に更新されます。これにより「クリック → バッファが再計算 → ランキング更新」の連鎖が起きます。Resetボタンは逆に全パラメータをデフォルト値(”None”・0.0・0.0)に戻す別のEdit Parameter Actionです。
④ p.select measure で表示切り替え
p.select measure(0=score / 1=distance)でランキングの軸を切り替えられます。
case [p.select measure]
when 0 then {avg([score])}
when 1 then {avg([c.distance])}
end
スコア重視か距離重視かでランキングの見え方が変わり、「近さで探す」「評価で探す」の両方に対応できます。
学び・振り返り
今回一番手間がかかったのは 「何も選んでいない状態の設計」 でした。パラメータがデフォルト値(”None”や0.0)のとき、距離計算・バッファ生成・ラベル表示がすべて適切にフォールバックするよう、iif と条件分岐を丁寧に挟む必要がありました。
「インタラクティブVizは初期状態が第一印象になる」という教訓です。初期状態でも地図が全店表示され、クリックを誘う視覚的な構成にしておくことで、ユーザーが自然に操作を始めてくれます。
空間関数(BUFFER・INTERSECTS・DISTANCE)はTableauで使える強力な武器ですが、「座標をスカラーとして取り出す」ためのFIXED LODとのセットで使うのが実践的なパターンだと改めて確認できました。
Tableau Public プロフィール: https://public.tableau.com/app/profile/tamaball38175/vizzes
⚠️ 注記: この記事はAIを活用して生成されています。内容に誤りが含まれる可能性があります。技術的な詳細については公式ドキュメントも合わせてご確認ください。
