JavaScript Tips | 配列ユーティリティ:可視化用変換

JavaScript JavaScript
スポンサーリンク

テーマの整理:「可視化用変換」とは何か

「可視化用変換」は、生の配列データを「グラフライブラリがそのまま読める形」に整えるユーティリティのことです。 業務だと、次のような場面でよく使います。

  • 売上データを折れ線グラフ・棒グラフにしたい
  • 店舗別・担当者別の集計を円グラフにしたい
  • 時系列データをチャートライブラリ(Chart.js, ECharts など)に渡したい

ポイントは、「グラフライブラリが欲しがる形」を理解して、 そこに合わせて配列を変換することです。

基本コンセプト:「生データ → グラフ用データ構造」に変換する

典型的なグラフライブラリの入力イメージ

例えば、棒グラフ・折れ線グラフでよくある形はこんな感じです。

const chartData = {
  labels: ["2024-07-01", "2024-07-02", "2024-07-03"],
  datasets: [
    {
      label: "売上",
      data: [100, 200, 150],
    },
  ],
};
JavaScript

つまり、

  • labels に「横軸のラベル」(日付・カテゴリ名など)
  • datasets に「系列ごとの値の配列」

という構造になっていることが多いです。

可視化用変換ユーティリティは、 「オブジェクト配列」からこの形を自動で作る」ためのものだとイメージしてください。

ユーティリティ 1:単一系列の折れ線・棒グラフ用データに変換する

シナリオ

次のような売上配列があるとします。

const sales = [
  { date: "2024-07-01", amount: 100 },
  { date: "2024-07-02", amount: 200 },
  { date: "2024-07-03", amount: 150 },
];
JavaScript

これを「日付を横軸」「amount を縦軸」にしたグラフにしたい。

実装:toSingleSeriesChartData

function toSingleSeriesChartData(records, labelField, valueField, seriesLabel) {
  if (!Array.isArray(records) || records.length === 0) {
    return {
      labels: [],
      datasets: [
        {
          label: seriesLabel ?? "",
          data: [],
        },
      ],
    };
  }

  const labels = records.map((r) => String(r[labelField]));
  const data = records.map((r) => {
    const v = r[valueField];
    return typeof v === "number" ? v : null;
  });

  return {
    labels,
    datasets: [
      {
        label: seriesLabel ?? String(valueField),
        data,
      },
    ],
  };
}
JavaScript

重要ポイントの深掘り

ラベルと値を「別々の配列」にする グラフライブラリは「labels」と「data」を別々に欲しがることが多いので、 labelFieldvalueField をそれぞれ map で取り出しています。

数値でない値は null にしておく typeof v === "number" ? v : null として、 おかしな値は「欠損」として扱えるようにしています。 多くのライブラリは null を「その点は描画しない」として扱ってくれます。

空配列への対応を決めておく records が空のときも、必ず { labels: [], datasets: [...] } を返すようにしておくと、 呼び出し側で「null チェック」をしなくて済みます。

例題 1:売上配列を折れ線グラフ用に変換する

const sales = [
  { date: "2024-07-01", amount: 100 },
  { date: "2024-07-02", amount: 200 },
  { date: "2024-07-03", amount: 150 },
];

const chartData = toSingleSeriesChartData(sales, "date", "amount", "売上");

console.log(JSON.stringify(chartData, null, 2));
JavaScript

出力イメージはこうなります。

{
  "labels": ["2024-07-01", "2024-07-02", "2024-07-03"],
  "datasets": [
    {
      "label": "売上",
      "data": [100, 200, 150]
    }
  ]
}
JavaScript

このまま Chart.js や ECharts に渡せば、 「日別売上の折れ線グラフ・棒グラフ」が描画できます。

ユーティリティ 2:カテゴリ別の円グラフ用データに変換する

シナリオ

次のような店舗別売上配列があるとします。

const sales = [
  { store: "A", amount: 100 },
  { store: "A", amount: 200 },
  { store: "B", amount: 150 },
];
JavaScript

これを「店舗別の合計売上」を円グラフにしたい。

