I have been going in circles for a few hours with this and have exhausted all the similar stackoverflow threads and also highcharts docs, so hopefully someone can help.
I am trying to plot a pie chart with a gender split. I have worked with line charts before and so had my data in the format for x and y axis, like this:
[{"y":"Mr","x":"145"},{"y":"Miss","x":"43"},{"y":"Mrs","x":"18"},{"y":"Ms","x":"2"}]
This was getting me somewhere, i could tap into the json and pull out the ints but i couldnt for the life of me get the titles associated with the figures...
function genderData() {
$.getJSON('/statsboard/gender', function(data_g) {
$.each(data_g, function(key_g, val_g) {
obj_g = val_g;
genderChart.series[0].addPoint(parseInt(obj_g.x));
//genderChart.xAxis[0].categories.push(obj_g.y);
});
});
}
I then just called the function genderData as follows:
genderChart = new Highcharts.Chart({
chart: {
renderTo: 'gender',
events: {
load: genderData
}
}
title: {
text: 'Gender Split'
},
plotOptions: {
pie: {
allowPointSelect: true,
cursor: 'pointer',
dataLabels: {
enabled: false
},
showInLegend: true
},
},
series: [{
type: 'pie',
name: 'Gender Split',
data: []
}]
});
So i ended up with an accurate chart but with out the labels, and they would just default to 'slice'...
So close but no cigar ;-)
Soooo i altered my serverside code to return the following format as per the docs :-), now returning the following:
[{"Mr":"145"},{"Miss":"43"},{"Mrs":"18"},{"Ms":"2"}]
This looks pretty much spot on to me, but alas, when i try to accomodate for this on the js code, everything falls apart.
I have been looking at this:
Write JSON parser to format data for pie chart (HighCharts)
but cant get the practice applied here to fit my circumstances.. Can anyone help?
The forms:
[{"name": "Mr", "y": 145}, ...]
or
[["Mr", 145], ...]
will work. Notice the second form is an array of arrays not an array of objects (you were close).
See basic-pie demo (click view options and scroll down to data), series.data docs, and series.addPoint docs for more info.
If you make the server side return the data in one of the two above forms you can just do:
function genderData() {
$.getJSON('/statsboard/gender', function(data_g) {
genderChart.series[0].setData(data_g, true);
});
}
You can set your points as follows:
genderChart.series[0].addPoint({
name: key_g,
y: val_g
});
By rearranging my Json to have "name" and "y" as the keys i was able to make progress i.e:
[{"name":"Mr","y":"145"},{"name":"Miss","y":"43"},{"name":"Mrs","y":"18"},{"name":"Ms","y":"2"}]
Then by looping through the json data and parsing the "y" value as a int with the function parseInt() in the JS i was able to get my desired result...
function genderData() {
$.getJSON('/statsboard/gender', function(data_g) {
$.each(data_g, function(key_g, val_g) {
obj_g = val_g;
genderChart.series[0].addPoint({
name: obj_g.name,
y: parseInt(obj_g.y)
});
console.log(obj_g.y)
});
});
}
I know this question has been solved. but the map function for array might be a good choice in these cases, I love map in functional language!
data = [{"y":"Mr","x":"145"},{"y":"Miss","x":"43"},
{"y":"Mrs","x":"18"},{"y":"Ms","x":"2"}];
var series = data.map(function(e){ return parseInt(e.x); });
.... hight chart ....
Related
i am generating a Highchart, Instead of assigning each series separately i am assigning all the series data to the variable and assigning this variable to the series section but it is not working.
Here is my code for chart
var seriesdata='{name: '2019',data:[3883,3961,3893,3780,4021,3765,3560,4099,3310,3403,3628,3137,]},{name: '2020',data:[3489,3883,3403,3331,2605,949,]}';
and my assignment of series section in chart is
series: [seriesdata];
but it is not working.
Instead of this if i am using as
series=[{name: '2019',data:[3883,3961,3893,3780,4021,3765,3560,4099,3310,3403,3628,3137,]},{name: '2020',data:[3489,3883,3403,3331,2605,949,]}];
this one is working perfectly.
Kindly help me to solve the issue.
It seems that the data which you are trying to attach is a long string, meanwhile, Highcharts require an array of objects.
Please check this demo: https://jsfiddle.net/BlackLabel/9fzod2ur/
I suggest using this data format:
var seriesdata = [{
name: '2019',
data: [3883, 3961, 3893, 3780, 4021, 3765, 3560, 4099, 3310, 3403, 3628, 3137, ]
},
{
name: '2020',
data: [3489, 3883, 3403, 3331, 2605, 949, ]
}];
I am trying to get JSON from Poloniex's public API method (specifically the returnChartData method) to display chart history of cryptocurrencies against one another into a Highchart Stockchart graph (looking like the demo one here.).
This is part of my JavaScript code to use the Poloniex returnChartData callback, get the JSON from it and implement it into the 'data' segment of the chart. So far it is not working and I can't for the life of me figure out what I need to change.
var poloniexUrl = "https://poloniex.com/public?command=returnChartData¤cyPair=BTC_XMR&start=1405699200&end=9999999999&period=14400";
$.getJSON(poloniexUrl, function(data){
results = data;
});
// Creates Chart
var chart = new Highcharts.StockChart({
chart: {
renderTo: 'cryptoChart',
backgroundColor: 'white'
},
title: {
text: currentTitle
},
series: [{
data: results,
turboThreshold: 1000
}],
xAxis: {
original: false
},
rangeSelector: {
selected: 1
},
plotOptions: {
line: {
gapSize: 2
}
}
});
Would love any help!
Refer to this live demo: http://jsfiddle.net/kkulig/0f4odg5q/
If you use turboThreshold the points' options need to be given as an integer or an array (Explanation: https://api.highcharts.com/highstock/plotOptions.series.turboThreshold). In your case the format is JSON, so I disabled turboThreshold to prevent Higcharts error 12 (https://www.highcharts.com/errors/12):
turboThreshold: 0
$.getJSON is asynchronous - the best way to make sure that data variable is initialized is using it inside callback function (second argument of getJSON):
$.getJSON(poloniexUrl, function(data) {
// Creates Chart
var chart = new Highcharts.StockChart({
chart: {
(...)
The data that you fetch looks like candlestick series - I changed the type of the series:
type: 'candlestick'
Date will be properly understood by Highcharts if it's kept in the x property of JSON object (not date):
data: data.map((p) => {
p.x = p.date;
return p
}),
I'm trying to dynamically add annotations to my high charts in React. I'm using the addAnnotation function to add a new annotation whenever a hover event is triggered on my app, but the annotation does not render. I dropped a debugger into my code, and when I call chart.annotations I can see there is currently an array of annotations, but they are not rendering. I even have make a call to the addPlotLine in this function and the plotline is rendered on the chart. My config file looks like this
chart: {
annotations: [{
labelOptions: {
backgroundColor: 'rgba(0, 0, 0, 0.5)',
verticalAlign: 'top',
align: 'right',
}
}],
annotationsOptions: {
},
.... some lots more config options
}
and my on hover function to add the annotation is as follows
if( isNumber(value) )
//this renders a plotline
chart.xAxis[0].addPlotLine(baseChartHandle.generateInteractivePlotLine(value));
// this doesn't render my annotation however
chart.addAnnotation({
linkedTo: value,
title: {
text: "It works!"
}
});
}
I found that when I added annotations using Highcharts that the "linkedTo" function never worked despite my trials.
Despite adding a guid to my point, it never was able to apply it. I would suggest in your case adding it by x and y value, then finding the point that way instead. Here is how I have added annotations in the past successfully:
series.data.forEach(function (point) {
var annotationObject =
{
id: point.id,
labelOptions: {
y: 15,
verticalAlign: 'bottom',
distance: 25
},
labels: []
};
}
var text = <get text you want to push>;
annotationObject.labels.push(
{
point: {
xAxis: 0,
yAxis: 0,
x: point.x,
y: point.y
},
text: text
}
);
_chart.addAnnotation(annotationObject);
});
I also found a bug in HighCharts when using remove annotations, as a heads up. Each point will need an id like above, but it should be called by this line:
_chart.removeAnnotation(id);
It will remove the annotation, however you will get lots of complaints from highcharts if you try to do anything after, and it will break. I found the answer here, in annotations.js :
The red box is code I added. If you do removeAnnotation(ann.id), and it rerenders, it will fail because the labels object is null. Adding this check lets you do that without the labelCollectors failing.
Happy charting.
I am trying to get data to load on my chart from an API. All the data is getting to the chart correctly, but the chart doesn't load and I get the unresponsive script error. I'm using Highcharts. Any suggestions? Thanks. My code is below.
Model
public function ajax_get_chart() {
$quotes = $this->rest->get('api/1/BTCUSD/trades/fetch');
$series_data = array();
$results = $quotes->return;
$i = 0;
foreach ($results as $quote)
{
$series_tmp = array(
'date' => $quote->date,
'price' => $quote->price
);
$series_data[]= $series_tmp;
$i= $i+1;
}
die (json_encode($series_data));
return TRUE;
}
Javascript
$(document).ready(function() {
var chart;
$.ajax({
url: "/chart/ajax_get_chart", // the URL of the controller action method
dataType: "json",
success: function(result)
{
chart = new Highcharts.Chart({
chart: {
renderTo: 'container',
defaultSeriesType: 'bar'
},
title: {
text: 'Stacked bar chart'
},
xAxis: {
title: {
text: 'Price'
}
},
yAxis: {
min: 0,
title: {
text: 'Date'
}
},
legend: {
backgroundColor: '#FFFFFF',
reversed: true
},
tooltip: {
formatter: function() {
return ''+
this.series.name +': '+ this.y +'';
}
},
plotOptions: {},
series: result
});
}
});
});
Sounds like the problem is that there's too much data to present.
You can try using a speedier browser (Chrome usually works pretty fast), limiting the data, or trying another charting library.
Limiting the data is probably the most likely one to work. If you need to show all the data, the best way to go about it would be to only load partial data and then if the user for example scrolls the chart, load the missing data.
Another way to present more data at the same time would be to calculate averages for the data on server. For example, if the ticker data is from every second, you could pre-calculate hourly or even daily averages on the server. This generally allows you to show a relatively accurate chart without causing performance problems, and many libraries also support dynamically loading more accurate data if you zoom the chart.
Highcharts can not handle so huge number of data, but using Highstock with dataGrouping or lazy-loading you should be able to handle a lot of points, see demo.
Also this article should help.
In flot, how can I create a pie chart where each wedge is a link to a different web-page?
I gave it a shot, but I wasn't able to do it. I started with this example, then added:
grid: { clickable: true },
right above the "pie: {" line. Then I added a plotclick function at the end:
$("#placeholder").bind("plotclick", function (event, pos, item) {
alert('click!');
for(var i in item){
alert('my '+i+' = '+ item[i]);
}
});
You'll see the "click!" message, but "item" has no properties.
I was thinking you'd just add URLs to the data ojects, then forward the browser to the appropriate URL from within the plotclick function. If you figure it out, I'd be interested to know!
Update: Here's something that might work -- it just turns the labels into links. Put the URLs in your data like this:
$.plot($("#placeholder"), [
{ label: "Serie1", data: 10, url: "http://stackoverflow.com"},
{ label: "Serie2", data: 30, url: "http://serverfault.com"},
{ label: "Serie3", data: 90, url: "http://superuser.com"},
{ label: "Serie4", data: 70, url: "http://www.google.com"},
{ label: "Serie5", data: 80, url: "http://www.oprah.com"},
{ label: "Serie6", data: 110, url: "http://www.realultimatepower.net/"}
],
Then set the labelFormatter to something like:
return ''+serie.label+'<br/>'+Math.round(serie.percent)+'%';
Clicking in the pie wedges themselves still does nothing special, though.
I know this is an old thread but I have discovered another way of doing this.
Make sure grid is set to clickable
var data = [{
"label" : "series1",
"data" : 24,
"url" : "http://stackoverflow.com"
},
{
// etc etc
}];
$.plot($('.chart'), data, function() {
// Your options
grid: {
clickable:true
}
});
Bind a click function to the element and use javascript to redirect to the url.
$('.chart').bind("plotclick", function(event,pos,obj) {
window.location.replace(data[obj.seriesIndex].url);
});
Adding to the answer by Derek Kurth...
It looks like flot is ignoring any additional objects that we include in the JSON. For example when I used
data: [10, 0, "http://stackoverflow.com"]
// 0 is used as an intercept value for y-axis
it worked without any trouble and I was able to access the data from the event handler like
$("#placeholder").bind("plotclick", function (event, pos, item) {
alert(item.series.data);
});
I am new to this flot library and not great at JavaScript. So probably this is not the right way to do things but it works. I have always felt that embedding additional information in UI elements in HTML is a pain :(