I am plotting a chart with ‘y’ axis being numeric values and ‘x’ axis being date time values.
I was able to process a JSON object of 3000 items. However, because of our business rules, we also need to display the time: hours + minutes in the chart’s tooltips.
This changed everything!
Now the chart takes about 15 seconds to plot 2000 records. This is unacceptable.
I can see clearly that when I remove the time part of my Date object the charts works perfectly. It is just when added the hours and minutes that performance gets affected.
Trying different things I realized that your charts should support the amount of data I am using since it is not massive.
We love the charts but performance is key for us to continue using your products.
Can you help me with this issue?
Please check this fiddle so you can understand my problem. Feel free to remove the hours and minutes variables from the DateUtc creation:
https://jsfiddle.net/17a3jry9/7/
Thanks in advance!
var pointStart = new Date();
var data = [{"date":"2017-11-08","time":"1712","perc":10},{"date":"2017-11-08","time":"1608","perc":10},{"date":"2017-11-08","time":"1506","perc":10},{"date":"2017-11-08","time":"1408","perc":10},{"date":"2017-11-08","time":"1309","perc":10},{"date":"2017-11-08","time":"1207","perc":10},{"date":"2017-11-08","time":"1110","perc":10},{"date":"2017-11-08","time":"1003","perc":10},{"date":"2017-11-08","time":"0910","perc":10},{"date":"2017-11-08","time":"0810","perc":10},{"date":"2017-11-08","time":"0708","perc":10},{"date":"2017-11-09","time":"1710","perc":10},{"date":"2017-11-09","time":"1604","perc":10},{"date":"2017-11-09","time":"1510","perc":10},{"date":"2017-11-09","time":"1406","perc":10},{"date":"2017-11-09","time":"1310","perc":10},{"date":"2017-11-09","time":"1205","perc":10},{"date":"2017-11-09","time":"1107","perc":10},{"date":"2017-11-09","time":"1010","perc":10},{"date":"2017-11-09","time":"0912","perc":10},{"date":"2017-11-09","time":"0806","perc":10}{"date":"2018-10-25","time":"0709","perc":10},{"date":"2018-10-25","time":"1009","perc":10},{"date":"2018-10-25","time":"1208","perc":10},{"date":"2018-10-25","time":"1309","perc":10},{"date":"2018-10-25","time":"1410","perc":10},{"date":"2018-10-25","time":"1510","perc":10},{"date":"2018-10-25","time":"1702","perc":10},{"date":"2018-10-26","time":"1409","perc":10},{"date":"2018-10-26","time":"0710","perc":10},{"date":"2018-10-26","time":"1505","perc":10},{"date":"2018-10-26","time":"1704","perc":10},{"date":"2018-10-29","time":"0708","perc":10},{"date":"2018-10-29","time":"1007","perc":10},{"date":"2018-10-29","time":"1208","perc":10},{"date":"2018-10-29","time":"1406","perc":10},{"date":"2018-10-29","time":"1509","perc":10},{"date":"2018-10-29","time":"1610","perc":10},{"date":"2018-10-30","time":"0710","perc":10},{"date":"2018-10-30","time":"1010","perc":10},{"date":"2018-10-30","time":"1207","perc":10},{"date":"2018-10-30","time":"1409","perc":10},{"date":"2018-10-30","time":"1510","perc":10},{"date":"2018-10-30","time":"1709","perc":10},{"date":"2018-10-31","time":"0708","perc":10},{"date":"2018-10-31","time":"1009","perc":10},{"date":"2018-10-31","time":"1206","perc":10},{"date":"2018-10-31","time":"1409","perc":10},{"date":"2018-10-31","time":"1509","perc":10},{"date":"2018-10-31","time":"1708","perc":10},{"date":"2018-11-01","time":"0707","perc":10},{"date":"2018-11-01","time":"1007","perc":10},{"date":"2018-11-01","time":"1108","perc":10},{"date":"2018-11-01","time":"1250","perc":10},{"date":"2018-11-01","time":"1509","perc":10},{"date":"2018-11-01","time":"1407","perc":10},{"date":"2018-11-01","time":"1709","perc":10},{"date":"2018-11-02","time":"0708","perc":10},{"date":"2018-11-02","time":"1007","perc":10},{"date":"2018-11-02","time":"1108","perc":10},{"date":"2018-11-02","time":"1210","perc":10},{"date":"2018-11-02","time":"1407","perc":10},{"date":"2018-11-02","time":"1509","perc":10},{"date":"2018-11-02","time":"1608","perc":10},{"date":"2018-11-02","time":"1715","perc":10},{"date":"2018-11-05","time":"0707","perc":10},{"date":"2018-11-05","time":"1007","perc":10},{"date":"2018-11-05","time":"1209","perc":10},{"date":"2018-11-05","time":"1408","perc":10},{"date":"2018-11-05","time":"1509","perc":10},{"date":"2018-11-05","time":"1611","perc":10},{"date":"2018-11-05","time":"1715","perc":10},{"date":"2018-11-06","time":"0708","perc":10},{"date":"2018-11-06","time":"1007","perc":10},{"date":"2018-11-06","time":"1201","perc":10},{"date":"2018-11-06","time":"1410","perc":10},{"date":"2018-11-06","time":"1510","perc":10},{"date":"2018-11-06","time":"1709","perc":10},{"date":"2018-11-07","time":"0708","perc":10},{"date":"2018-11-07","time":"1007","perc":10},{"date":"2018-11-07","time":"1209","perc":10},{"date":"2018-11-07","time":"1307","perc":10},{"date":"2018-11-07","time":"1410","perc":10},{"date":"2018-11-07","time":"1506","perc":10},{"date":"2018-11-07","time":"1708","perc":10},{"date":"2018-11-08","time":"0707","perc":10},{"date":"2018-11-08","time":"1009","perc":10},{"date":"2018-11-08","time":"1207","perc":10},{"date":"2018-11-08","time":"1309","perc":10},{"date":"2018-11-08","time":"1412","perc":10},{"date":"2018-11-08","time":"1508","perc":10}];
var newSeries = data.map(function (key) {
var utilDate = new Date(key.date);
var hours = parseInt(key.time.slice(0, 2));
var minutes = parseInt(key.time.slice(2, 4));
return { x: Date.UTC(utilDate.getFullYear(), utilDate.getMonth(), utilDate.getDate(), hours, minutes), y: key.perc, key: key.id };
});
Highcharts.stockChart('container', {
xAxis: {
type: 'datetime',
title: {
text: 'Date'
}
},
yAxis: {
title: {
text: 'Util (%)'
},
min: 0
},
tooltip: {
headerFormat: '<b>{point.x: %A, %b %e, %I:%M %p}</b><br>'
//pointFormat: '{point.x:%e. %b}: {point.y:.2f} m'
},
colors: ['teal', 'red'],
// Define the data points. All series have a dummy year
// of 1970/71 in order to be compared on the same x axis. Note
// that in JavaScript, months start at 0 for January, 1 for February etc.
series: [{
name: "Util",
data: newSeries
}],
title: {
text: 'Util Movement'
},
subtitle: {
text: ""
},
plotOptions: {
series: {
cursor: 'pointer',
turboThreshold: 10000,
point: {
events: {
}
},
label: {
connectorAllowed: false
},
pointStart: pointStart.getFullYear()
}
},
responsive: {
rules: [{
condition: {
maxWidth: 200
},
chartOptions: {
legend: {
layout: 'horizontal',
align: 'center',
verticalAlign: 'bottom'
}
}
}]
}
});
Please take a look to the browser console, you have information there about error: Highcharts error #15: www.highcharts.com/errors/15.
This means that you have unsorted data, so you need to sort them:
newSeries.sort(function(a, b){
return a.x - b.x
});
Live demo: https://jsfiddle.net/BlackLabel/onq0Lurx/
I'm trying to get this chart to only be dotted for the last month:
chart_data = [[1496275200000, 981], [1498867200000, 1089], [1501545600000, 1595], [1504224000000, 1296], [1506816000000, 1678], [1509494400000, 1879], [1512086400000, 2028], [1514764800000, 1885], [1517443200000, 1366], [1519862400000, 1558], [1522540800000, 1636], [1525132800000, 2438], [1527811200000, 2899], [1530403200000, 2521], [1533081600000, 2879], [1535760000000, 1702]]
Highcharts.chart('container', {
title: {
text: 'Zone with dash style'
},
subtitle: {
text: 'Dotted line typically signifies prognosis'
},
xAxis: {
type: 'datetime',
labels: {
formatter: function () {
return Highcharts.dateFormat('%Y-%m', this.value)
}
},
tickInterval: 30 * 24 * 3600 * 1000,
},
series: [{
data: chart_data,
zoneAxis: 'x',
zones: [{
value: chart_data.length - 2
}, {
dashStyle: 'dot'
}]
}]
});
https://jsfiddle.net/aL57381b/
(This highcharts code is basically the same as: http://jsfiddle.net/gh/get/library/pure/highcharts/highcharts/tree/master/samples/highcharts/series/color-zones-dashstyle-dot/ from the highcharts documentation, just with my time-series data instead.
However, it makes the entire chart turn dotted instead of just the last bit. Any ideas why? I can't seem to fix this.
You need the real value not the starting index like that :
dottedStartIndex = chart_data[chart_data.length - 2][0];
Highcharts.chart('container', {
...
zones: [{
value: dottedStartIndex
}, {
dashStyle: 'dot'
}]
Fiddle
I'm new to Highcharts and have been experimenting with the Gantt chart type, unfortunately there isnt a whole heap of documentation around right now.
My requirement is quite basic, I need to plot multiple series of milestones in order to show slippage of different projects. I've used some example code I found online to start me off however I need to remove the blank ('My 1st Row') line between the series. see:-
https://jsfiddle.net/z86aq99g
var today = new Date(),
day = 1000 * 60 * 60 * 24;
var grey_OrigTargDate = '#A6A6A6';
var blue_Completed = '#2e75b6';
var green_Ontarget = '#00b050';
var yellow_OfftrackMinor = '#ffc000';
var red_OffTrackMajor = '#ff0000';
// Set to 00:00:00:000 today
today.setUTCHours(0);
today.setUTCMinutes(0);
today.setUTCSeconds(0);
today.setUTCMilliseconds(0);
today = today.getTime();
// THE CHART
Highcharts.setOptions({
colors: ['#058DC7']
});
Highcharts.ganttChart('container', {
title: {
text: 'Gantt Chart Test'
},
xAxis: {
currentDateIndicator: true,
min: today - 3 * day,
max: today + 18 * day
},
series: [{
name: 'Test series',
data: [{
taskName: 'My 1st row',
id: 'r1',
start: today + 4.5 * day,
milestone: true,
color: grey_OrigTargDate
}, {
taskName: 'My 1st row',
id: 'r2',
start: today + 7.5 * day,
milestone: true,
color: green_Ontarget
}, {
taskName: 'My 2nd row',
id: 'r3',
start: today + 9.5 * day,
milestone: true,
color: blue_Completed
}, {
taskName: 'My 2nd row',
id: 'r4',
start: today + 11.5 * day,
milestone: true,
color: red_OffTrackMajor
}]
}]
});
I am trying to chart 2 milestones on each line. I know that the x range series chart could accomplish something similar but I'd much prefer to use the gantt option. I'd appreciate any help.
You can solve this problem by assigning categories to the Y-axis
yAxis: {
type: 'category',
categories: ['A', 'B'],
reversed: true,
},
In order for this to work you could change the taskName with y: 0 / y: 1. It will work if your taskName is identical to your category names, but using y: 0 is more dynamic if you were to change the categories.
Your code will look like this in the end:
var today = new Date(),
day = 1000 * 60 * 60 * 24;
var grey_OrigTargDate = '#A6A6A6';
var blue_Completed = '#2e75b6';
var green_Ontarget = '#00b050';
var yellow_OfftrackMinor = '#ffc000';
var red_OffTrackMajor = '#ff0000';
// Set to 00:00:00:000 today
today.setUTCHours(0);
today.setUTCMinutes(0);
today.setUTCSeconds(0);
today.setUTCMilliseconds(0);
today = today.getTime();
// THE CHART
Highcharts.setOptions({
colors: ['#058DC7']
});
Highcharts.ganttChart('container', {
title: {
text: 'Gantt Chart Test'
},
xAxis: {
currentDateIndicator: true,
min: today - 3 * day,
max: today + 18 * day
},
yAxis: {
type: 'category',
categories: ['A', 'B'],
reversed: true,
},
series: [{
name: 'Test series',
data: [{
y: 0, // taskName: 'A' works too
id: 'r1',
start: today + 4.5 * day,
milestone: true,
color: grey_OrigTargDate
}, {
y: 0,
id: 'r2',
start: today + 7.5 * day,
milestone: true,
color: green_Ontarget
},{
y: 1,
id: 'r3',
start: today + 9.5 * day,
milestone: true,
color: blue_Completed
}, {
y: 1,
id: 'r4',
start: today + 11.5 * day,
milestone: true,
color: red_OffTrackMajor
}]
}]
});
Here is a working JSFiddle https://jsfiddle.net/z86aq99g/1/
in my application I use angular Highstock for charts. I have a lot of data (many millions), and now i want to put the existing buttons for set date range (1week, 1 month, 3 months, 1year, all), but also to click on any button to send a new request to the server to not accumulating data. Example, if pressed button "one week", that only the server retrieves the data for one week, if you click on a button to one month, to take data for a single month. I do not want to call unnecessary data, and that the server slows down, if I'm looking for data for one month, and the server comes back to me all data. Here is the code. Thanks in advance
> https://jsfiddle.net/tf7pr1ft/
Thnx to #Grzegorz Blachliński i fix this. here is code
$scope.chartConfig1 = {
xAxis: {
ordinal: false,
//za dodat date range postavit events i range selectors
events : {
afterSetExtremes: getDateRange //here i add my custom function
}
},
yAxis: {
plotLines: [{
color: '#FF0000',
width: 1,
value: 11.50,
label: {text: '11.50'}
}]
},
options: {
chart: {
zoomType: 'x',
backgroundColor: 'rgba(255, 255, 255, 1)',
polar: true,
type: 'line',
borderRadius: 5
},
legend: {
enabled: true
},
rangeSelector: {
selected : 0, //here i defined default range
enabled: true,
inputStyle: {
color: 'black'
}
},
navigator: {
enabled: true
}
},
series: [],
title: {
text: 'Solar and Battery voltage average'
},
useHighStocks: true
},
$scope.chartConfig1.series.push({
id: 1,
name: "Solar voltage average",
data: $scope.data[0],
tooltip: {
valueDecimals: 2
}
}, {
id: 2,
name: "Battery voltage average",
data: $scope.data[1],
tooltip: {
valueDecimals: 2
}
}
);
and here is my custom function
getDateRange = function (e) {
var date1 = new Date(e.min);
var date2 = new Date(e.max);
var timeDiff = Math.abs(date2.getTime() - date1.getTime());
var diffDays = Math.ceil(timeDiff / (1000 * 3600 * 24));
$http.get(serviceBase + 'aaaaa/aaaaaa/' + $stateParams.klupaID + '/aaaaaaa?days=' + diffDays, function(data){
//ukoliko buden dodavat još koji config obavezno dodat broj koliko ih ima na i<=8
for (i=1; i<=8; i++){
$scope.chartConfigString = 'chartConfig' + i;
$scope.chartConfigString.series[0].setData(data);
$scope.chartConfigString.hideLoading();
}
});
};
Now i have another problems, i want to have four selectors (buttons), 1months, 3months, 1year and ALL. I set default range, when open app, on 1month, and here is problem. Buttons for another range is disabled, beacause i get data from url only for one month. I want to have enabled all buttons for select any range. Thnx