Highcharts Line Charts Out of memory - javascript

I am trying to populate a line chart using Highcharts. It was working great until a couple of days ago, then it started crashing Chrome and Internet Explorer gives the "SCRIPT7: Out of memory" error. I have 3 other line charts built the exact same way, that work fine. This chart works great as a column chart.
Here is the JSFIDDLE. Code below:
function average(arr) {
return _.reduce(arr, function(memo, num) {
var total = memo + num;
return memo + num;
}, 0) / (arr.length === 0 ? 1 : arr.length);
}
function translateMonth(d) {
var month;
if (d.getMonth() === 0) {
month = 'Jan';
} else if (d.getMonth() === 1) {
month = 'Feb';
} else if (d.getMonth() === 2) {
month = 'Mar';
} else if (d.getMonth() === 3) {
month = 'Apr';
} else if (d.getMonth() === 4) {
month = 'May';
} else if (d.getMonth() === 5) {
month = 'Jun';
} else if (d.getMonth() === 6) {
month = 'Jul';
} else if (d.getMonth() === 7) {
month = 'Aug';
} else if (d.getMonth() === 8) {
month = 'Sep';
} else if (d.getMonth() === 9) {
month = 'Oct';
} else if (d.getMonth() === 10) {
month = 'Nov';
} else if (d.getMonth() === 11) {
month = 'Dec';
}
return month;
}
var npsData = [];
npsData = [{
avg: 100,
coach: "NUNES",
date: "Jul"
},{
avg: 100,
coach: "NUNES",
date: "Jul"
},{
avg: 100,
coach: "NUNES",
date: "Jul"
},{
avg: 100,
coach: "NUNES",
date: "Jul"
},{
avg: 100,
coach: "NUNES",
date: "Aug"
},{
avg: 100,
coach: "NUNES",
date: "Aug"
}]
var npsChartData = [];
npsChartData = _.chain(npsData)
.groupBy("date")
.map(function(value, key) {
return {
name: key,
y: parseFloat(Math.round(average(_.pluck(value, "avg"))))
}
})
.value();
var chart4 = new Highcharts.Chart({
chart: {
type: 'line',
renderTo: 'postCoachingSurvey',
plotBorderColor: '#0574AC',
borderWidth: .5,
plotShadow: true
},
credits: {
enabled: false
},
title: {
text: 'Post Coaching Survey',
style: {
color: '#666666',
fontWeight: 'bold'
}
},
legend: {
enabled: false,
itemStyle: {
color: '#868686',
fontSize: '10px'
}
},
xAxis: {
categories: _.pluck(npsChartData, name),
labels: {
enabled: true,
formatter: function() {
return this.value;
}
}
},
yAxis: {
tickPositioner: function () {
var positions = [],
tick = Math.floor(this.dataMin),
increment = Math.ceil((this.dataMax - this.dataMin) / 6);
for (tick; tick - increment <= this.dataMax; tick += increment) {
positions.push(tick);
}
//console.log (positions);
return positions;
}, title: {
text: 'eNPS',
style: {
color: '#666666'
}
},
labels: {
format: '{value}%'
}
},
tooltip: {
enabled:false,
pointFormat: '{point.y}' + '%',
crosshairs: true
//percentageDecimals: 1
},
plotOptions: {
series: {
cursor: 'pointer',
dataLabels: {
enabled: true,
//formatter: function() {
//return '{point.y}' + '%';
//}
}
}
},
series: [{
type: 'line',
name: 'Nps Average Score',
data: npsChartData,
color: '#EB6E00'
}]
});//end chart4

The particular data for this chart brings out an error in your code. You have an endless loop in your yAxis.tickPositioner function. You have this code:
increment = Math.ceil((this.dataMax - this.dataMin) / 6);
for (tick; tick - increment <= this.dataMax; tick += increment) {
// ...
}
In short, your increment value becomes 0 if the min and max value of the data is the same, and therefore your for loop statement tick += increment does nothing, and it keeps going forever.
This can be fixed by assuring your increment value is a minimum of 1. You could try (JSFiddle):
increment = Math.max(1, Math.ceil((this.dataMax - this.dataMin) / 6));

Related

Plotline (vertical line) in highcharts scatter chart

