gamda gamda - 6 months ago 32
JSON Question

How to set smart Morris.js line chart y boundaries?

I recently started a dashboard project and part of it is showing charts. I have been learning Morris.js for the charts and I got to the point where I am properly retrieving JSON data from my

localserver
and creating a chart.

The problem is that the y-axis is too wide. All the points plotted fall in about a third of the chart height. I am aware that I can manually set the
ymax
and
ymin
when creating the chart, but this would require that I loop through all the objects to find the highest and lowest data point. While I am not opposed to do that, I am very new to JavaScript and I'm not sure about the specific syntax. Preferably, I would like to change a setting in Morris so it sets the
ymax
and
ymin
to something reasonable.

Here is an image of the plot and JSON received:
enter image description here

And in case it matters, my code for creating the chart:

new Morris.Line({
element: 'chart',
data: data,
xkey: 'date',
ykeys: ['csi', 'econtrack', 'gurtam', 'pointer'],
labels: ['csi', 'econtrack', 'gurtam', 'pointer'],
behaveLikeLine: true,
});

Answer

I could find nothing else to manage the y-axis in Morris so I built my own function to find min and max:

function min_and_max(json_data) {
    var min = Number.MAX_VALUE;
    var max = Number.MIN_VALUE;
    for (var data_key in json_data) {
        var entry = json_data[data_key]
        for(var key in entry) {
            var x = entry[key];
            if (!isNaN(x)) { // to avoid using date object
                if (x < min) {min = x;}
                else if (x > max) {max = x;}
            }
        }
    }
    return {'min': min, 'max': max};
}

So I could use it when creating the chart like:

var limits = min_and_max(data);
var keys = Object.keys(data[0]);
keys = keys.filter(function(e){return e!=='date'});
new Morris.Line({
    element: element,
    data: data,
    xkey: 'date',
    ykeys: keys,
    labels: keys,
    ymin: limits['min'],
    ymax: limits['max'],
    hideHover: true
});