How to remove y-axis on removing dataset in chart.js - javascript

I need to add multiple datasets to the chart, and remove the dataset from chart based on id. I am adding different y-axis for each dataset using yAxisID. When I remove the dataset from chart, y-axis is not being removed. how to remove the corresponding y-axis?
the code is as follows:
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/3.5.1/chart.min.js"></script>
<div style="width: 400px;height: 200px;">
<canvas id="myChart"></canvas>
</div>
<button onclick="add_dataset()">add dataset </button>
<button onclick="remove_dataset()">remove random dataset</button>
<script>
const ctx = document.getElementById('myChart');
my_chart = new Chart(ctx, {
type: 'line',
data: {
labels: [0,1,2,3,4,5,6,7,8,9,10],
datasets: [{
label: "0",
yAxisID: "0",
data: Array.from({length: 10}, () => Math.floor(Math.random() * 10)),
backgroundColor: getRandomColor(),
}]
},
options: {
responsive: true,
},
});
function getRandomColor() {
var letters = '0123456789ABCDEF'.split('');
var color = '#';
for (var i = 0; i < 6; i++) {
color += letters[Math.floor(Math.random() * 16)];
}
return color;
}
function add_dataset(){
temp = Array.from({length: 10}, () => Math.floor(Math.random() * 10));
let data_store = {
label: String(my_chart.data.datasets.length),
yAxisID: String(my_chart.data.datasets.length),
data: temp,
backgroundColor: getRandomColor(),
};
my_chart.data.datasets.push(data_store)
my_chart.update();
}
function remove_dataset(){
let temp_num = Math.floor(Math.random() * my_chart.data.datasets.length);
my_chart.data.datasets.splice(temp_num, 1);
my_chart.update();
}
</script>
I tried removing the scales from my_chart. but no effect.

in the options object, try:
options: {
responsive: true,
scales: {
[yAxisId]: {
display: false,
},
},
}

Related

chart.js doughnut chart with links if onclick

I try to make a link if a onclick event on a doughnut chart slice happens. My datasources are 3 arrays with labels, value, and the id for the url.
HTML:
<canvas id="pie-chart" style='display: none;'></canvas>
<!-- Php Arrays to JS -> PIE-CHARTDATA -->
<script type="text/javascript">
var chartIds = [[12,14,17,18]];
var chartValues = [[208.09,296.86,634.975,972.808]];
var chartLabels = [["BTC","AAPL","MSFT","ETH"]];
</script>
JS:
if (chartValues.length != 0 ) {
document.getElementById("pie-chart").style.display= "block";
}
Chart.register(ChartDataLabels);
var chartValuesInt = [];
length = chartValues[0].length;
for (var i = 0; i < length; i++)
chartValuesInt.push(parseInt(chartValues[0][i]));
var data = [{
data: chartValuesInt,
chartIds,
backgroundColor: [
"#f38000",
"#5f44f5",
"#333333",
],
borderColor: "#000"
}];
var options = {
borderWidth: 4,
hoverOffset: 6,
plugins: {
legend: {
display: false
},
tooltip: {
enabled: false,
},
datalabels: {
formatter: (value, ctx) => {
let sum = 0;
let dataArr = ctx.chart.data.datasets[0].data;
dataArr.map(data => {
sum += data;
});
let percentage = (value*100 / sum).toFixed(2)+"%";
return [ctx.chart.data.labels[ctx.dataIndex],
percentage,
'$' + value ] ;
},
textAlign: 'center',
color: '#fff',
borderRadius: 50,
padding:10,
labels: {
title: {
font: {
weight: 'bold',
size: '16px'
}
},
}
}
},
options:{
onClick: (e, activeEls) => {
let datasetIndex = activeEls[0].datasetIndex;
let dataIndex = activeEls[0].index;
let datasetLabel = e.chart.data.datasets[datasetIndex].label;
let value = e.chart.data.datasets[datasetIndex].data[dataIndex];
console.log("In click", datasetLabel, value);
//link to url with:[chartIds]
}
}
};
//IMAGE CENTER
const image = new Image();
image.src = 'img/pie-home2.png';
const plugin = {
id: 'custom_canvas_background_image',
beforeDraw: (chart) => {
if (image.complete) {
const ctx = chart.ctx;
const {top, left, width, height} = chart.chartArea;
const x = left + width / 2 - image.width / 2;
const y = top + height / 2 - image.height / 2;
ctx.drawImage(image, x, y);
} else {
image.onload = () => chart.draw();
}
}
};
var ctx = document.getElementById("pie-chart").getContext('2d');
var myChart = new Chart(ctx, {
type: 'doughnut',
data: {
labels: chartLabels[0],
datasets: data,
chartIds
},
options: options,
plugins: [plugin],
});
why does the onclick didn't work ?
how do i get the id with the right index from the slice where the event happens?
I searched already, but couldn't find a answer to these 2 questions.
You onClick function does not work because you define an options object within your options object and put the onClick in there. This is not supported. When you remove the inner options layer it will work:
const options = {
borderWidth: 4,
hoverOffset: 6,
plugins: {
legend: {
display: false
},
tooltip: {
enabled: false,
},
datalabels: {
formatter: (value, ctx) => {
let sum = 0;
let dataArr = ctx.chart.data.datasets[0].data;
dataArr.map(data => {
sum += data;
});
let percentage = (value * 100 / sum).toFixed(2) + "%";
return [ctx.chart.data.labels[ctx.dataIndex],
percentage,
'$' + value
];
},
textAlign: 'center',
color: '#fff',
borderRadius: 50,
padding: 10,
labels: {
title: {
font: {
weight: 'bold',
size: '16px'
}
},
}
}
},
onClick: (e, activeEls) => {
let datasetIndex = activeEls[0].datasetIndex;
let dataIndex = activeEls[0].index;
let datasetLabel = e.chart.data.datasets[datasetIndex].label;
let value = e.chart.data.datasets[datasetIndex].data[dataIndex];
console.log("In click", datasetLabel, value);
//link to url with:[chartIds]
}
};