https://jsfiddle.net/7zL0v5oq/
I would like to have a plotline at today's date. The list can get quite long and in that case it helps with having an oversight. I fear it doesn't work because it is a scatter chart but I don't know what the problem is. I've searched all over the place but everything leads to plotlines, which clearly doesn't work. I would also be thankful if anyone knew, whether there was an easy way to filter my data the way I have it (standard highcharts filtering is deactivated but doesn't really help because of the static y values, so I get a huge, white space in the middle unless I filter at the edges. Thank you in advance for your help.
data = [{
"id": 1,
"release": "Software1",
"routine_failure_analysis_ended_on": null,
"sw_maintenance_releases_ended_on": "2014-04-01",
"sale_ended_on": "2013-04-01",
"security_vul_support_ended_on": "2015-04-01",
"service_contract_renewal_ended_on": null,
"svc_attach_ended_on": null,
"support_ended_on": "2018-03-31",
"updated_dates_on": "2012-10-03",
"created_at": "2018-05-04T18:53:21.301+02:00",
"updated_at": "2018-05-16T08:36:24.940+02:00"
},
{
"id": 2,
"release": "Software2",
"routine_failure_analysis_ended_on": null,
"sw_maintenance_releases_ended_on": "2019-07-24",
"sale_ended_on": "2017-07-31",
"security_vul_support_ended_on": "2020-07-24",
"service_contract_renewal_ended_on": null,
"svc_attach_ended_on": null,
"support_ended_on": "2022-07-31",
"updated_dates_on": "2015-08-14",
"created_at": "2018-05-05T04:00:44.170+02:00",
"updated_at": "2018-05-16T08:36:29.325+02:00"
},
{
"id": 3,
"release": "Software3",
"routine_failure_analysis_ended_on": null,
"sw_maintenance_releases_ended_on": "2018-03-01",
"sale_ended_on": "2017-03-01",
"security_vul_support_ended_on": "2018-12-01",
"service_contract_renewal_ended_on": null,
"svc_attach_ended_on": null,
"support_ended_on": "2022-02-28",
"updated_dates_on": "2016-09-02",
"created_at": "2018-05-05T04:00:44.401+02:00",
"updated_at": "2018-05-16T08:36:31.643+02:00"
}
];
const colors = ["#516", "#1781e3", "#25b252", "#20c997", "#ffc107", "#ff8b2e", "#dd1122"];
//Change to store y value paired to release/pid
var change = {};
//Which y values need to be displayed
var ticks = [0];
//Description of events
var sale = "Sale";
var support = "Support";
var svc = " SVC attach";
var sw = "Software maintenance";
var routine = "Routine failure analysis";
var service = "Service contract renewal";
var security = "Security vulnerability support";
//Data array for series
var high = [];
data.sort(function(a, b) {
return Date.parse(a.support_ended_on) < Date.parse(b.support_ended_on) ? 1 : -1
})
for (var i = 0; i < data.length; i++) {
var arr = [{
x: Date.parse(data[i].sale_ended_on),
y: (i + 1) * 20,
color: colors[0],
myValue: sale
},
{
x: Date.parse(data[i].sw_maintenance_releases_ended_on),
y: (i + 1) * 20,
color: colors[1],
myValue: sw
},
{
x: Date.parse(data[i].security_vul_support_ended_on),
y: (i + 1) * 20,
color: colors[2],
myValue: security
},
{
x: Date.parse(data[i].svc_attach_ended_on),
y: (i + 1) * 20,
color: colors[3],
myValue: svc
},
{
x: Date.parse(data[i].routine_failure_analysis_ended_on),
y: (i + 1) * 20,
color: colors[4],
myValue: routine
},
{
x: Date.parse(data[i].service_contract_renewal_ended_on),
y: (i + 1) * 20,
color: colors[5],
myValue: service
},
{
x: Date.parse(data[i].support_ended_on),
y: (i + 1) * 20,
color: colors[6],
myValue: support
}
];
var key, value;
line = [{
x: Date.parse(data[i].sale_ended_on),
y: (i + 1) * 20
}, {
x: Date.parse(data[i].support_ended_on),
y: (i + 1) * 20
}]
//Adding to change list, so we can add release/pid as label to y axis
key = (i + 1) * 20;
ticks.push(key);
if (data[i].pid) {
value = data[i].pid;
} else {
value = data[i].release;
}
change[key] = value;
//Expanding high (which is used for the highcharts series) with arr (all points for one pid)
if (data[i].pid) {
high.push({
label: data[i].pid,
name: data[i].pid,
type: 'scatter',
data: arr
}, {
type: 'line',
data: line,
linkedTo: ":previous"
});
} else {
high.push({
label: data[i].release,
name: data[i].release,
type: 'scatter',
data: arr,
showInLegend: false
}, {
type: 'line',
data: line,
linkedTo: ":previous"
});
}
}
Highcharts.chart("container", {
chart: {
height: data.length * 75
},
credits: {
enabled: false
},
yAxis: {
title: {
text: null
},
tickPositions: ticks,
visible: true,
labels: {
formatter: function() {
var value = change[this.value];
return value !== 'undefined' ? value : this.value;
}
}
},
xAxis: {
plotlines: [{
color: "#dd1122",
width: 2,
value: +new Date()
}],
type: 'datetime',
},
plotOptions: {
scatter: {
marker: {
symbol: 'circle',
radius: 7,
lineWidth: 2
}
},
line: {
enableMouseTracking: false,
marker: {
enabled: false
},
color: '#bbb',
lineWidth: 3
}
},
tooltip: {
formatter: function() {
var str = '<b>' + this.series.name + '</b><br/>'
if (this.point.myValue) {
str += this.point.myValue;
} else {
str += "Corrupted data!";
}
if (this.point.x < Date.parse(new Date))
return str += " ended on:<br/>" + Highcharts.dateFormat('%e %b %Y', new Date(this.x));
else
return str += " will end on:<br/>" + Highcharts.dateFormat('%e %b %Y', new Date(this.x));
},
shared: false
},
series: high
})
You have a typo, use plotLines instead of plotlines:
xAxis: {
plotLines: [{
...
}],
...
}
Live demo: https://jsfiddle.net/BlackLabel/p3u8ejtb/
API Reference: https://api.highcharts.com/highcharts/xAxis.plotLines

