John Doe John Doe - 1 month ago 12
Javascript Question

Adding color to the max value in a dynamically generated chart?

The jsfiddle link is here http://jsfiddle.net/MzQE8/110/

The problem here I feel is in my JavaScript.

I input values to the series object in a HighChart from an array. On the array I am trying to find index and the value of the maximum element and then I am saving the maximum array element back with this modification

yArr[index] = {
y: value,
color: '#aaff99'
};


So that It appears as a diferent color from the rest of the points on the graph which is a dynamic one. That is its sliding one.

Here is my code

$(function () {
$(document).ready(function () {
Highcharts.setOptions({
global: {
useUTC: false
}
});

var chart;

$('#container').highcharts({
chart: {
type: 'spline',
animation: Highcharts.svg, // don't animate in old IE
marginRight: 10,
events: {
load: function () {

// set up the updating of the chart each second
var series = this.series[0];
//As this graph is generated due to random values. I am creating an Array with random values.
var yArr = [];
yArr[0] = Math.random();

yArr[1] = Math.random();

yArr[2] = Math.random();

yArr[3] = Math.random();



setInterval(function () {
console.log(yArr.length);
var x = (new Date()).getTime(), // current time
y = Math.random();
var index = findIndexOfGreatest(yArr);
var value = yArr[index];
yArr[index] = {
y: value,
color: '#aaff99'
};
series.addPoint([x, yArr.shift()], true, true);
yArr.push(Math.random());

}, 1000);
}
}
},
title: {
text: 'Live random data'
},
xAxis: {
type: 'datetime',
tickPixelInterval: 450
},
yAxis: {
title: {
text: 'Value'
},
plotLines: [{
value: 0,
width: 1,
color: '#808080'
}]
},
plotOptions: {

series: {
lineWidth: 1
}
},
tooltip: {
formatter: function () {
return '<b>' + this.series.name + '</b><br/>' + Highcharts.dateFormat('%Y-%m-%d %H:%M:%S', this.x) + '<br/>' + Highcharts.numberFormat(this.y, 2);
}
},
legend: {
enabled: false
},
exporting: {
enabled: false
},
series: [{
name: 'Random Data',
data: (function () {
// generate an array of random data
var data = [],
time = (new Date()).getTime(),
i;

for (i = -19; i <= 0; i++) {
data.push({
x: time + i * 1000,
y: yArr.shift()
});
}
return data;
})(),
color: 'red'
}]
});
});

function findIndexOfGreatest(array) {
var greatest;
var indexOfGreatest;
for (var i = 0; i < array.length; i++) {
if (!greatest || array[i] > greatest) {
greatest = array[i];
indexOfGreatest = i;
}
}
return indexOfGreatest;
}


});

I feel my idea is correct but there are big holes in my implementation. I guess.

Thanks

Answer

See demo: http://jsfiddle.net/MzQE8/350/

All y-values are stored in series.yData, so you don't have to create another array for that. Now just update point which is the highest one, and add new points. Something like above demo, code:

            events: {
                load: function () {

                    // set up the updating of the chart each second
                    var series = this.series[0],
                        index = series.yData.indexOf(series.yData.max());

                    // mark first max points
                    this.series[0].prevMax = this.series[0].data[index];
                    this.series[0].prevMax.update({
                        color: '#aaff99'
                    });

                    setInterval(function () {
                        var x = (new Date()).getTime(), // current time
                            y = Math.random(),
                            color = null,
                            index, max;
                        if (series.prevMax && series.prevMax.update) {
                            // remove previously colored point
                            if (y > series.prevMax.y) {
                                series.prevMax.update({
                                    color: null
                                }, false);
                                color = '#aaff99';

                                // store max, which is last point
                                series.prevMax = series.data[series.yData.length]; 
                            }
                        } else {
                            max = series.yData.max();
                            index = series.yData.indexOf(max);

                            if(y > max) {
                               color = '#aaff99'; 
                               series.prevMax = series.data[series.yData.length];     
                            } else {
                                series.prevMax = series.data[index]; 
                                series.prevMax.update({
                                    color: '#aaff99'
                                }, false)
                            }
                        }

                        // add new point
                        series.addPoint({
                            x: x,
                            y: y,
                            color: color
                        }, true, true);

                    }, 1000);
                }
            }
Comments