I'm wanting to create a combo line/column chart where the line points are discreetly presented (1 for each day) and then have columns with other values for a given date range (say, by month), and have the line points show in that month. Is this possible in Highcharts?
I'm guessing I'd need to create categories for the X axes (months) but am unsure how to retain the day-level detail in my line series as it seems like a 1:1 mapping?.
In the example below, is it possible to "group" the last line points between say Sept and Nov? Attempt at adding and grouping an additional (test) series to stock example:
{
name: 'Foo',
type: 'line',
data: [20, 34.8, 39.3, 41.4, 47.0, 48.3, 59.0, 59.6, 52.4, 65.2, 59.3, 51.2, 90, 40, 22, 10, 12, 30, 36, 50],
pointPadding: 0.2,
grouping: true
},
https://jsfiddle.net/023a1ypj/
Any tips appreciated
I am using advanced accessible high charts and I need to be able to increase and decrease the height of gridlines based on the data points for a particular series. If the data points for a particular series is less than 10 I want the height of the gridline to be 30 px else if the data points is between 10 and 15 I want the height to be 50px if the data points are more than 20 i will need the gridline height to be 100px
The only solution that came to my mind is to attach each series into an independent axis which allows setting each axis height (in percentage or pixel value).
xAxis: [{
height: '30%',
}, {
height: '60%',
top: '30%',
offset: 0
}, {
top: '80%',
height: '10%',
offset: 0
}],
series: [{
data: [2, 3, 4],
xAxis: 0
}, {
data: [10, 12],
xAxis: 1
}, {
data: [10, 12],
xAxis: 2
}]
Demo: https://jsfiddle.net/BlackLabel/8pu13s7d/
API: https://api.highcharts.com/highcharts/yAxis.height
API: https://api.highcharts.com/highcharts/yAxis.top
I am a bit confused by the documentation regarding the notation for point values when it comes to 3+ value charts such as HeatMap and BoxPlot.
I see that point values can be supplied as n length arrays:
data: [
[760, 801, 848, 895, 965],
[733, 853, 939, 980, 1080]...
]
And that they can be config objects with additional/custom properties:
data: [{
name: 'Point 1',
color: '#00FF00',
x: 1,
y: 3
}, {
name: 'Point 2',
color: '#FF00FF',
x: 2,
y: 5
}]
But how does one use the config object notation for HeatMap/BoxPlot when the only documented value properties seem to be 'x' and 'y'?
Is there a supported property of the config object that will be interpreted as the n length array? Something like this?
data: [{
name: 'Point 1',
color: '#00FF00',
values: [1,2,3]
}, {
name: 'Point 2',
color: '#FF00FF',
values: [4,5,6]
}]
It depends on the type of chart.
For HeatMap (reference):
A heat map has an X and Y axis like any cartesian series. The point definitions however, take three values, x, y as well as value, which serves as the value for color coding the point. These values can also be given as an array of three numbers.
In other words you could do { x: 0, y: 1, value: 10 } or [0,1,10].
For BoxPlot (reference):
Each point in a box plot has five values: low, q1, median, q3 and high. Highcharts recognizes three ways of defining a point:
Object literal. The X value is optional.
{ x: Date.UTC(2013, 1, 7), low: 0, q1: 1, median: 2, q3: 3, high: 4 }
Array of 5 values. The X value is inferred.
[0, 1, 2, 3, 4]
Array of 6 values. The X value is the first position.
[Date.UTC(2013, 1, 7), 0, 1, 2, 3, 4]
As shown in the picture (which is not the same code as the fiddle, but exhibits the problem), with Highcharts new bubble charts it seems like dataLabels like to sit on top of each other. Is there an easy workaround for this? I'd be happy to manually change the z-index on a per label basis, but this doesn't seem to work for bubble charts. Here's some sample code that fails to work as expected (try it in a fiddle):
series: [{
data: [{
x: 99,
y: 36,
z: 50
}, {
x: 99,
y: 74,
z: 55,
dataLabels: {
zIndex:15,
enabled: true,
}
}, {
x: 99,
y: 76,
z: 55,
dataLabels: {
zIndex: 1,
enabled: true
}
}
]
}],
You can set useHTML: true flag, and then set z-index: x property for dataLabels, see: http://jsfiddle.net/ZLmU8/4/
Apparently there is a labelrank property on the Highcharts point objects that can be used to dictate which point labels are on top. It can be used when you're creating your data like this:
data: [{
x: 1, y: 1, labelrank: 1, name: 'A'
},{
x: 1, y: 1, labelrank: 2, name: 'B'
}]
Or it can be updated on an individual point to bring that point's dataLabel to the front by doing something like this: chart.series[0].points[0].update({labelrank: 3});
I had a similar issue and created this question on SO that just was answered.
Edit
They have added info regarding series.data.labelrank to their docs as well: http://api.highcharts.com/highcharts#series.data.labelrank
Background
I was trying to show the average traffic with respect to the hours DYNAMICALLY using highchart. That is to say I want it show the traffic repeatedly like this, when the time comes to 23:00 next I want it back to 0:00.
I am doing this by setting 24 categories ['0:00', '1:00'...,'23:00'], and adding points when the data is updated by ajax, say every 1 second.
var chart = new Highcharts.Chart({
...//some options
xAxis: {
categories:['0:00','1:00','2:00',...,'23:00']
},
load: function() {setInterval(updateData,1000)}
series: [] //empty series here, adding dynamically by ajax
})
the updateData is defined as a function
function updateData(){
var data = $.ajax(...)// get the data
var series = chart.series[0];
if(series.data.length < 24){ //when data.length is < 24 add directly
chart.series[0].addPoint(data,true,false);
}else{
chart.series[0].addPoint(data,true,true);//set the 3rd option to true to remove the first data point, actually here this data is equal to the first one since this is a circle, when it comes to 24:00 it is actually 0:00, and I should update the xAxis.
//code updating the axis categories to [1:00, 2:00...23:00,0:00]
xAxis.setCategories(categories);
}
}
the x-axis turns out to be [2:00, 3:00, ...23:00, 0:00, 24], That is to say the point that I add this time does NOT correspond to the categories[24]:0:00, It is actually corresponding to the categories[25] which is not exist, so it is set to 24 in default.
A solution (quick and dirty)
do not ring shift the categories but push a new circle to it,like:
categories.push("time");//time is 0:00-23:00
xAxis.setCategories(categories);
but this will make the categories larger and larger..which is bad.
How can I fix this.
Another solution(also with some problems)
By using datetime as the type of x-axis, there is another problem. My data format is as follws
time count
8:00 23
9:00 56
... ...
and I can construct Points like [time, count], the question is I have time only. Even if I construct data by manually adding a date like
time = (new Date("2012-11-17 "+time)).getTime()
seems feasible. But when it got through 24 hours, the spline comes back to the left of the chart since the x-axis value here is equal to the first one.
BTW: how can I make the x-axis show only the time, the image above showed date at the left side, and the time interval is automatically display how to make it display all?
Thank You for your attention!!!
I followed your advice #Ruchit Rami and revised my code:
/*update part*/
var time = series.points.length > 0 ? series.points[series.points.length-1].category+3600 : 0;
//from 1970-1-1 0:00 And **add 1 hour everytime**
if (series.data.length < 24) {
series.addPoint([time, sum],true,false);
} else {
series.addPoint([time, sum],true,true);
}
/*chart part*/
xAxis: {
type: 'datetime',
dateTimeLabelFormat: {
second: '%H:%M',
minute: '%H:%M',
hour: '%H:%M',
day: '%H:%M',
week: '%H:%M',
month: '%H:%M',
year: '%H:%M'
}
tickInterval: 3600
}
The result
The date label format seems not affected though I specify it
And the time is not correct. Why? Thanks!
still didnt displayed right
To display only time on the X-axis you can use dateTimeLabelFormats property of xaxis and you can use tickInterval for setting tick interval on xaxis.
//Sets tickInterval to 24 * 3600 * 1000 if display is by day
tickInterval : 24 * 3600 * 1000,
dateTimeLabelFormats : {
hour : '%H:%M',
day : "%H:%M"
}
Now, for the issue of chart redraw from the first point, you will need to increase the date of the xaxis point. I am unable to come up with any elegant solution but you can check for time "0:00" while adding new points dynamically and before adding that point increase its date part by one compared to last point in the series.You can find the last point of the series by series.points[series.points.length-1]. Hope i haven't missed anything.
Now, this may not be what you are looking for but I am making some assumptions about what you want to show:
Data by hour for one "day" 0000-2300
Do not care to show the date just the time
Data fluctuates across "days" for a given time
I have created an example here of the chart iterating through 4 "days" of data. I did this by creating an empty data series first to draw the chart, then on load of the chart I iterate through an array of data sets every 1.5 seconds. It then loops back over to the beginning. I have it updating a DIV with what the "day" is. Please let me know if I have missed some condition you need.
Here is the looping code:
var data1 = [5, 8, 2, 5, 7, 4, 1, 2, 30, 20, 50, 30, 150, 130, 70, 50, 20, 47, 32, 18, 20, 15, 16, 8];
var data2 = [9, 15, 3, 4, 1, 1, 0, 0, 60, 75, 112, 190, 267, 365, 258, 164, 168, 190, 47, 16, 20, 18, 5, 8];
var data3 = [15, 18, 12, 5, 7, 4, 1, 2, 130, 20, 150, 130, 150, 130, 70, 50, 20, 47, 32, 18, 20, 15, 16, 8];
var data4 = [19, 15, 13, 4, 11, 11, 0, 0, 60, 175, 112, 190, 267, 365, 258, 164, 168, 190, 47, 16, 20, 18, 15, 18];
var dataSet = [data1, data2, data3, data4];
var dataIter = 0;
$(function() {
var chart = new Highcharts.Chart({
chart: {
renderTo: 'container',
events: {
load: function() {
var series = this.series[0];
setInterval(function() {
if (dataIter >= dataSet.length) dataIter = 0;
series.setData(dataSet[dataIter], true);
$("#dayLabel").text("Day - " +dataIter.toString());
dataIter += 1;
}, 1500);
}
}
},
xAxis: {
categories: ['0000', '0100', '0200', '0300', '0400', '0500', '0600', '0700', '0800', '0900', '1000', '1100', '1200', '1300', '1400', '1500', '1600', '1700', '1800', '1900', '2000', '2100', '2200', '2300'],
labels: {
rotation: 90
}
},
yAxis: {
min: 0,
max: 500
},
series: [{
data: []}]
});
});