我已经构建了这个javascript / canvas规范库,可以有效地创建阈值和目标值,并围绕这些指标呈现指标。
我的问题不是javascript中特定于画布绘制等的任何内容,而是标签放置的策略。目前,我在标准角度上绘制了与弧心相距一定距离的标签。这似乎有效,但是我有一个问题,标签文本可以与另一个标签重叠(如果下界和目标太近)或标签与弧本身重叠。
只要我可以放下标签,我就可以轻松地画一条线到它需要指向仪表本身的位置。 (如本例所示)
我已经想到了在内存中创建粗略的猜测,然后沿着弧调整值,直到它们不再重叠。 (这看起来非常低效)
我希望有人可以提供一个指针,填补我的高中数学的空白以及它在这里的适用方式=)
答案 0 :(得分:0)
这是制定衡量标准的一种策略
示例代码和演示:http://jsfiddle.net/m1erickson/v2AaD/
<!doctype html>
<html lang="en">
<head>
<style>
body{ background-color: ivory; }
#wrapper{ position:relative; }
canvas{ position:absolute; left:40px; top:5px; border:1px solid red;}
#amount{ position:absolute; left:1px; top:5px; margin-bottom:15px; width:23px; border:0; color:#f6931f; font-weight:bold; }
#slider-vertical{ position:absolute; left:5px; top:40px; width:15px; height:225px; border:0px; color:#f6931f; font-weight:bold; }
</style>
<link rel="stylesheet" href="http://code.jquery.com/ui/1.10.3/themes/smoothness/jquery-ui.css" />
<script src="http://code.jquery.com/jquery-1.9.1.js"></script>
<script src="http://code.jquery.com/ui/1.10.3/jquery-ui.js"></script>
<script>
$(function() {
var canvas=document.getElementById("canvas");
var ctx=canvas.getContext("2d");
var PI=Math.PI;
var cx=200;
var cy=200;
var radius=100;
var min=0;
var max=1000;
var minBound=250;
var maxBound=750;
var arcWidth=40;
var tickWidth=4;
var tickValue=400;
var tickColor="black";
$( "#slider-vertical" ).slider({
orientation: "vertical",
range: "min",
min: min,
max: max,
value:tickValue,
slide:function( event, ui ) {
$( "#amount" ).val(ui.value);
draw(ui.value);
}
});
$( "#amount" ).val( $( "#slider-vertical" ).slider( "value" ) );
draw(tickValue);
function draw(value){
tickValue=value;
tickColor="green";
if(tickValue<minBound){tickColor="blue";}
if(tickValue>maxBound){tickColor="red";}
//
ctx.clearRect(0,0,canvas.width,canvas.height);
drawArc();
drawTick(minBound,"gray");
drawTick(maxBound,"gray");
drawTick(tickValue,tickColor,10);
drawLabel(minBound,"gray",20,18);
drawLabel(maxBound,"gray",20,18);
drawLabel(tickValue,tickColor,55,24);
}
function drawArc(){
ctx.beginPath();
ctx.arc(cx,cy,radius,0,PI,true);
ctx.lineWidth=arcWidth;
ctx.strokeStyle="lightgray";
ctx.stroke();
}
function drawTick(tickValue,color,extension){
var plus=extension||0;
var angle=PI+tickValue/(max-min)*PI;
var x1=cx+(radius-arcWidth/2)*Math.cos(angle);
var y1=cy+(radius-arcWidth/2)*Math.sin(angle);
var x2=cx+(radius+arcWidth/2+plus)*Math.cos(angle);
var y2=cy+(radius+arcWidth/2+plus)*Math.sin(angle);
ctx.beginPath();
ctx.moveTo(x1,y1);
ctx.lineTo(x2,y2);
ctx.lineWidth=tickWidth;
ctx.strokeStyle=color;
ctx.stroke();
}
function drawLabel(tickValue,color,extension,fontsize){
var angle=PI+tickValue/(max-min)*PI;
var x=cx+(radius+arcWidth/2+extension)*Math.cos(angle);
var y=cy+(radius+arcWidth/2+extension)*Math.sin(angle);
ctx.textAlign="center";
ctx.fillStyle=color;
ctx.font=fontsize+"px arial";
ctx.fillText(tickValue,x,y);
}
}); // end $(function(){});
</script>
</head>
<body>
<div id="wrapper">
<input type="text" id="amount" />
<div id="slider-vertical"></div>
<canvas id="canvas" width=425 height=300></canvas>
</div>
</body>
</html>