Reputation: 409
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]:
With input array [1,2,3,4,5,6,1000]:
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
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).
Math.pow(x, y)
for 0 > y > 1.Math.pow(Math.log10(x + 1), y)
for y > 1Upvotes: 1