ChartJS show value in legend (Chart.js V3.5)

I need the value of chart show after name of data for example ([colour of data] Car 50, [colour of data] Motorcycle 200). I've tried change the value of legend title but it doesn't work at all
Here is it my code:
var ctx = document.getElementById('top-five').getContext('2d');
var myChartpie = new Chart(ctx, {
type: 'pie',
data: {
labels: {!! $top->pluck('name') !!},
datasets: [{
label: 'Statistics',
data: {!! $top->pluck('m_count') !!},
backgroundColor: {!! $top->pluck('colour') !!},
borderColor: {!! $top->pluck('colour') !!},
}]
},
options: {
plugins: {
legend: {
display: true,
title: {
text: function(context) {//I've tried to override this but doesn't work
var value = context.dataset.data[context.dataIndex];
var label = context.label[context.dataIndex];
return label + ' ' + value;
},
}
},
},
responsive: true,
}
});
You can use a custom generateLabels function for this:
var options = {
type: 'doughnut',
data: {
labels: ["Red", "Blue", "Yellow", "Green", "Purple", "Orange"],
datasets: [{
label: '# of Votes',
data: [12, 19, 3, 5, 2, 3],
backgroundColor: ["Red", "Blue", "Yellow", "Green", "Purple", "Orange"],
}]
},
options: {
plugins: {
legend: {
labels: {
generateLabels: (chart) => {
const datasets = chart.data.datasets;
return datasets[0].data.map((data, i) => ({
text: `${chart.data.labels[i]} ${data}`,
fillStyle: datasets[0].backgroundColor[i],
index: i
}))
}
}
}
}
}
}
var ctx = document.getElementById('chartJSContainer').getContext('2d');
new Chart(ctx, options);
<body>
<canvas id="chartJSContainer" width="600" height="400"></canvas>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/3.5.1/chart.js"></script>
</body>
The below is a direct over ride of the default label generation found in the controller here. I have made one change on the text property within the generateLabels function in order to append the data value. It preserves the data toggling and strikethrough styling when a label is toggled.
plugins: {
legend: {
labels: {
generateLabels(chart) {
const data = chart.data;
if (data.labels.length && data.datasets.length) {
const {labels: {pointStyle}} = chart.legend.options;
return data.labels.map((label, i) => {
const meta = chart.getDatasetMeta(0);
const style = meta.controller.getStyle(i);
return {
text: `${label}: ${data['datasets'][0].data[i]}`,
fillStyle: style.backgroundColor,
strokeStyle: style.borderColor,
lineWidth: style.borderWidth,
pointStyle: pointStyle,
hidden: !chart.getDataVisibility(i),
// Extra data used for toggling the correct item
index: i
};
});
}
return [];
}
},
onClick(e, legendItem, legend) {
legend.chart.toggleDataVisibility(legendItem.index);
legend.chart.update();
}
}
//...
}
[1]: https://github.com/chartjs/Chart.js/blob/master/docs/samples/legend/html.md
You can also use the base implementation to reduce the amount of copied code. Note that some chart types (like donut) already overrides the default label generation.
plugins: {
legend: {
labels: {
generateLabels: function (chart) {
return Chart.defaults.plugins.legend.labels.generateLabels(chart).map(function (label) {
var dataset = chart.data.datasets[label.datasetIndex];
var total = 0;
for (var j = 0; j < dataset.data.length; j++)
total += dataset.data[j].y;
label.text = dataset.label + ': ' + total;
return label;
});
}
}
}
}

