【问题标题】:How to set the dynamic or static tick size in a Rickshaw.js plot?如何在 Rickshaw.js 图中设置动态或静态刻度大小?
【发布时间】:2013-04-25 20:11:55
【问题描述】:

我正在创建一个 Rickshaw.js 驱动的图表,就像在这个示例中一样:http://code.shutterstock.com/rickshaw/tutorial/example_07.html 基于我自己通过 AJAX 调用返回的数据。数据以字节(典型值范围为几 GB 或数百 MB)或秒(介于 10 秒到 50 分钟之间)为单位。我尝试对字节使用Rickshaw.Fixtures.Number.formatBase1024KMGTP 格式化程序,并为几秒钟编写自己的格式化程序,这很好。问题是我需要以一种智能的方式定位刻度线 - 最好是动态的,但即使是静态设置(例如,每隔 1024*1024*1024=1 GB 或每个 60 s 放置一个刻度线)也可以。

我尝试将tickSize 设置为1024^3,如下所示:

var y_axis = new Rickshaw.Graph.Axis.Y({
    graph: graph,
    tickSize: 1073741824 // 1 GB
});
y_axis.render();

但我最终没有看到任何蜱虫。我做错了什么,正确的方法是什么?

【问题讨论】:

  • 这可能会有所帮助:github.com/shutterstock/rickshaw/issues/188 您给出的示例中的默认 tickSize 是 4
  • @Mehdi Karamosly,所以我的理解是否正确,目前存在一个错误会阻止我正确使用 Rickshaw.js?如果不是,那你能详细说明一下吗?也许提供一个单独的答案?
  • @HamishGrubijan 感谢您将我指向 Rickshaw.js。在过去的 2 年里,我使用了 highcharts.com(这也很棒),但似乎图书馆正在受到一些竞争。

标签: javascript plot rickshaw


【解决方案1】:

基本上,你需要适配Rickshaw中Axis.XAxis.YAxis.Time类的tickOffsets()函数。

tickSize 不会帮你解决这个问题——就像@Old Pro stated 一样——它表示粗体刻度线的大小(以像素为单位)。它与间距无关。

对于基于时间的轴

我的解决方案主要包括替换这些文件中的标准tickOffsets() 函数

this.tickOffsets = function() {
    var domain = this.graph.x.domain();

    var unit = this.fixedTimeUnit || this.appropriateTimeUnit();
    var count = Math.ceil((domain[1] - domain[0]) / unit.seconds);

    var runningTick = domain[0];
    var offsets = [];

    for (var i = 0; i < count; i++) {
        var tickValue = time.ceil(runningTick, unit);
        runningTick = tickValue + unit.seconds / 2;

        offsets.push( { value: tickValue, unit: unit } );
    }

    return offsets;
};

通过自定义例程。这会成功的:

this.tickOffsets = function() {
    var domain = this.graph.x.domain();
    var unit = this.fixedTimeUnit || this.appropriateTimeUnit();

    var tickSpacing = args.tickSpacing || unit.seconds;
    var count = Math.ceil((domain[1] - domain[0]) / tickSpacing);

    var runningTick = domain[0];
    var offsets = [];

    for (var i = 0; i < count; i++) {
        var tickValue = time.ceil(runningTick, unit);
        runningTick = tickValue + tickSpacing;

        offsets.push( { value: tickValue, unit: unit } );
    }
    return offsets;
};

有了这些,你就可以写出类似的东西了

var time = new Rickshaw.Fixtures.Time();
var timeUnit = time.unit('year');

var x_axis = new Rickshaw.Graph.Axis.ExtendedTime( 
    { 
        graph: graph, 
        tickSpacing: 60*60*24*365*13, // 13 years
        timeUnit: timeUnit
    } );

每 13 年均匀间隔一次。

对于基于值的轴

对于基于值的轴,您需要扩展 render() 函数以包含“手动”设置轴刻度的工具。我是这样做的:

this.render = function() {

    if (this.graph.height !== this._renderHeight) this.setSize({ auto: true });

    var axis = d3.svg.axis().scale(this.graph.y).orient(this.orientation);

    if (this.tickSpacing) {
        var tickValues = [];

        var min = Math.ceil(axis.scale().domain()[0]/this.tickSpacing);
        var max = Math.floor(axis.scale().domain()[1]/this.tickSpacing);

        for (i = min * this.tickSpacing; i < max; i += 1) {
            console.log(i);
            tickValues.push(i * this.tickSpacing);
        }
        axis.tickValues(tickValues);
    }

    axis.tickFormat( args.tickFormat || function(y) { return y } );

    if (this.orientation == 'left') {
        var berth = this.height * berthRate;
        var transform = 'translate(' + this.width + ', ' + berth + ')';
    }

    if (this.element) {
        this.vis.selectAll('*').remove();
    }

    this.vis
        .append("svg:g")
        .attr("class", ["y_ticks", this.ticksTreatment].join(" "))
        .attr("transform", transform)
        .call(axis.ticks(this.ticks).tickSubdivide(0).tickSize(this.tickSize));

    var gridSize = (this.orientation == 'right' ? 1 : -1) * this.graph.width;

    this.graph.vis
        .append("svg:g")
        .attr("class", "y_grid")
        .call(axis.ticks(this.ticks).tickSubdivide(0).tickSize(gridSize));

    this._renderHeight = this.graph.height;
};

这里的重要部分是if (this.tickSpacing) 子句中的语句。它们计算配置数组中tickSpacing 变量给出的刻度,并将它们分配给axis.tickValues(tickValues) 语句中的轴。注意this.tickValues是在initialize()函数的this.tickSpacing = args.tickSpacing语句中赋值的,上面没有说明。

自己试试

看看这个jsfiddle,这里有完整的代码。这肯定会给你一些指示。如果您愿意,您可以使用您的价值观创建自己的 jsfiddle,并告诉我您是否需要其他任何东西。

【讨论】:

  • 不适用于时区 :( 无论设置如何,始终显示 GMT 时间
【解决方案2】:

tickSize 是刻度的大小(以像素为单位)。不是您想要设置的巨大数字。

ticks 设置为图表上您想要的刻度数,Rickshaw(实际上是 d3)会做一些魔术,为您提供漂亮的刻度值,在图表上生成大约该刻度数。

如果您想进一步控制,您将不得不深入研究d3,在那里您将能够使用axis.tickValues() 显式设置刻度值。我可能会复制现有的Rickshaw.Graph.Axis.Y 代码并创建我自己的 Y 轴类,其中包括对tickValues 的访问或使用我自己的scale 的能力。 Rickshaw 在 graph.render() 函数中创建 Y 比例有点不干净,因此您不能轻易覆盖 Y 比例,但 Rickshaw 创建的 Y 比例确实具有从图形数据设置的范围,这是您将在创建自己的刻度值时需要。

【讨论】:

  • 谢谢。 axis.tickValues 应该有帮助,但是 A)我应该如何调用这个函数? B) 我如何使用自定义逻辑来确定刻度值应该是什么?欢迎使用小代码示例。我很挑剔,因为我提供了赏金。我想奖励你的辛勤工作,但我觉得为了我和他人的利益,答案可以扩大。谢谢。
  • Rickshaw 不允许您访问tickValues()。它甚至不允许您替换轴刻度函数,因为它在graph.render() 内部生成它。您必须重写和替换一些 Rickshaw 代码才能获得所需的完全控制权。这不是一件简单的事情。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-08-11
  • 2011-11-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多