How to pass series to plot options in highcharts - javascript

I am trying to update the series data option for 'pie' type chart:
I am using exporting buttons to display options to change chart type, all other chart types work well except pie which needs a different format of series data.
exporting: {
buttons: {
lineButton: {
text: 'line',
onclick: function () {
for(i=0;i<this.series.length;i++) {
this.series[i].update({
type: "line"
});
}
}
},
barButton: {
text: 'bar',
onclick: function () {
for(i=0;i<this.series.length;i++) {
this.series[i].update({
type: "column"
});
}
}
},
pieButton: {
text: 'pie',
onclick: function () {
var pieSeries = [];
$.each(category_totals, function(j, k) {
pieSeries.push( { name: j , y: k } );
});
for(i=0;i<this.series.length;i++) {
this.series[i].remove();
}
this.series = [{
name: title,
colorByPoint: true,
data: pieSeries
}];
this.series[0].update({
type: "pie"
});
}
}
}
...
And I get this error: Uncaught TypeError: this.series[0].update is not a function

The problem is that you sequentially remove the series from the chart, after each call the chart is redrawn and by the end of the for loop the chart doesn't have any series. When you do
this.series = [{
name: title,
colorByPoint: true,
data: pieSeries
}]
you are modifying the javascript object and therefore update method is not available when you try to do
this.series[0].update({
type: "pie"
});
because you are trying to call Highcharts method on a generic javascript object.
What you should do is
this.addSeries({
name: title,
colorByPoint: true,
data: pieSeries,
type: 'pie'
})
Also, a suggestion: pass argument false to remove method so that it it doesn't redraw every time. Just redraw when you add the new series.
So above call would look like
this.addSeries({
name: title,
colorByPoint: true,
data: pieSeries,
type: 'pie'
}, true)

1.
for(i=0;i<this.series.length;i++) {
this.series[i].remove();
}
The code above will not remove series items: see here
2.
The correct way to add series is:
this.addSeries({...});
3.
Final working code:
...
pieButton: {
text: 'pie',
onclick: function () {
var pieSeries = [];
$.each(category_totals, function(j, k) {
pieSeries.push( { name: j , y: k } );
});
while(this.series.length > 0) {
this.series[0].remove(true);
}
this.addSeries({
name: title,
colorByPoint: true,
data: pieSeries,
type: 'pie'
});
// As Rahul Sharma pointed out in comments above,
// you can pass the "type" option to
// addSeries method, making this call redundant
// this.series[0].update({
// type: "pie"
// });
}
}
...

Related

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'
}],
},
});

Highcharts X-axis labels on the side

I'm using Highcharts, and I used to be able to get labels on the side. But it's not working now, am I missing something? The red arrow is where I would want the labels like in the following example.
http://jsfiddle.net/gh/get/jquery/1.9.1/highslide-software/highcharts.com/tree/master/samples/highcharts/demo/bar-basic/
This is the code I'm using, I add the series in a dynamic way.
credits: {
enabled: false
},
chart: {
type: 'bar'
},
xAxis: {
categories: ['Jan', 'Feb'],
labels: {
enabled: true,
}
},
yAxis: {
min: 0,
max: 100,
title: {
text: 'Score',
align: 'high'
}
},
plotOptions: {
bar: {
dataLabels: {
enabled: true
}
}
}
});
// Add Series
var detailchart = $('#chart-detail').highcharts();
var categories = new Array;
// Set Chart Title
detailchart.setTitle({text: results[0].category});
$.each(results, function(i, data){
categories.push(data.name);
detailchart.addSeries({
name: data.name,
data: [data.score]
});
});
detailchart.xAxis[0].setCategories(["1", "2"]);
$('#chart-detail').highcharts().reflow();
Results is an array that looks like this (I get it through ajax):
As I understand from your code here, you wish to specify two categories with names 1 and 2 but you are not specifying any data for second category, So the only category that is showing on your chart is 1. Your data array for each series must have elements per each category. For example if you have two category you should consider having two data elements in each series. In this line data: [data.score] you are just specifying one element in data array. Your code should be something like this: (make it dynamic per your need)
$.each(results, function(i, data){
categories.push(data.name);
detailchart.addSeries({
name: data.name,
data: [data.score, 40], //40 is some data for your second category.
});
});
Demo: http://jsfiddle.net/u6crkatv/
Only what you need is use 4 series, each of them with single data point.
series: [{
name: 'Year 1800',
data: [107]
}, {
name: 'Year 1900',
data: [138]
}, {
name: 'Year 2008',
data: [973]
},{
name: 'Year 20098',
data: [973]
}]
Example: http://jsfiddle.net/y9wzggc4/

highcharts; add arbitrary data which lasts when rendered

