CanvasJS and multiple piecharts. - javascript

I have to create pie charts for a website. It seems to me that I can't dynamically render pie charts depending on how many I need. At max I have to render 28. So, I'm thinking that I would have to type out
<script type="text/javascript">
window.onload = function () {
var chart = new CanvasJS.Chart("chartContainer",
{
title:{
text: "Gaming Consoles Sold in 2012"
},
legend: {
maxWidth: 350,
itemWidth: 120
},
data: [
{
type: "pie",
showInLegend: true,
legendText: "{indexLabel}",
dataPoints: [
{ y: 4181563, indexLabel: "PlayStation 3" },
{ y: 2175498, indexLabel: "Wii" },
{ y: 3125844, indexLabel: "Xbox 360" },
{ y: 1176121, indexLabel: "Nintendo DS"},
{ y: 1727161, indexLabel: "PSP" },
{ y: 4303364, indexLabel: "Nintendo 3DS"},
{ y: 1717786, indexLabel: "PS Vita"}
]
}
]
});
chart.render();
}
</script>
<script type="text/javascript" src="https://canvasjs.com/assets/script/canvasjs.min.js"></script>
</head>
<body>
<div id="chartContainer" style="height: 300px; width: 100%;"></div>
this code 28 times. But, sometimes I won't need all 28 pie charts. So I was thinking I could hide the pie charts if they aren't needed. But, the main question is, "can I dynamically allocate canvasJS pie charts"? So I only have one main block of code that can create X amount of pie charts.

Got it. So following my original comment. I hard coded the 2 tuple variable in the data section just to get the basic idea running. So the variable data was not used. But, I followed through with just simply creating an array of charts. With a naming convention of pieContainer+i. Where in my html code. I have 29 div elements with the convention pieContainer+1.
var charts = [];
var data = [];
function populatePieCharts(size)
{
for (i = 0; i < size; i++)
{
console.log("FFFF" + i)
charts[i] = new CanvasJS.Chart("pieContainer" + i,
{
title: {
text: i
},
legend: {
maxWidth: 350,
itemWidth: 120
},
data: [
{
type:"pie",
showInLegend: true,
legendText: "{indexLabel}",
dataPoints: [
{ y: 4181563, indexLabel: "PlayStation 3" },
{ y: 2175498, indexLabel: "Wii" },
{ y: 3125844, indexLabel: "Xbox 360" },
{ y: 1176121, indexLabel: "Nintendo DS" }
]
}]
});
}
renderCharts(size)
}
function renderCharts(chartAmount)
{
console.log(charts.length);
for (i2 = 0; i2 < chartAmount; i2++)
{
charts[i2].render();
console.log(i2);
}
}
Which leads me to another step. Instead of hard coding the 29 div elements. I could probably just dynamically create the div elements based on the pie charts needed.

Related

HighChart Column chart, render portion of column with color from corresponding zone

I am trying to figure out how to render a section of each column in a simple, single series, column chart with multiple colors. Using series.zones:
series: [
{
name: "Mod",
colorByPoint: true,
data: seriesData,
zones: [
{ value: 101, color: '#1D681B' },
{ value: 121, color: '#ECC518' },
{ color: '#D50D0D' }
]
}
]
I can get each column to be a different color based on the zone that the y value is within.
In my example above the zone are:
0 through 100 should be green
101 to 120 should be yellow
121 and above should be red
The above works to an extent, but looks like the following:
However, what my boss wants is something like this:
Can this be achieved using highcharts?
Instead of zones you can use stacked columns. Below is a simple example of how you can automatically calculate series structure:
const steps = [100, 20];
const data = [42, 100, 96, 120, 110, 90, 140];
const series = [{
color: '#1D681B',
data: []
}, {
linkedTo: ':previous',
color: '#ECC518',
data: []
}, {
linkedTo: ':previous',
color: '#D50D0D',
data: []
}];
data.forEach((dataEl, i) => {
let rest = dataEl;
let counter = 0;
let value;
while (rest > 0) {
value = steps[counter] < rest ? steps[counter] : rest;
series[counter].data.push({
x: i,
y: value
});
rest -= value;
counter++;
}
});
Highcharts.chart('container', {
chart: {
type: 'column'
},
yAxis: {
reversedStacks: false
},
plotOptions: {
series: {
stacking: 'normal'
}
},
series
});
Live demo: http://jsfiddle.net/BlackLabel/3h6o0ncg/
Docs: https://www.highcharts.com/docs/advanced-chart-features/stacking-charts

apex chart semi donut with custom custom indicator

