TechVue.jsJapanese

vue3-charts with TypeScript – Bar Chart 編

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

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

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

棒グラフ コンポーネント 作成

[ads]

棒グラフ (Bar Chart) を components/BarChart.vue に実装していきます。 ベース となる コード は 公式サイト で提供されていますので、それを活用していきます。

<scirpt><template> の順番だけ、Vue3 with TypeScript のお作法に従って修正した コンポーネント は以下の通りです。

<script lang="ts">
import { defineComponent, ref } from 'vue'
import { Chart, Grid, Line } from 'vue3-charts'
import { plByMonth } from '@/data'

export default defineComponent({
    name: 'LineChart',
    components: { Chart, Grid, Line },
    setup() {
        const data = ref(plByMonth)
        const direction = ref('horizontal')
        const margin = ref({
            left: 0,
            top: 20,
            right: 20,
            bottom: 0
        })

        const axis = ref({
            primary: {
                type: 'band'
            },
            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: '#90e0ef' }" />
            <Bar :dataKeys="['name', 'avg']" :barStyle="{ fill: '#0096c7' }" />
            <Bar :dataKeys="['name', 'inc']" :barStyle="{ fill: '#48cae4' }" />
            <Marker :value="1000" label="Avg." color="#e76f51" strokeWidth="2" strokeDasharray="6 6" />
        </template>

        <template #widgets>
            <Tooltip borderColor="#48CAE4" :config="{
                pl: { color: '#90e0ef' },
                avg: { color: '#0096c7' },
                inc: { color: '#48cae4' }
            }" />
        </template>

    </Chart>
</template>

但し、このままでは棒グラフを表示できません。 次の セクション 以降で、この ベースとなるコード を修正して TypeScript 環境でも動作するようにしていきます。

BarChart.vue エラー 対処

まず最初に対処していくのは 正しく components を登録していくところです。 公式のコードでは Line コンポーネント を登録していますが、 ここでは Bar コンポーネント を登録する必要があります。

Bar component の登録

defineComponent 部分で components を登録しますが、 Bar ではなく Line を登録してしまっているので、ここを修正します。 あわせて nameBarChart に修正しておきます。

BarChart.vue
import { Chart, Grid, Bar } from 'vue3-charts'
export default defineComponent({
    name: 'BarChart',
    components: { Chart, Grid, Bar },

error TS2322 対応

続いて対処するのは TS2322 という TypeScript のエラーになります。 エラー の概要は「型がきちんと一致していない値を代入しようとしている」 というような内容です。

いくつかの箇所でこの エラー が出力されます。例えば以下のようなところです。 Chart コンポーネント の プロパティ :direction への設定部分で問題が発生しています。

BarChart.vue
<template>
    <Chart :size="{ width: 500, height: 420 }" :data="data" :margin="margin" :direction="direction" :axis="axis">

LineChart.vue でも同様のエラーが発生していましたので、この BarChart.vue でも同様に対処していきます。、Chart コンポーネント の direction プロパティ に正しく値を設定するために Ref を用いて Direction 型として設定することでこの エラー に対処していきます。
詳細は、LineChart.vue 作成記事 を参照してください。

なお、 direction 以外に axis でも同様の TS2322 エラー が出ていますので ChartAxis 型を用いて値を設定するように修正していきます。

BarChart.vue

必要な import を追加します。

import { defineComponent, ref, Ref } from 'vue'
import { Chart, Grid, Bar } from 'vue3-charts'
import { Direction, ChartAxis } from 'vue3-charts/src/types'

direction の型を Direction にします。

    setup() {
        const data = ref(plByMonth)
        const direction: Ref<Direction> = ref('horizontal')

axis の型を ChartAxis にします。

        const axis: Ref<ChartAxis> = ref({

ChartAxis 型に必要な情報の補完

次に axis に設定する値について修正していきます。 LineChart.vue でも同様の問題が発生していたので、同様に修正していきます。具体的には primarydomain に値を設定していきます。

BarChart.vue
        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
            }
        })

ここまでで プロジェクト の ビルド は成功し、以下のような 棒グラフ が表示されるようになります。 画面上部の Bar Chart リンク を忘れずにクリックして デフォルトの 折れ線グラフから画面を切り替えてください。

次の セクション では、この 棒グラフに インタラクティブ な ツールチップ や 目安を表示することができる マーカー を追加していきます。

Tooltip, Marker サブコンポーネント 追加

[ads]

vue3-charts には Tooltip, Marker という サブコンポーネント が備わっていて、これを用いることでさらに グラフ の表現力が高まります。

コンポーネント説明
Tooltipデータポイント上にマウスを合わせると、実際の値を表示することができる
Markerグラフのデータとは別の系列で線を引くことができる
Sub component of vue3-charts

コンポーネント インポート

以下のように TooltipMarker を インポートしていきます。 なお、 Marker コンポーネント は 予約済みの名前と バッティング してしまうため、 ChartMarker として インポート していきます。

BarChart.vue

Tooltip, Marker を インポートします。

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'

components に登録します。 ChartMarker という名称で登録している点に注意してください。

export default defineComponent({
    name: 'BarChart',
    components: { Chart, Grid, Tooltip, ChartMarker, Bar },

テンプレート に ChartMarker を追加します。 既存の コード では Marker という名称であったり、 strokeWidth に必要な セミコロン がないなどがありますので、注意してください。

        <template #layers>
            <Grid strokeDasharray="2,2" />
            <Bar :dataKeys="['name', 'pl']" :barStyle="{ fill: '#90e0ef' }" />
            <Bar :dataKeys="['name', 'avg']" :barStyle="{ fill: '#0096c7' }" />
            <Bar :dataKeys="['name', 'inc']" :barStyle="{ fill: '#48cae4' }" />
            <ChartMarker :value="1000" label="Avg." color="#e76f51" :strokeWidth="2" strokeDasharray="6 6" />
        </template>

この状態で プロジェクト を 実行すると、以下のように ChartMarker が 赤点線 が追加されていることがわかります。

また、グラフにマウスカーソルを合わせると ツールチップ が表示されていることが確認できます。

バリエーション を試してみる

Bar コンポーネント の理解を深める意味で、少し色々な バリエーション を試してみます。

BarChart.vue

barStyle プロパティ に opacity を追加して透明度を変更したり、 :gap, :max-width プロパティを追加して、棒グラフの 幅を変更しています。 また、データの系列を色分けし、他のグラフとの比較を容易にします。

        <template #layers>
            <Grid strokeDasharray="2,2" />
                <Bar :dataKeys="['name', 'pl']" :barStyle="{ fill: '#FF6347', opacity: 0.3 }" />
                <Bar :dataKeys="['name', 'avg']" :barStyle="{ fill: '#3CB371' }" :gap=10 :max-width=10 />
                <Bar :dataKeys="['name', 'inc']" :barStyle="{ fill: '#1E90FF' }" :gap=1 :max-width=30 />
                <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>

:gap は 各棒グラフ間の間隔を指定し、 :max-width は 棒グラフの最大幅を指定します。 この辺りは、 バンドスケール などやや複雑な ロジック になっていますので、実際に色々と試してみるのがよいと思います。

上記修正後の 棒グラフ は以下のようになります。

最終的な BarChart.vue コンポーネント の コード は以下のようになっています。

BarChart.vue
<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', opacity: 0.3 }" />
                <Bar :dataKeys="['name', 'avg']" :barStyle="{ fill: '#3CB371' }" :gap=10 :max-width=10 />
                <Bar :dataKeys="['name', 'inc']" :barStyle="{ fill: '#1E90FF' }" :gap=1 :max-width=30 />
                <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>

まとめ

[ads]

Vue3 と TypeScript での棒グラフ作成における解説はここまでです。vue3-charts を用いた棒グラフの実装から、エラー対処、カスタマイズ、そしてインタラクティブな要素の追加まで、さまざまな技術を探求してきました。これらの知識を活用し、あなたのプロジェクトに魅力的なビジュアルを加えてみてください。

TypeScript に対応するために、 TS2322 への対処が必要

Tooltip, Marker コンポーネント を活用することで より インタラクティブ な グラフ に

barStyle プロパティ や gap, max-width プロパティ を調整することで 棒グラフ の見た目を調整することが可能

Series Navigation
Ads