Chart js animating a line while changing x-axis labels

I achieved animating a plot using Jukka Kurkela example here.
Now I am having trouble customizing this plot further.
Logic of the custom plot
The plot starts animating with the x-axis labels being 0-20. When the plot reaches 20 then update the x-axis to be 20-40. Increment i or 20 until the x-axis reach its limit.
How to apply the logic above to the Example below?
// Generating data
var data = [];
var prev = 100;
for (var i=0;i<200;i++) {
prev += 5 - Math.random()*10;
data.push({x: i, y: prev});
}
var delayBetweenPoints = 100;
var started = {};
var ctx2 = document.getElementById("chart2").getContext("2d");
var chart2 = new Chart(ctx2, {
type: "line",
data: {
datasets: [
{
backgroundColor: "transparent",
borderColor: "rgb(255, 99, 132)",
borderWidth: 1,
pointRadius: 0,
data: data,
fill: true,
animation: (context) => {
var delay = 0;
var index = context.dataIndex;
if (!started[index]) {
delay = index * delayBetweenPoints;
started[index] = true;
}
var {x,y} = index > 0 ? context.chart.getDatasetMeta(0).data[index-1].getProps(['x','y'],
true) : {x: 0, y: 100};
return {
x: {
easing: "linear",
duration: delayBetweenPoints,
from: x,
delay
},
y: {
easing: "linear",
duration: delayBetweenPoints * 500,
from: y,
delay
},
skip: {
type: 'boolean',
duration: delayBetweenPoints,
from: true,
to: false,
delay: delay
}
};
}
}
]
},
options: {
scales: {
x: {
type: 'linear'
}
}
}
});
<div class="chart">
<canvas id="chart2"></canvas>
</div>
<script src="https://www.chartjs.org/dist/master/Chart.js"></script>
Solved it! Instead of incrementing 20 seconds, it is incrementing every 5 seconds ahead of time. Definitely a better experience for the user.
Got help from Rowf Abd's post.
var myData = [];
var prev = 100;
for (var i=0;i<60;i++) {
prev += 5 - Math.random()*10;
myData.push({x: i, y: prev});
}
var ctx = document.getElementById('myChart').getContext('2d');
var chart = new Chart(ctx, {
type: 'line',
data: {
datasets: [{
data: [myData[0]],
pointRadius: 0,
fill: false,
borderColor: "black",
lineTension: 0
}]
},
options: {
legend: {
onClick: (e) => e.stopPropagation()
},
title:{
fontColor: 'Black'
},
layout: {
padding: {
right: 10
}
},
scales: {
xAxes: [{
type: 'linear',
ticks: {
}
}],
yAxes: [{
scaleLabel: {
// fontFamily: 'Lato',
fontSize: 19,
fontColor: "Black"
}
}]
}
}
});
var next = function() {
var data = chart.data.datasets[0].data;
var count = data.length;
var xabsmin = 20;
var xabsmax = 60;
var incVar = 5;
data[count] = data[count - 1];
chart.update({duration: 0});
data[count] = myData[count];
chart.update();
if (count < myData.length - 1) {
setTimeout(next, 500);
}
if (data[count].x < xabsmin) {
chart.config.options.scales.xAxes[0].ticks.min = xabsmin - xabsmin;
chart.config.options.scales.xAxes[0].ticks.max = xabsmin;
chart.update();
}
if(data[count].x >= xabsmin && data[count].x < (xabsmax)){
var currentT = parseFloat(data[count].x);
var modDiv = (currentT % incVar);
var tempXMax = (currentT) + (incVar - modDiv);
chart.config.options.scales.xAxes[0].ticks.max = tempXMax;
chart.config.options.scales.xAxes[0].ticks.min = tempXMax - xabsmin;
chart.update();
}
}
setTimeout(next, 500);
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.7.3/Chart.min.js"></script>
<canvas id="myChart"></canvas>

