Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How does jqplot calculate bar width?

Tags:

jqplot

I'm trying to understand how jqplot calculates the width of bars when the width is not specified. Say I have the following chart:

$.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 tickInterval between 7 days and 14 days, the width of the bars alters, despite there being the same number of bars on the same physical area. How is tickInterval used in the calculation of bar widths? Or failing that, how can I alter this example such that tickInterval can vary (it will be calculated from data eventually) but the width of the bars be set to something sensible?

like image 766
elo96 Avatar asked Jan 14 '23 08:01

elo96


1 Answers

In jqplot.barRenderer.js there is a property called barWidth:

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

When setting the series options, you can also supply rendererOptions. Adding this:

rendererOptions: { barWidth: 10 }

So the series becomes:

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

Will force all bars to be 10 pixels wide, regardless of the tickInterval.

Edit:

The details for determining bar widths are in the setBarWidth function in jqplot.barRenderer.js.

To give you an example, calculating the bar widths for an unstacked x-axis (it's very similar for 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, we first take the width (or height) of the axis, and divide it by the maximum number of bins (in this case bars). From this we subtract the total padding between series (in this case it is zero as there is only one series) and then subtract the margin around the outside of the bar. After that the total bar width is divided by the number of series in the plot.

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

like image 100
nick_w Avatar answered Jan 21 '23 20:01

nick_w