let's say I am generating chart json that might look something like this:
return jsonify({
chart: {
post_url: '/some/url/'
type: column
},
title: {
text: this is a chart
},
tooltip: {
shared: true
},
xAxis: {
categories: [x[0].strftime('%b %y') for x in arr]
},
plotOptions: {
column: {
stacking: normal
}
}
series: [{
data: [[x.thing for x in month].count(True) for month in arr]
}, {
data: [[x.thing for x in month].count(False) for month in arr]
}]
})
In setOptions, I do the following.
Highcharts.setOptions({
plotOptions: {
series: {
cursor: 'pointer',
point: {
events: {
click: function(el) {
$.post(this.chart.post_url + this.category, function(data) {
console.log(data);
});
}
}
}
}
}
});
However, this does not allow me to click and go to the post url, saying post_url is not defined. So I imagine that data is lost when the chart is rendered.
What's a way around this?
The this in a point.events.click referres to a point object and not a chart object. You can walk backwards to the chart configuration using this.series.chart.userOptions.chart.post_url like so:
point: {
events: {
click: function() {
alert(this.series.chart.userOptions.chart.post_url);
}
}
}
Here's an example fiddle.
If I understand correctly you want to have the series.points go to a URL when you click on them? You are missing an ending comma after your post_url definition and quotes around the type value. That being said I would set the URL in the series options and not the chart options. Then you might need to set it like:
series: [{
post_url: '/some/url/',
data: [[x.thing for x in month].count(True) for month in arr]
}, {
post_url: '/some/url/',
data: [[x.thing for x in month].count(False) for month in arr]
}]
Then in the click event:
events: {
click: function(el) {
$.post(this.post_url + this.category, function(data) {
console.log(data);
});
}
Demo.
If you still want to use the chart.post_url method you need to fix your typos. Demo.

Displaying a json file with highstock

I have some difficulties displaying a graph with Highstock. It seems like I can't have access to the x-axis part where the graph should be displayed. I am new with Highstocks so my code could seem like a mess but my idea was the following:
First access the json file from the server. Convert it in the right format [[datestamp, value], ....]. Then display the graph.
Here is my Json file (file.json):
[{"date":"2013-10-04T22:31:12.000Z","value":30000},{"date":"2013-10-04T22:31:58.000Z","value":35000},{"date":"2013-10-04T22:32:05.000Z","value":60000},{"date":"2013-10-04T22:32:12.000Z","value":45000}]
My code is the following:
$(function() {
chartOjb = new Object();
var mydata = [];
$.getJSON('file.json', function(data) {
$.each(data, function (index, item) {
chartOjb.name = getTimestamp(item.date);
chartOjb.data = item.value;
mydata.push({ x: chartOjb.name, y: parseFloat(chartOjb.data) });
});
$('#container').highcharts('StockChart', {
chart: {
type: 'candlestick',
zoomType: 'x'
},
navigator: {
adaptToUpdatedData: false,
series: {
data: mydata
}
},
scrollbar: {
liveRedraw: false
},
xAxis: {
type: 'datetime',
title: 'Time',
//minRange: 3600 * 1000/15 // one hour
},
rangeSelector : {
selected : 1
},
title : {
text : value
},
series : [{
name : 'Capacité',
data : data,
tooltip: {
valueDecimals: 2
}
}] }); });
});
Thank you very much for your help
Could you add your function getTimestamp()? Maybe there is something wrong.
Keep in mind that:
x-value should be timestamp,
when using a lot of objects { x: x, y: y }, set turboThreshold

Treeview checkbox selection with graph updation is not working properly

In my project i have chart and treeview while pageload chart update is not working properly means here in treeview only two checkboxes are checked in pageload but chart is displaying all the field values.i need to display only checkbox checked field values in chart while pageload,( after page-load it's working fine).
here is the fiddle: http://jsfiddle.net/RHh67/64/
My chart code:
$("#myChart").kendoChart({
theme: $(document).data("kendoSkin") || "default",
dataSource: {
data: tmpData2,
sort: {
field: "date",
dir: "asc"
},
schema: {
model: {
fields: {
date: {
type: "date"
}
}
}
}
},
title: {
text: "My Date-aware Chart"
},
legend: {
position: "bottom"
},
seriesDefaults: {
type: "line",
labels: {
visible: true
},
missingValues: "gap"
},
series: series,
valueAxis: [{
name: "A",
labels: {
format: "{0}%"
}
},
{
name: "B",
labels: {
format: "{0}D"
}
}],
categoryAxis: {
type: "Date",
field: "date",
axisCrossingValue: [0, 1000]
}
});
Define a redrawChart that refreshes the Chart with the new series as:
function redrawChart() {
var chart = $("#myChart").data("kendoChart");
var checkedSeries = [];
$("#treeview").find(":checked").each(function () {
var nodeText = $(this).parent().parent().text();
$.each(series, function (index, series) {
if (series.field == nodeText) {
checkedSeries.push(series);
}
});
});
chart.options.series = checkedSeries;
chart.refresh();
}
This functions needs to be invoked:
On your tree change.
After setting the initial visible series.
In addition, move the selection of the initial series to the end of the JavaScript code. I mean, first initialize treeview and chart and only then initialize the initial values.
tree.dataItem(".k-item:nth(2)").set("checked", true);
tree.dataItem(".k-item:nth(3)").set("checked", true);
updateChks();
redrawChart();
The complete running version is in here http://jsfiddle.net/OnaBai/RHh67/68/

Categories

Resources