Hello I have the following design That I have to implement. I am using apexcharts as a chart library in my application .
I could not find any gauge/indicator related information of apexchart while googling and now
quite not sure weather it is possible to implement the chart as required design.
2 important elements on my design
custom indicator
rounded edges of the arc
Do you have any idea that could help me here ?
Thank You.
var options = {
series: [44, 55, 41, 17, 15],
chart: {
type: "donut"
},
plotOptions: {
pie: {
startAngle: -90,
endAngle: 90,
offsetY: 10
}
},
grid: {
padding: {
bottom: -80
}
},
responsive: [
{
breakpoint: 480,
options: {
chart: {
width: 200
},
legend: {
position: "bottom"
}
}
}
]
};
var chart = new ApexCharts(document.querySelector("#chart"), options);
chart.render();
<div id="chart"></div>
<script src="https://cdn.jsdelivr.net/npm/apexcharts"></script>
there is one in Echarts i use it before
https://echarts.apache.org/examples/en/editor.html?c=gauge-progress

How to display large amount of information properly without cramping too much in Chart.js

I am trying to display live data that gets very large. The problem is that the lines look very cramped... I don't want all the data points to be on the spot, and I can loose a bit accuracy here and there...
**Here it is: **
So, is there a way, I can clean up the lines in my chart?
Preferably, without deleting the starting elements in the data.
**Here is the code: **
var ctx = document.getElementById("myChart").getContext("2d");
var myChart = new Chart(ctx, {
type: "line",
data: {
labels: [new Date()],
datasets: [
{
label: "# of Votes",
data: [Math.random()],
borderWidth: 4,
},
],
},
options: {
elements: {
line: {
backgroundColor: "#22ff2252",
borderColor: "#00de00",
fill: true,
borderWidth: 10,
tension: 0.05,
},
point: {
radius: 0,
borderWidth: 0,
pointStyle: "triangle",
},
},
scales: {
y: {
beginAtZero: false,
},
xAxis: {
type: "time",
ticks: {
source: "auto",
autoSkip: true,
maxTicksLimit: 10,
maxRotation: 0,
minRotation: 0,
},
time: {
unit: "second",
},
},
},
},
});
setInterval(() => {
colors = ["#00de00", "#de0000"];
myChart.options.elements.line.borderColor =
colors[Math.floor(Math.random() * colors.length)];
myChart.data.datasets[0].data.push(Math.random());
var today = new Date();
var time =
today.getHours() + ":" + today.getMinutes() + ":" + today.getSeconds();
myChart.data.labels.push(new Date());
myChart.update();
}, 2500);
<script src="https://cdn.jsdelivr.net/npm/chart.js#3.3.2/dist/chart.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/moment#2.27.0"></script>
<script src="https://cdn.jsdelivr.net/npm/chartjs-adapter-moment#0.1.1"></script>
<div style="height: 90%; width: 90%">
<canvas id="myChart"></canvas>
</div>
You can use the decimation plugin that lets you define the 'lttb' or 'min-max' algorithm option.
LTTB decimation reduces the number of data points significantly. This is most useful for showing trends in data using only a few data points.
Min/max decimation will preserve peaks in your data but could require up to 4 points for each pixel. This type of decimation would work well for a very noisy signal where you need to see data peaks.
Please take a look at the Data Decimation Sample and see how it works.

plot a bar chart.js time series

I am trying to plot a bar chart with multiple datasets on a time series, however some of the data gets lost along the way.
for simplicity I have removed the ajax call and plotted some data:-
var config = {
type: 'bar',
data: {
datasets: [{
label: "Dataset 1",
data: [{
x: new Date('2017-03-01'),
y: 1
}, {
x: new Date('2017-03-02'),
y: 2
}, {
x: new Date('2017-03-03'),
y: 3
}, {
x: new Date('2017-03-04'),
y: 4
}],
backgroundColor: "red"
}, {
label: "Dataset 2",
data: [{
x: new Date('2017-03-01'),
y: 1
}, {
x: new Date('2017-03-02'),
y: 2
}, {
x: new Date('2017-03-03'),
y: 3
}, {
x: new Date('2017-03-04'),
y: 4
}],
backgroundColor: "blue"
}]
},
options: {
scales: {
xAxes: [{
type: "time",
time: {
unit: 'day',
round: 'day',
displayFormats: {
day: 'MMM D'
}
}
}],
yAxes: [{
ticks: {
beginAtZero: true
}
}]
}
}
}
var ctx = document.getElementById("canvas").getContext("2d");
window.myLine = new Chart(ctx, config);
using the above configuration dataset 1 point 1 and dataset 2 point 4 (so basically the first and last points) do not get drawn.
Any ideas where I am going wrong here?
Also I am using this time series version because I was hoping to have "gaps" in the chart, for example dataset 1 might have a series for 2017-03-01 and dataset 2 might not, in this case dataset 2's next date will bunch up to dataset 1's making it look like it does belong to that date.
Any help would be appreciated
I had the exact same issue when displaying a bar chart with time as the X axes.
Inside your xAxes you need to add an additional configuration option:
xAxes: [{
offset: true
}]
Description from the ChartJS documentation:
If true, extra space is added to the both edges and the axis is scaled to fit into the chart area. This is set to true in the bar chart by default.
ChartJS Documentation Cartesian

