Chart.jsでクリック位置に値をセットする方法

技術備忘録

アンケートなどで値を得たいときに、直接グラフ上をクリックさせた方がより直観的な入力が実現できるケースがあると思います。こちらをreact-chartjs-2で実装します。

【2021年10月追記】Chart.js3.x系での実装はこちら

具体的にはチャートのoptions内のonHoverでグラフ上にカーソルが行った時のマウスイベントを取得し、クリックイベント時の座標を取得してセットするという流れです。

import React, { createRef } from 'react';
import { Bar } from 'react-chartjs-2';

function ChartInput(props){
    const chartReference = createRef()
    const options = () => {
        let linesOn = false
        return {
            scales: {
                xAxes: [{
                    labels: props.labels// ['data1']
                }],
                yAxes: [{
                    ticks: {
                        max: 100,
                        min: 0,
                        stepSize: 100,
                        beginAtZero: true
                    },
                }]
            },
            onClick: function(evt) {
                let chartInstance = chartReference.current.chartInstance
                let x, y, dataIndex;
                x = chartInstance.scales["x-axis-0"].getValueForPixel(evt.clientX-chartInstance.canvas.getBoundingClientRect().left)
                y = chartInstance.scales["y-axis-0"].getValueForPixel(evt.clientY-chartInstance.canvas.getBoundingClientRect().top)
                if (x>=0 && x<props.labels.length){
                    dataIndex = 0
                    y = Math.floor(y)
                    y = y > chartInstance.scales["y-axis-0"].max ? chartInstance.scales["y-axis-0"].max : y
                    y = y < chartInstance.scales["y-axis-0"].min ? chartInstance.scales["y-axis-0"].min : y
                    // chartInstanceを直接編集(propsを直接いじるのでも可)
                    chartInstance.data.datasets[dataIndex].data[x] = y
                    chartInstance.update()
                    props.setNewData(y) // 親側でpropsを変更させたり
                }
            },
            responsive: true,
            maintainAspectRatio: false
        }
    }
    const data = () => {
        return {
            datasets: [{
                type: 'bar',
                label: 'data1',
                data: props.data, // [10]
                backgroundColor: 'rgba(51, 255, 153, 0.2)',
                borderColor: 'rgba(51, 255, 153, 1)',
                borderWidth: 2,
            }]
        }
    }
    return (
        <Bar width={props.width} height={props.height}
            ref={chartReference}
            data={data()} options={options()} />
    )
}
クリック時の挙動
スポンサーリンク

追記

chartjsは複数回renderを行うと挙動がおかしくなるらしく、redrawで対処をしました。

react-chartjs-2でrenderが複数回呼び出されるときに生じた不具合の対処

コメント

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