在画布线图中显示负值

时间:2015-02-10 14:03:04

标签: javascript html5 canvas charts

我使用html5 canvas元素绘制折线图。该图表正常值正常。但是当提供负值时,图表绘制不正确。

这是我尝试过的。任何帮助将不胜感激。

http://jsfiddle.net/nshX6/142/

  function getMinY () {

        var min = 0;
            for(var i = 0; i < data.values.length; i ++) {
                if(data.values[i].Y < min) {
                    min = data.values[i].Y;
                                   }
            }
        return Math.ceil(min);
    }

2 个答案:

答案 0 :(得分:2)

enter image description here

以下是一些可用于构建灵活图表的工具函数。

您的灵活图表将能够显示任何数据范围,并且始终适合可用的画布尺寸。

calcSourceMinMax:计算数据数组的最小值和最大值。

mapRange:获取任何数据值并将其映射到一个比例值,该值保证在图表的最小值和最大值之内可显示宽度&amp;高度。这允许您的数据数组包含任何值范围,但仍然不会超出图形显示区域。

getDisplayXY:获取指定的x,y数据值,并在图表上找到其显示的X,Y坐标。

这是示例代码和演示:

var canvas=document.getElementById("canvas");
var ctx=canvas.getContext("2d");
var cw=canvas.width;
var ch=canvas.height;


var xPadding = 40;
var yPadding = 30;

// Notice I changed The X values
var data = { values:[
  { X: 0, Y: -120 },
  { X: 2, Y: 28 },
  { X: 3, Y: 18 },
  { X: 4, Y: 34 },
  { X: 5, Y: 40 },
  { X: 6, Y: 80 },
  { X: 7, Y: 80 }
]};


// calc the drawable graph boundaries
var graphLeft=xPadding;
var graphRight=canvas.width-xPadding;
var graphTop=yPadding;
var graphBottom=canvas.height-yPadding;

// graph styling
var dotRadius=3;

// calc the min & max values of data.values (calc both X & Y ranges)
var rangeX=calcSourceMinMax(data.values,'X');
var rangeY=calcSourceMinMax(data.values,'Y');

// draw the graph content
var starting=getDisplayXY(data.values[0].X,data.values[0].Y);
dot(starting,dotRadius);
for(var i=1;i<data.values.length;i++){
  var ending=getDisplayXY(data.values[i].X,data.values[i].Y);
  connector(starting,ending);
  dot(ending,dotRadius);
  starting=ending;
}

// draw the graph axes
var y0=getDisplayXY(graphLeft,0).displayY;
ctx.beginPath();
ctx.moveTo(graphLeft,graphTop);
ctx.lineTo(graphLeft,graphBottom);
ctx.moveTo(graphLeft,y0);
ctx.lineTo(graphRight,y0);
ctx.strokeStyle='#D3E';
ctx.stroke();

// draw the graph legends
ctx.textAlign='right';
ctx.textBaseline='middle';
var y0=getDisplayXY(graphLeft,0).displayY;
var yMin=getDisplayXY(graphLeft,rangeY.min).displayY;
var yMax=getDisplayXY(graphLeft,rangeY.max).displayY;
var xMax=getDisplayXY(graphRight,rangeX.max).displayX;
ctx.fillText(rangeY.min,graphLeft-10,yMin);
ctx.fillText(0,graphLeft-10,y0);
ctx.fillText(rangeY.max,graphLeft-10,yMax);
ctx.fillText(rangeX.max,graphRight+10,y0);



///////////////////////////////////
// HELPER FUNCTIONS
///////////////////////////////////

// 
function getDisplayXY(valueX,valueY){
  // calc the display X & Y from data.values[i]
  x=mapRange(valueX,rangeX.min,rangeX.max,graphLeft,graphRight);
  // Note: canvas y values increase going downward
  // so swap graphTop & graphBottom
  y=mapRange(valueY,rangeY.min,rangeY.max,graphBottom,graphTop);
  return({displayX:x,displayY:y})
}
//
function connector(starting,ending){
  ctx.beginPath();
  ctx.moveTo(starting.displayX,starting.displayY);
  ctx.lineTo(ending.displayX,ending.displayY);
  ctx.stroke();
}
//
function dot(position,radius){
  ctx.beginPath();
  ctx.moveTo(position.displayX,position.displayY);
  ctx.arc(position.displayX,position.displayY,radius,0,Math.PI*2);
  ctx.closePath();
  ctx.fill();
}


// map source values into a designated range
function mapRange(value, sourceLow, sourceHigh, mappedLow, mappedHigh) {
  return mappedLow + (mappedHigh - mappedLow) * (value - sourceLow) / (sourceHigh - sourceLow);
}
// mapping helper function
function calcSourceMinMax(a,prop){
  var min=1000000;
  var max=-1000000;
  for(var i=0;i<a.length;i++){
    var value=a[i][prop];
    if(value<min){min=value;}
    if(value>max){max=value;}
  }
  return({min:min,max:max});
}
body{ background-color: ivory; padding:10px; }
#canvas{border:1px solid red;}
<canvas id="canvas" width=350 height=300></canvas>

您需要根据自己的设计需求设置图形样式。此最小示例显示包含x,y轴和最小值,最大值范围的图例。

此外,x轴位于y = 0值。您还需要检查y值范围内确实存在y = 0。如果没有,您可以移动图表底部的x轴。

祝你的项目好运!

答案 1 :(得分:0)

尝试修改此参数:

var xPadding = 30;
var yPadding = 30;

致:

var xPadding = 30;
var yPadding = 100;

之后你需要将Y步更改为更大。

修改

如果您有动态数据,则需要规范化值。

第1步:找到Y的最小值

第2步:如果最小值小于零(0),则需要将所有值标准化为正值。将该值添加到数组的每个元素

第3步:将Y轴移动到新的位置。