店舗別に集計するヘルパー

function groupSum(records, groupField, valueField) {
  const map = new Map();

  records.forEach((r) => {
    const key = String(r[groupField]);
    const v = r[valueField];
    if (typeof v !== "number" || Number.isNaN(v)) return;

    const current = map.get(key) ?? 0;
    map.set(key, current + v);
  });

  return map;
}
JavaScript

実装:toPieChartData

function toPieChartData(records, groupField, valueField) {
  if (!Array.isArray(records) || records.length === 0) {
    return { labels: [], data: [] };
  }

  const map = groupSum(records, groupField, valueField);

  const labels = [];
  const data = [];

  map.forEach((sum, key) => {
    labels.push(key);
    data.push(sum);
  });

  return { labels, data };
}
JavaScript

重要ポイントの深掘り

まず「カテゴリ別に合計」を作る 円グラフは「カテゴリごとの割合」を描くので、 まず groupSum で「店舗ごとの合計」を作っています。

円グラフ用の形はシンプルにする 多くのライブラリは、 labels(カテゴリ名)と data(値)だけで円グラフを描けるので、 { labels, data } というシンプルな形にしています。

例題 2:店舗別売上を円グラフ用に変換する

const sales = [
  { store: "A", amount: 100 },
  { store: "A", amount: 200 },
  { store: "B", amount: 150 },
];

const pieData = toPieChartData(sales, "store", "amount");

console.log(pieData);
JavaScript

出力イメージはこうなります。

{
  labels: ["A", "B"],
  data: [300, 150]
}
JavaScript

この形をそのまま円グラフに渡せば、 「店舗 A が 300、店舗 B が 150」という割合が可視化できます。

ユーティリティ 3:時系列チャート用に「ソート+欠損補完」してから変換する

シナリオ

日付順がバラバラな配列を、 「日付順に並べて」「欠損日を 0 で補完して」からグラフにしたい。

日付ソート+欠損補完のヘルパー

function sortByDate(records, dateField) {
  return [...records].sort(
    (a, b) => new Date(a[dateField]) - new Date(b[dateField])
  );
}
JavaScript

欠損補完は、以前の「欠損補完」ユーティリティと組み合わせてもいいです。 ここではシンプルに「そのままソートだけ」してから可視化用変換します。

実装:toTimeSeriesChartData

function toTimeSeriesChartData(records, dateField, valueField, seriesLabel) {
  const sorted = sortByDate(records, dateField);
  return toSingleSeriesChartData(sorted, dateField, valueField, seriesLabel);
}
JavaScript

重要ポイントの深掘り

「グラフに渡す前に並びを整える」 時系列グラフは「順番」が命なので、 可視化用変換の前に必ずソートしておくと安心です。

既存ユーティリティを組み合わせる toSingleSeriesChartData を再利用して、 「時系列専用ユーティリティ」を薄く作っています。 こういう“組み合わせ方”を覚えると、コードがどんどん整理されていきます。

ユーティリティ 4:可視化用変換の「インターフェース」を決めておく

シナリオ

プロジェクトのあちこちでグラフを描く。 毎回「labels と data をどう作るか」を考えるのはしんどい。

可視化用変換モジュールのイメージ

例えば、こんな感じでまとめておくと使いやすいです。

export const ChartTransform = {
  singleSeries: toSingleSeriesChartData,
  pie: toPieChartData,
  timeSeries: toTimeSeriesChartData,
};
JavaScript

使う側はこう書くだけになります。

const chartData = ChartTransform.singleSeries(sales, "date", "amount", "売上");
const pieData   = ChartTransform.pie(sales, "store", "amount");
JavaScript

ここでのポイントは、

  • 「グラフ用の形を作る処理」を一箇所に閉じ込めている
  • 画面側のコードは「どのフィールドを軸にするか」だけを意識すればよい

という状態を作っていることです。

可視化用変換ユーティリティで意識してほしい重要ポイント

「グラフライブラリが欲しがる形」を先に知る

