🦔

Nuxt.jsでWebアプリケーション開発メモ30

に公開

概要

雑多な機能改善、見た目改善。

プロンプト30

- ヘッダのアプリタイトルを`Training Logger`に修正して。
- ヘッダのユーザーメニューの一番上に、ログイン中ユーザーの名前を`ニックネーム(ユーザー名)`形式で表示して。(ニックネームが空白ならユーザー名のみ。)
- ユーザー名の下にセパレータを追加して、既存のメニューを表示するようにして。
- ユーザーメニューの`パスワード変更`の上に`ダッシュボード`メニューを追加して、ダッシュボード画面(topページ)に遷移できるようにして。
- `<!-- 統計・グラフエリア -->`のヘッダに`統計・グラフ`というタイトルを追加して。追加したタイトルの右側に少しスペース空けて、既存のボタン群が表示されるようにしてください。
- `統計・グラフ`のボタンに`今年`を追加して、選択したら今年のグラフとサマリーが表示されるようにして。ボタンの位置は`今月`の右隣で。
- `体重・体脂肪率推移チャート`、と`消費カロリー推移`について、以下の修正を実施して。
    - タイトルと同じヘッダ領域の右端に`広く表示`というリンクっぽいボタンを追加。
    - `広く表示`をクリックすると、グラフは横スクロールありのグラフに。ボタンは、`標準表示`に変更し、`標準表示`をクリックすると、横スクロールなしの表示に戻してください。
    - デフォルトでは横スクロールなしの表示にしてください。
    - `標準表示`、`広く表示`ボタンはデータロード中disabledになるようにして。

対応内容

  • アプリタイトルをTraining Loggerにした。
  • ユーザーメニューにログイン中ユーザー名表示。
  • ユーザーメニューにダッシュボードメニュー追加。
  • 右側ガジェットのタイトルを統計・グラフにした。
  • 統計・グラフ今年ボタン追加。(今年分の統計グラフ情報に切替える。)
  • 推移グラフのワイド表示機能追加。

画面

ソース差分

https://github.com/tkure/prototype-frontend/commit/1516e0f88254a3fdbc885225825d3ab6a76cfd23

グラフ(vue-chart)の横スクロール付け方

  • チャート要素(独自components<TrainingChart>)の上に<div>タグ付けてwidthを広めにとってやることで横スクロールが自動で付与された。
  • vue-chartのresponsive設定は変更なし。(デフォルトTrueのまま運用。)
  • 当初responsiveを指定する方法を採っていたが、チャート要素全体がスクロールする形で意図した動きにならなかった。
  • 以下、Claude Codeによる横スクロール実装について、resonsiveが不要だった件についての回答。
  現在の実装では:
  - 標準表示:responsive: true(デフォルト)でレスポンシブ表示
  - 広く表示:同じresponsive: true設定で、コンテナサイズを動的に変更して横スクロール実現

  当初試した responsive: false は不要だった理由:
  1. Chart.jsのresponsive: falseはチャート自体を固定サイズにするが、コンテナの横スクロールとは相性が悪い
  2. 代わりにHTMLコンテナの幅を動的に変更する方法で、Chart.jsはresponsive: trueのまま適切に描画される
  3. 横スクロールは外側のCSSで制御し、Chart.js自体はレスポンシブのまま動作

  つまり、Chart.jsオプションではなく、HTMLコンテナの動的サイズ変更で横スクロール機能を実現したため、responsive設定の変更は不要でした。

参考コード

pages/top.vue
@@ -174,7 +174,17 @@
             <!-- 体重・体脂肪推移グラフ -->
             <BaseCard>
               <template #header>
-                <h2 class="text-sm font-semibold">⚖️ 体重・体脂肪率推移</h2>
+                <div class="flex items-center justify-between">
+                  <h2 class="text-sm font-semibold">⚖️ 体重・体脂肪率推移</h2>
+                  <UButton
+                    size="xs"
+                    variant="ghost"
+                    :label="isWideWeightChart ? '標準表示' : '広く表示'"
+                    @click="isWideWeightChart = !isWideWeightChart"
+                    :disabled="chartLoading"
+                    class="text-blue-600 hover:text-blue-800"
+                  />
+                </div>
               </template>
               
               <!-- チャートローディング中 -->
@@ -186,13 +196,30 @@
               </div>
               
               <!-- チャート表示 -->
-              <div v-else-if="weightChartData.labels && weightChartData.labels.length > 0" class="h-48">
-                <TrainingChart
-                  type="line"
-                  :data="weightChartData"
-                  :options="weightChartOptions"
-                  :height="192"
-                />
+              <div v-else-if="weightChartData.labels && weightChartData.labels.length > 0" 
+                   :class="isWideWeightChart ? 'overflow-x-auto overflow-y-hidden' : 'h-48'"
+                   :style="isWideWeightChart ? { height: '210px' } : {}">
+                <div v-if="isWideWeightChart"
+                     :style="{ 
+                       minWidth: '800px',
+                       width: `${Math.max(800, (weightChartData.labels?.length || 0) * 10 + 200)}px`,
+                       height: '192px'
+                     }">
+                  <TrainingChart
+                    type="line"
+                    :data="weightChartData"
+                    :options="weightChartOptions"
+                    :height="192"
+                  />
+                </div>
+                <div v-else>
+                  <TrainingChart
+                    type="line"
+                    :data="weightChartData"
+                    :options="weightChartOptions"
+                    :height="192"
+                  />
+                </div>
               </div>

→ Nuxt.jsでWebアプリケーション開発メモ31

Discussion