2👍
✅
There are probably some other ways (maybe even some nicer ways), but this is how I would do this quick and dirty.
In the onClick
event I would set the data for the other Chart and than just call update
on the second chart. (link to the documentation)
Here a demo, how I would do this:
(Click on the pieChart to see the LineChart)
// Original Data
let dataSet = [
{"date": "06/01/2023 16:45", "item": "Apple", "cat": "Fruit", "price": "9.00"},
{"date": "06/01/2023 16:45", "item": "Orange", "cat": "Fruit", "price": "8.00"},
{"date": "06/01/2023 16:45", "item": "Pear", "cat": "Fruit", "price": "7.00"},
{"date": "06/01/2023 16:45", "item": "Water", "cat": "Drink", "price": "2.00"},
{"date": "06/01/2023 16:45", "item": "Soda", "cat": "Drink", "price": "3.00"},
{"date": "07/01/2023 16:45", "item": "Apple", "cat": "Fruit", "price": "9.50"},
{"date": "07/01/2023 16:45", "item": "Orange", "cat": "Fruit", "price": "8.50"},
{"date": "06/01/2023 16:45", "item": "Pear", "cat": "Fruit", "price": "7.50"},
{"date": "07/01/2023 16:45", "item": "Water", "cat": "Drink", "price": "2.50"},
{"date": "07/01/2023 16:45", "item": "Soda", "cat": "Drink", "price": "3.50"}
]
// pre split data
let drinkData = dataSet.filter(n => n.cat =='Drink')
let fruitData = dataSet.filter(n => n.cat =='Fruit')
let fruitDataSets = []
let drinkDataSets = []
let lineChartColors = ['#4BC0C0', '#FF9F40', '#9966FF']
// prepare Data for LineChart -- START
let formatedData = fruitData.reduce((p,c) => {
if(!p[c.item]){
p[c.item] = []
}
p[c.item].push({x: new Date(c.date), y: parseFloat(c.price), label: c.item})
return p
}, {});
Object.values(formatedData).forEach((n, i) => fruitDataSets.push({
data: n,
label: n[0].label,
backgroundColor: lineChartColors[i],
borderColor: lineChartColors[i]
}));
formatedData = drinkData.reduce((p,c) => {
if(!p[c.item]){
p[c.item] = []
}
p[c.item].push({x: new Date(c.date), y: parseFloat(c.price), label: c.item})
return p
}, {});
Object.values(formatedData).forEach((n, i) => drinkDataSets.push({
data: n,
label: n[0].label,
backgroundColor: lineChartColors[i],
borderColor: lineChartColors[i]
}));
// prepare Data for LineChart -- END
// create data for the pieChart
let preparedPieData = dataSet.reduce((p,c) => {
p[c.cat]++
return p
}, { Drink:0, Fruit: 0});
const pieData = {
// create labels for the pieChart
labels: Object.keys(preparedPieData),
datasets: [{
data: Object.values(preparedPieData),
backgroundColor: ['#35A2EB', '#FF6283'],
borderWidth: 1,
}],
};
let lineData = {
datasets: [],
};
// PieChart Configuration
const config = {
type: 'pie',
data: pieData,
options: {
maintainAspectRatio: false,
onClick: function(e, item){
lineData.datasets = item[0].index == 0 ? drinkDataSets : fruitDataSets
lineChart.update();
}
}
};
// LineChart Configuration
const config2 = {
type: 'line',
data: lineData,
options: {
maintainAspectRatio: false,
scales: {
x: {
type: 'time',
time: {
unit: 'week'
}
}
}
}
};
new Chart(
document.getElementById('chart1'),
config
);
let lineChart = new Chart(
document.getElementById('chart2'),
config2
);
<script src="//cdnjs.cloudflare.com/ajax/libs/Chart.js/3.9.1/chart.js"></script>
<script src="//cdn.jsdelivr.net/npm/moment@^2"></script>
<script src="//cdn.jsdelivr.net/npm/chartjs-adapter-moment@^1"></script>
<div class="chart" style="float:left;height:184px; width:250px;">
<canvas id="chart1" ></canvas>
</div>
<div class="chart" style="float:left;height:184px; width:250px;">
<canvas id="chart2" ></canvas>
</div>
Source:stackexchange.com