Legend color not working with randomly generated background colors in chartjs pie chart

var ctx = document.getElementById('myChart').getContext('2d');
var labels = ["Mar-2019","Apr-2019","May-2019","Jun-2019","Jul-2019","Aug-2019","Sep-2019","Oct-2019","Nov-2019","Dec-2019","Jan-2020","Feb-2020","Mar-2020"];
var dataSet = {"ADVERTS_PUBLISHED":["0","0","1","0","4","0","2","0","1","0","1","1","1"],"ADVERT_ACTIONS":["5","1","2","1","2","0","1","0","1","2","1","0","0"],"VIEWS":["34","1","4","3","5",0,"1",0,"2","5","6",0,0],"CLICKS":["13","0","3","3","3",0,"1",0,"2","4","6",0,0],"SUBMITTED":["3",0,"2","2","2",0,"1",0,"7","3","2",0,0],"PENDING":["0",0,"2","0","0",0,"0","2","0","1","0",0,0],"FILTERED":["3",0,"1","2","2",0,"1","0","7","3","0",0,0],"SHORTLISTED":["0",0,"0","2","0",0,"0","5","0","0","0",0,0],"REGRETTED":["0",0,"0","0","0",0,"0","1","0","0","0",0,0],"INTERVIEWED":["0",0,"0","2","0",0,"0","1","0","0","0",0,0],"OFFERED":["1",0,"0","0","1",0,"11","0","0","0","0",0,0],"OFFERED_AND_DECLINED":["0",0,"0","0","0",0,"0","1","0","0","0",0,0],"REGRETTED_AND_COMM":["0",0,"0","0","0",0,"0","1","0","0","2",0,0],"ACTUAL_HIRED":["0",0,"0","0","0",0,"0","0","0","1","0",0,0]};
myChart = new Chart(ctx, {
type: 'pie',
data: {
labels: labels,
datasets: [{
label: 'Adverts Published',
data: dataSet.ADVERTS_PUBLISHED,
backgroundColor: function() {
return getRandomColorHex()
},
borderWidth: 1
}]
},
options: {
responsive: true,
maintainAspectRatio: true,
// onClick: graphClickEvent,
hover: {
onHover: function (e, el) {
$("#myChart").css("cursor", el[0] ? "pointer" : "default");
}
},
scales: {
yAxes: [{
ticks: {
beginAtZero: true
}
}]
}
}
});
function getRandomColorHex() {
var hex = "0123456789ABCDEF",
color = "#";
for (var i = 1; i <= 6; i++) {
color += hex[Math.floor(Math.random() * 16)];
}
return color;
}
<script src="https://cdn.jsdelivr.net/npm/chart.js#2.8.0/dist/Chart.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="">
<canvas class="chart__graph" id="myChart"></canvas>
</div>
I am creating a pie using chartjs, the data set is dynamically generate from a php back end and could be of any size so i cant set fixed colors for the pie chart.
I have managed to get the pie chart generating with a random background color for each section but the legend is not taking on the background color. Another issue is that if I use the legend to hide a slice of the pie the colors randomly generate again. I don't want this to to happen.
Send array (["red", "blue","orange"] as value for backgroundColor.
Simple forEach example:
var colors = [];
labels.forEach((element) => {
var hex_color = getRandomColorHex();
colors.push(hex_color);
})
console.log(colors) /* ["#5076FA", "#2832C4", "#36DEA3", "#7A940B", "#FD8E0D", "#6214DF", "#9CF566", "#71459C", "#98F6B5", "#B111A4", "#AAB800", "#D8DA57", "#836BD9"] */
And use this array as a value for backgroundColor:
backgroundColor: colors,
Working example:
var ctx = document.getElementById('myChart').getContext('2d');
var labels = ["Mar-2019","Apr-2019","May-2019","Jun-2019","Jul-2019","Aug-2019","Sep-2019","Oct-2019","Nov-2019","Dec-2019","Jan-2020","Feb-2020","Mar-2020"];
var dataSet = {"ADVERTS_PUBLISHED":["0","0","1","0","4","0","2","0","1","0","1","1","1"],"ADVERT_ACTIONS":["5","1","2","1","2","0","1","0","1","2","1","0","0"],"VIEWS":["34","1","4","3","5",0,"1",0,"2","5","6",0,0],"CLICKS":["13","0","3","3","3",0,"1",0,"2","4","6",0,0],"SUBMITTED":["3",0,"2","2","2",0,"1",0,"7","3","2",0,0],"PENDING":["0",0,"2","0","0",0,"0","2","0","1","0",0,0],"FILTERED":["3",0,"1","2","2",0,"1","0","7","3","0",0,0],"SHORTLISTED":["0",0,"0","2","0",0,"0","5","0","0","0",0,0],"REGRETTED":["0",0,"0","0","0",0,"0","1","0","0","0",0,0],"INTERVIEWED":["0",0,"0","2","0",0,"0","1","0","0","0",0,0],"OFFERED":["1",0,"0","0","1",0,"11","0","0","0","0",0,0],"OFFERED_AND_DECLINED":["0",0,"0","0","0",0,"0","1","0","0","0",0,0],"REGRETTED_AND_COMM":["0",0,"0","0","0",0,"0","1","0","0","2",0,0],"ACTUAL_HIRED":["0",0,"0","0","0",0,"0","0","0","1","0",0,0]};
var colors = [];
labels.forEach((element) => {
var hex_color = getRandomColorHex();
console.log("hello" + hex_color);
colors.push(hex_color);
})
var myChart = new Chart(ctx, {
type: 'pie',
data: {
labels: labels,
datasets: [{
label: 'Adverts Published',
data: dataSet.ADVERTS_PUBLISHED,
backgroundColor: colors,
borderWidth: 1
}]
},
options: {
responsive: true,
maintainAspectRatio: true,
// onClick: graphClickEvent,
hover: {
},
scales: {
yAxes: [{
ticks: {
beginAtZero: true
}
}]
}
}
});
function getRandomColorHex() {
var hex = "0123456789ABCDEF",
color = "#";
for (var i = 1; i <= 6; i++) {
color += hex[Math.floor(Math.random() * 16)];
}
return color;
}
div{
border: 1px solid red;
}
<div id="">
<canvas class="chart__graph" id="myChart"></canvas>
</div>
<script src="https://cdn.jsdelivr.net/npm/chart.js#2.8.0/dist/Chart.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

Put the value into the doughnut chart

I need to input the value of the first percentage into the chart, like this image
In this case, put the value of pedro(33%) within the chart.
I am beginner with chartJS and do not know it completely. Is it possible to do that?
var randomScalingFactor = function() {
return Math.round(Math.random() * 100);
};
var config = {
type: 'doughnut',
data: {
datasets: [{
data: [
33,
67,
],
backgroundColor: [
"#F7464A",
"#46BFBD",
],
label: 'Expenditures'
}],
labels: [
"Pedro: 33 ",
"Henrique: 67 ",
]
},
options: {
responsive: true,
legend: {
position: 'bottom',
},
title: {
display: true,
text: 'Pedro Henrique Kuzminskas Miyazaki de Souza'
},
animation: {
animateScale: true,
animateRotate: true
},
tooltips: {
callbacks: {
label: function(tooltipItem, data) {
var dataset = data.datasets[tooltipItem.datasetIndex];
var total = dataset.data.reduce(function(previousValue, currentValue, currentIndex, array) {
return previousValue + currentValue;
});
var currentValue = dataset.data[tooltipItem.index];
var precentage = Math.floor(((currentValue / total) * 100) + 0.5);
return precentage + "%";
}
}
}
}
};
var ctx = document.getElementById("myChart").getContext("2d");
window.myDoughnut = new Chart(ctx, config); {
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.3.0/Chart.min.js"></script>
<canvas id="myChart" width="400" height="200"></canvas>
This is not part of the default behavior. You will need to modify the chart.js script.
How to add text inside the doughnut chart using Chart.js?

Categories