🦔
Nuxt.jsでWebアプリケーション開発メモ30
概要
雑多な機能改善、見た目改善。
プロンプト30
- ヘッダのアプリタイトルを`Training Logger`に修正して。
- ヘッダのユーザーメニューの一番上に、ログイン中ユーザーの名前を`ニックネーム(ユーザー名)`形式で表示して。(ニックネームが空白ならユーザー名のみ。)
- ユーザー名の下にセパレータを追加して、既存のメニューを表示するようにして。
- ユーザーメニューの`パスワード変更`の上に`ダッシュボード`メニューを追加して、ダッシュボード画面(topページ)に遷移できるようにして。
- `<!-- 統計・グラフエリア -->`のヘッダに`統計・グラフ`というタイトルを追加して。追加したタイトルの右側に少しスペース空けて、既存のボタン群が表示されるようにしてください。
- `統計・グラフ`のボタンに`今年`を追加して、選択したら今年のグラフとサマリーが表示されるようにして。ボタンの位置は`今月`の右隣で。
- `体重・体脂肪率推移チャート`、と`消費カロリー推移`について、以下の修正を実施して。
- タイトルと同じヘッダ領域の右端に`広く表示`というリンクっぽいボタンを追加。
- `広く表示`をクリックすると、グラフは横スクロールありのグラフに。ボタンは、`標準表示`に変更し、`標準表示`をクリックすると、横スクロールなしの表示に戻してください。
- デフォルトでは横スクロールなしの表示にしてください。
- `標準表示`、`広く表示`ボタンはデータロード中disabledになるようにして。
対応内容
- アプリタイトルを
Training Logger
にした。 - ユーザーメニューにログイン中ユーザー名表示。
- ユーザーメニューに
ダッシュボード
メニュー追加。 - 右側ガジェットのタイトルを
統計・グラフ
にした。 -
統計・グラフ
に今年
ボタン追加。(今年分の統計グラフ情報に切替える。) - 推移グラフのワイド表示機能追加。
画面
ソース差分
グラフ(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>
Discussion