0👍
I answered this by storing the individual data sets outside of the config, and switching what the config is pointing at based on the button clicks.
I used d3
s rollup function to group my data, then leveraged the fade class to see what datasets should and should not be seen!
original_data = [
{x: "A", y: 65, mygroup: "Group 1"},
{x: "B", y: 59, mygroup: "Group 1"},
{x: "C", y: 20, mygroup: 'Group 1'},
{x: "D", y: 12, mygroup: 'Group 2'},
{x: "E", y: 11, mygroup: 'Group 2'},
{x: "F", y: 10, mygroup: 'Group 2'},
{x: "G", y: 12, mygroup: 'Group 3'},
{x: "H", y: 11, mygroup: 'Group 3'},
{x: "I", y: 10, mygroup: 'Group 3'}
]
original_data2 = [
{x: "A", y: 65},
{x: "B", y: 59,},
{x: "C", y: 20,},
{x: "D", y: 12,},
{x: "E", y: 11},
{x: "F", y: 10}
]
config = {colors: ['red', 'blue', 'green']}
let chartified = d3.rollups(
original_data,
(group) => {
return {
label: group[0].mygroup,
data: group,
};
},
(d) => d.mygroup
).map((group, i) => {
const dataset = group[1];
dataset.backgroundColor = config.colors[i];
return dataset;
});
console.log(chartified)
// 1. break out your data by dataset
/*
let data2 = [
{
label: "Dataset #2",
backgroundColor: 'blue',
data: [
{x: "D", y: 12},
{x: "E", y: 11},
{x: "F", y: 10}
],
}
]
let data1 = [{
label: "Dataset #1",
backgroundColor: 'red',
data: [
{x: "A", y: 65},
{x: "B", y: 59},
{x: "C", y: 20}
],
}]
let all_data = [ ...data1, ...data2 ]
console.log(all_data)*
let named_data = [
{name: "Dataset #1", data: data1},
{name: "Dataset #2", data: data2}
]
*/
var option = {
plugins: {
legend: {
display: false,
}
}
};
function updateLegend(click, output) {
const element = click.target.parentNode;
element.classList.toggle('fade');
output.update();
}
function generateLegend(output, container) {
if (document.querySelectorAll('.customLegend').length === 0) {
const chartBox = document.querySelector(container);
const div = document.createElement('DIV');
div.setAttribute('class', 'customLegend');
const ul = document.createElement('UL');
output.legend.legendItems.forEach((dataset, index) => {
const text = dataset.text;
const stroke = dataset.strokeStyle;
const fill = dataset.fillStyle;
const fontColor = '#666';
const dat = dataset.data;
const li = document.createElement('LI');
const spanBox = document.createElement('SPAN');
spanBox.style.borderColor = stroke;
if (fill == 'rgba(0,0,0,0.1)') {
spanBox.setAttribute('class', 'legend-annotation');
} else {
spanBox.setAttribute('class', 'legend-content');
spanBox.style.backgroundColor = fill;
}
const p = document.createElement('P');
const textNode = document.createTextNode(text);
li.onclick = (event) => {
var target = event.target || event.srcElement;
target.parentElement.classList.toggle('fade');
// get all elements that are currently faded
let to_omit = target.parentElement
.parentElement
.querySelectorAll(".fade")
let omitted_data = [...to_omit].map(x => x.querySelector('p').innerHTML)
if (to_omit.length === 0) {
output.data.datasets = chartified
} else if (to_omit.length === chartified.length) {
output.data.datasets = []
} else {
output.data.datasets = chartified.filter(x => !omitted_data.includes(x.label))
}
output.update()
};
ul.appendChild(li);
li.appendChild(spanBox);
li.appendChild(p);
p.appendChild(textNode);
});
chartBox.prepend(div);
div.appendChild(ul);
}
}
const customLegend = {
id: 'customLegend',
afterDraw(chart, args, options) {
generateLegend(chart, '.chart-container');
},
};
new Chart('chart_0', {
// this is the string the constructor was registered at, ie Chart.controllers.MyType
type: 'bar',
data: {datasets: chartified },
options: option,
plugins: [customLegend],
});
/*
data: [
{},
{},
{},
]
*/
.chart-container {
position: relative;
max-width: 800px;
margin: auto;
}
.chartBox {
width: 80%;
}
.customLegend ul {
display: flex;
flex-direction: row;
margin: 0 auto;
list-style: none;
justify-content: center;
}
.customLegend ul li {
margin: 15px;
display: flex;
align-items: center;
cursor: pointer;
flex-direction: row;
line-height: 22px;
}
.customLegend p {
font-family: 'Helvetica';
font-size: 12px;
color: #666;
}
.customLegend ul li.fade p {
color: rgba(102, 102, 102, 0.5);
}
li.fade span {
opacity: 0.3;
}
.customLegend ul li span {
display: inline-block;
margin-right: 15px;
}
.legend-content {
height: 10px;
width: 10px;
}
.legend-annotation {
border-top-style: dotted;
height: 0px;
width: 20px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/7.6.1/d3.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/3.9.1/chart.min.js"></script>
<div class="chart-container">
<canvas id="chart_0"></canvas>
</div>
- Chartjs-How to set the number of of rows in a line chart in chart.js?
- Chartjs-Fill remaining parent height in ChakraUI
Source:stackexchange.com