Auto Generating Pie Chart Legend - javascript

I am trying to create a pie chart in JavaScript. I would like this chart to display in the legend only the labels that are non zero.
Does anyone have any ideas how this can be done?
Here is the code I have so far. Currently the legend of the pie chart shows all possible 12 Labels, even though 8 of these have zero value. "Data" will eventually be filled from a database and therefore it is important that this is an automated process.
var ctx = document.getElementById("myPieChart");
var myPieChart = new Chart(ctx, {
type: 'pie',
data: {
labels: ["Astronomica", "Deuteronic", "Floral", "Galactic","Celestrial","Heliosphere","Jupiter","Interstella","Koronis","Eclipse,"Borealis","Lunatic"],
datasets: [{
data: [12.21, 15.58, 11.25, 8.32],
backgroundColor: ['#007bff', '#dc3545', '#ffc107', '#28a745'],
}],
},
});

You can manage data before use they.
var ctx = document.getElementById("myPieChart");
var input_lables = ["Astronomica" , "Deuteronic", "Floral", "Galactic", "Celestrial", "Heliosphere", "Jupiter", "Interstella","Koronis", "Eclipse", "Borealis", "Lunatic"];
var input_values = [12.21, 15.58, 11.25, 8.32];
var output_lables = [];
var output_values = [];
for(var i=0;i<input_lables.length;i++){
if(!values[i]){
output_lables.push(input_lables[i]);
output_values.push(input_values[i]);
}
}
var myPieChart = new Chart(ctx, {
type: 'pie',
data: {
labels: output_lables,
datasets: [{
data: output_values,
backgroundColor: ['#007bff', '#dc3545', '#ffc107', '#28a745'],
}],
},
});
if you went to automatic it just enough make a function like this code.

According with the documentation you can use the filter parameter in the label
http://www.chartjs.org/docs/latest/configuration/legend.html
and you can make a validation to validate the data and if it is 0 you can return false
Filter a legend Item with Chartjs.org V2.7

Related

chart.js - how to draw and manage line when only one label present in chart js Linechart

I'm using Chart.JS v 2.9.3 to create a line chart
line-chart diagram to show the month-wise total of expenses of selected product
For example, if the user select XYZ product then this charts would show the monthly expenses [Jan-2021-Dec-2021]
and if that respective product expense only present Jan-2021 then it displays month on y-Axes at staring
here is jsfiddle example
Adding offset trick I had already tried xAxes : [{ offset:true }],
var config = {
type: 'line',
data: {
labels: ["jan-2021"],
datasets: [{
label: "month-year",
data: [65],
backgroundColor: "rgb(118, 101, 228)",
}],
},
scales : {
xAxes : [{
offset:true
}],
},
};
var ctx = document.getElementById("myChart").getContext("2d");
new Chart(ctx, config);
<div class="myChart">
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.9.3/Chart.bundle.js"></script>
<canvas id="myChart"></canvas>
</div>
please refer to the above image for getting an idea of what I'm trying to archive, I'm not concern about dot that on the chart
As you can see, the points are stick to the y-axis. Is there a possibility to center the line chart when only one data is present in the diagram?
Chart.js does not support this kind of use case since it gives a distorted image of your chart since point and label don't align anymore. If you really want this you can check beforehand in your code if there is only 1 data point there. If this is the case add an empty string in your labels array in the front and back and add zero at the front of back of your data array (or a slightly lower value as your single datapoint so that the scales don't get big steps) like so:
var config = {
type: 'line',
data: {
labels: ["", "January-2021", ""],
datasets: [{
label: "month-year",
data: [0, 134335066, 0],
backgroundColor: "rgb(118, 101, 228)",
}],
},
scales: {},
};
var ctx = document.getElementById("myChart").getContext("2d");
new Chart(ctx, config);
<div class="myChart">
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.9.4/Chart.bundle.js"></script>
<canvas id="myChart"></canvas>
</div>
You can use align option:
var mybarChart = new Chart(ctx, {
type: 'bar',
responsive: true,
data: data,
options: {
legend: {
display: false,
position: 'bottom',
align: 'center'
},
var config = {
type: 'line',
data: {
labels: ["", "January-2021", ""],
datasets: [{
label: "month-year",
data: [0, 134335066, 0],
backgroundColor: "rgb(118, 101, 228)",
}],
options: {
legend: {
display: false,
position: 'bottom',
align: 'center'
},
},
scales: {},
};
refer to this

Chart.js loads data when i resize window

My chart isnt refreshing when i click search. My chart works and shows the data only when i search and resize the window. I tried moving my chart function inside my search function but it gives me an error. Is there another approach to this? my code is:
$(`#stock-search`).click(function(){
var searchValue = $('#stock-name').val();
$.getJSON(`https://sandbox.iexapis.com/stable/stock/${searchValue}/chart/1m?token=demo`,
function(data){
console.log(data);
for (x = 0; x < 22; x++){
const time = data[`${x}`].label;
xlabel.push(time);
const value = data[`${x}`].high;
ydata.push(value);
console.log(value);
console.log(time);
}
});
});
const ctx = document.getElementById('myChart').getContext('2d');
const xlabel= [];
const ydata= [];
const myChart = new Chart(ctx, {
type: 'line',
data: {
labels: xlabel,
datasets: [{
label: "Highs of the month",
data: ydata,
borderWidth: 1
}]
},
options: {
scales: {
yAxes: [{
ticks: {
callback: function(value, index, values) {
return '$' + value;
}
}
}]
}
}
});
You may want to look at this Question though while a bit dated does seems to provide numerous ways to accomplish your goal:
chart.js load totally new data

Storing Highcharts in array issue

I am plotting a number of highcharts dynamically in a loop and pushing each highchart to an array. So that while clicking on an external button, I can export the charts. But while pushing charts to array, only the last entry is properly set with options.
i had a reference to a fiddle that suggests to clone the options. [https://jsfiddle.net/ndb21y1w/][2]
https://www.highcharts.com/forum/viewtopic.php?t=38574
The fiddle have same series data plotted on all the charts. How to solve this if the data is different for each chart populated. Thanks for any help in advance.
Adding more clarity to question :
The data is populated dynamically in loop. My code logic is like:
counter i;
setInterval(function() {
//logic to populated data...
//It is a multiline chart, so three sets of arrays are populated.
//filling data1[], data2[] and data3[] .
drawChart(data1, data2, data3);
if(condition true) clearInterval();
i++;
});
drawChart(data1, data2, data3) {
var chart = new Highcharts.Chart({
title: {
text: "title",
},
xAxis: {
categories: [1,2,3,4...],
},
series: [{
type: 'line',
data: data1,
}, {
type: 'line',
data: data2,
}, {
type: 'line',
data: data3,
},
});
chartArray.push(chart);
}
This chartArray is where I mentioned to get the last entry only properly.
To create a chart you have to pass an HTML element that will be a chart container. In your code that what's missing. Check the demo I have prepared to reproduce this issue: https://jsfiddle.net/BlackLabel/c60y1t2v/
Code:
var chartArray = [],
counter = 1,
dataArr = [
[1, 2, 3],
[4, 5, 6],
[7, 8, 9]
],
containers = document.getElementById('containers');
function drawChart(data) {
var cnt = document.createElement('div'),
cntId = 'container' + counter++,
chart;
cnt.setAttribute('id', cntId);
containers.appendChild(cnt);
chart = new Highcharts.Chart(cntId, {
title: {
text: "title",
},
xAxis: {
categories: [1, 2, 3, 4],
},
series: [{
type: 'line',
data: data,
}]
});
return chart;
}
dataArr.forEach(function(data) {
var chart = drawChart(data);
chartArray.push(chart);
});
You need to define options each time you use a new chart. Reinitialize the OriginalOptions every time you create a new chart.
const options = [...Array(5)].map(() => {
const originalOptions = {
series: [{
data: [], // some random data
type: 'column'
}]
}
return Object.assign(originalOptions)
})
Fiddle
Updated:
For dynamically repopulating the chart, you have to initialize an empty chart and then add new series + redraw whenever your data is populated.
Your redraw function will look something like this:
var i = 0;
var data = [];
var chart = new Highcharts.Chart('container',{
series: []
});
var interval = setInterval(function() {
i++;
data[i] = [i*10 + 1, i*10+2, i*10+3];
drawChart(data[i]);
if(i > 2) clearInterval(interval);
},1000);
function drawChart(data) {
var series = {
type: 'line',
data: data
}
chart.addSeries(series, false);
chart.redraw();
}
See Updated Fiddle
To Print HTML as PDF you can use this software "wkhtmltopdf"
in Linux you need to use this command :
sudo apt-get install wkhtmltopdf
There are many library based on "wkhtmltopdf" in many languages so you can use it.
Library for PHP : https://github.com/mikehaertl/phpwkhtmltopdf
Store chart options in Array then map over to Initialize Highchart for each options.
var chartArray = [];
function drawChart(data1, data2, data3, i) {
// Create container for charts
const el = document.createElement('div');
document.body.appendChild(el).setAttribute("id", "container"+i);
// Create charts
var chart = new Highcharts.chart(el, {
series: [{
type: 'line',
data: data1,
}, {
type: 'line',
data: data2,
}, {
type: 'line',
data: data3,
}]
});
chartArray.push(chart);
console.log(chartArray);
}
var counter = 0;
var delayTime = 2000;
var timer = setInterval(function(){
var data1 = [30, 70, 50];
var data2 = [40, 70, 60];
var data3 = [10, 90, 20];
drawChart(data1, data2, data3, counter);
if(counter == 2){
clearInterval(timer);
}
counter++;
},delayTime);
<script src="https://code.highcharts.com/highcharts.js"></script>

Pie chart isn't loading, but the labels are

I'm using Chart.js in Laravel to display data.
I'm following this tutorial, which worked for the bar chart. But now I'm trying a pie chart.
This is my controller which gets the data.
public function chart()
{
$result = \DB::table('users')
->where('userType','=','Landlord')
->orderBy('created_at', 'ASC')
->get();
return response()->json($result);
}
The view is this
<script>
var url = "{{url('/users')}}";
var Name = new Array();
var Email = new Array();
$(document).ready(function(){
$.get(url, function(response){
response.forEach(function(data){
Name.push(data.name);
Email.push(data.email);
});
var ctx = document.getElementById("canvas").getContext('2d');
var myPieChart = new Chart(ctx,{
type: 'pie',
data : {
datasets: [{
data: [Name,Email]
}],
// These labels appear in the legend and in the tooltips when hovering different arcs
labels: [Name, Email]
}
});
});
});
</script>
This is the output
According to the ChartJS documenation, the expected data passed for a pie chart is numbers only. Here's an example of a dataset that should work:
data = {
datasets: [{
data: [10, 20, 30]
}],
// These labels appear in the legend and in the tooltips when hovering different arcs
labels: [
'Red',
'Yellow',
'Blue'
]
};
Currently, your Ajax request is getting the name and email from the /users route; you will need to update the request to get some sort of number value from /users and add that to the dataset.

Pushing data from json to Chart.js labels and data

I am using the Chart.js lib to make charts.
I have a json array that I am getting from a database.
Here is the console log of it: Data
I need to get the address, speed, and speed limit for every element in the list and use it in a chart.
My current code is as follows:
function ShowChart() {
var popCanvas = document.getElementById("speedLimitsChart");
console.dir(speeddata);
var labels = speeddata.map(function (e) {
return e.Adress;
});
var speed = speeddata.map(function (e) {
return e.Speed;
});
var speedlimits = speeddata.map(function (e) {
return e.SpeedLimits;
});
console.dir(labels);
var barChart = new Chart(popCanvas, {
type: 'bar',
data: {
datasets: [{
label: 'Speed',
data: speed,
backgroundColor: '#1E90FF'
}, {
label: 'Speed Limits',
data: speedlimits,
backgroundColor: '#B22222',
type: 'line'
}],
},
labels: labels
});
}
But in the result I only have the first element in my chart, and there are no labels.
Here is the output screen: Chart
I checked speed, speedlimits and labels and all of them have 2 elements. Can you please advise where my problem might be?
I found where is my problem
I need to write labels inside of data
Like this
var barChart = new Chart(popCanvas, {
type: 'bar',
data: {
labels: labels ,
datasets: [{
label: 'Speed',
data: speed,
backgroundColor: '#1E90FF'
}, {
label: 'Speed Limits',
data: speedlimits,
backgroundColor: '#B22222',
type: 'line'
}],
},
});

Categories

Resources