「You are invited — Open Data Day」
コロナ禍の今年は富山、石川、福井、北陸三県合同でオンライン開催!情報提供タイムの後は、ブレイクアウトルームに分かれてオープンデータかるたを使ったアイデアソン!
オープンデータが書かれたカルタを並べて、データをちょい足し、アイデアをまとめて発表しました!
インターナショナルオープンデータデイ@北陸オンラインでの学び、オープンデータとSDGsを組み合わせたカードゲームがおもしろそう!
力強いメッセージ「誰だってオープンデータは作れる!」 by Code for Toyama City の寺田さん
早速、データづくりから始めます。
「code4sabae/SDGs_ja: SDGS(持続可能な開発目標)、17の目標(ゴール)と169のターゲットのCSVデータ(English/Japanese)」
GitHubで検索して発見した「datapopalliance/SDGs: Excel and CSV versions of the goals, targets, and indicators from the Sustainable Development Goals (SDGs).」をフォークして、日本語とタイトルと色と画像を足しました。
作成したCSVは、csvbeautyを通しているのでExcelからプログラムまで幅広く活用いただけます。webアプリやサーバーでのDenoで使う場合、下記のようなコードで簡単に使えます!
<script type="module"> import { CSV } from "https://code4sabae.github.io/js/CSV.js"; window.onload = async () => { const baseurl = "https://code4sabae.github.io/SDGs_ja/"; const goals = CSV.toJSON(await CSV.fetch(baseurl + "SDG-goals.csv")); console.log(goals); const targets = CSV.toJSON(await CSV.fetch(baseurl + "SDG-targets.csv")); console.log(targets); }; </script>
オープンデータかるたとSDGsを組み合わせる準備ができました!
データの準備だけではちょっとさみしいので、簡単なゲームを作ってみました。
「SDGs GOALQUIZ」
169のターゲットをランダムにシャッフルし、クイズゲーム風に表示されるターゲットから、対応するゴール(目標)を選び、正答率を競うゲームです。
日本語、英語、両対応。途中での切り替えもできます(アイコンを切り替えるにはリロードが必要)。なかなかに難しいです。
SDGsアイコンはオープンデータではありません。非営利で資金調達目的でなければ申請なしに使用できます。詳しくは、国連のサイトをご確認ください。
「SDGsのポスター・ロゴ・アイコンおよびガイドライン | 国連広報センター」
クイズゲームのメインプログラム、JavaScriptでなかなか分かりやすく書けたと思います。
window.onload = async () => { const baseurl = "https://code4sabae.github.io/SDGs_ja/"; const goals = CSV.toJSON(await CSV.fetch(baseurl + "SDG-goals.csv")); const targets = CSV.toJSON(await CSV.fetch(baseurl + "SDG-targets.csv")); const body = document.body; add(body, "h1", "SDGs " + lang("ゴールクイズ", "GOALQUIZ")); const result = add(body, "div"); result.className = "result"; const quiz = add(body, "div"); quiz.className = "quiz"; const logos = add(body, "div"); logos.className = "logos"; const sels = []; for (const goal of goals) { const img = new Image(); img.src = baseurl + goal[lang("logo_ja", "logo")]; logos.appendChild(img); sels.push(img); } const credit = add(body, "div"); credit.className = "credit"; add(credit, "span", "App: CC BY @taisukef", "https://fukuno.jig.jp/3146"); add(credit, "span", " "); add(credit, "span", "(src on GitHub)", "https://github.com/code4sabae/goalquiz"); add(credit, "br"); add(credit, "div", "Data: SDGs_ja on GitHub", "https://github.com/code4sabae/SDGs_ja"); add(credit, "span", "Japanese", "#ja"); add(credit, "span", " / "); add(credit, "span", "English", "#en"); add(body, "qr-code"); shuffle(targets); let point = 0; for (let i = 0; i < targets.length; i++) { quiz.innerHTML = " "; quiz.style.backgroundColor = "white"; quiz.style.color = "black"; const target = targets[i]; const goal = goals[target.goal - 1]; const desc = lang("description_ja", "description"); const title = lang("title_ja", "title"); const tid = startShowText(quiz, target[desc], lang(50, 25)); const ans = await waitClick(sels) + 1; clearInterval(tid); quiz.textContent = target[desc]; quiz.innerHTML += "<br>" + lang("あなたの回答", "Your Choice") + ":" + ans + " 「" + goals[ans - 1][title] + "」"; await sleep(300); quiz.style.backgroundColor = goal.color; quiz.style.color = "white"; if (ans == target.goal) { quiz.innerHTML += "<br>" + lang("正解!", "Correct!"); point++; } else { quiz.innerHTML += "<br>" + lang("まちがい! 正解は ", "Wrong.. Correct answer is ") + target.goal + " 「" + goal[title] + "」"; } result.textContent = lang( (i + 1) + "問中" + point + "問正解 正解率" + (point / (i + 1) * 100).toFixed(1) + "%", "Q cnt " + (i + 1) + ", Corrects " + point + ", Rate " + (point / (i + 1) * 100).toFixed(1) + "%" ); await sleep(1000); } alert(lang("おめでとうございます!全169ターゲットのクイズを終えました!", "Congratulations!! You've finished quiz of 169 targets.")) };