I am using the bar chart. I want to add the new bar in the existing bar chart which is already drawn.
How to do that?
I have used the following
chartObject.series[i].addPoint(99, true);
But didn't get the result. It's automatically add the value with the default label name.
I want to insert the E bar with the value under A. How can I do that?
chartObject = Highcharts.chart('chartContainer', {
chart: {
type: 'bar'
},
title: {
text: ''
},
xAxis: {
categories: ["A", "B", "C", "D"],
title: {
text: null
}
},
yAxis: {
min: 0,
},
plotOptions: {
bar: {
dataLabels: {
enabled: true
}
},
series: {
cursor: 'pointer',
point: {
events: {
click: function () {
debugger
for (var i = 0; i < chartObject.series.length; i++) {
chartObject.series[i].addPoint(99, true);
}
alert('Category: ' + this.category + ', value: ' + this.y);
}
}
}
},
showInLegend: false
},
legend: {
enabled: false
},
credits: {
enabled: false
},
tooltip: {
enabled: false
},
series: [{
showInLegend: false,
data: [
50,
35,
25,
80
]
}]
});
Please refer to this jsfiddle: http://jsfiddle.net/kkulig/rhneon2q/
I think that one of the convenient ways to do this is to move categories definitions to name properties of points:
data: [
{y: 50, name: 'A'},
{y: 35, name: 'B'}
]
and change xAxis type to category:
type: 'category'
It's explained here: http://api.highcharts.com/highcharts/xAxis.categories
Then you can update chart with new point just like that:
UPDATE:
Code:
chartObject.series[i].addPoint({y: this.y, name: 'E'}, true);
Adds new point with category on the end of a serie.
If you wan't new point with category to appear after the clicked one, you can use this code:
var data = chartObject.userOptions.series[i].data.slice(); // clone original userOptions
data.splice(this.index + 1, 0, {
y: 10,
name: "New cat. " + (chartObject.series[i].data.length - 2) // 2 - initial categories number
});
chartObject.series[i].update({
data: data
});
END OF UPDATE
Unfortunately if you set categories like you did before:
categories: ["A", "B", "C", "D"]
name property of added point won't be used as category.
Related
Here is my js code:
Highcharts.stockChart('utilizations', {
chart: {
zoomType: 'x'
},
title: {
text: 'KPI'
},
subtitle: {
text: 'CCE & PRB Utilization (%)'
},
rangeSelector: {
buttons: [{
type: 'day',
count: 1,
text: '1d'
}, {
type: 'day',
count: 3,
text: '3d'
}, {
type: 'day',
count: 7,
text: '1w'
}, {
type: 'day',
count: 14,
text: '2w'
}, {
type: 'all',
text: 'All'
}],
selected: 1
},
yAxis: {
labels: {
formatter: function () {return this.value + '%';}
},
max: 100,
min: 0,
tickInterval: 20,
plotLines: [{
value: 0,
width: 2,
color: 'silver'
},{
value: 70,
width: 1,
color: 'red'
}]
},
tooltip: {
crosshairs: true,
shared: true
},
plotOptions: {
series: {
compare: 'value',
showInNavigator: true
}
},
legend: {
layout: 'vertical',
align: 'right',
verticalAlign: 'middle'
},
xAxis: {
type: 'datetime'
},
series: [{
name: 'CCE Util',
type: 'spline',
yAxis: 0,
data: (function(){
var data = [];
for (var i = 0; i < result.length; i++) {
var time = result[i]["time"];
var kpi = result[i]["cce"];
data.push([time, kpi]);
}
return data;
})(),
tooltip: {
valueSuffix: '%',
valueDecimals: 2,
split: true
}
},{
name: 'PRB Util',
type: 'spline',
yAxis: 0,
data: (function(){
var data = [];
for (var i = 0; i < result.length; i++) {
var time = result[i]["time"];
var kpi = result[i]["prb"];
data.push([time, kpi]);
}
return data;
})(),
tooltip: {
valueSuffix: '%',
valueDecimals: 2,
split: true
}
And my plot:
While dragging the navigator bar, sometimes the plot goes to the right position and sometimes it looks like the capture above. According to my experience, the plot position is related to the left end (let's note this as A) position of the navigator selector. When A is on the lowest part of the whole plot in navigator, the shown plot positioned well; and when A goes like the capture above, the plot shown sunk.
Please refer to a short demo with 100 data here: https://jsfiddle.net/ghqyvo0x/
How can I make my plot stable?
Your problem is caused by series.compare: property, which you set in plotOptions configuration object. If you delete this line of code, everything should work as you need. We could read in Highstock API:
Compare the values of the series against the first non-null, non- zero value in the visible range.
plotOptions: {
series: {
//compare: 'percent',
showInNavigator: true
}
}
JSFiddle example
API Reference
Currently i have my bar chart displaying a bar chart graph and for each bar the title and the data value is shown with no problem. But i would also like to add the id for each displayed bar because i have the bars clickable and with a click on a bar i would like to pass in the id of that individual bar so i can display page with another set of graphs particular to the item id that was passed in.
This is an example of the current json data that i am using to create my chart:
Array:...
{id: 1, uuid: "0ff158d7-09a7-41df-81d1-fd3ac752a967", name: "Example 1", percentage: 34}
{id: 2, uuid: "81aa6eb2-b6fe-4d14-a3ea-f5487b67784a", name: "Example 2", percentage: 0}
{id: 7, uuid: "b7d7fd90-d9af-4a56-aceb-20bfdeda3af4", name: "Example 3", percentage: 12}
....
This is how i am populating my chart:
var value: Array<any> = [];
var name: Array<any> = [];
var ids: Array<any> = [];
this.myService.getData(url).subscribe(
data => {
this.results = data;
this.results.map(function(result){
value.push(result.percentage);
name.push(result.name);
ids.push(result.id);
})
this.chart = {
title: {
text: '',
style: {
display: 'none'
}
},
credits: {
enabled: false
},
chart: {
type: 'bar'
},
xAxis: {
categories: name,
},
yAxis: {
min: 0,
max: 100,
labels: {
overflow: 'justify'
}
},
tooltip: {
valueSuffix: ' %'
},
plotOptions: {
bar: {
dataLabels: {
enabled: false
}
},
series: {
cursor: 'pointer',
point: {
events: {
click: function(event:any){
console.log(event.target.id);
}
}
}
}
},
series: [{
showInLegend: false,
data: value,
name: 'Demo'
}]
};
}
);
Currently when i click on a bar i could only get the name and its percentage. is there a way to pass in the whole object or at least include the id reference with each data value so i can extract it once clicked?
1.First proper data series has to be form
var dataObj=[{id: 1, uuid: "0ff158d7-09a7-41df-81d1-fd3ac752a967",
name: "Example 1", percentage: 34},
{id: 2, uuid: "81aa6eb2-b6fe-4d14-a3ea-f5487b67784a", name: "Example 2", percentage: 0},
{id: 7, uuid: "b7d7fd90-d9af-4a56-aceb-20bfdeda3af4", name: "Example 3", percentage: 12}];
var value=[];
for(var i=0;i<dataObj.length;i++){
value.push({name:dataObj[i].name,y:dataObj[i].percentage,uuid:dataObj[i].uuid,id:dataObj[i].id})
}
console.log(value);
2.PlotOptions will be
plotOptions: {
bar: {
dataLabels: {
enabled: false
}
},
series: {
cursor: 'pointer',
point: {
events: {
click: function(event){
console.log(event.point.id);
console.log(event.point.uuid);
}
}
}
}
},
Fiddle demo
I'm using one the official highstock chart demo to create something similar with 2 charts stacked on top of each other. The problem is that the bottom chart (volume) is not displayed jsfiddle
A brief explanation of aapl-ohlc.json file will be helpful.
...
const data = JSON.parse(document.getElementById('ohlc-data').innerHTML);
// split the data set into ohlc and volume
const ohlc = data.map((a) => [a[0], a[1], a[2], a[3], a[4]])
const volume = data.map((a) => [a[0], a[5]])
// set the allowed units for data grouping
const groupingUnits = [
[
'week', // unit name
[1] // allowed multiples
],
[
'month', [1, 2, 3, 4, 6]
]
]
// create the chart
Highcharts.stockChart('container', {
legend: {
enabled: false
},
credits: {
enabled: false
},
exporting: {
enabled: false
},
scrollbar: {
enabled: false
},
rangeSelector: {
selected: 4,
inputEnabled: false
},
title: {
text: ''
},
yAxis: [{
labels: {
align: 'right',
x: -3
},
title: {
text: ''
},
height: '60%',
lineWidth: 2
}, {
labels: {
align: 'right',
x: -3
},
title: {
text: ''
},
top: '65%',
height: '35%',
offset: 0,
lineWidth: 2
}],
tooltip: {
split: true
},
series: [{
type: 'candlestick',
name: 'AAPL',
data: ohlc,
dataGrouping: {
units: groupingUnits
}
}, {
type: 'column',
name: 'Volume',
data: volume,
yAxis: 1,
dataGrouping: {
units: groupingUnits
}
}],
navigator: {
enabled: false
}
});
This line:
const volume = data.map((a) => [a[0], a[5]])
Points to an element that doesn't exist. a[5] is not defined (there are only five elements to each sub array, no sixth element), therefore you have no y values in your data, and therefore no data series to display.
I don't know what data element is supposed to represent volume, but for reference, just to show that it does work, here is an updated fiddle using
const volume = data.map((a) => [a[0], a[1]])
https://jsfiddle.net/jlbriggs/0t9rq1f7/1/
EDIT:
Note that in the demo example that you based your fiddle on, the file that they use is aapl-ohlcv.json, not aapl-ohlc.json, which does in fact have a 6th data element in each sub array.
https://www.highcharts.com/samples/data/jsonp.php?filename=aapl-ohlcv.json
https://github.com/highcharts/highcharts/blob/master/samples/data/aapl-ohlcv.json
Hi I'm trying to update my piechart LIVE without redrawing the piechart, any advice?
this is the function that is being called
var i = 0;
setInterval(function(){
piecharts(i, 1, 2, 3, 4, 5);
i++;
},5000);
function piecharts(sector0Data, sector1Data, sector2Data, sector3Data, sector4Data, sector5Data)
{
$('#container').highcharts({
chart: {
plotBackgroundColor: null,
plotBorderWidth: null,
plotShadow: false,
type: 'pie',
options3d: {
enabled: false,
alpha: 45,
beta: 0
}
},
title: {
text: 'Number of person in each sector'
},
tooltip: {
pointFormat: '{series.name}: <b>{point.y}</b>'
},
plotOptions: {
pie: {
allowPointSelect: true,
cursor: 'pointer',
depth: 35,
dataLabels: {
enabled: true,
format: '<b>{point.name}</b>: {point.y} ', //change percentage to y for decimal value
style: {
color: (Highcharts.theme && Highcharts.theme.contrastTextColor) || 'black'
}
}
}
},
series: [{
name: 'Avg number of person in this sector over the total of ',
colorByPoint: true,
data: [{
name: 'Sector0',
y: sector0Data
},{
name: 'Sector1',
y: sector1Data
},{
name: 'Sector2',
y: sector2Data
},{
name: 'Sector3',
y: sector3Data
},{
name: 'Sector4',
y: sector4Data
}, {
name: 'Sector5',
y: sector5Data
}]
}]
});
}
For every 5 second, my i will increase by 1 and my pie-chart will be drawn, this works fine but it kept redrawing my chart. any advice? thanks. also, i'm using v4.1.8 of highchart
You should use the update() method for this. Init your chart on the DOM ready event and just call a function in order to update data :
Demo
function updatePiechart(sector0Data, sector1Data, sector2Data, sector3Data, sector4Data, sector5Data)
{
var chart = $('#container').highcharts();
chart.series[0].update({
data: [{
name: 'Sector0',
y: sector0Data
},{
name: 'Sector1',
y: sector1Data
},{
name: 'Sector2',
y: sector2Data
},{
name: 'Sector3',
y: sector3Data
},{
name: 'Sector4',
y: sector4Data
}, {
name: 'Sector5',
y: sector5Data
}]
})
}
The reason for the re-render is that you create a new chart every five seconds instead of updating its data.
You need to call the update method for your y point on your chart series data:
chart.series[0].data[0].update(y);
Here is a simple example on how to update the data: Update pie data jsfiddle
Or have a look at the documentation for live data
I'm playing around with a backbone marionette app trying to dynamically populate highcharts data but I'm running into some trouble.
I created a basic survey app and I wanted to create a chart that shows the results of each question. However I don't know how many questions the survey might have or how many answers each question might have.
So what I do is populate an array that looks like this answerArray[answerId] = numberOfTimesSelected like this:
questions: (survey) =>
questions = survey.get('questions')
questions.each (question) =>
length = question.get('answers').length
answers = question.get('answers')
answerArray = []
if length < 7
question.get('answers').each (answer) ->
answerArray[answer.id] = 0
survey.get('responses').each (response) =>
date = Math.floor(new Date(response.get('created_date')) / 86400000)
if date > (#minDate - 1) && date < (#maxDate + 1)
if response.get('completed')
choices = response.get('choices')
choices.each (choice) ->
if choice.get('question_id') == question.get('id')
answerArray[choice.get('answer_id')] = answerArray[choice.get('answer_id')] + 1
Now a highcharts chart is populated like this:
$('#' + question.get('id')).highcharts({
chart: {
marginRight: 50,
marginTop: 0,
plotBackgroundColor: null,
plotBorderWidth: null,
plotShadow: false
},
title: {
text: '',
style: {
fontSize: 10
}
},
tooltip: {
pointFormat: '<b>{point.percentage:.1f}%</b>'
},
credits: {
enabled: false
},
exporting: {
enabled: true
},
plotOptions: {
pie: {
size: 300,
allowPointSelect: true,
cursor: 'pointer',
dataLabels: {
enabled: false
},
showInLegend: true
}
},
series: [{
type: 'pie',
name: question.get('title'),
states: {
hover: {
brightness: 0
}
},
data: [
{
name: "14-17",
y: 22,
color: "#E8DF66"
},
{
name: "18-24",
y: 42,
color: "#8C8C8B"
},
{
name: "25-34",
y: 11,
color: "#687D68"
},
{
name: "35-44",
y: 55,
color: "#217C7E"
},
{
name: "45-54",
y: 231,
color: "#BEE7E8"
},
{
name: "55+",
y: 224,
color: "#634357"
}
]
}]
})
So I'm able to populate a graph for each question with that static data. But I need some way to dynamically change the data. Something like
data: [ question.get('answers').each (answer) ->
{
name: answer.get('title'),
y: answerArray[answer.get('id')],
color: "#E8DF66"
}
]
But that doesn't actually work. Any ideas how I could do something like that?
So I just ended up dynamically creating an object for each and then creating an array of those and using that array as the data.
Create the array/object:
graphData = []
question.get('answers').each (answer) ->
graphPiece = {}
graphPiece["name"] = answer.get('title')
graphPiece["y"] = answerArray[answer.get('id')]
graphPiece["color"] = "#E8DF66"
graphData.push(graphPiece)
Use the data in the highcharts graph:
series: [{
type: 'pie',
name: question.get('title'),
states: {
hover: {
brightness: 0
}
},
data: graphData
}]