jqplot如何计算条形图的宽度?

4

我想理解jqplot在未指定宽度时如何计算条形图的宽度。假设我有以下图表:

$.jqplot(chartDiv.attr("id"), [
    [
        ['2013-02-15', 0],
        ['2013-03-01', 2],
        ['2013-03-15', 4],
        ['2013-03-29', 6],
        ['2013-04-12', 8],
        ['2013-04-26', 10],
        ['2013-05-10', 12],
        ['2013-05-24', 14],
        ['2013-06-07', 16],
        ['2013-06-21', 18],
        ['2013-07-05', 20],
        ['2013-07-19', 22],
        ['2013-08-02', 24],
        ['2013-08-16', 26],
        ['2013-08-30', 28],
        ['2013-09-13', 30],
        ['2013-09-27', 32],
        ['2013-10-11', 34],
        ['2013-10-25', 36],
        ['2013-11-08', 38], , ], ], {


    axes: {
        xaxis: {
            renderer: $.jqplot.DateAxisRenderer,
            min: '2013-1-20',
            max: '2013-12-1',
            tickRenderer: $.jqplot.CanvasAxisTickRenderer,
            tickInterval: '14 days',
            tickOptions: {
                angle: 45,
                formatString: '%d/%m/%Y',
            },
        }
    },
    series: [{
        xaxis: 'xaxis',
        yaxis: 'yaxis',
        renderer: $.jqplot.BarRenderer,
    }],
    seriesDefaults: {
        shadow: false,
    },
    axesDefaults: {
       useSeriesColor: true,
        rendererOptions: {
            alignTicks: true
        }
    },
});

当我将tickInterval从7天改为14天时,尽管同一区域上有相同数量的条形图,但条形图的宽度会发生改变。tickInterval如何用于计算条形图的宽度?或者,如果tickInterval可以变化(最终将根据数据计算),但希望条形图的宽度保持合理,该怎么修改此示例?
2个回答

9
jqplot.barRenderer.js 中有一个叫做 barWidth 的属性:
// prop: barWidth
// Width of the bar in pixels (auto by devaul).  null = calculated automatically.
this.barWidth = null;

设置系列选项时,您还可以提供rendererOptions。添加此选项:

rendererOptions: { barWidth: 10 }

因此,series 变成了:
series: [{
    xaxis: 'xaxis',
    yaxis: 'yaxis',
    renderer: $.jqplot.BarRenderer,
    rendererOptions: { barWidth: 10 }
}],

将强制所有条形图宽度为10个像素,不管 tickInterval

编辑:

确定条形图宽度的详细信息在 jqplot.barRenderer.js 中的 setBarWidth 函数中。

举个例子,计算未堆叠的 x 轴(y 轴也非常类似)的条形图宽度如下:

var nticks = paxis.numberTicks;
var nbins = (nticks-1)/2;

this.barWidth = ((paxis._offsets.max - paxis._offsets.min) / nbins -
    this.barPadding * (nseries - 1) - this.barMargin * 2) / nseries;

基本上,我们首先取出轴的宽度(或高度),并将其除以最大柱数(在这种情况下是条形)。然后从中减去系列之间的总填充(在这种情况下为零,因为只有一个系列),再减去条形外围的边距。之后,总条形宽度再除以绘图中的系列数。
从该代码可以看出,重要的部分实际上是确定要显示的刻度数。在您的特定情况下,这发生在DateAxisRenderer中,它基本上找到最大和最小日期之间的天数('2013-1-20'和'2013-12-1') - 315 - 然后通过时间间隔内的天数除以此数,根据您的问题,时间间隔为7或14,分别得出46和24。

谢谢你的回复,nick_w。我的困惑更多是关于当未指定barWidth并且“自动计算”时。我不明白这个计算基于什么。 - elo96
1
nick_w:非常感谢您清晰的解释。看起来在使用DateAxisRenderer时,自动计算条形宽度并不实用,因为它取决于刻度线的数量而不是条形的数量。 - elo96

0

非常感谢您的回答。虽然这是旧问题,但以下是我在我的情况下解决问题的方法。

$.jqplot.DateBarRenderer = function(){
    $.jqplot.BarRenderer.call(this);
};
$.jqplot.DateBarRenderer.prototype = new $.jqplot.BarRenderer();

  $.jqplot.DateBarRenderer.prototype.setBarWidth = function() {
  // need to know how many data values we have on the approprate axis and figure it out.
  var i;
  var nvals = 0;
  var nseries = 0;
  var paxis = this[this._primaryAxis];
  var s, series, pos;
  var temp = this._plotSeriesInfo = this.renderer.calcSeriesNumbers.call(this);
  nvals = temp[0];
  nseries = temp[1];
  var nticks = paxis.numberTicks;
  var nbins = (nticks-1)/2;
  // so, now we have total number of axis values.
  if (paxis.name == 'xaxis' || paxis.name == 'x2axis') {
      if (this._stack) {
          this.barWidth = (paxis._offsets.max - paxis._offsets.min) / nvals * nseries - this.barMargin;
      }
      else {
          this.barWidth = ((paxis._offsets.max - paxis._offsets.min)/ (nvals + 1 )  - this.barPadding * (nseries-1) - this.barMargin*2)/nseries;
          //this.barWidth = ((paxis._offsets.max - paxis._offsets.min)/nbins  - this.barPadding * (nseries-1) - this.barMargin*2)/nseries;
          // this.barWidth = (paxis._offsets.max - paxis._offsets.min) / nvals - this.barPadding - this.barMargin/nseries;
      }
  }
  else {
      if (this._stack) {
          this.barWidth = (paxis._offsets.min - paxis._offsets.max) / nvals * nseries - this.barMargin;
      }
      else {
          this.barWidth = ((paxis._offsets.min - paxis._offsets.max)/nbins  - this.barPadding * (nseries-1) - this.barMargin*2)/nseries;
          // this.barWidth = (paxis._offsets.min - paxis._offsets.max) / nvals - this.barPadding - this.barMargin/nseries;
      }
  }
  return [nvals, nseries];
};

我只是将BarRenderersetBarWidth替换为使用值的数量而不是刻度的数量。其余的代码来自于BarRenderer对象,保持不变以防更新。

要使用它,只需使用:

var plot = $.jqplot('graphID', [graphData], {
    axes:{
      xaxis:{
        renderer:$.jqplot.DateAxisRenderer
      }
    },
    seriesDefaults:{
      renderer:$.jqplot.DateBarRenderer
    }
  });

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接