time scatter plot w/ chart.js

I'm trying to render a scatter plot in chart.js of (x,y) data where x is a date string. I've seen many examples and tutorials online where the instructor uses a function to generate the time stamp for an example chart, but I haven't found any examples that use real data like one might collect.
I have data that looks like this (collected from cron):
2017-07-08T06:15:02-0600,23.375
2017-07-08T06:20:02-0600,23.312
2017-07-08T06:25:02-0600,23.312
2017-07-08T06:30:02-0600,23.25
I tried a data like this in chart.js (both with and without "quotes" around the data string):
data: [{
x: 2017-07-08T06:15:02-0600,
y: 23.375
},{
x: 2017-07-08T06:20:02-0600,
y: 23.312
},{
x: 2017-07-08T06:25:02-0600,
y: 23.312
},{
x: 2017-07-08T06:30:02-0600,
y: 23.25
}],
Nothing renders. What am I doing wrong?
According to the documentation of scatter charts:
Unlike the line chart where data can be supplied in two different formats, the scatter chart only accepts data in a point format.
So you can't use values like 2017-07-08T06:15:02-0600. You can convert dates into numbers and use them in your data.
In your case:
data: [{
x: 1499516102000,
y: 23.375
}, {
x: 1499516402000,
y: 23.312
}, {
x: 1499516702000,
y: 23.312
}, {
x: 1499517002000,
y: 23.25
}
]
Now your xAxes will be with numbers, so you can use a callback to modify xAxes labels.
That advice isn't quite right. The javascript moment.js makes it possible to plat scatter data using dates as the x axis value. For some reason the bundled version in Chart.bundle.js wasn't working for me, so I downloaded moment.js directly. I'm using this to setup:
<script src="js/moment.js"></script>
<script src="js/Chart.min.js"></script>
and this for my chart.js data details:
data: [
{x: moment("2017-07-08T06:15:02-0600"), y: 23.375},
{x: moment("2017-07-08T06:20:02-0600"),y: 23.312},
{x: moment("2017-07-08T06:25:02-0600"),y: 23.312},
{x: moment("2017-07-08T06:30:02-0600"),y: 23.25}
],
It's working great!
Another solution that worked great for me, was to just use the line type for the chart, configure it for using dates for the x axis, and addtionally disable the lines, so that it just looks like a scatterplot.
new Chart(ctx, {
type: 'line',
data: {
datasets: [{
x: 2017-07-08T06:15:02-0600,
y: 23.375
},{
x: 2017-07-08T06:20:02-0600,
y: 23.312
},{
x: 2017-07-08T06:25:02-0600,
y: 23.312
},{
x: 2017-07-08T06:30:02-0600,
y: 23.25
}]
},
options: {
showLine: false,
scales: {
x:{
type: 'time',
display: true,
title: {
display: true,
text: 'Date'
},
},
}
}
}
);
I see this as a quite elegant solution. The documentation even specifies:
The scatter chart supports all of the same properties as the line chart. By default, the scatter chart will override the showLine property of the line chart to false.
I couldn't find a working example from these answers, so here's mine.
new Chart(document.getElementById("chart"), {
type: "line",
data: {
datasets: [
{
showLine: false,
fill: false,
data: [
{
x: new Date(Date.now()),
y: 100,
},
{
x: new Date(Date.now() + 1000 * 60 * 60),
y: 200,
},
{
x: new Date(Date.now() + 2000 * 60 * 60),
y: 300,
},
{
x: new Date(Date.now() + 3000 * 60 * 60),
y: 400,
},
],
},
],
},
options: {
plugins: {
legend: {
display: false,
},
title: {
text: "Chart.js Time Scale",
display: true,
},
},
scales: {
x: {
type: "time",
time: {
unit: "hour",
// Luxon format string
// tooltipFormat: "DD T",
},
title: {
display: true,
text: "Hour",
},
},
y: {
title: {
display: true,
text: "value",
},
},
},
},
});
I pulled it from here: https://www.chartjs.org/docs/latest/samples/scales/time-line.html
You'll need to install momentjs and its adapter:
npm install moment chartjs-adapter-moment --save
..and then import all libraries like
import Chart from "chart.js/auto";
import "chartjs-adapter-moment";

Categories

Resources