Change chart subtitle programmatically - javascript

Maybe not the best title, but what I'm trying to do is change the subtitle of my chart to include the last temperature displayed in it. Something like this
Last value: 4 degrees
The chart's data is in a csv file.
$(document).ready(function () {
var lastVal = 0;
$.get('csv/Temp.csv', function (csv) {
$('#Temp').highcharts({
chart: {
type: 'spline',
zoomType: 'xy'
},
data: {
csv: csv
},
title: {
text: 'Outside Temperature'
},
subtitle: {
text: 'Last value: '
},
yAxis: {
title: {
text: 'Units'
}
}
});
});
});
If I change the subtitle to:
subtitle: {
text: function () {
lastVal = this.yData[this.yData.length - 1];
return 'Last Value: ' + lastVal;
}
},
I only get the text. How do I do this?

You can change the chart subtitle programmatically using the function (API):
chart.setTitle(Object title, object subtitle, Boolean redraw)
An example would be:
chart.setTitle(null, { text: "New subtitle" }, true);
If you want this to happen on load with data from CSV, you could do it like this (JSFiddle):
chart: {
events: {
load: function(event) {
var lastValue = this.series[0].data[this.series[0].data.length-1].y;
this.setTitle(null,{ text: 'Last y-value: '+lastValue }, true);
}
}
}

Related

Generate javascript and html blocks on the fly

