Highcharts - Stacked column data series - javascript

Im working with stacked column using Highcharts.
The data series im constructing is similar to this
series: [{
name: 'Apples',
data: [['2014-01-01',5], ['2014-01-02',3], ['2014-01-04',2], ['2014-01-05',7], ['2014-01-06',8]]
}, {
name: 'Oranges',
data: [['2014-01-01',3], ['2014-01-02',7], ['2014-01-04',9], ['2014-01-05',11], ['2014-01-06',19]]
}, {
name: 'Grapes',
data: [['2014-01-01',15], ['2014-01-02',23], ['2014-01-03',12], ['2014-01-05',17], ['2014-01-06',18]]
}]
http://jsfiddle.net/emgq47px/
If you take a closer look at the data, im missing 2014-01-04 data for Apples but instead the data is stacked on 2014-01-03.
One way of solving this would be to prepopulate categories and follow the same order for inserting my y values but that wont be a good way to solve as i may deal with large data sets down the line.
Any tips to head in the right direction is greatly appreciated.
UPDATE:
I'm populating my x and y co-ordinates with values from database. Database gives me date in (YYYY-mm-dd) format. So i'm converting that string to epoch time using strtotime function in PHP strtotime($res[0])
But then when I populate draw the highchart, i see wrong dates. I checked with online available epoch converters and it looks like conversion is right but i still cant figure out whats wrong here.
Even the x axis ticks seems to be slightly off.
Many thanks for your suggestions.
http://jsfiddle.net/emgq47px/3/
RESOLVED:
I had to multiply epoch time with 1000. This works.
Original answer: HighCharts - timeseries chart - irregular datetime interval on xAxis

Probably the best way is to use a datetime axis. This allows highcharts to know the data contains dates, and it can sort out the axis properly.
xAxis: {
lineWidth: 2,
type: 'datetime'
},
Once you do this, you need to supply valid date times in your data like this:
data: [[Date.UTC(2014, 0, 1),5],
[Date.UTC(2014, 0, 2),3],
[Date.UTC(2014, 0, 4),2],
[Date.UTC(2014, 0, 5),7],
[Date.UTC(2014, 0, 6),8]]
Note, months go from 0 to 11, not 1 to 12, so zero is January.
http://jsfiddle.net/0ofLx86d/

