Search code examples
javascriptmorris.js

Remove extra x axis lines in the middle from morris.js Line chart


I'm trying to create a Line Chart using morris.js but the chart is showing extra lines with float values. But I only need the chart to show 0 and 1 axis enter image description here

This is my graph configuration

config = {
    data: graphData,
    xkey: 'x',
    ykeys: ['a','b'],
    parseTime: false,
    fillOpacity: 0.6,
    hideHover: 'auto',
    behaveLikeLine: true,
    resize: false,
    pointFillColors:['#ffffff'],
    pointStrokeColors: ['black'],
    lineColors:['red','orange'],
    hoverCallback: function(index, options, content, row) {
      return(content);
    },
    gridIntegers: true,
    ymax: 1,
    ymin: 0,

  };
config.element = 'line-chart';

$("#line-chart").empty();

Morris.Line(config);

I'm only submitting 1 and 0 for the x axis.

[
    {
        "x": "2020-02-15 06:36:21",
        "a": 1,
        "b": 1
    },
    {
        "x": "2020-02-14 21:35:37",
        "a": 0,
        "b": 0
    }
]

Solution

  • The official latest version of Morris v0.5.1 doesn't have a gridIntegers parameter. It was added in a pull request and available in this version of Morris.

    You can also use the latest official version of Morris and extend it to add this parameter like in my code snippet. Then, this parameter set to true like you tried should work as expected.

    Please try the following snippet:

    (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);
    
    var graphData = [
        { "x": "2020-02-15 06:36:21", "a": 1, "b": 1 },
        { "x": "2020-02-14 21:35:37", "a": 0, "b": 0 }
    ];
    
    var config = {
        data: graphData,
        element: 'line-chart',
        xkey: 'x',
        ykeys: ['a','b'],
        parseTime: false,
        fillOpacity: 0.6,
        hideHover: 'auto',
        behaveLikeLine: true,
        resize: false,
        pointFillColors:['#ffffff'],
        pointStrokeColors: ['black'],
        lineColors:['red','orange'],
        labels: ['A', 'B'],
        gridIntegers: true,
        ymax: 1,
        ymin: 0
      };
    
    $("#line-chart").empty();
    
    Morris.Line(config);
    <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="line-chart"></div>

    Note that you don't need your hoverCallback function if it stays like this. You should also add the labels parameter to define your labels.