0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

ZENITH Code実践⑦ PCとスマホで使いやすい分析画面に整える

0
Posted at

分析画面は、数字が正しいだけでは使い続けられません。暗い部屋では白い画面がまぶしく、スマホでは4列のカードが窮屈で、毎回同じ設定をし直すのは面倒です。

今回は、企業分析画面の見た目と操作を整える部分を読みます。テーマの切り替え、画面幅に応じた並び替え、グラフの描き直し、表示設定の保存の4つです。最後に、自分用のテーマを1つ追加します。

スマホ幅390pxでダークテーマにした企業分析画面。数値カードが2列、業績の推移グラフが1列で並ぶ。企業名と数値は架空のサンプル

画面の企業と数値は架空のサンプルです。 実企業のデータへの切り替えは次回の実践⑧で扱います。

私たち株式会社Crabgrassは、企業の財務データなどをAPIで提供するZENITH Codeを開発しています。本記事は自社サービスのデータを使うためのテンプレートを題材にした実装例です。

この記事のコードは、公開サンプル集のcompany-analysisテンプレート(執筆時点の版)に対応しています。起動方法は実践④の「ローカルで開く準備」と同じです。前回の実践⑥では、決算期の選択と前期比を読みました。

1. 今回扱う画面と操作

操作 画面で変わるもの 今回読むコード
右上の「表示をカスタマイズ」を押す テーマと表示項目の設定画面 index.html の #preferences
テーマを「ダーク」にする 背景・文字・グラフの色 setTheme() と style.css の色の変数
ブラウザの幅を狭くする カードの列数、グラフの並び style.css の @media
設定を変えて再読み込みする 前回の設定のまま開く localStorage への保存と読み込み

表示をカスタマイズの画面。クール・ポップ・ダークのテーマ、企業比較を表示・各カードにAPIの説明を表示・コンパクト表示のチェック、表示設定だけをこのブラウザに保存する旨の注記

2. テーマは色の変数を入れ替える

テーマを切り替える処理は、body に印を付けるだけです。

function setTheme(theme) {
  document.body.dataset.theme = theme;
  document
    .querySelectorAll("[data-theme-choice]")
    .forEach((button) =>
      button.setAttribute(
        "aria-pressed",
        String(button.dataset.themeChoice === theme),
      ),
    );
  // Layout widths change between themes; redraw using the existing snapshot.
  if (current) {
    chart("barChart", $("metric").value);
    chart("marginChart", "operatingMargin", true);
  }
}

document.body.dataset.theme = "dark" とすると、HTMLの <body> に data-theme="dark" が付きます。色を変える仕事は、CSSの側にあります。次は style.css の抜粋です。

:root {
  color-scheme: light;
  --navy: #0b1326;
  --ink: #17263e;
  --muted: #617187;
  --line: #e1e8ef;
  --accent: #087d98;
  --surface: #f4f7fa;
}
body[data-theme="dark"] {
  color-scheme: dark;
  --ink: #f1f5fa;
  --muted: #b7c1cf;
  --accent: #c4f36b;
  --surface: #0e131a;
  --line: #39475a;
}

--ink や --accent は、CSSの変数(カスタムプロパティ)です。画面のあちこちでは color: var(--ink) のように変数を使っているので、テーマごとに変数の値を入れ替えるだけで、全体の色が変わります。部品ごとにダーク用の色を書き足す必要はありません。

ダークテーマは、明るいテーマの色を反転して作っているわけではありません。style.css のコメントにあるとおり、数値のラベルや出典の文字が、どのカードの上でも読めるように色を選び直しています。color-scheme: dark は、スクロールバーやプルダウンなど、ブラウザが描く部品も暗い色にする指定です。

グラフも描き直す

setTheme() の最後で、グラフを描き直しています。グラフはSVGで、chart() が描くときの枠の幅から棒の位置を計算しています。

