John Smith
John Smith

Reputation: 409

Adjusting bar size in bar chart

I'm trying to make JavaScript bar chart plotter. For values that are close enough to each other, it works quite nice. This is how it looks like with input array [1, 2, 3, 4, 5, 6, 7]: 1-7 bar chart

With input array [1,2,3,4,5,6,1000]: enter image description here

I would say that technically this should be correct behavior, because it's only showing the difference between the large number and the rest, but the chart loses it's lucidity. I can't figure out how to calculate coefficient, which would adjust the bars to proper (taller relative to the canvas height) sizes.

Here's the code:

function barplot()
{
    this.load = function(canvas)
    {
        this.canvas = canvas;
        this.ctx = canvas.getContext("2d");
    },

    this.makebar = function(width, height, start)
    {
        this.ctx.beginPath();
        this.ctx.strokeStyle = "black";
        this.ctx.moveTo(start.x, start.y);
        this.ctx.lineTo(start.x,start.y-height);
        this.ctx.lineTo(start.x+width, start.y-height);
        this.ctx.lineTo(start.x+width,start.y);
        this.ctx.stroke();
        this.ctx.closePath();
    },

    this.plot = function(arr)
    {
        var width = this.canvas.width/arr.length;
        var max = Math.max.apply(null,arr);
        var min = Math.min.apply(null,arr);

        for(var i=0;i<arr.length;i++)    // Bar height generated here!
        {
            var coe = arr[i]/max;
            arr[i] = this.canvas.height*coe;  // The actual heights!
        }

        for(var i=0;i<arr.length;i++)
        {
            this.makebar(width, arr[i], {x:i*width,y:this.canvas.height});
        }
    }
}

Also the usage is quite simple if anyone wanted to try:

var b = new barplot();
b.load(your_canvas_element);
b.plot(array_of_numbers);

Upvotes: 0

Views: 175

Answers (1)

BoffinBrain
BoffinBrain

Reputation: 6525

It sounds to me like you want to use some kind of exponential or logarithmic scale to represent the relative magnitudes between the values. This will effectively give small numbers a 'boost'. In your code, you'll need to calculate the min and max based on the scaling method instead of their original values.

Picking a method that looks 'good' for your circumstances would be subjective and I don't know the context of the data you're graphing, but here are some examples of how a few methods might look (plotted using data bars in Excel).

  • On the first row, we have Math.pow(x, y) for 0 > y > 1.
  • On the second line we have Math.pow(Math.log10(x + 1), y) for y > 1

Graphs

Upvotes: 1

Related Questions