In my website, I'm currently using 3 csv files, that are rendered by highcharts with the following javascript:
$(document).ready(function() {
$.get('export_xxxx.csv', function(csv) {
$('#xxx').highcharts({
data: {
csv: csv
},
title: {
text: 'Twitter (#xxxxx)'
},
yAxis: {
allowDecimals: false,
title: {
text: 'Users'
}
},
series: [{
visible: true
}, {
visible: false
}],
plotOptions: {
line: {
dataLabels: {
enabled: true
}
}
},
});
});
});
$(document).ready(function() {
$.get('export_xxxxyy.csv', function(csv) {
$('#xxx').highcharts({
data: {
csv: csv
},
title: {
text: 'Twitter (#xxxx)'
},
yAxis: {
allowDecimals: false,
title: {
text: 'Users'
}
},
series: [{
visible: true
}, {
visible: false
}],
plotOptions: {
line: {
dataLabels: {
enabled: true
}
}
},
});
});
});
$(document).ready(function() {
$.get('export_xxx_.csv', function(csv) {
$('#xxx').highcharts({
data: {
csv: csv
},
title: {
text: 'Twitter (#xxx)'
},
yAxis: {
allowDecimals: false,
title: {
text: 'Users'
}
},
series: [{
visible: true
}, {
visible: false
}],
plotOptions: {
line: {
dataLabels: {
enabled: true
}
}
},
});
});
});
and 3 html lines (It's like a dashboard).
<div id="xxx" style="width: 49%; height: 400px; margin: 0 auto;float:left;"></div>
My wish is to craft an HTML page with javascript of highcharts, to handle as many as csv there is in the DocumentRoot of my website.
For example, if I put 10 csv files, the generic HTML file will display 10 different charts on the same page, without editing manually the HTML page and add javascript too. Generated on the fly, in function of how many csv file there is.
Thanks for your help,
Instead of Repetitive code you can wrap your common code into function and call when you need to render chart with data.
renderCharts function accept csv data and id value.
function renderCharts(data,key){
$('#' + key).highcharts({
data: {
csv: data
},
title: {
text: 'Twitter (#xxx)'
},
yAxis: {
allowDecimals: false,
title: {
text: 'Users'
}
},
series: [{
visible: true
}, {
visible: false
}],
plotOptions: {
line: {
dataLabels: {
enabled: true
}
}
}})
};
$(document).ready(function() {
var ids = ['export_xxx_.csv','export_xxxxyy.csv','export_xxxxyyddd.csv'];
var promises = [];
ids.forEach(function(id){
promises.push($.get(id));
});
$.when(promises).then(function(values){
values.forEach(function(value){
renderCharts(value,'xxx');
})
});
}
Assuming your webserver gives a JSON response for list of files, say like this,
[ '/data1.csv', /date2.csv', ... ]
You can use something like this
$.get('/data', function(listOfFiles) {
for (var i = 0; i < listOfFiles.length; i++) {
$('body').append('<div id="chart' + i + '" style="width: 49%; height: 400px; margin: 0 auto;float:left;"></div>');
$.get(listOfFiles[i], function(csv) {
$('#chart' + i).highcharts({
.....
});
});
}
});
Ideally though, you should have a API retrieving data from a
database instead of using files.

Can't show array values in console log outisde of loop?

I push array outside loop with (cpu_usage, timestamp and clientID).Now i want to read on console log values of clientID console.log(result[0][2]); .But it shows me a error "Cannot read property '2' of undefined". Is someone knows where is a problem ? Also if i call this array inside loop it works
content of array:
error after i used console.log(result[0][2]);
<div id="cont"></div>
<script type="text/javascript">
$.getJSON( "http://localhost:8000/api/devices", function( res) {
var result= [];
var devNames = new Array();
console.log(result[0][2]);
$.each( res, function(i) {
var deviceNames=data[i].clientAllias;
var clientId=data[i].clientId;
devNames .push(deviceNames);
$.each( res[i].clientData, function(a) {
$.each( res[i].clientData[a], function(key, val) {
clientId2=res[i].clientData[a].clientId
var cpu=res[i].clientData[a].cpuUsage;
var time_usages=res[i].clientData[a].timestamp;
final=[];
final.push(time_usages, cpu, clientId2);
result.push(final);
});
});
});
result.sort();
$(document).ready(function(){
var Object = {
marker: {
states: {
enabled: true,
}
},
rangeSelector: {
buttons: [{
count: 1,
type: 'minute',
text: 'Sec'
}, {
count: 1,
type: 'hour',
text: 'Min'
},
{
count: 1,
type: 'day',
text: 'Hours'
},
{
type: 'all',
text: 'All'
}],
title:'hours',
inputEnabled: true,
_selected: 1
},
title: {
text: clientNames,
},
xAxis: {
title: {
enabled: true,
text: 'CPU USAGE'
},
type: 'datetime',
dateTimeLabelFormats: {
second: '%H:%M:%S',
minute: '%H:%M',
hour: '%H:%M',
},
},
plotOptions: {
series: {
marker: {
enabled: false,
}
}
},
series: [{
name:"CPU USAGE",
data: result,
}],
chart: {
renderTo: 'cont'
}
};
var chart = new Highcharts.StockChart(dataObject);
//var chart = $('#container').highcharts('StockChart', dataObject);
});
});
</script>
You’re console logging at the wrong spot. There’s nothing in result when you’re logging so it errors out when you try to access a nested element.
Put the console log at the end (after result.sort()) and you should get what you need

How do I attach a click event handler to null data points on HighMaps

I have already tried changing the data (null to some out of range number) and toying with colorAxis min and mas and color stops and while that works if it where a single map, it does not work for what I am doing.
I really need to be able to hang code on a click event.
Thanks
https://jsfiddle.net/alex_at_pew/nbz9npyg/5/
$(function () {
// Instantiate the map
$('#container').highcharts('Map', {
plotOptions: {
map: {
events: {
mouseOver: function (e) {
console.log(e);
}
}
}
},
chart : {
borderWidth : 1
},
title : {
text : 'Nordic countries'
},
subtitle : {
text : 'Demo of drawing all areas in the map, only highlighting partial data'
},
legend: {
enabled: false
},
colorAxis: {
dataClasses: [{
from: -100,
to: 1,
color: '#C40401',
name: 'pseudonull(1s are the new null)'
}],
},
series : [{
name: 'Country',
mapData: Highcharts.maps['custom/europe'],
data: [
{
code: 'DE',
value: 1
}, {
code: 'IS',
value: 2
}, {
code: 'NO',
value: 2
}, {
code: 'SE',
value: 2
}, {
code: 'FI',
value: 2
}, {
code: 'DK',
value: 2
}
],
joinBy: ['iso-a2', 'code'],
dataLabels: {
enabled: true,
color: 'white',
formatter: function () {
if (this.point.value > 1) {
return this.point.name;
} else if(this.point.value == 1) {
return 'this is "null"';
}
}
},
tooltip: {
headerFormat: '',
pointFormat: '{point.name}'
}
}]
});
});
I am not very sure about what you try to achieve, but from my understanding, you want to attach click events to countries with NULL values.
I have created this example here: http://jsfiddle.net/on6v5vhr/
Apparently, if a country has a NULL value, it won't be able to have click events, but what I've done is to simulate this behaviour so I went through these steps:
Process your data and give all the null value the same particular value (France was null so I gave it the value of -999)
{code: 'FR', value: -999}
Show datalabels only for the countries that have a value and that values is different than -999
formatter: function() {
if (this.point.value && (this.point.value !== -999)) {
return this.point.name;
}
}
Show tooltip only for the countries that have a value different than -999
tooltip: {
formatter: function() {
if (this.point.value !== -999) {
return this.point.name;
} else {
return false;
}
}
}
Manually set the color same as the NULL color for all countries that have the value of -999
colorAxis: {
dataClasses: [{
from: -100,
to: 1,
color: '#C40401',
name: 'pseudonull(1s are the new null)'
}, {
from: -999,
to: -999,
color: 'rgba(0,0,0,0)',
name: 'No data'
}],
}

Populate JSON object to highchart bar chart

I am newbie parsing JSON object to highchart and I would like to plot basic bar graph.
I have done on the title of graph. The problem is that the series that I would like to show is not showing.(count as series and qpAnswer as xAxis).
Here is my JSON data
[
{
qpQuestion: "Is that a dog?",
qpAnswerId: "1",
qpAnswer: "Yes",
count: "0"
},
{
qpQuestion: "Is that a dog?",
qpAnswerId: "2",
qpAnswer: "No",
count: "0"
},
{
qpQuestion: "Is that a dog?",
qpAnswerId: "3",
qpAnswer: "ok",
count: "0"
}
]
Here is my JS
var url="sections.php?request=graph";
$.getJSON(url,function(data1){
var options={
chart: {
renderTo: 'container',
type: 'column'
},
title: {
text: data1[0].qpQuestion
},
xAxis:{
categories: data1.qpAnswer
title: {
text: 'Answer'
}
},
yAxis: {
min: 0,
title: {
text: 'Answer Count'
}
},
series:data1
};
var chart = new Highcharts.Chart(options);
});
You can pre-process the data to form like
var answers = ['Yes','No' ,'OK'];
var answer_counts= [
{name: 'Yes', data : [2,0,0]},
{name: 'No', data: [0,3,0]},
{name: 'OK', data: [0,0,1]} ];
Then plot it with
var options={
chart: {
renderTo: 'container',
type: 'column'
},
title: {
text:'QA Answers'
},
xAxis:{
categories: answers,
title: {
text: 'Answer'
}
},
yAxis: {
min: 0,
title: {
text: 'Answer Count'
}
},
series:answer_counts
};
var chart = new Highcharts.Chart(options);
I have done in the fiddle, http://jsfiddle.net/gwC2V/1/
Let us know if it helps.
Below Example can help you
The JSON file
[
[1,12],
[2,5],
[3,18],
[4,13],
[5,7],
[6,4],
[7,9],
[8,10],
[9,15],
[10,22]
]
use getJSON() to retrive data from JSON file and Populate to CHART
$(document).ready(function() {
var options = {
chart: {
renderTo: 'container',
type: 'spline'
},
series: [{}]
};
$.getJSON('data.json', function(data) {
options.series[0].data = data;
var chart = new Highcharts.Chart(options);
});
});
Here is link

ExtJS 4.1 - Pie chart refresh

I have some problem with pie charts on ExtJS 4.1.
I load by Ajax and Json the datastore:
Ext.define('MyModel', {
extend: 'Ext.data.Model',
fields: ['status', 'data', 'data1', 'data2']
});
var store1 = Ext.create('Ext.data.JsonStore', {
model: 'MyModel',
proxy: {
type: 'ajax',
url : 'PieChartJsonServlet',
},
autoLoad: true
});
I would like to display pie charts representing:
1) data by status
2) data1 by status
3) data2 by status
To display each pie chart, I click on buttons from tbar on a panel.
When I load HTML page, the first chart (data by status) is correctly loaded and display.
My problem is after clicking on buttons from tbar, data seem to be loaded but pie chart doesn't refresh! (When I highlight slices, I display loaded data and I see data are well loaded)
My code:
Ext.require('Ext.chart.*');
Ext.require(['Ext.layout.container.Fit', 'Ext.window.MessageBox']);
Ext.require('Ext.JSON.*');
Ext.onReady(function () {
Ext.define('MyModel', {
extend: 'Ext.data.Model',
fields: ['status', 'data', 'data1', 'data2']
});
var store1 = Ext.create('Ext.data.JsonStore', {
model: 'MyModel',
proxy: {
type: 'ajax',
url : 'PieChartJsonServlet',
},
autoLoad: true
});
var titlePieChart = 'Data by status',
dataToDisplay = 'data',
highlightToDisplay = ' data',
chart = Ext.create('Ext.chart.Chart', {
xtype: 'chart',
animate: true,
store: store1,
shadow: true,
legend: {
position: 'right'
},
insetPadding: 60,
theme: 'Base:gradients',
items: [{
type : 'text',
text : titlePieChart,
font : '18px Arial',
width : 100,
height: 30,
x : 155,
y : 30
}],
series: [{
type: 'pie',
field: dataToDisplay,
showInLegend: true,
tips: {
trackMouse: true,
width: 180,
height: 35,
renderer: function(storeItem, item) {
var total = 0;
store1.each(function(rec) {
total += rec.get(dataToDisplay);
});
this.setTitle(storeItem.get('status') + ' : ' + storeItem.get(dataToDisplay) + highlightToDisplay + '\n(' + Math.round(storeItem.get(dataToDisplay) / total * 100) + '%)');
}
},
highlight: {
segment: {
margin: 20
}
},
label: {
field: 'status',
display: 'rotate',
font: '18px Arial',
}
}]
});
var panel1 = Ext.create('widget.panel', {
width: 600,
height: 500,
renderTo: 'chartCmp',
layout: 'fit',
tbar: [{
text: 'Data',
handler: function(button, evt) {
titlePieChart = 'Data by status',
dataToDisplay = 'data';
highlightToDisplay = ' data',
chart.refresh(); // Doesnt' work !
}
}, {
text: 'Data 1',
handler: function(button, evt) {
titlePieChart = 'Data1 by status',
dataToDisplay = 'data1';
highlightToDisplay = ' data1',
chart.refresh(); // Doesnt' work !
}
}, {
text: 'Data 2',
handler: function(button, evt) {
titlePieChart = 'Data2 by status',
dataToDisplay = 'data2';
highlightToDisplay = ' data2',
chart.refresh(); // Doesnt' work !
}
}],
items: chart
});
});
Each line "chart.refresh();" from tbar doesn't work whereas I would like a refreshed chart.
For information, I use ExtJS 4.1 on java web application.
With these lines of code for tbar, it works :
tbar: [{
text: 'Data',
handler: function(button, evt) {
titlePieChart = 'Data by status',
dataToDisplay = 'data';
chart.series.first().field = dataToDisplay,
highlightToDisplay = ' data',
chart.refresh();
}
}, {
text: 'Data 1',
handler: function(button, evt) {
titlePieChart = 'Data1 by status',
dataToDisplay = 'data1';
chart.series.first().field = dataToDisplay,
highlightToDisplay = ' data1',
chart.refresh();
}
}, {
text: 'Data 2',
handler: function(button, evt) {
titlePieChart = 'Data2 by status',
dataToDisplay = 'data2';
chart.series.first().field = dataToDisplay,
highlightToDisplay = ' data2',
chart.refresh();
}
}],

Categories

Resources