Javascript 如何在Rickshaw.js绘图中设置动态或静态刻度大小?
我正在创建一个Rickshaw.js-powered图,非常类似于本例:基于通过AJAX调用返回的我自己的数据。数据以字节(典型值范围为几GB或数百MBs)或秒(10到50分钟之间的任意位置)为单位测量。我尝试使用Javascript 如何在Rickshaw.js绘图中设置动态或静态刻度大小?,javascript,plot,rickshaw,Javascript,Plot,Rickshaw,我正在创建一个Rickshaw.js-powered图,非常类似于本例:基于通过AJAX调用返回的我自己的数据。数据以字节(典型值范围为几GB或数百MBs)或秒(10到50分钟之间的任意位置)为单位测量。我尝试使用Rickshaw.Fixtures.Number.formatBase1024KMGTP格式化程序处理字节,并在几秒钟内编写了自己的格式化程序,这一部分做得很好。问题是我需要以智能方式定位刻度线-最好是动态定位,但即使是静态设置(例如,每隔1024*1024*1024=1 GB或每隔6
Rickshaw.Fixtures.Number.formatBase1024KMGTP
格式化程序处理字节,并在几秒钟内编写了自己的格式化程序,这一部分做得很好。问题是我需要以智能方式定位刻度线-最好是动态定位,但即使是静态设置(例如,每隔1024*1024*1024=1 GB或每隔60秒设置一个刻度)也可以
我尝试将tickSize
设置为1024^3
如下:
var y_axis = new Rickshaw.Graph.Axis.Y({
graph: graph,
tickSize: 1073741824 // 1 GB
});
y_axis.render();
但我最终没有看到蜱虫。我做错了什么?正确的方法是什么?tickSize
是以像素为单位的刻度大小。而不是你想要的设置为一个巨大的数字
将ticks
设置为您想要在图形上显示的ticks数量,人力车(实际上是d3)将发挥一些神奇的作用,为您提供在图形上生成大约该数量的ticks的漂亮值
如果您想要进一步控制,您必须深入研究,您将能够使用显式设置刻度值。我可能会复制现有代码并创建自己的Y轴类,该类包括对tickValues
的访问或使用自己的Y轴类的能力。这有点不干净,因为Rickshaw在graph.render()
函数中创建了Y比例,因此您无法轻松覆盖Y比例,但Rickshaw创建的Y比例确实具有从图形数据设置的范围,这是您在创建自己的刻度值时需要的信息。基本上,您需要调整人力车中的、和类的功能
tickSize
将无法帮助您正确地执行此操作-它指示粗体刻度线的大小(以像素为单位)。它与间距无关
对于基于时间的轴
我的解决方案基本上包括替换这些文件中的标准tickOffset()
函数
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;
};
每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;
};
this.render=function(){
if(this.graph.height!==this.\u renderHeight)this.setSize({auto:true});
var axis=d3.svg.axis().scale(this.graph.y)、orient(this.orientation);
如果(本条间隔){
var值=[];
var min=Math.ceil(axis.scale().domain()[0]/this.tickSpacing);
var max=Math.floor(axis.scale().domain()[1]/this.tickSpacing);
对于(i=min*this.tickSpacing;i
这里重要的部分是if(this.tickSpacing)
子句中的语句。它们计算config数组中tickSpacing
变量给出的刻度,并将它们分配给axis.tickValues(tickValues)
语句中的轴。请注意,this.tickValues
是在initialize()
函数中的this.tickSpacing=args.tickSpacing
语句中指定的,上面没有说明
你自己试试看
看看这个,这里有完整的代码。这肯定会给你一些提示。如果需要,您可以使用您的值创建自己的JSFIDLE,并告诉我您是否还需要其他内容 多谢各位。axis.tickValues应该有帮助,但是A)我应该如何准确地调用此函数?B) 如何使用自定义逻辑来确定刻度值应该是什么?欢迎使用小代码示例。我很挑剔,因为我提供了赏金。我想奖励你的辛勤工作,但我觉得为了我和其他人,答案可以扩大。谢谢。人力车不允许您访问tickValues()
。它甚至不允许您替换axis scale函数,因为它是在graph.render()的内部生成的。你必须重写和替换一些人力车代码,以获得你想要的完全控制权。这不是一件简单的事情。这可能会有所帮助:在您给出的示例中,默认的tickSize是4@MehdiKaramosly,那么我的理解是否正确,目前存在一个bug,它会阻止我正确使用Rickshaw.js?如果没有,你能详细说明一下吗?也许能提供一个单独的答案?@HamishGrubijan谢谢你给我指了指人力车.js。在过去的两年里,我一直在使用(这也很好),但似乎图书馆正在面临一些竞争。不适用于时区:(无论设置如何,总是显示GMT时间
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
} );
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;
};