From 258c83996e4722799a1f354758adb5821ac0d7e0 Mon Sep 17 00:00:00 2001 From: Yohei Yasukawa Date: Sun, 6 Jul 2025 23:40:48 +0900 Subject: [PATCH] =?UTF-8?q?=E8=8B=B1=E8=AA=9E=E8=A9=B1=E8=80=85=E5=90=91?= =?UTF-8?q?=E3=81=91=E3=81=AB=E7=B5=B1=E8=A8=88=E3=83=9A=E3=83=BC=E3=82=B8?= =?UTF-8?q?=E3=81=AE=E8=8B=B1=E8=AA=9E=E7=89=88=E3=82=92=E5=AE=9F=E8=A3=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - /english/stats ルートを追加 - StatsController に言語判定機能を追加(@lang パラメータ) - グラフタイトル、凡例、軸ラベルを英語対応 - ページ内のすべてのテキストを条件分岐で英語化 - 都道府県名の英語表記に対応(Hokkaido, Tokyo など) - 言語切り替えリンクを各ページの冒頭に追加 既存のコードパターンを活用し、DRY原則に従った最小限の実装。 将来的なi18n導入を見据えた設計となっている。 --- app/controllers/stats_controller.rb | 12 ++- app/helpers/application_helper.rb | 56 +++++++++++ app/models/high_charts_builder.rb | 39 ++++---- app/models/stat.rb | 12 +-- app/views/stats/show.html.erb | 142 ++++++++++++++++++---------- config/routes.rb | 1 + 6 files changed, 182 insertions(+), 80 deletions(-) diff --git a/app/controllers/stats_controller.rb b/app/controllers/stats_controller.rb index 49c11fc7e..90f323c1a 100644 --- a/app/controllers/stats_controller.rb +++ b/app/controllers/stats_controller.rb @@ -2,6 +2,9 @@ class StatsController < ApplicationController # GET /stats[.json] def show + # 言語設定 + @lang = params[:lang] || 'ja' + # 2012年1月1日〜2024年12月31日までの集計結果 @period_start = 2012 @period_end = 2024 @@ -10,9 +13,9 @@ def show # 推移グラフ @high_charts_globals = HighChartsBuilder.global_options - @annual_dojos_chart = stats.annual_dojos_chart - @annual_event_histories_chart = stats.annual_event_histories_chart - @annual_participants_chart = stats.annual_participants_chart + @annual_dojos_chart = stats.annual_dojos_chart(@lang) + @annual_event_histories_chart = stats.annual_event_histories_chart(@lang) + @annual_participants_chart = stats.annual_participants_chart(@lang) # 最新データ @sum_of_dojos = Dojo.active_dojos_count @@ -24,7 +27,8 @@ def show # 道場タグ分布 @dojo_tag_chart = LazyHighCharts::HighChart.new('graph') do |f| number_of_tags = 10 - f.title(text: "CoderDojo タグ分布 (上位 #{number_of_tags})") + title_text = @lang == 'en' ? "CoderDojo Tag Distribution (Top #{number_of_tags})" : "CoderDojo タグ分布 (上位 #{number_of_tags})" + f.title(text: title_text) # Use 'tally' method when using Ruby 2.7.0 or higher # cf. https://twitter.com/yasulab/status/1154566199511941120 diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb index 8ad2b2343..93be0ab1a 100644 --- a/app/helpers/application_helper.rb +++ b/app/helpers/application_helper.rb @@ -94,4 +94,60 @@ def facebook_page_url; 'https://www.facebook.com/coderdojo.jp'; end def twitter_url; 'https://twitter.com/CoderDojoJapan'; end def youtube_url; 'https://youtube.com/CoderDojoJapan'; end + def prefecture_name_in_english(prefecture_name) + # 都道府県名の英語表記を返す簡易マッピング + # データベースには「県」「都」「府」が省略された形で保存されている + prefecture_names = { + '北海道' => 'Hokkaido', + '青森' => 'Aomori', + '岩手' => 'Iwate', + '宮城' => 'Miyagi', + '秋田' => 'Akita', + '山形' => 'Yamagata', + '福島' => 'Fukushima', + '茨城' => 'Ibaraki', + '栃木' => 'Tochigi', + '群馬' => 'Gunma', + '埼玉' => 'Saitama', + '千葉' => 'Chiba', + '東京' => 'Tokyo', + '神奈川' => 'Kanagawa', + '新潟' => 'Niigata', + '富山' => 'Toyama', + '石川' => 'Ishikawa', + '福井' => 'Fukui', + '山梨' => 'Yamanashi', + '長野' => 'Nagano', + '岐阜' => 'Gifu', + '静岡' => 'Shizuoka', + '愛知' => 'Aichi', + '三重' => 'Mie', + '滋賀' => 'Shiga', + '京都' => 'Kyoto', + '大阪' => 'Osaka', + '兵庫' => 'Hyogo', + '奈良' => 'Nara', + '和歌山' => 'Wakayama', + '鳥取' => 'Tottori', + '島根' => 'Shimane', + '岡山' => 'Okayama', + '広島' => 'Hiroshima', + '山口' => 'Yamaguchi', + '徳島' => 'Tokushima', + '香川' => 'Kagawa', + '愛媛' => 'Ehime', + '高知' => 'Kochi', + '福岡' => 'Fukuoka', + '佐賀' => 'Saga', + '長崎' => 'Nagasaki', + '熊本' => 'Kumamoto', + '大分' => 'Oita', + '宮崎' => 'Miyazaki', + '鹿児島' => 'Kagoshima', + '沖縄' => 'Okinawa' + } + + prefecture_names[prefecture_name] || prefecture_name + end + end diff --git a/app/models/high_charts_builder.rb b/app/models/high_charts_builder.rb index df94e11cc..04a319888 100644 --- a/app/models/high_charts_builder.rb +++ b/app/models/high_charts_builder.rb @@ -8,51 +8,54 @@ def global_options end end - def build_annual_dojos(source) + def build_annual_dojos(source, lang = 'ja') data = annual_chart_data_from(source) + title_text = lang == 'en' ? 'Number of Dojos' : '道場数の推移' LazyHighCharts::HighChart.new('graph') do |f| - f.title(text: '道場数の推移') + f.title(text: title_text) f.xAxis(categories: data[:years]) - f.series(type: 'column', name: '増加数', yAxis: 0, data: data[:increase_nums]) - f.series(type: 'line', name: '累積合計', yAxis: 1, data: data[:cumulative_sums]) + f.series(type: 'column', name: lang == 'en' ? 'New' : '増加数', yAxis: 0, data: data[:increase_nums]) + f.series(type: 'line', name: lang == 'en' ? 'Total' : '累積合計', yAxis: 1, data: data[:cumulative_sums]) f.yAxis [ - { title: { text: '増加数' }, tickInterval: 15, max: 75 }, - { title: { text: '累積合計' }, tickInterval: 50, max: 250, opposite: true } + { title: { text: lang == 'en' ? 'New' : '増加数' }, tickInterval: 15, max: 75 }, + { title: { text: lang == 'en' ? 'Total' : '累積合計' }, tickInterval: 50, max: 250, opposite: true } ] f.chart(width: HIGH_CHARTS_WIDTH, alignTicks: false) f.colors(["#A0D3B5", "#505D6B"]) end end - def build_annual_event_histories(source) + def build_annual_event_histories(source, lang = 'ja') data = annual_chart_data_from(source) + title_text = lang == 'en' ? 'Number of Events' : '開催回数の推移' LazyHighCharts::HighChart.new('graph') do |f| - f.title(text: '開催回数の推移') + f.title(text: title_text) f.xAxis(categories: data[:years]) - f.series(type: 'column', name: '開催回数', yAxis: 0, data: data[:increase_nums]) - f.series(type: 'line', name: '累積合計', yAxis: 1, data: data[:cumulative_sums]) + f.series(type: 'column', name: lang == 'en' ? 'Events' : '開催回数', yAxis: 0, data: data[:increase_nums]) + f.series(type: 'line', name: lang == 'en' ? 'Total' : '累積合計', yAxis: 1, data: data[:cumulative_sums]) f.yAxis [ - { title: { text: '開催回数' }, tickInterval: 500, max: 2000 }, - { title: { text: '累積合計' }, tickInterval: 3000, max: 12000, opposite: true } + { title: { text: lang == 'en' ? 'Events' : '開催回数' }, tickInterval: 500, max: 2000 }, + { title: { text: lang == 'en' ? 'Total' : '累積合計' }, tickInterval: 3000, max: 12000, opposite: true } ] f.chart(width: HIGH_CHARTS_WIDTH, alignTicks: false) f.colors(["#F4C34F", "#BD2561"]) end end - def build_annual_participants(source) + def build_annual_participants(source, lang = 'ja') data = annual_chart_data_from(source) + title_text = lang == 'en' ? 'Number of Participants' : '参加者数の推移' LazyHighCharts::HighChart.new('graph') do |f| - f.title(text: '参加者数の推移') + f.title(text: title_text) f.xAxis(categories: data[:years]) - f.series(type: 'column', name: '参加者数', yAxis: 0, data: data[:increase_nums]) - f.series(type: 'line', name: '累積合計', yAxis: 1, data: data[:cumulative_sums]) + f.series(type: 'column', name: lang == 'en' ? 'Participants' : '参加者数', yAxis: 0, data: data[:increase_nums]) + f.series(type: 'line', name: lang == 'en' ? 'Total' : '累積合計', yAxis: 1, data: data[:cumulative_sums]) f.yAxis [ - { title: { text: '参加者数' }, tickInterval: 2500, max: 12500 }, - { title: { text: '累積合計' }, tickInterval: 14000, max: 64000, opposite: true } + { title: { text: lang == 'en' ? 'Participants' : '参加者数' }, tickInterval: 2500, max: 12500 }, + { title: { text: lang == 'en' ? 'Total' : '累積合計' }, tickInterval: 14000, max: 64000, opposite: true } ] f.chart(width: HIGH_CHARTS_WIDTH, alignTicks: false) f.colors(["#EF685E", "#35637D"]) diff --git a/app/models/stat.rb b/app/models/stat.rb index 399633a1d..c6c88602d 100644 --- a/app/models/stat.rb +++ b/app/models/stat.rb @@ -31,17 +31,17 @@ def annual_sum_of_participants @annual_sum_of_participants = year_hash_template.merge!(hash) end - def annual_dojos_chart + def annual_dojos_chart(lang = 'ja') # MEMO: トップページの道場数と一致するように Active Dojo を集計対象としている - HighChartsBuilder.build_annual_dojos(Dojo.active.annual_count(@period)) + HighChartsBuilder.build_annual_dojos(Dojo.active.annual_count(@period), lang) end - def annual_event_histories_chart - HighChartsBuilder.build_annual_event_histories(annual_count_of_event_histories) + def annual_event_histories_chart(lang = 'ja') + HighChartsBuilder.build_annual_event_histories(annual_count_of_event_histories, lang) end - def annual_participants_chart - HighChartsBuilder.build_annual_participants(annual_sum_of_participants) + def annual_participants_chart(lang = 'ja') + HighChartsBuilder.build_annual_participants(annual_sum_of_participants, lang) end private diff --git a/app/views/stats/show.html.erb b/app/views/stats/show.html.erb index acac66cbf..2594088d6 100644 --- a/app/views/stats/show.html.erb +++ b/app/views/stats/show.html.erb @@ -1,7 +1,8 @@ -<% provide(:title, '統計情報') %> -<% provide(:desc, 'CoderDojo の統計情報をまとめたページです。全国の活動状況を把握したい場面などでご活用ください。') %> -<% provide(:url, stats_url) %> +<% provide(:title, @lang == 'en' ? 'Statistics' : '統計情報') %> +<% provide(:desc, @lang == 'en' ? 'Statistics of CoderDojo in Japan. Use this page to understand activities across the country.' : 'CoderDojo の統計情報をまとめたページです。全国の活動状況を把握したい場面などでご活用ください。') %> +<% provide(:url, @lang == 'en' ? english_stats_url : stats_url) %> <% provide(:meta_image, '/img/ogp-stats.jpeg') %> +<% provide(:lang, @lang) %> @@ -11,14 +12,25 @@
-

統計情報

+

<%= @lang == 'en' ? 'Statistics' : '統計情報' %>

- 本ページでは CoderDojo の統計情報をまとめています。
全国の活動状況を把握したい場面などでご活用ください。 + <% if @lang == 'en' %> + This page presents statistics of CoderDojo in Japan.
Use this to understand activities across the country. + <% else %> + 本ページでは CoderDojo の統計情報をまとめています。
全国の活動状況を把握したい場面などでご活用ください。 + <% end %> +
+
+ <% if @lang == 'en' %> + » Switch to Japanese + <% else %> + » View in English + <% end %>

📊 - 推移グラフ + <%= @lang == 'en' ? 'Transition Charts' : '推移グラフ' %>