Filter categories in highcharts by using checkboxes

I would like to filter the categories by using the checkboxes. For example, if the user checks Server - only Categories belonging to class Server should be visible and redraw the highchart.
Like this:
And if the user checks all checkboxes, all categories should be visible.
Here is the fiddle: http://jsfiddle.net/Lqcrgrbh/
Thanks in advance!
$(function() {
var chart = new Highcharts.Chart('container', {
chart: {
type: 'columnrange',
inverted: true,
height: 100
},
title: {
text: null
},
xAxis: {
categories: [{"name":"Email","sys_class":"Business Service"},{"name":"Server","sys_class":"Server"}],
labels: {
formatter: function () {
return this.value.name;
},
useHTML: true
}
},
yAxis: {
type: 'datetime',
tickInterval: 1000 * 60 * 60 * 24 * 30 * 6,
title: {
text: null
},
labels: {
formatter: function () {
return Highcharts.dateFormat('%b %Y', this.value);
}
}
},
plotOptions: {
series: {
grouping: false,
stacking: 'normal',
pointPadding: 0,
groupPadding: 0.0,
allowPointSelect: true,
dataLabels: {
enabled: true,
align: 'center',
x: -10,
formatter: function() {
return this.series.name;
}
}
}
},
tooltip: {
formatter: function() {
var categories = this.x.name,
series_name = this.series.name,
low = this.point.low,
high = this.point.high,
duration = high - low;
return '<b>' +series_name + '</b><br/><b>'+ categories + ': </b>'+ Highcharts.dateFormat('%d %b %Y',
new Date(low)) + " - " + Highcharts.dateFormat('%d %b %Y',
new Date(high)) + '<br/><b>Duration: </b>' + parseInt(duration / (1000 * 60 * 60 * 24 * 365)) + " years, " + new Date(duration).getUTCMonth() + " months, " + new Date(duration).getUTCDate() + " days";
}
},
legend: {
enabled: false
},
series: [{"color":"#f47700","data":[[],[1475539200000,1570147200000]],"name":"Concept"},{"color":"#f43701","data":[[1475625600000,1570233600000],[]],"name":"Planing"}]
});
});
You should be able to edit your togglePointsByClass method so you will not hide your series, but you will change extremes on your xAxis. In this case you can use Axis.update() method.
function togglePointsByClass(className, shouldShow, chart) {
var isChartDirty = false;
if (shouldShow) {
chart.xAxis[0].userOptions.categories.forEach(function(category, i) {
if (category.class === className) {
visibleArr.push(i);
}
});
} else {
chart.xAxis[0].userOptions.categories.forEach(function(category, i) {
if (category.class === className && visibleArr.indexOf(i) > -1) {
visibleArr.splice(visibleArr.indexOf(i), 1);
}
});
}
if (visibleArr.length) {
chart.xAxis[0].update({
min: Math.min.apply(null, visibleArr),
max: Math.max.apply(null, visibleArr)
})
}
}
Here you can see simple example how it can work: http://jsfiddle.net/Lqcrgrbh/1/

