对数y轴与morris.js [英] Logarithmic y axis with morris.js

查看:94
本文介绍了对数y轴与morris.js的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试获得morris.js折线图的y轴的对数刻度。

I'm trying to get a logarithmic scale for the y-axis of a morris.js line chart.

http://www.oesmith.co.uk/morris.js/lines.html

我已尝试使用yLabelFormat选项,但这不是我需要的。
任何提示都表示赞赏。

I already tried playing with the yLabelFormat option, but it's not what I need. Any hint is appreciated.

如果没有办法用morris.js做这个,你可以建议另一个轻量级的javascript库来制作具有对数比例的简单折线图。

If there is no way of doing this with morris.js, you can suggest another lightweight javascript library to make simple line charts with logarithmic scale.

推荐答案

您可以扩展Morris并修改 transY 函数来执行对数刻度。

You can extend Morris and modify the transY function to do the logarithmic scale.

我还添加了 gridIntegers 参数,只在y轴上有整数。

I also added the gridIntegers parameter to have only integers on the y-Axis.

如果只想要 yLogScale transY 函数后面的代码>。

Remove the code after the transY function if you want only the yLogScale.

使用以下代码段查看结果, yLogScale 参数设置为 true false

Use the following snippet to view the result with yLogScale parameter set as true or false.

(function () {
    var $, MyMorris;

    MyMorris = window.MyMorris = {};
    $ = jQuery;

    MyMorris = Object.create(Morris);

    MyMorris.Grid.prototype.gridDefaults["yLogScale"] = false;
    MyMorris.Grid.prototype.gridDefaults["gridIntegers"] = false;

    MyMorris.Grid.prototype.transY = function (y) {
        if (!this.options.horizontal) {
            if (this.options.yLogScale) {
                return this.bottom - (this.height * Math.log((y + 1) - this.ymin) / Math.log(this.ymax / (this.ymin + 1)));
            } else {
                return this.bottom - (y - this.ymin) * this.dy;
            }
        } else {
            return this.left + (y - this.ymin) * this.dy;
        }
    };

    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 data = [
    { y: '2016-01', a: 1, b: 5 },
    { y: '2016-02', a: 2,  b: 3 },
    { y: '2016-03', a: 2,  b: 2 },
    { y: '2016-04', a: 1,  b: 1000 },
    { y: '2016-05', a: 2,  b: 2 },
    { y: '2016-06', a: 3,  b: 3 },
    { y: '2016-07', a: 1, b: 2 }
  ];

var morrisArea =
Morris.Area({
    element: 'chart',
    data: data,
  xkey: 'y',
  ykeys: ['a', 'b'],
  labels: ['Label A', 'Label B'],
  fillOpacity: 0.6,
  hideHover: 'auto',
  resize: true,
  yLogScale: true,
  gridIntegers: true,
  pointFillColors: ['#ffffff'],
  pointStrokeColors: ['black'],
  lineColors: ['gray', 'blue'],
  gridIntegers: true,
  ymin: 0
});

$(".button").on("click", function() {
  $(".button").removeClass("on");
  $(this).addClass("on");
});

function setYLogScale(status) {
  morrisArea.options["yLogScale"] = status;
  morrisArea.setData(data);
}

<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" />
<style>
  body { font-family: Arial; }
  .button {
    padding: 3px 5px;
    border: 1px solid black;
    background-color: #eeeeee;
    display: inline-block;
    cursor: pointer;
  }
  .on { background-color: lightblue; }
</style>

<div class="button" onclick="setYLogScale(true);">yLogScale ON</div>
<div class="button" onclick="setYLogScale(false);">yLogScale OFF</div>
<div id="chart"></div>

这篇关于对数y轴与morris.js的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