やりたいこと
Reactでchart.jsを使って円グラフを表示しました。
そのグラフの特定の項目をクリックしたときに、ラベル値とデータ値を取得したいです。
ソースコード
react
1import {Pie} from "react-chartjs-2"; 2import styled from "styled-components"; 3import { useEffect, useState } from "react"; 4import axios from "axios"; 5import ChartDataLabels from 'chartjs-plugin-datalabels'; 6import "chart.js"; 7 8const Container = styled.div` 9 position: relative; 10 width: 330px; 11 margin: 20px auto 0 auto; 12 @media(min-width: 376px) { 13 width: 360px; 14 } 15 @media(min-width: 600px) { 16 width: 400px; 17 } 18 @media(min-width: 900px) { 19 width: 50%; 20 padding: 0; 21 margin-top: 0; 22 margin-left: 20px; 23 } 24`; 25 26const TimeChart = (props) => { 27 28 const [chartData, setChartData] = useState([]); 29 30 let dateString = `${props.nowDay.getFullYear()},${props.nowDay.getMonth()+1},${props.nowDay.getDate()}` 31 32 useEffect(() => { 33 axios.get(`http://localhost:3001/timeLog/timeChart/${dateString}`, 34 { 35 headers: {accessToken: localStorage.getItem("accessToken")} 36 } 37 ).then((res) => { 38 const tmp = []; 39 res.data.forEach((data) => { 40 const startTimeData = data.start_time.split(","); 41 const startTime = new Date(startTimeData[0], startTimeData[1]-1, startTimeData[2], startTimeData[3], startTimeData[4]); 42 const finishTimeData = data.finish_time.split(","); 43 const finishTime = new Date(finishTimeData[0], finishTimeData[1]-1, finishTimeData[2],finishTimeData[3], finishTimeData[4]); 44 data.start_time = startTime; 45 data.finish_time = finishTime; 46 if (finishTime - startTime > 0) tmp.push(data); 47 }); 48 setChartData(tmp); 49 }); 50 }, [dateString, props.isDoing]); 51 52 if (chartData.length !== 0) { 53 chartData.sort((a, b) => a.start_time - b.start_time); 54 if ( 55 chartData[0].start_time.getDate() !== chartData[0].finish_time.getDate() 56 ) { 57 const newDate = chartData[0].start_time.getDate()+1; 58 chartData[0].start_time = new Date(chartData[0].start_time.getFullYear(), chartData[0].start_time.getMonth(), newDate); 59 } 60 if ( 61 chartData[chartData.length-1].start_time.getDate() !== chartData[chartData.length-1].finish_time.getDate() 62 ) { 63 const newDate = chartData[chartData.length-1].finish_time.getDate()-1; 64 chartData[chartData.length-1].finish_time = new Date(chartData[chartData.length-1].finish_time.getFullYear(), chartData[chartData.length-1].finish_time.getMonth(), newDate); 65 } 66 67 const makeFree = (start_time, finish_time) => { 68 return { 69 item_name: "空き時間", 70 start_time: start_time, 71 finish_time: finish_time, 72 color: '#d5d5d5' 73 } 74 } 75 const ts = chartData[0].start_time; 76 if (ts - new Date(ts.getFullYear(), ts.getMonth(), ts.getDate()) > 0) { 77 const free = makeFree(new Date(ts.getFullYear(), ts.getMonth(), ts.getDate()), ts); 78 setChartData([...chartData, free]); 79 } 80 81 const tf = chartData[chartData.length -1].finish_time; 82 if (new Date(tf.getFullYear(), tf.getMonth(), tf.getDate(), 23, 59) - tf > 4*6000) { 83 const free = makeFree(tf, new Date(tf.getFullYear(), tf.getMonth(), tf.getDate(), 23, 59)); 84 setChartData([...chartData, free]); 85 } 86 87 for (let i = 0; i < chartData.length-1; i++) { 88 const timeLog = chartData[i+1].start_time - chartData[i].finish_time; 89 if (timeLog > 4) { 90 const free = makeFree(chartData[i].finish_time, chartData[i+1].start_time); 91 setChartData([...chartData, free]); 92 } 93 } 94 } 95 96 const times = []; 97 const labels = []; 98 const backgroundColors = []; 99 chartData.forEach((data) => { 100 let time = (data.finish_time - data.start_time) / (60 * 1000); 101 if (chartData[chartData.length-1] === data) time += 1; 102 times.push(time); 103 labels.push(data.item_name); 104 backgroundColors.push(data.color); 105 }); 106 107 const data = { 108 labels: labels, 109 datasets: [{ 110 data: times, 111 backgroundColor: backgroundColors, 112 borderWidth: 0.5, 113 borderColor: '#0d0d0d', 114 datalabels: { 115 labels: { 116 data: { 117 align: 'start', 118 formatter: (value, context) => { 119 const label = context.chart.data.labels[context.dataIndex]; 120 let hour = ~~(value / 60); 121 const tmp = hour * 60; 122 let minutes = value - tmp; 123 hour = ("0" + hour).slice(-2); 124 minutes = ("0" + minutes).slice(-2); 125 if (label === "空き時間") return null; 126 return `${label}\n ${hour}:${minutes}`; 127 }, 128 }, 129 } 130 } 131 }] 132 } 133 134 const options = { 135 plugins: { 136 datalabels: { 137 color: '#0d0d0d', 138 anchor: 'end', 139 font: { 140 size: 10, 141 }, 142 clamp: true, 143 }, 144 legend: { 145 display: false 146 }, 147 }, 148 } 149 150 return ( 151 <Container> 152 <Pie 153 data={data} 154 plugins={[ChartDataLabels]} 155 options={options} 156 /> 157 </Container> 158 ); 159 160} 161 162export default TimeChart;
試したこと
Qiitaの記事を参考にして、「Pie」コンポーネントに「onElementsClick」を追加したところ、 Unknown event handler property `onElementsClick`. It will be ignored.
と警告が出て、クリックイベントが作動しませんでした。
あなたの回答
tips
プレビュー