TechVue.jsJapanese

vue3-charts with TypeScript – Stacked Bar Chart 編

Vue.js
This entry is part 1 of 7 in the series Vue3 / vue3-charts with TypeScript

本記事では Vue.js v3とTypeScriptを使用して、積み上げ棒グラフ (Stacked Bar Chart) を作成する方法を紹介します。 vue3-charts ライブラリ を活用し、TypeScript を有効にした Vue3 プロジェクト において、簡単に グラフ を追加する方法を ステップバイステップ で説明します。 実装にあたり必要となる エラーハンドリング から スタイリング、 インタラクティブ な要素の追加まで、実践的な アプローチ を通じて Vue3 での グラフ作成を実現していこうと思います。

本記事では 積み上げ棒グラフ (Stacked Bar Chart) に関する コンポーネント 部分についてのみ説明するため、前提となる プロジェクト の概要や シンプルな棒グラフ (Bar Chart) については、以下の記事を参考にしてください。

積み上げ棒グラフ コンポーネント 作成

[ads]

積み上げ棒グラフ (Stacked Bar Chart) を components/StackedBarChart.vue に実装してきます。Stacked Bar Chart に関しては 公式から ベースとなるコード が提供されていませんので、 Bar Chart で用いた以下のものを ベース として進めていきます。

<script lang="ts">
import { defineComponent, ref, Ref } from 'vue'
import {
    Chart,
    Grid,
    Tooltip,
    Marker as ChartMarker,
    Bar
} from 'vue3-charts'
import { Direction, ChartAxis } from 'vue3-charts/src/types'
import { plByMonth } from '@/data'

export default defineComponent({
    name: 'BarChart',
    components: { Chart, Grid, Tooltip, ChartMarker, Bar },
    setup() {
        const data = ref(plByMonth)
        const direction: Ref<Direction> = ref('horizontal')
        const margin = ref({
            left: 0,
            top: 20,
            right: 20,
            bottom: 0
        })

        const axis: Ref<ChartAxis> = ref({
            primary: {
                domain: ['dataMin', 'dataMax + 100'],
                type: 'band'    // show the every value of the data
            },
            secondary: {
                domain: ['dataMin', 'dataMax + 100'],
                type: 'linear',
                ticks: 8
            }
        })

        return { data, direction, margin, axis }
    }
})
</script>
<template>
    <Chart :size="{ width: 500, height: 420 }" :data="data" :margin="margin" :direction="direction" :axis="axis">

        <template #layers>
            <Grid strokeDasharray="2,2" />
            <Bar :dataKeys="['name', 'pl']" :barStyle="{ fill: '#FF6347' }" />
            <Bar :dataKeys="['name', 'avg']" :barStyle="{ fill: '#3CB371' }" />
            <Bar :dataKeys="['name', 'inc']" :barStyle="{ fill: '#1E90FF' }" />
            <ChartMarker :value="1200" label="Target" color="black" :strokeWidth="2" strokeDasharray="6 6" />
        </template>

        <template #widgets>
            <Tooltip borderColor="#48CAE4" :config="{
                pl: { color: '#FF6347' },
                avg: { color: '#3CB371' },
                inc: { color: '#1E90FF' }
            }" />
        </template>

    </Chart>
</template>

現状は、以下のとおり、3つのデータ系列 (pl, avg, inc) が横並びになって Jan, Feb,,, と続いています。

このグラフを以下のように、 3 つの データ系列 を縦に積み上げた形にしていきたいと思います。

積み上げを有効にする

vue3-charts では 棒グラフ (Bar), 面グラフ (Area) に関して積み上げを有効にすることができます。 具体的には Bar, Area コンポーネント に対して Provide / Inject を用いて layerProps を指定の形式で渡します。

StackedBarChart.vue

まずは provide を インポート します

import { defineComponent, ref, Ref, provide } from 'vue'

defineComponent の中で layerProps を以下のように provide します

        provide('layerProps', {
            stacked: true, // enable stacking
        });

        return { data, direction, margin, axis }

Provide / Indect については、以下の公式ドキュメントを参考にしてください。

この状態で プロジェクト を実行すると、以下のような 積み上げ棒グラフ が生成されます。

通常の 棒グラフ にも言えることですが、 凡例 が自動的に適切な値に調整される点がとても素晴らしいと思います。 次のセクションでは layerProps のもう一つの パラメータ である maxWidth を用いて 積み上げ棒グラフ の見た目を調整していきます。

積み上げ棒グラフ カスタマイズ

[ads]

積み上げ棒グラフ 幅の調整

layerProps には stacked パラメータの他に、 maxWidth パラメータが存在します。 この値は デフォルト では -1 となっていますが、この値を調整することで 棒グラフの幅を調整することができます。

StackedBarChart.vue

ここでは maxWidth として 20 を指定してみます。

        provide('layerProps', {
            stacked: true, // enable stacking
             maxWidth: 20, // set the maximum width of the bar
        })

この状態での 積み上げ棒グラフは以下のようになります。 棒グラフが細くなっていることがわかります。

積み上げ棒グラフ 横位置 (x position) の調整

先ほど作成した 細い棒グラフはよくみると、 X軸の判例とズレた位置に棒グラフが表示されています。 ここでは、少し調整して判例の位置に棒グラフが表示されるようにしてみます。

StackedBarChart.vue

以下のように 全ての Bar コンポーネント に :gap プロパティ を全て同じ値で設定します。 ここでは 40 としています。

        <template #layers>
            <Grid strokeDasharray="2,2" />
            <Bar :dataKeys="['name', 'pl']" :barStyle="{ fill: '#FF6347' }" :gap=40 />
            <Bar :dataKeys="['name', 'avg']" :barStyle="{ fill: '#3CB371' }" :gap=40 />
            <Bar :dataKeys="['name', 'inc']" :barStyle="{ fill: '#1E90FF' }" :gap=40 />
            <ChartMarker :value="1200" label="Target" color="black" :strokeWidth="2" strokeDasharray="6 6" />
        </template>

この状態での 積み上げ棒グラフ は以下のようになっています。 完全な中央とは言えませんが、 gap プロパティ を用いることで 棒グラフの左側に余白を作成することができたため、凡例の上に棒グラフが表示されるようになりました。

但し、この方法は力技のため、gap の値が表示する データ の数に依存することもあり、実際はもう少し計算ロジックを組むべきかもしれません。

まとめ

[ads]

Vue.js v3 と TypeScript で 積み上げ棒グラフ を実装する過程では、さまざまな チャレンジ がありましたが、vue3-charts ライブラリの力を借りて、美しい グラフ を作成することができました。 今回色々と パラメータ を試しましたが、プロジェクト 側では少ない コード でここまで綺麗な グラフ を作成できる vue3-charts は、素晴らしいと改めて感動しました。

積み上げを有効にするにはstacked: true とした layerPropsprovide する

[layerProps] maxWidth: 積み上げ棒グラフの最大幅を指定する

積み上げ棒グラフ の横位置 (x positon) を調整するには Bar コンポーネント の gap プロパティを活用する

Series Navigation
Ads