How does jqplot calculate the stroke width?

I am trying to understand how jqplot calculates the width of bars when no width is specified. Let's say I have the following diagram:

$.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 } }, }); 

When I change the tickInterval value for 7 days and 14 days, the width of the bars changes even though there are the same number of bars in the same physical area. How is tickInterval used to calculate stroke widths? Or, if this fails, how can I change this example so that tickInterval can change (it will be calculated from the data in the end), but the width of the bars will be set to something reasonable?

+4
source share
2 answers

There is a property in barWidth called barWidth :

 // prop: barWidth // Width of the bar in pixels (auto by devaul). null = calculated automatically. this.barWidth = null; 

When configuring the series, you can also put rendererOptions . Add this:

 rendererOptions: { barWidth: 10 } 

So series becomes:

 series: [{ xaxis: 'xaxis', yaxis: 'yaxis', renderer: $.jqplot.BarRenderer, rendererOptions: { barWidth: 10 } }], 

Will force all stripes 10 pixels wide, regardless of tickInterval .

Edit:

Details for determining stroke widths are found in setBarWidth in jqplot.barRenderer.js .

To give you an example, calculating the stroke width for the unfastened x axis (which is very similar to the y axis) is as follows:

 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; 

Essentially, first we take the width (or height) of the axis and divide it by the maximum number of cells (in this case, bars). From this, we subtract the total filling between the rows (in this case, it is zero, since there is only one series), and then subtract the margin around the outside of the bar. After that, the total width of the bar is divided by the number of series on the chart.

As you can see from this code, an important bit really sets the number of ticks to display. In your particular case, this happens in the DateAxisRenderer , where it actually finds the number of days between the date max and min ( '2013-1-20' and '2013-12-1' ) - 315 - before dividing by the number of days in the interval, which from The question yoru was either 7 or 14, which gives 46 and 24, respectively.

+9
source

Thanks a lot for your answer. This is old, but here is what I did to solve the problem in my case

 $.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]; }; 

I simply replaced setBarWidth BarRenderer to use the number of values ​​instead of the number of ticks. The rest of the code belongs to the BarRenderer object, keeping it unchanged when updated.

To use it, just use:

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

All Articles