How to improve performance of Highcharts and avoid error 15 inspite of sorted data?

I am trying to create a gantt chart representation in highcharts with navigator. I get a JSON response from server (below is a typical response strucutre). In order to create a gantt chart representation I am creating a line between 2 points. Each point has a start_date and end_date and inorder to create this representation I am plotting a line between start_date and end_date of each point (which I have accomplished).
Response Structure from server
{
"took": 312,
"timed_out": false,
"_shards": {
"total": 5,
"successful": 5,
"failed": 0
},
"hits": {
"total": 4115,
"max_score": 1,
"hits": [
]
},
"aggregations": {
"top-tags": {
"doc_count_error_upper_bound": 0,
"sum_other_doc_count": 0,
"buckets": [
{
"key": "Process1",
"doc_count": 6,
"process": {
"value": {
"1449878649000": {
"start_date": 1449878649000,
"process_initiator": "lol#surg.com",
"end_date": 1449878734000,
"total_seconds": 85
},
"1449879753000": {
"start_date": 1449879753000,
"process_initiator": "lol#surg.com",
"end_date": 1449879850000,
"total_seconds": 97
},
"1449881550000": {
"start_date": 1449881550000,
"process_initiator": "lol#surg.com",
"end_date": 1449881631000,
"total_seconds": 81
}
}
}
},
{
"key": "Process2",
"doc_count": 1,
"process": {
"value": {
"1449971262000": {
"start_date": 1449971262000,
"process_initiator": "lol#surg.com",
"end_date": 1449971266000,
"total_seconds": 4
}
}
}
}
]
}
}
}
Code also sharing a plunker demo
var app = angular.module('app', []);
app.directive('operationalhighstackstock', function() {
return {
restrict: 'E',
scope: true,
link: function postLink(scope, element, attrs) {
scope.$watch('operationHighChartsData', function(values) {
new Highcharts.StockChart(values);
});
}
};
});
//2014-11-30T18:15:25.000-08:00
app.controller('MainCtrl', ['$scope', function($scope) {
$scope.excludeValue = {
data: 0
};
$scope.isExcludeNeeded = true;
var opExcludeMinutes = 1,
AGENT_NAMES = "agent_names",
colorCodes = ["#8CC051", "#967BDC", "#5D9CEC", "#FB6E52", "#EC87BF", "#46CEAD", "#FFCE55", "#193441", "#193441", "#BEEB9F", "#E3DB9A", "#917A56"];
var setSummaryDisplay = function(e) {
if (e.min === null || e.max === null)
$scope.hideRangeSlider = true;
else
$scope.hideRangeSlider = false;
$scope.minimumSelectedValue = e.min;
$scope.maximumSelectedValue = e.max;
}
var getHichartsData = function(result) {
var tasksArr = [],
seriesArr = [],
userArr = [],
processArr = [];
var agentSeries = [],
agentData = {},
processSeries = [],
taskData = {},
idx = 0,
opProcessBucket = esResponse.aggregations["top-tags"].buckets,
seriesData = {};
var opBucketLength = opProcessBucket.length;
for (var opProcessBucketIndex = 0; opProcessBucketIndex < opBucketLength; ++opProcessBucketIndex) {
//opProcessBucket.forEach(function(processEntry) {
//if (opProcessBucket[opProcessBucketIndex]["key"] == $scope.gpDropDownTitle) {
var intervalBucket = opProcessBucket[opProcessBucketIndex]["process"]["value"], //opProcessBucket[opProcessBucketIndex]["top_tag_hits"]["hits"]["hits"],
intervalArr = [],
tasksIntervalArr = [],
opTaskidObj = {},
opTaskidIntervalObj = {},
process_name = null,
sortElementArr = [];
for (var key in intervalBucket) {
//intervalBucket.forEach(function(intervalEntry, intervalIndex) {
var intervalObj = {},
intervalObj2ndpoint = {},
processIntervalObj = {},
tintervalArr = [],
intervalIndex = 0,
start_temp = parseInt(key),
end_temp = intervalBucket[key].end_date; //start_temp = intervalBucket[key].start_date, end_temp = intervalBucket[key].end_date;
//added here since response contains null value and data load will take almost 1 date, verified with Bhavesh
$scope.currentDateTime = new Date().getTime();
if (end_temp == null)
end_temp = $scope.currentDateTime;
var st = new Date(moment(start_temp).valueOf()).getTime();
var et = new Date(moment(end_temp).valueOf()).getTime();
var duration = moment.duration(moment(et).diff(moment(st)));
var minutes = duration.asMinutes();
if (minutes > $scope.excludeValue.data && $scope.isExcludeNeeded) {
if (intervalIndex == 0 || process_name == null) {
process_name = opProcessBucket[opProcessBucketIndex]["key"];
processArr.push(opProcessBucket[opProcessBucketIndex]["key"]);
}
userArr.push(intervalBucket[key].process_initiator);
processIntervalObj["task_id"] = opProcessBucket[opProcessBucketIndex]["key"];
processIntervalObj["from"] = st;
var lFromtime = moment.utc(st).toDate();
lFromtime = moment(lFromtime).format('MM/DD/YY HH:mm');
var lTotime = moment.utc(et).toDate();
lTotime = moment(lTotime).format('MM/DD/YY HH:mm');
processIntervalObj["to"] = et;
processIntervalObj["color"] = "#FFCC4E";
processIntervalObj["fromDateString"] = lFromtime;
processIntervalObj["toDateString"] = lTotime;
processIntervalObj["process_initiator"] = intervalBucket[key].process_initiator == null ? 'Unknown' : intervalBucket[key].process_initiator;
processIntervalObj["total_seconds"] = intervalBucket[key].total_seconds;
//sortElementArr.push(intervalEntry["sort"][0]);
tasksIntervalArr.push(processIntervalObj);
}
}
opTaskidObj["name"] = process_name;
opTaskidIntervalObj["name"] = process_name;
opTaskidObj["data"] = [];
opTaskidIntervalObj["intervals"] = tasksIntervalArr;
opTaskidIntervalObj["intervals"] = tasksIntervalArr;
idx++;
if (tasksIntervalArr.length > 0) {
processSeries.push(opTaskidIntervalObj);
agentSeries.push(opTaskidObj);
}
//}
}
seriesData["title"] = "Test"; //item["key"];
var series = [];
(processSeries.reverse()).forEach(function(task, i) {
var item = {
name: task.name,
data: [],
turboThreshold: 1100000
};
(task.intervals).forEach(function(interval, j) {
item.data.push({
task_id: interval.task_id,
x: interval.from,
y: i,
from: interval.from,
to: interval.to,
color: interval.color,
fromDateString: interval.fromDateString,
toDateString: interval.toDateString,
total_seconds: interval.total_seconds,
process_initiator: interval.process_initiator
}, {
task_id: interval.task_id,
x: interval.to,
y: i,
from: interval.from,
to: interval.to,
color: interval.color,
fromDateString: interval.fromDateString,
toDateString: interval.toDateString,
total_seconds: interval.total_seconds,
process_initiator: interval.process_initiator
});
// add a null value between intervals
if (task.intervals[j + 1]) {
item.data.push([(interval.to + task.intervals[j + 1].from) / 2, null]);
}
});
series.push(item);
})
seriesData["data"] = series;
seriesData["tasks"] = processSeries;
seriesArr.push(seriesData);
return seriesArr;
}
$scope.agentSeriesData = getHichartsData(esResponse);
var tasks = $scope.agentSeriesData[0].tasks;
var seriesData = $scope.agentSeriesData[0].data;
var xAxisStepping = 1 * 3600 * 1000;
var chart = new Highcharts.StockChart({
chart: {
renderTo: 'container',
height: 600,
events: {
load: function(e) {
var max = this.xAxis[0].max;
var range = (24 * 3600 * 1000) * 7; // one day * 7
if ($scope.isInit || $scope.filterReseted) {
$scope.filterReseted = false;
this.xAxis[0].setExtremes(max - range, max);
}
setSummaryDisplay.call(this.xAxis[0], {
trigger: "navigator",
min: this.xAxis[0].min,
max: this.xAxis[0].max
});
}
}
},
title: {},
credits: {
enabled: false
},
xAxis: {
type: 'datetime',
gridLineWidth: 1,
tickInterval: xAxisStepping,
//ordinal:false,
dateTimeLabelFormats: {
month: '%b %e, %Y'
},
events: {
afterSetExtremes: setSummaryDisplay
},
minRange: 1000
},
yAxis: {
tickInterval: 1,
gridLineWidth: 1,
labels: {
enabled: false,
formatter: function() {
if (tasks[this.value]) {
return tasks[this.value].name;
}
}
},
startOnTick: false,
endOnTick: false,
title: {
text: 'Process'
}
},
animation: false,
rangeSelector: {
enabled: false
},
navigator: {
enabled: true
},
legend: {
enabled: false
},
tooltip: {
shared: false,
formatter: function() {
var str = '';
str += 'Process: ' + this.series.name + '<br>';
str += 'From: ' + Highcharts.dateFormat('%m/%d/%y %H:%M:%S', this.point.from) + '<br>';
str += 'To: ' + Highcharts.dateFormat('%m/%d/%y %H:%M:%S', this.point.to) + '<br>';
return str;
}
},
plotOptions: {
line: {
lineWidth: 10,
marker: {
enabled: false
},
dataLabels: {
enabled: false,
borderRadius: 5,
borderWidth: 1,
y: -6,
formatter: function() {
return this.series.name;
}
},
states: {
hover: {
lineWidth: 10
}
}
},
series: {
cursor: 'pointer',
animation: false,
point: {
events: {
click: function() {
$scope.selectedGuide = this.series.name;
//$scope.showTableView();
}
}
},
turboThreshold: 100000000,
dataGrouping: {
enabled: false
}
}
},
scrollbar: {
enabled: false
},
series: seriesData
});
$scope.operationHighChartsData = chart;
}]);
I have sorted data (ascending order) but I am still getting Highcharts error #15: www.highcharts.com/errors/15 errors in thousands (mostly 80k +), which is hanging the browser.
What could be the issue and how can I get rid of it and increase performance? Sharing a plunker which has code and relatively small number of errors.
Note: I am using Highstock JS v2.1.5
There are two problems with this code:
First thing you need to sort the series in ascending order of X. I did not want to debug your code on how do you construct your data so I added a simple loop in the end to sort everything.
for (var i in seriesData) {
seriesData[i].data.sort(function(a, b) {
if (a.x > b.x) {
return 1;
}
if (b.x > a.x) {
return -1;
}
return 0;
});
}
The other problem is that the data array contains in correct data because of this line
if (task.intervals[j + 1]) {
item.data.push([(interval.to + task.intervals[j + 1].from) / 2, null]);
}
so I changed it to this
// add a null value between intervals
if (task.intervals[j + 1]) {
item.data.push({
task_id: interval.task_id,
x: (interval.to + task.intervals[j + 1].from) / 2,
y: null,
from: (interval.to + task.intervals[j + 1].from) / 2,
to: (interval.to + task.intervals[j + 1].from) / 2
});
}
here is the fixed plnkr
http://plnkr.co/edit/OEMuVfTMhHNQsTYGUyuy?p=preview
Please read this link to improve highcharts performance. A few months ago Highcharts released boost.js to improve chart performance with millions of data points.