The problem is that you are marking x-axis type is category
xAxis: {
lineWidth: 2,
type: 'category'
},
So when you assign data data: [['2014-01-01',5], ['2014-01-02',3], like this to it then the first value is considered as category so when you assign ['2014-01-03',12] as last then it replaces previous one ['2014-01-04',12]. You can test it by keeping first two as 03 and last one as 04, then it will take 04 and not show 03.
Solution
Replace
type: 'category' to 'datetime'
and date to epoch time
data: [[1388534400000,5], [1388620800000,3], [1388793600000,2], [1388880000000,7]]
You can use custom function for label if you want to display date on x-axis in different format or use Date.UTC
Demo

Related

Tickinterval for date from json file - Highcharts

I understand we could use tick interval for type:"datetime". It works for type: category also as shown below:
http://jsfiddle.net/n0s72zeh/1/
But tick interval does not work when I use 'categories: dateFromJson'. I get custom date from json file. Is it possible to have set interval on my x-axis (like for every one hour on average ?)
xAxis: {
categories: DateFromJson,
labels: {
rotation: 270,
}
}
For eg: rite now it shows 15:06, 15:56, 15:58, instead can we make it show just 15:00?.. It should show 13:00, 14:00, 15:00 and so on(every one hour). Thank you

Vue Chart.js -- can I give a line chart a default value for missing data?

I'm creating a line chart with Vue.js, but there are gaps in the data I'm passing to renderChart(). I haven't been able to find anything so far in the documentation but I'm still curious -- is there a way to fill in those gaps with a default value? I'd use zero in this case but it would be cool if it was configurable. Or is my best bet to backfill the data with dummy values before passing it in to renderChart()?
I'm assuming you have some kind of regular time interval for your labels.
In Chart.js datasets are mapped to labels by their indexes in the arrays. Chart.js doesn't really know where the "gaps" in your data are. Also Chart.js doesn't know the date interval used for your label. I assume this choice of design in Chart.js is for performance reasons.
This would work as expected:
data: [1,0,0,10]
labels: ['June','July','Aug', 'Sept']
Here Chart.js would assume the first two values are for June and July:
data: [1,10]
labels: ['June','July','Aug','Sept']
Here Chart.js has no idea that July and Aug are missing:
data: [1,10]
labels: ['June','Sept']
If you API returns data like this:
{'June': 1, 'July': 0, 'Aug': 0, 'Sept': 10}
Then you can just do this:
const labels = Object.keys(response);
const datasets = [];
datasets.push({
label: 'Line 1',
data: labels.map(date => response[date]),
});
this.renderChart({
labels,
datasets,
});
You can use something like this in your backend to fill out the empty dates/months etc.
$interval = \DateInterval::createFromDateString('1 month');
$datePeriod = new \DatePeriod($begin, $interval, $end);
foreach ($datePeriod as $dt) {
if (!isset($data[$dt->format('Y.m')])) {
$data[$dt->format('Y.m')] = 0;
}
}
Hope this helps.

Plotting data on x axis in Highstock

I am currently trying to plot some data which I receive via a HTTP request. The issue that I am having is that the x-axis doesn't plot the timestamp correctly because it it's in Unix format. I've read some other similar question on SO such as: Example One
The issue is that I'm not passing an object but directly an Unix time data. When hovering the graph, you can see that the x-axis doesn't display the date and hour correctly.
Here is a fiddle with my current graph: Graph Fiddle
Since you actually have datetime values, showing them using category is sort of a hack, and would also not show gaps between points correctly if they are not evenly spaced.
Instead you could merge your two arrays into pairs and then supply it to the series as proper X-Y values for a datetime axis. You also have to multiply your datetime values by 1000 to get milliseconds, which Highcharts expects.
For example (JSFiddle), merging:
dataArray.push(selectedData);
timeDataArray.push(selectedTime);
var mergedArray = timeDataArray.map(function(e, i) {
return [e*1000, dataArray[i]];
});
And axis and series:
xAxis: {
type: 'datetime'
},
series: [{
name: 'AAPL',
data: mergedArray
}]

Incorrect values on Highcharts (compared to input)

I have a (Highcharts) graph with a percentage over time. The input for my series looks something like:
series: [{
name: "Percentage",
data: [
[1472515200000, 49],
[1472601600000, 48.83],
[1472688000000, 49.6],
[1472774400000, 48.77]
]
}]
However on the actual chart (areaspline) I get different values:
30 Aug, 48.91
31 Aug, 49.36
1 Sep, 49.6
2 Sep, 48.87
Not entirely sure why this is the case, I'm assuming it's because the graph has a datetime type and it's figuring out the average over time. Is there a way I can make the values exact as they are input? Couldn't find anything in docs
Thanks for any ideas/help/advice.
Upon further research, it seems like it's not so much a Highcharts problem but a React one. I seem to be getting different values on each render. Will look into this further and update for the curious.
Problem seemed to be related to React re-rendering and therefore recalculating my percentage values - not a Highcharts issue. Thanks for everyone who commented, bit of a wild goose chase.
Jamie, to make the input values be taken literally, you need to either leave the type value of your x-axis unset or change it to type: 'literal'.
Here's a basic fiddle I created with your data to show how it can be interpreted exactly as input (vs. converted to dates): http://jsfiddle.net/brightmatrix/vtLswcex/1/
$(function () {
Highcharts.setOptions({
lang: {
thousandsSep: ',' // adds comma for axis labels
}
});
Highcharts.chart('container', {
xAxis: {
labels: {
formatter: function() {
return Highcharts.numberFormat(this.value,0);
}
}
},
series: [{
name: "Percentage",
data: [
[1472515200000, 49],
[1472601600000, 48.83],
[1472688000000, 49.6],
[1472774400000, 48.77]
]
}]
});
});
Note that I've added formatting for the x-axis labels, as well as a thousands separator in the Highcharts.setOptions() function, so that your labels will be more easily readable as trillions.
Does this help answer your question? If you are instead looking for a better way to format time-specific data, the comment by #morganfree is well worth looking into.

Highcharts - Aligning dateTime series for shared tooltip

I have 2 timeseries that I would like to 'share' tooltip across. However, I have a problem where only the first point of each series is aligned and shares the tooltip. The rest of the points are slightly misaligned and therefore fail to show in the tooltip at the same time.
This fiddle will help demonstrate the problem. Fiddle
If you hover over the very first point, the tooltip appears with an entry for both series. But the very next datapoint only displays a single entry in the tooltip.
May I ask for your advice please? What have I missed for 'aligning' both series in order to share the tooltip? Clearly it's not enough to just add
tooltip: {
shared: true,
}
Thank you.
Assuming that the end goal is to compare two different dates based on the time of day, and assuming that the data points are at regular intervals, or are close enough and can be fudged (ie 1 point per hour, or every 10 minutes, etc), I would approach this differently:
1) use a single date. it can be today's date, or any other date, it doesn't matter, as the time of day is the important segment of the date string.
2) use the pointStart and pointInterval properties to set the proper timing (based on the artificial date, but the correct time interval)
3) Set the actual date of each data series as the series name, which will show in the legend and the shared tooltip to properly display the date of each data set.
4) use the formatting options on the x axis labels to show only the time portion of the label and not the date
In this way you remove the need for a 2nd x axis, remove any complications in tooltip formatting, remove the need to use more complex data structures like in your comment ( "{"y":0.87,"realDateTime":'25/12/2015 03:00'}" ), and only ever have to pass the appropriate date to the name property of each series.
//use the current date as the base - the date doesn't matter, just the time
var d = new Date();
var date = new Date(d.getFullYear(), d.getMonth(), d.getDate(), 0,0,0);
var pointStart = date.getTime();
var pointInterval = 3600 * 1000 // 1 hour
.
series: [{
name : 'Apr 17, 2015',
data : [2,5,8,9,8,7,4,5,6,9,8,7,8,9,8,7,8,5,3,2,1,4,4,5]
},{
name : 'Jun 12, 2015',
data : [3,6,9,5,4,7,8,5,2,1,4,5,9,8,7,5,6,9,8,7,4,5,6,3]
}]
Example:
http://jsfiddle.net/jlbriggs/b3t7ueam/
[[and, of course, you can do this with as many different dates as desired (though this many obviously doesn't make sense):
http://jsfiddle.net/jlbriggs/v76u9w2L/
]]
I know that this is an old question, but an alternative approach which I've found to work is to reformat the data into a CSV format and add an import for the data module.
There's a demo on the Highcharts site which does pretty much what you're asking for (albeit nested inside an ajax request) over here. The two key parts from there are:
<script src="https://code.highcharts.com/modules/data.js"></script>
and
data: {
csv: csvData
}
The example reads in an actual csv file, but it'll accept any string which is formatted similarly. Also, if you set up headers in that csv string, you don't need to declare their names in your series options.

Categories