Multiple chartist charts on same page without ID - javascript

The code below renders only the last chart from JSON. I want it to append every chart from JSON to a div with a class of reportdiv.
Markup
<div class="reportdiv>
</div>
json
{reportvals:
{
labels:["Apple 25%", "Banana 15%", "Mango 10%", "Orange 35%", "Avocado15% "],
series: [25, 15, 10, 35, 15]
},
{
labels:["Apple 15%", "Banana 25%", "Mango 35%", "Orange 10%", "Avocado15% "],
series: [15, 25, 35, 10, 15]
}
}
JS
for (reportindex = 0; reportindex < settings.json.reportvals.length; reportindex++){
new Chartist.Pie('.reportdiv', {
labels: settings.json.reportvals[reportindex].labels,
series: settings.json.reportvals[reportindex].series
}, options);
}
How can I make my code append all charts to the div?
I can use an ID selector, but I am not sure count of charts are received from the JSON.

Related

Highcharts update x-axis categories dynamically

i'm looking for help with updating the x-axis categories on a Highcharts chart with periodically received data.
The chart is defined in a file called forecastgraph.html. It is loaded to index.php, the webpage where I want it displayed, by means of <?php require("widget/forecastgraph.html"); ?>. The chart renders as expected.
Live data which is handled via a js script (called mqtt.js) that receives incoming mqtt data in json format and using jquery updates various parts of index.php in this way: $("#elementid").html(a.b.c);. I load mqtt.js in the head of index.php using <script src="./js/mqtt.js"></script> This again works flawlessly.
What I am struggling with is how to pass incoming data from mqtt.js to the chart to update it as new data comes in. Specifically, I am trying to update the xAxis categories and the corresponding value pairs. Periodically, mqtt.js receives a new weather forecast and so the xAxis categories need to be updated with the new time period that the forecast applies to and the data needs to be updated to reflect the new high and low temperatures for the respective forecast periods.
The code for the chart is posted below. Any help would be appreciated.
Baobab
<script type="text/javascript">
$(function () {
$('#forecastgraph').highcharts({
chart: {
type: 'columnrange',
backgroundColor: 'rgba(0,0,0,0)',
borderWidth: 0,
margin: [12, 6, 36, 20]
},
title: {
text: null,
},
exporting: {
enabled: false
},
credits: {
enabled: false
},
xAxis: {
categories: [1,2,3,4],
labels: {
y: 30,
style: {
color: 'white',
fontSize: '10px',
fontWeight: 'bold'
}
}
},
yAxis: {
title: {
enabled: false,
x: -14,
},
labels: {
align: 'left'
},
maxPadding: 0.5,
plotLines: [{
value: 10, //normmax
width: 2,
color: '#FF0000'
},{
value: 2, //normmin
width: 2,
color: '#009ACD'
}]
},
tooltip: {
enabled: false
},
plotOptions: {
columnrange: {
dataLabels: {
enabled: true,
style: {
textOutline: 'none'
},
crop: false,
overflow: 'none',
formatter: function () {
var color = this.y === this.point.high ? '#33C4FF' : 'red';
return '<span style="font-size: 12px; font-family:helvetica; font-weight:normal; text-shadow: none; color:' + color + '">' + this.y + '°</span>';
}
}
}
},
legend: {
enabled: false
},
series: [{
name: 'Temperatures',
data: [
[20, -3],
[5, -2],
[6, -2],
[8, -15]
],
color: '#b9deea',
borderColor: '#92cbde',
borderRadius: 4
}]
});
});
</script>
EDIT: Additional Information.
The incoming json data looks like this:
[{
"period": "Monday",
"condition": "Cloudy",
"high_temperature": "7",
"low_temperature": "-2"
"icon_code": "10",
"precip_probability": "20"
}, {
"period": "Tuesday",
"condition": "A mix of sun and cloud",
"high_temperature": "6",
"low_temperature": "-2"
"icon_code": "02",
"precip_probability": "20"
}, {
"period": "Wednesday",
"condition": "A mix of sun and cloud",
"high_temperature": "3",
"low_temperature": "-5"
"icon_code": "02",
"precip_probability": "20"
}, {
"period": "Thursday",
"condition": "A mix of sun and cloud",
"high_temperature": "1",
"low_temperature": "-10"
"icon_code": "02",
"precip_probability": "20"
}]
The function responsible for the incoming json formatted data in the mqtt.js script loaded to index.php handles the incoming data in this way (mqtt.js is started when index.php is loaded):
function onMessageArrived(message) {
console.log("onMessageArrived: " + message.payloadString);
//Env Canada forecast
if (message.destinationName == "myHome/ec/json_data_ec") {
var data = JSON.parse(message.payloadString);
$("#forecast_period_1").html(data[0].period); // update div forecast_period_1 in index.php for debugging purposes and show that data is coming in
forecast_period_1 = (data[0].period); // assign to global var
forecast_period_1_high = (data[0].high_temperature); // global var
forecast_period_1_low = (data[0].low_temperature); // global var
Updating various html elements throughout index.php with the incoming data works great and is stable. What I have attempted to do, but with no success, is to update the chart using the data placed in the global variables (declared as global at he beginning of the script) by the mqtt.js script. In the example above, forecast_period_1 needs to be used as the first of the four xAxis categories and forecast_period_1_high and forecast_period_1_low, to update the respective hi and lo values in the chart's data.
Is this an output that you want to achieve? In the below demo, I wrote a function that takes a high and low temperatures value and next is triggered on the button. The new data is attached to the chart via using the series.update feature.
Demo: https://jsfiddle.net/BlackLabel/he768cz3/
API: https://api.highcharts.com/class-reference/Highcharts.Series#update
I have found a solution for it. First, you have to store the chart in a variable then after you are able to update chart data. Like below
var chart = $('#forecastgraph').highcharts({ ...option })
Update xAxis or series data
// Update xAxis data label
chart.update({
xAxis: {
categories: [1,2,3,4]
}
});
// Update series data
chart.series[0].update({
data: [
[20, -3],
[5, -2],
[6, -2],
[8, -15]
]
});

How do I customize y-axis labels and randomly pick the value from the data range for x-axis in Chart js

I have been working on a chart using charts.js that show workouts duration each day. The y-axis should have dates and the x-axis should have the duration of the Series,
Here is my dataset:
public lineChartData: ChartDataSets[] = [
{ data: [65, 19, 40, 81, 56, 5, 40], label: 'Series A' },
{ data: [95, 69, 40, 81, 56, 96, 40], label: 'Series B' },
{ data: [65, 74, 40, 41, 54, 55, 40], label: 'Series C' }
];
public lineChartLabels: Label[] = ['2020/05/20', '2020/05/21', '2020/05/22', '2020/05/23', '2020/05/24', '2020/05/25'];
So far I am unable to find any implementation-related it, it would be very helpful if anyone can help me out on this.
I have tried the stackblitz with horizontal with a bar chart, we need to same like in LINE CHART
Here is stackblitz link
You need to use a scatter chart and define the option showLine: true on each dataset. Further you have to define the y-axis as a time cartesian axis as follows.
yAxes: [
{
type: "time",
time: {
parser: "YYYY/MM/DD",
unit: "day",
displayFormats: {
day: "YYYY/MM/DD"
}
},
ticks: {
reverse: true
}
}
]
Since the scatter chart expects the data in point format, you have to generate appropriate data structure in the ngOnInit method as follows:
ngOnInit() {
this.lineChartData.forEach(ds => {
ds.data = ds.data.map((v, i) => ({ x: v, y: this.lineChartLabels[i] }));
});
}
Also remove [labels]="lineChartLabels" from the canvas, this is not needed when defining the data in point format.
Unfortunately however ng2-charts can't cope with this configuration and displays wrong colors for the data points and the legend labels. Therefore I also had to remove [colors]="lineChartColors" from the canvas and define the colors on the datasets.
You'll probably have to get rid of this wrapper library and use Chart.js directly in order to obtain the expected result.
Please take a look at your amended code in this StackBlitz.

Chart js pie or doughnut charts 3 inside instead of 1

Is it possible to have multiple charts inside each other:
Please check js fiddle for "single" and what I would like is to have that as a first one, inside second one and so on...
var data = [
{
label: "title 1",
value: 32,
color: "#444334"
}, {
label: "title 2",
value: 51,
color: "#f0f0f0"
}, {
label: "title 3",
value: 17,
color: "#8ba43a"
}];
Check image attached (sorry about bad graphic)
Thanks.
You can do this with jqplot or chart.js
An example from jsplot:
$(document).ready(function(){
var s1 = [['a',6], ['b',8], ['c',14], ['d',20]];
var s2 = [['a', 8], ['b', 12], ['c', 6], ['d', 9]];
var plot3 = $.jqplot('chart3', [s1, s2], {
seriesDefaults: {
// make this a donut chart.
renderer:$.jqplot.DonutRenderer,
rendererOptions:{
// Donut's can be cut into slices like pies.
sliceMargin: 3,
// Pies and donuts can start at any arbitrary angle.
startAngle: -90,
showDataLabels: true,
// By default, data labels show the percentage of the donut/pie.
// You can show the data 'value' or data 'label' instead.
dataLabels: 'value'
}
}
});
});
According to the jqplot page, it requires minimum of jquery 1.9.1, along with it's main jqplot, plus jqplot pieRenderer/donutRenderer scripts and the jqplot css.
The code above will produce something like this:
You can add another series, which will create a third circle.

Define Div text in JavaScript var String

I need Define Div(chartContainer1) value in a JavaScript "Var" So that it can be defined in JavaScript Chart Unfortunately am unable to do
HTML:code
<div id="chartContainer" style="height: 300px; width: 100%;">
<div id="chartContainer1">[
{y: 10, legendText:"Wii U", label: "Wii U 10%"},
{y: 13, legendText:"3DS", label: "3DS 13%"},
{y: 18, legendText:"PS3", label: "PS3 18%"},
{y: 20, legendText:"Xbox One", label: "Xbox One 20%"}
];</div>
Chart Code:
I have tried With
var dsp = document.getElementById("mySpan").innerHTML;
var dps = document.getElementById("chartContainer1").innerText;
dataPoints is the place Where i need to define text of Div
var chart = new CanvasJS.Chart("chartContainer",{
title :{
text: "Test title"
},
data: [{
type: "stackedBar100",
dataPoints : dps,
showInLegend: true,
toolTipContent:"{label}"
}],
});
chart.render();
You could use eval to turn it into an object
var dps = eval(document.getElementById("chartContainer1").innerText);
But be warned about using eval Why is using the JavaScript eval function a bad idea?
It is not a good practice storing the data inside a DIV that way, because that JSON data will get displayed on the screen before the chart is rendered.
Please read : https://developer.mozilla.org/en-US/docs/Web/Guide/HTML/Using_data_attributes
Instead, if you really want to attach the data along with a particular HTML element, you should store it in a data-something attribute like this:
<div id="chartContainer1" data-content='[
{"y": 10, "legendText":"Wii U", "label": "Wii U 10%"},
{"y": 13, "legendText":"3DS", "label": "3DS 13%"},
{"y": 18, "legendText":"PS3", "label": "PS3 18%"},
{"y": 20, "legendText":"Xbox One", "label": "Xbox One 20%"}
]'></div>
And fetch the data from the attribute for render by:
var dps = JSON.parse(document.getElementById("chartContainer1").dataset.content);
Or classically,
var dps = JSON.parse(document.getElementById("chartContainer1").getAttribute("data-content"));

how do you set the yaxis values in highcharts

my json data looks like this:
[
[1362027751000, 1362027781000, 1362027811000, 1362027841000, 1362027871000, 1362027901000, 1362027931000, 1362027961000, 1362027991000, 1362028021000 ],
[ 66, 72, 69, 72, 69, 68, 71, 73, 63, 57 ],
[ 50, 5, 67, 72, 34, 100, 10, 100, 23, 56 ]
]
the first row is date in epoch time, the second is cpu utilization and the third is the memory utilization. I would like to create time series chart, date being on xaxis and CPU and mmeory data on yaxis with different lines. How would I accomplish this given the data provided with the json external file. I see examples where that the in the javascript but this is really not realistics. Any help is greatly appriciated.
I attempted to the following where I wanted to split cpu and memory. I am not getting any results back, empty page. Is this the way to address this or there are other ways to draw multiple variables in one chart?
my javascript looks like this:
<script type="text/javascript">
$(document).ready(function() {
var options = {
chart: {
renderTo: 'container',
type: 'area'
},
xAxis: {
type: 'datetime'
},
//series: [{}]
series: [{{
type: 'spline',
name: 'CPU',
data: cpu
}, {
type: 'spline',
name: 'memory',
data: memory
}}]
};
$.getJSON('data.json', function(data) {
options.series[0].data = data;
var cpu = [];
var memory=[];
for(i=0; i< data.length, i++) {
for(j=0; j<data[i].length; j++){
alert(data[i].length);
cpu.push([
data[i][j], // the date
data[1][j] // the cpu
]);
memory.push([
data[i][j], // the date
data[2][j] // the volume
])
}
}
var chart = new Highcharts.Chart(options);
//alert(JSON.stringify(data, null, 4));
});
});
</script>
the charts does not look right. It looks like xaxis and yaxix are both reporting the date value. Is there a way to set the yaxis values?
My preference is to send in the data for a series as [x,y] pairs. So your data would look like:
[
[1362027751000, 66], [1362027781000, 72], [1362027811000, 69], [1362027841000, 72], [1362027871000, 69], [1362027901000, 68], [1362027931000, 71], [1362027961000, 73], [1362027991000, 63], [1362028021000, 57 ]
]
and:
[
[1362027751000, 50], [1362027781000, 5], [1362027811000, 67], [1362027841000, 72], [1362027871000, 34], [1362027901000, 100], [1362027931000, 10], [1362027961000, 100], [1362027991000, 23], [1362028021000, 23]
]
You would need to send this in as 2 different series.data blocks.
for(i=0; i< data.length-2; i++) {
for(j=0; j<data[i].length; j++){
cpu.push([
data[i][j], // the date
data[1][j] // the cpu
]);
memory.push([
data[i][j], // the date
data[2][j] // the volume
])
}
}

Categories

Resources