Creating Highchart Graph with JavaScript

I want to create high chart graph .
Here is FIDDLE LINK of My code.
I am giving two values a and b . a for x-axis b for y-axis. Problem is that when i gave values of a and b . when the difference between a and b is less, then no graph appears
i-e. a= -9 , b= -9 . Otherwise it works
$(function () {
var a, b, x, j;
a = -9;
b = -9;
if (a > b) {
x = a;
j = b
} else {
x = b;
j = a
}
alert("X is " + x);
alert("Y is" + j);
$('#container').highcharts({
chart: {
type: 'bar',
backgroundColor: null
},
credits: {
enabled: false
},
tooltip: {
enabled: false,
},
title: {
text: ''
},
xAxis: {
categories: ["", "", ""],
//minTickInterval:20000,
},
yAxis: {
min: j - (j * 5 / 100),
max: x + (x * 5 / 100),
//min: -50,
//max: -50,
//minTickInterval:20000,
endOnTick: true,
tickPixelInterval: 340,
maxPadding: 0.25,
title: {
text: ''
},
labels: {
formatter: function () {
if (j - (j * 5 / 100) > 1000000) {
return Highcharts.numberFormat((this.value) / 1000000, 0, '', ',') + 'M';
} else if (j - (j * 5 / 100) > 1000) {
return Highcharts.numberFormat((this.value) / 1000, 0, '', ',') + 'K';
} else {
return Highcharts.numberFormat((this.value), 0, '', ',');
}
},
x: 6
}
},
legend: {
backgroundColor: '#FFFFFF',
reversed: true
},
plotOptions: {
series: {
stacking: 'normal'
}
},
series: [{
name: ' ',
data: [a]
},
{
name: ' ',
data: [0, b]
}, ]
});
});
Here's a working fiddle
Just remove:
min: j-(j*5/100),
max: x+(x*5/100)
from the yAxis: { --- some options --- }
Also try this with one value positive and other negative for a and b.
Hope this helps.

