如何使用D3.js或C3.js自定义仪表针指针?

时间:2018-06-01 13:37:13

标签: javascript d3.js c3.js gauge

我需要在我的项目中绘制一个Gauge。我正在使用 d3.js 绘制一个标尺。 我Followed this link

效果很好,但我需要自定义针尖。我搜索了很多,但我不喜欢任何解决方案来定制针指针。

这是我的结果:

Result

预期结果:

Expected

如何使用d3.js或c3.js实现它。如果有人有想法与我分享。 提前谢谢。

1 个答案:

答案 0 :(得分:0)

根据您提供的链接,您需要进行修改:

Needle.prototype.render = function() {
  this.el.append('circle').attr('class', 'needle-center').attr('cx', 0).attr('cy', 0).attr('r', this.radius);

  return this.el.append('path').attr('class', 'needle').attr('id', 'client-needle').attr('d', recalcPointerPos.call(this, 0));


};

在此代码中,附加圆是针的中心,路径是针尖。 d位置使用recalcPointerPos函数计算

 var recalcPointerPos = function(perc) {
      var centerX, centerY, leftX, leftY, rightX, rightY, thetaRad, topX, topY;
      thetaRad = percToRad(perc / 2);
      centerX = 0;
      centerY = 0;
      topX = centerX - this.len * Math.cos(thetaRad);
      topY = centerY - this.len * Math.sin(thetaRad);
      leftX = centerX - this.radius * Math.cos(thetaRad - Math.PI / 2);
      leftY = centerY - this.radius * Math.sin(thetaRad - Math.PI / 2);
      rightX = centerX - this.radius * Math.cos(thetaRad + Math.PI / 2);
      rightY = centerY - this.radius * Math.sin(thetaRad + Math.PI / 2);
      return "M " + leftX + " " + leftY + " L " + topX + " " + topY + " L " + rightX + " " + rightY;
    };

如您所见,此函数的返回部分发送针尖路径的坐标。编辑此返回值将允许您自定义它。

更新:有关此问题的更多详细信息可在此page by Jake Trent找到。

我希望这会有所帮助。有关更详细的说明,请分享您自己的代码,以便我们对其进行专门审核。

更新:或者,这是一个基于问题创建者的评论的更简单的解决方案:

只需在适当的半径上在测量仪顶部附加一个白色圆圈即可。将它放在针后面并将其附加到图表中:

chart.append("circle")
    .attr("r", 70)
    .style("fill", "white")
    ;

查看这个plunker:https://plnkr.co/edit/25KSME35LewdkQaybBc5?p=preview

更新2:想出一个更好但更复杂的方法,与上面相同,但使用SVG Masks 在此方法中,您可以避免创建白色圆圈,因此如果将测量仪放在不同的背景上,则不会显示白色圆圈。该方法利用掩模。我们必须定义一个带有两个圆圈的面具:

  1. 填充白色的圆圈 - 这是将显示的区域,即半径将是整个规格的半径。
  2. 一个黑色填充的圆圈 - 这是隐藏/遮盖的区域。
  3. 应在将弧路径附加为:

    后定义此蒙版
    chart.append("defs")
        .append("mask")
        .attr ("id", "mask-1")
        .append("circle")
        .attr("r", 180)
        .style("fill", "#FFF")
        ;
    d3.select("#mask-1")
          .append("circle")
        .attr("r", 70)
        .style("fill", "#000");
    

    接下来,我们需要将此面罩添加到针头和针头中心:

    Needle.prototype.render = function() {
     this.el.append('circle').attr('class', 'needle-center').attr('cx', 0).attr('cy', 0).attr('r', this.radius)
    .attr("mask", "url(#mask-1)");
    
      return this.el.append('path').attr('class', 'needle').attr('id', 'client-needle').attr('d', recalcPointerPos.call(this, 0))
    .attr("mask", "url(#mask-1)");
    };
    

    检查此plunker以获取此方法的演示。 https://plnkr.co/edit/4SQSNO?p=preview