const w = Math.max(300, Math.min(line ? 410 : 580, box.clientWidth - 32)),

テーマによってカードの枠線や余白が違い、グラフを置く枠の幅も少し変わります。そのため、色を変えたあとに今の幅で描き直します。データを取り直すわけではなく、すでにある current を使います。

3. 画面幅に応じて並びを変える

style.css には、画面幅で並びを変える @media が3段階あります。

画面幅 主な変化
1150px以下 左のメニューを細くし、余白と数値カードの文字を少し小さくする
900px以下 左のメニューを隠し、2つのグラフを同じ幅で並べる(広い画面では1.5対1)
620px以下 カードを2列、グラフを1列にし、余白を詰める

620px以下の設定の一部です。

@media (max-width: 620px) {
  .kpis {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
  .charts {
    grid-template-columns: 1fr;
  }
}

minmax(0, 1fr) の 0 は、中の数字が長くても列の幅を押し広げないための指定です。1fr だけだと、桁の多い金額が入ったカードの列が広がり、2列の幅がそろわなくなることがあります。

グラフは画面幅が変わるたびに描き直す

CSSで枠の幅が変わっても、SVGの中の棒の位置は自動では変わりません。そこで、ブラウザの幅が変わったときにもグラフを描き直しています。

window.addEventListener("resize", () => {
  if (current) {
    chart("barChart", $("metric").value);
    chart("marginChart", "operatingMargin", true);
  }
});

画面全体を縮小表示するのではなく、その幅に合わせてグラフを作り直します。スマホでも目盛りの文字が小さくなりすぎないのはこのためです。

財務表は表の中だけ横に動かす

3期分の金額を円で並べる財務表は、スマホの幅に収まりません。表を .table-scroll で囲み、その中だけを横にスクロールできるようにしています。

.table-scroll {
  overflow-x: auto;
}
table {
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

white-space: nowrap で金額が途中で折り返されないようにし、font-variant-numeric: tabular-nums で数字の幅をそろえています。数字の幅がそろうと、縦に並んだ金額の桁が一致して、大小を比べやすくなります。

620px以下では、表の1列目(項目名)を position: sticky で左に固定しています。横にスクロールしても、どの行が売上高かを見失いません。

スマホの入力欄は16px

.field select,.field input{font-size:16px}

iPhoneのSafariは、文字が16pxより小さい入力欄を選ぶと、画面を自動で拡大します。証券コードを入れるたびに拡大されると、そのあとの操作がしにくくなるので、スマホ幅の入力欄だけ16pxにしています。

4. 表示設定を保存する

テーマとチェックの状態は、ブラウザの localStorage に保存します。

const save=()=>{try{localStorage.setItem("zenith-research-display",JSON.stringify({theme:document.body.dataset.theme,comparison:$("showComparison").checked,help:$("showHelp").checked,compact:$("compactView").checked}));}catch{/* Storage may be unavailable in private mode. */}};

保存するのは、テーマと3つのチェックの状態だけです。企業のデータ、選んだ企業、APIキーは保存しません。設定画面の下にも「表示設定だけをこのブラウザに保存します。企業データやAPIキーは保存しません。」と書いています。

try で囲んでいるのは、ブラウザのプライベートモードなどで localStorage が使えないことがあるためです。保存できなくても、画面はそのまま使えます。

読み込むときは、保存された値をそのまま信じずに確かめます。

try{const pref=JSON.parse(localStorage.getItem("zenith-research-display")||"null");if(pref){if(["cool","pop","dark"].includes(pref.theme))setTheme(pref.theme);for(const [id,key]of [["showComparison","comparison"],["showHelp","help"],["compactView","compact"]])if(typeof pref[key]==="boolean")$(id).checked=pref[key];}}catch{/* Use defaults when saved preferences are invalid. */}

テーマは3つの名前のどれかのときだけ使い、チェックは true か false のときだけ反映します。古い版で保存した設定や、壊れた値が残っていても、既定の表示で開けるようにするためです。

5. コンパクト表示

「コンパクト表示」にチェックを入れると、body に compact が付き、余白とグラフの高さを詰めます。

.compact .kpi{padding:14px 18px}
.compact .chart svg{max-height:175px}
.compact th,.compact td{padding-top:8px;padding-bottom:8px}

文字の大きさは変えていません。ノートPCの小さな画面でも、スクロールせずに数値カードとグラフを一度に見られるようにするための設定です。

6. 自分用のテーマを1つ追加する

ここまでの仕組みを使って、4つ目のテーマ「ウォーム」を追加します。変更する場所は4つです。

1. ボタンを足す(index.html)。ダークのボタンの後ろに足します。

<button type="button" data-theme-choice="warm" aria-pressed="false">
  <span class="swatch warm" aria-hidden="true"></span
  ><span data-i18n="warm"></span
  ><small data-i18n="warmNote"></small>
</button>

2. 色の変数を足す(style.css の末尾)。

body[data-theme="warm"] {
  --navy: #3a2a1f;
  --ink: #2f241c;
  --muted: #7a6656;
  --accent: #b5562b;
  --bar-soft: #f1c7a8;
  --surface: #fbf6f0;
  --line: #eadccd;
}
.swatch.warm {
  background: linear-gradient(135deg, #3a2a1f 50%, #b5562b 50%);
}

3. ボタンの文字を足す(app.mjs の texts)。ja と en の両方に足します。

warm: "ウォーム",
warmNote: "紙の資料に近い色",
warm: "Warm",
warmNote: "Close to printed reports",

4. 保存した設定の確認に名前を足す(app.mjs)。

if(["cool","pop","dark","warm"].includes(pref.theme))setTheme(pref.theme);

4つ目を忘れると、ウォームを選んだあとに再読み込みしたとき、クールに戻ってしまいます。保存はできているのに、読み込むときの確認で弾かれるためです。

保存してブラウザを再読み込みし、「表示をカスタマイズ」でウォームを選びます。背景と文字、グラフの色が変わり、再読み込みしてもウォームのまま開けば完成です。

直近終値のカードは、どのテーマでも目立つように別の色を指定しています。ウォームでも色を変えたい場合は、style.css で .kpi.price の指定を探してください。

7. 確認箇所

症状 確認箇所
テーマを変えても一部の色が変わらない その部品が var(--ink) などの変数ではなく、色を直接書いていないか
再読み込みするとテーマが戻る 読み込み時の確認の配列に名前を足したか
幅を変えるとグラフがはみ出す resize で描き直しているか
スマホで入力欄を選ぶと拡大される 入力欄の文字が16px以上か
表の金額が途中で折り返される white-space: nowrap が効いているか
設定が保存されない プライベートモードではないか。保存できなくても画面は動く仕様

見た目の変更をAIに頼む場合も、データや計算に触れないことを明記すると、確認する範囲を絞れます。

company-analysisテンプレートに、4つ目のテーマ「warm」を追加してください。

index.html のテーマのボタン、style.css の body[data-theme="warm"] の色の変数、
app.mjs の texts(ja と en)、保存した設定を読み込むときのテーマ名の確認、の4か所を変更します。
既存の3つのテーマの色は変えないでください。
グラフの計算、JSON、APIの呼び出しは変更しないでください。
文字と背景の色の差が十分あるかも確認し、変更箇所と確認する操作を説明してください。

8. 次回は実データにつなぐ

ここまでの4回は、架空の2社で画面の仕組みを読んできました。次回のZENITH Code実践⑧では、ZENITH CodeのAPIキーを使って、実在する企業のデータをこの画面に表示します。APIキーをブラウザに渡さない仕組みや、取得に失敗したときの表示も読みます。

ZENITH Code — 日本企業の財務データを、APIで。サービスサイトを見る

ZENITH Codeを見る · APIドキュメント

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?