highcharts / highstock doesn't show markers after 500 pts

It seems that over 500 points causes our highstocks markers not to show at all - you can see
http://www.ethnographicedge.com/topic/senkaku-trial-400/ (400 pts) vs http://www.ethnographicedge.com/topic/senkaku-trial-600-s1/ (600pts). The data that's not showing is the "event" represented by the green sphere.
I've looked into editing the turboThreshold, but no luck..
Here's a simplified jsfiddle, and my full code below:
jsfiddle.net/marquex/etdL7/1
when you change the var points = 200; to 400, the red dot doesn't display. Is there a way to force certain mandatory points to show, regardless of the data size?
graphdata = <?php echo topic_data(get_the_ID()); ?>;
extradata = <?php echo extra_data(get_the_ID()); ?>;
eventdata = <?php global $events; echo json_encode($events) ?>;
eventdata.sort(function(a,b){
return a.date - b.date;
});
;(function($){
var parseData,
container = $('#graphcontainer'),
last = false,
m_names = new Array("January", "February", "March",
"April", "May", "June", "July", "August", "September",
"October", "November", "December");
;
if(! container.length)
return;
getEventPoint = function(e,idx){
var color = 'gray';
if(e.forecast == 'fore_successful_down')
color = 'red';
else if(e.forecast == 'fore_successful_up')
color = 'green';
return {
x: parseInt(e.stringdate),
y: parseInt(e.value),
marker: {
enabled: true,
radius:8,
fillColor: color,
lineWidth:3,
lineColor: 'white',
states: {
hover: {
enabled: true,
radius:8,
fillColor: 'white',
lineWidth:3,
lineColor: color
}
}
},
name: idx
}
}
dateDay = function(day){
if( day % 10 == 1)
return day + 'st';
if( day % 10 == 2)
return day + 'nd';
if( day % 10 == 3)
return day + 'rd';
return day + 'th';
}
formatDate = function(timestamp){
var date = new Date(timestamp);
return m_names[date.getMonth()] + ' ' + date.getDay() + ', ' + date.getFullYear();
}
tooltipFormatter = function(data){
var point = data.points[0],
name = point.point.name,
output = '<div class="tooltip-date">' + formatDate(data.x) + '</div><div class="tooltip-value"><span class="tooltip-unit"><?php the_field("value_text") ?>:</span> ' + data.y + '</div>';
if(typeof name !== "undefined"){
var e = eventdata[name];
return '<div class="tooltip-date">' + formatDate(data.x) + '</div>' +
'<div class="tooltip-title">' + e.number + '</div>' +
'<div class="tooltip-trend tooltip-' + e.trend + '"></div> <!-- I will resize the image > background-size: -->' +
'<div class="tooltip-cycle">' + e.cycle + '</div>';
}
if(data.points[1])
output += '<div class="tooltip-secondary><div class="tooltip-value"><span class="tooltip-unit"><?php the_field("extra_value_text") ?>:</span> ' + data.points[1].y + '</div>'
return output;
}
parseData = function(data, eventsData){
var parsedData = [],
eventIdx = 0,
events = eventsData ? eventsData.slice(0) : [],
e = events[0]
;
if(e)
e.stringdate = (new Date(e.date.substring(0,4) + '/' + e.date.substring(4,6) + '/' + e.date.substring(6,8))).getTime();
for (var i = 0; i < data.length; i++) {
var item = data[i],
timestamp = false;
if(item.date && item.date.match(/^\d{4}\/\d{2}\/\d{2}$/) && item.value && parseFloat(item.value) == item.value){
timestamp = (new Date(item.date)).getTime();
if(e && timestamp > e.stringdate > last) {
parsedData.push(getEventPoint(e, eventIdx));
parsedData.push([timestamp, parseFloat(item.value)]);
e = events[++eventIdx];
if(e)
e.stringdate = (new Date(e.date.substring(0,4) + '/' + e.date.substring(4,6) + '/' + e.date.substring(6,8))).getTime();
}
else if(e && timestamp == e.stringdate) {
parsedData.push(getEventPoint(e, eventIdx));
e = events[++eventIdx];
if(e)
e.stringdate = (new Date(e.date.substring(0,4) + '/' + e.date.substring(4,6) + '/' + e.date.substring(6,8))).getTime();
}
else
parsedData.push([timestamp, parseFloat(item.value)]);
}
};
while(e){
parsedData.push(getEventPoint(e, eventIdx));
e = events[++eventIdx];
if(e)
e.stringdate = (new Date(e.date.substring(0,4) + '/' + e.date.substring(4,6) + '/' + e.date.substring(6,8))).getTime();
}
return parsedData;
};
var series = [{
name: 'Topic Data',
data: parseData(graphdata, eventdata),
color: '#666'
}];
if(extradata && extradata.length){
series.push({
name: 'Extra Data',
data: parseData(extradata),
yAxis: 1,
color: '#fbb800'
});
}
var yAxis = [{
title: {
text: '<?php the_field("value_text") ?>',
style: { color: '#BBBBBB', fontSize: '1.2em' },
margin: 12,
},
labels: {
enabled: false,
formatter: function() {
return this.value
}
},
height: 300,
lineColor: '#FFFFFF'
}];
if(extradata && extradata.length){
yAxis[0].lineWidth = 2;
yAxis.push({
title: {
text: '<?php the_field("extra_value_text") ?>'
},
height: 200,
top:350,
offset:0,
lineWidth:2,
lineColor: '#FFFFFF'
});
}
container.highcharts('StockChart', {
chart: {
type: 'spline',
events: {
load: function(e){
$('#tapapubli')
.detach()
.addClass('tapapubli')
.appendTo('#graphcontainer');
}
}
},
rangeSelector: {
enabled: false,
buttons:[
{
type: '<?php echo $initial_zoom["type"] ?>',
count: <?php echo $initial_zoom["count"] ?>,
text: 'Initial'
},
{
type: 'All',
text: 'Reset'
}
],
},
scrollbar: {
enabled: false,
},
navigator: {
maskFill: 'rgba(170, 170, 170, 0.75)',
series: {
color: '#FFD600',
lineColor: '#AE8800'
}
},
xAxis: {
labels: {
enabled: false
},
lineColor: '#FFF', /* BITBUCKET */
tickColor: '#666666',
tickLength: 0,
tickWidth: 1,
tickPosition: 'outside',
type: 'datetime',
dateTimeLabelFormats: { // don't display the dummy year
day: '%e of %b',
}
},
yAxis: yAxis,
plotOptions: {
lineColor: 'green',
spline: {
lineWidth: 3,
states: {
hover: {
lineWidth: 3
}
},
marker: {
enabled: false
},
pointInterval: 36000000000,
point: {
events: {
click: function(){
//console.log(this);
if(this.name)
window.location.href = '#event-' + eventdata[this.name].number;
}
}
}
}
},
series: series,
tooltip: {
formatter: function(){
return tooltipFormatter(this);
},
useHTML: true,
borderColor: '#333',
shadow: false,
borderRadius: 0
}
});
if(!window.chart)
window.chart = container.highcharts();
})(jQuery);
var getPointRecursive = function(date, list){
if(list.length < 5){
var found = false;
for (var i = 0; i < list.length; i++) {
var point = list[i];
};
}
}
var getSeriesPoint = function(date){
}
As #Sebastian Bochan said, you just need to set plotOptions.series.dataGrouping.enabled = false explicitly. Then the problem will disappear.

Categories

Resources