Search code examples
javascriptmorris.js

Graduate YAxis using Morris.js


I used Morris.js to draw a chart.

I populate my data correctly and I got my chart nice.

See this picture:

enter image description here

This is the configuration I used for drawing:

var config = {
        data: data,
        xkey: 'y',
        ykeys: ['a', 'b'],
        labels: ['Individual Score', 'Team Score'],
        fillOpacity: 0.6,
        hideHover: 'auto',
        behaveLikeLine: true,
        resize: true,
        pointFillColors: ['#ffffff'],
        pointStrokeColors: ['black'],
        lineColors: ['gray', 'blue']
    };

My question is: How can I graduate the Y axis to have a display of only 3 values: 1, 2 and 3 ?


Solution

  • There's actually no parmeter to do that in the latest official Morris.js v0.5.1.

    But you can hide the y values that are not integers with the yLabelFormat:

    Morris.Area({
      element: 'chart',
      data: [
        { y: '2015-01', a: 1, b: 2 },
        { y: '2015-02', a: 2,  b: 3 },
        { y: '2015-03', a: 2,  b: 2 },
        { y: '2015-04', a: 1,  b: 1 },
        { y: '2015-05', a: 2,  b: 2 },
        { y: '2015-06', a: 3,  b: 3 },
        { y: '2015-07', a: 1, b: 2 }
      ],
      xkey: 'y',
      ykeys: ['a', 'b'],
      labels: ['Individual Score', 'Team Score'],
      fillOpacity: 0.6,
      hideHover: 'auto',
      behaveLikeLine: true,
      resize: true,
      pointFillColors: ['#ffffff'],
      pointStrokeColors: ['black'],
      lineColors: ['gray', 'blue'],
      yLabelFormat: function(y){ return y != Math.round(y)?'':y; }
    });
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
    <script src="//cdnjs.cloudflare.com/ajax/libs/raphael/2.1.0/raphael-min.js"></script>
    <script src="//cdnjs.cloudflare.com/ajax/libs/morris.js/0.5.1/morris.min.js"></script>
    <link href="//cdnjs.cloudflare.com/ajax/libs/morris.js/0.5.1/morris.css" rel="stylesheet"/>
    
    <div id="chart"></div>

    Or you can use a modified version of Morris.js that adds a gridIntegers parameter. See this question: Integers as y-axis in a morris.js line chart.

    These parameters must be set in the modified Morris Area configuration:

    gridIntegers: true
    ymin: 0 // ymin and/or ymax (a value of your choice)
    

    Or you can use the latest official Morris.js v.0.5.1 and extend it to add the gridIntegers parameter:

    (function () {
        var $, MyMorris;
    
        MyMorris = window.MyMorris = {};
        $ = jQuery;
    
        MyMorris = Object.create(Morris);
    
        MyMorris.Grid.prototype.gridDefaults["gridIntegers"] = false;
    
        MyMorris.Grid.prototype.setData = function (data, redraw) {
            var e, idx, index, maxGoal, minGoal, ret, row, step, total, y, ykey, ymax, ymin, yval, _ref;
            if (redraw == null) {
                redraw = true;
            }
            this.options.data = data;
            if ((data == null) || data.length === 0) {
                this.data = [];
                this.raphael.clear();
                if (this.hover != null) {
                    this.hover.hide();
                }
                return;
            }
            ymax = this.cumulative ? 0 : null;
            ymin = this.cumulative ? 0 : null;
            if (this.options.goals.length > 0) {
                minGoal = Math.min.apply(Math, this.options.goals);
                maxGoal = Math.max.apply(Math, this.options.goals);
                ymin = ymin != null ? Math.min(ymin, minGoal) : minGoal;
                ymax = ymax != null ? Math.max(ymax, maxGoal) : maxGoal;
            }
            this.data = (function () {
                var _i, _len, _results;
                _results = [];
                for (index = _i = 0, _len = data.length; _i < _len; index = ++_i) {
                    row = data[index];
                    ret = {
                        src: row
                    };
                    ret.label = row[this.options.xkey];
                    if (this.options.parseTime) {
                        ret.x = Morris.parseDate(ret.label);
                        if (this.options.dateFormat) {
                            ret.label = this.options.dateFormat(ret.x);
                        } else if (typeof ret.label === 'number') {
                            ret.label = new Date(ret.label).toString();
                        }
                    } else {
                        ret.x = index;
                        if (this.options.xLabelFormat) {
                            ret.label = this.options.xLabelFormat(ret);
                        }
                    }
                    total = 0;
                    ret.y = (function () {
                        var _j, _len1, _ref, _results1;
                        _ref = this.options.ykeys;
                        _results1 = [];
                        for (idx = _j = 0, _len1 = _ref.length; _j < _len1; idx = ++_j) {
                            ykey = _ref[idx];
                            yval = row[ykey];
                            if (typeof yval === 'string') {
                                yval = parseFloat(yval);
                            }
                            if ((yval != null) && typeof yval !== 'number') {
                                yval = null;
                            }
                            if (yval != null) {
                                if (this.cumulative) {
                                    total += yval;
                                } else {
                                    if (ymax != null) {
                                        ymax = Math.max(yval, ymax);
                                        ymin = Math.min(yval, ymin);
                                    } else {
                                        ymax = ymin = yval;
                                    }
                                }
                            }
                            if (this.cumulative && (total != null)) {
                                ymax = Math.max(total, ymax);
                                ymin = Math.min(total, ymin);
                            }
                            _results1.push(yval);
                        }
                        return _results1;
                    }).call(this);
                    _results.push(ret);
                }
                return _results;
            }).call(this);
            if (this.options.parseTime) {
                this.data = this.data.sort(function (a, b) {
                    return (a.x > b.x) - (b.x > a.x);
                });
            }
            this.xmin = this.data[0].x;
            this.xmax = this.data[this.data.length - 1].x;
            this.events = [];
            if (this.options.events.length > 0) {
                if (this.options.parseTime) {
                    this.events = (function () {
                        var _i, _len, _ref, _results;
                        _ref = this.options.events;
                        _results = [];
                        for (_i = 0, _len = _ref.length; _i < _len; _i++) {
                            e = _ref[_i];
                            _results.push(Morris.parseDate(e));
                        }
                        return _results;
                    }).call(this);
                } else {
                    this.events = this.options.events;
                }
                this.xmax = Math.max(this.xmax, Math.max.apply(Math, this.events));
                this.xmin = Math.min(this.xmin, Math.min.apply(Math, this.events));
            }
            if (this.xmin === this.xmax) {
                this.xmin -= 1;
                this.xmax += 1;
            }
            this.ymin = this.yboundary('min', ymin);
            this.ymax = this.yboundary('max', ymax);
            if (this.ymin === this.ymax) {
                if (ymin) {
                    this.ymin -= 1;
                }
                this.ymax += 1;
            }
            if (((_ref = this.options.axes) === true || _ref === 'both' || _ref === 'y') || this.options.grid === true) {
                if (this.options.ymax === this.gridDefaults.ymax && this.options.ymin === this.gridDefaults.ymin) {
                    this.grid = this.autoGridLines(this.ymin, this.ymax, this.options.numLines);
                    this.ymin = Math.min(this.ymin, this.grid[0]);
                    this.ymax = Math.max(this.ymax, this.grid[this.grid.length - 1]);
                } else {
                    step = (this.ymax - this.ymin) / (this.options.numLines - 1);
                    if (this.options.gridIntegers) {
                        step = Math.max(1, Math.round(step));
                    }
                    this.grid = (function () {
                        var _i, _ref1, _ref2, _results;
                        _results = [];
                        for (y = _i = _ref1 = this.ymin, _ref2 = this.ymax; step > 0 ? _i <= _ref2 : _i >= _ref2; y = _i += step) {
                            _results.push(y);
                        }
                        return _results;
                    }).call(this);
                }
            }
            this.dirty = true;
            if (redraw) {
                return this.redraw();
            }
        };
    }).call(this);
    
    Morris.Area({
        element: 'chart',
        data: [
        { y: '2015-01', a: 1, b: 2 },
        { y: '2015-02', a: 2,  b: 3 },
        { y: '2015-03', a: 2,  b: 2 },
        { y: '2015-04', a: 1,  b: 1 },
        { y: '2015-05', a: 2,  b: 2 },
        { y: '2015-06', a: 3,  b: 3 },
        { y: '2015-07', a: 1, b: 2 }
      ],
      xkey: 'y',
      ykeys: ['a', 'b'],
      labels: ['Individual Score', 'Team Score'],
      fillOpacity: 0.6,
      hideHover: 'auto',
      behaveLikeLine: true,
      resize: true,
      pointFillColors: ['#ffffff'],
      pointStrokeColors: ['black'],
      lineColors: ['gray', 'blue'],
      gridIntegers: true,
      ymin: 0
    });
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
    <script src="//cdnjs.cloudflare.com/ajax/libs/raphael/2.1.0/raphael-min.js"></script>
    <script src="//cdnjs.cloudflare.com/ajax/libs/morris.js/0.5.1/morris.min.js"></script>
    <link href="//cdnjs.cloudflare.com/ajax/libs/morris.js/0.5.1/morris.css" rel="stylesheet" />
    
    <div id="chart"></div>