【问题标题】:Strategy for laying out labels on a gauge在量规上布置标签的策略
【发布时间】:2014-06-02 09:22:30
【问题描述】:

我已经构建了这个 javascript / canvas 量表库,它可以有效地让您创建阈值以及目标值并围绕这些指标呈现量表。

我的问题不是 JavaScript 中特定于画布绘图等的任何内容,而是标签放置的策略。目前,我在计算的角度上绘制标签与圆弧中心的距离。这似乎可行,但是我遇到了一个问题,标签文本可能与另一个标签重叠(如果下限和目标太接近)或标签与弧本身重叠。

一旦我可以将标签放置下来,我总是可以轻松地在仪表本身上画一条线到它需要指向的位置。 (如本例所示)

我尝试过在内存中创建一个粗略的猜测,然后沿着弧线调整值直到它们不再重叠。 (这似乎非常低效)

我希望有人能提供一个指针来填补我高中数学的空白,以及它在此处的应用方式 =)

【问题讨论】:

  • 您将不得不更改数字的布局。只要您的 250 位于灰色针的外部中心,那么当它们接近时,250 将始终与 1 或 1000 重叠。也许将 1 和 1000 移动到灰色弧内的白色区域并使其变小。
  • 这就是问题的重点,我可以检测标签的冲突并将它们移开一个度数,直到它们不再重叠(然后只需画线以指向适当的位置仪表),但我认为这是非常低效的。我希望有人有一些数学技巧可以帮助我聪明地说哦 0 和 5 标签会重叠,把它们放在碰撞检查循环以外的地方

标签: javascript canvas drawing


【解决方案1】:

这是布置你的语气的一种策略

示例代码和演示: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>

【讨论】:

    猜你喜欢
    • 2023-02-07
    • 1970-01-01
    • 1970-01-01
    • 2011-01-20
    • 2021-07-09
    • 1970-01-01
    • 2011-10-08
    • 2023-01-03
    • 2023-03-09
    相关资源
    最近更新 更多