可視化用変換を書くときは、 「使うグラフライブラリの入力形式」を先に確認するのが大事です。

  • Chart.js なら labelsdatasets
  • ECharts なら xAxis.dataseries.data
  • D3 ならもう少し自由度が高い

これを知ったうえで、「そこに合わせて配列を変換する」ユーティリティを作ると、 画面側のコードがすっきりします。

「生データを直接グラフに渡さない」癖をつける

生データには、

  • 並びがバラバラ
  • 型がバラバラ
  • 欠損が混ざっている

など、グラフにそのまま渡すと事故る要素がたくさんあります。

可視化用変換ユーティリティを必ず通すことで、

  • 並びを整える
  • 型を揃える
  • 欠損を扱える形にする

という前処理を自動化できます。

手を動かして「可視化用変換」の感覚をつかむ

次のコードを実行して、

  • 単一系列グラフ
  • 円グラフ
  • 時系列グラフ

の 3 パターンの変換を体感してみてください。

function toSingleSeriesChartData(records, labelField, valueField, seriesLabel) {
  if (!Array.isArray(records) || records.length === 0) {
    return {
      labels: [],
      datasets: [{ label: seriesLabel ?? "", data: [] }],
    };
  }

  const labels = records.map((r) => String(r[labelField]));
  const data = records.map((r) => {
    const v = r[valueField];
    return typeof v === "number" ? v : null;
  });

  return {
    labels,
    datasets: [
      {
        label: seriesLabel ?? String(valueField),
        data,
      },
    ],
  };
}

function groupSum(records, groupField, valueField) {
  const map = new Map();
  records.forEach((r) => {
    const key = String(r[groupField]);
    const v = r[valueField];
    if (typeof v !== "number" || Number.isNaN(v)) return;
    const current = map.get(key) ?? 0;
    map.set(key, current + v);
  });
  return map;
}

function toPieChartData(records, groupField, valueField) {
  if (!Array.isArray(records) || records.length === 0) {
    return { labels: [], data: [] };
  }
  const map = groupSum(records, groupField, valueField);
  const labels = [];
  const data = [];
  map.forEach((sum, key) => {
    labels.push(key);
    data.push(sum);
  });
  return { labels, data };
}

function sortByDate(records, dateField) {
  return [...records].sort(
    (a, b) => new Date(a[dateField]) - new Date(b[dateField])
  );
}

function toTimeSeriesChartData(records, dateField, valueField, seriesLabel) {
  const sorted = sortByDate(records, dateField);
  return toSingleSeriesChartData(sorted, dateField, valueField, seriesLabel);
}

function demo() {
  const sales = [
    { date: "2024-07-02", store: "A", amount: 200 },
    { date: "2024-07-01", store: "A", amount: 100 },
    { date: "2024-07-03", store: "B", amount: 150 },
  ];

  console.log("=== singleSeries ===");
  console.log(JSON.stringify(toSingleSeriesChartData(sales, "date", "amount", "売上"), null, 2));

  console.log("=== pie ===");
  console.log(JSON.stringify(toPieChartData(sales, "store", "amount"), null, 2));

  console.log("=== timeSeries ===");
  console.log(JSON.stringify(toTimeSeriesChartData(sales, "date", "amount", "売上"), null, 2));
}

demo();
JavaScript

まとめ:可視化用変換ユーティリティで「配列を、そのままグラフに載せられる形にする」

可視化用変換は、 「生の配列データを、グラフライブラリがそのまま読める形に整えるためのユーティリティ」です。

プロジェクトでは、例えばこうまとめておくと扱いやすいです。

export const ChartTransform = {
  singleSeries: toSingleSeriesChartData,
  pie: toPieChartData,
  timeSeries: toTimeSeriesChartData,
};
JavaScript

そして、

  • ダッシュボード
  • レポート画面
  • モニタリング画面

など、「グラフを描く前」に必ずこの変換を通す。

そうすると、 「配列をどうグラフに渡すか」で悩む時間が減って、 「何を可視化したいか」に集中できるようになります。

データを“見える形”に変える、その橋渡しが可視化用変換ユーティリティです。

タイトルとURLをコピーしました