如何使用D3.js或C3.js自定义仪表针指针? [英] How to customise Gauge needle pointer using D3.js or C3.js?

查看:174
本文介绍了如何使用D3.js或C3.js自定义仪表针指针?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要在项目中绘制仪表。我正在使用 d3.js 绘制量规。



如何使用d3.js或c3.js来实现它。
预先感谢。

解决方案

根据您提供的链接,您需要进行编辑:

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

返回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);
返回 M + leftX + + leftY + L + topX + + topY + L + rightX + + rightY;
};

您可以看到此函数的返回部分发送了针尖路径的坐标。编辑此返回值将使您可以自定义它。



更新:有关此数学的更多详细信息,请参见此页面。



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



更新:或者,这是基于以下注释的更简单解决方案问题创建者:



只需在仪表盘上附加一个带有适当半径的白色圆圈即可。将其放在指针后面并将其附加到图表中:

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

看看这个小家伙: https://plnkr.co/edit/25KSME35LewdkQaybBc5?p=preview



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


  1. 用白色填充的圆-这是要显示的区域,即半径

  2. 带有黑色填充的圆圈-这是将被隐藏/遮盖的区域。

应在圆弧路径后面附加以下内容来定义此蒙版:

 图表。 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));

返回this.el.append('path')。attr('class','needle')。attr('id','client-needle')。attr('d', recalcPointerPos.call(this,0))
.attr( mask, url(#mask-1));
};

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


I need to plot a Gauge in my project. I am using d3.js to plot a gauge. I Followed this link

It works good but i need to customise the needle point. I searched quite a lot but i could not fond any solution to customise the needle pointer.

This is my result:

Expected Result:

How to achieve it using d3.js or c3.js.If anyone has idea share with me. Thanks in advance.

解决方案

Based on the link you have provided you need to edit :

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));


};

In this code the append circle is the center of the needle and the path is the needle tip. The d positions are calculated using the recalcPointerPos function

 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;
    };

As you can see the return part of this function sends the coordinates for the path for the needle tip. Editing this return values will let you customize it.

Update: more details of the mathematics involved in this can be found on this page by Jake Trent.

I hope this helps. For more detailed explanation, please share your own code so that we can review it specifically.

Update: Alternatively, here is a simpler solution based on the comments by the question creator:

Just append a white circle on top of the guage with an appropriate radius. Put this after the needle and append it to the chart:

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

Check out this plunker: https://plnkr.co/edit/25KSME35LewdkQaybBc5?p=preview

Update 2 : Thought up a better but slightly more complicated way of doing the same as above but using SVG Masks. In this method, you avoid creating a white circle, thereby if you place the gauge on a different background, it will not show the white circle. This method utilizes masks. We have to define a mask with two circles:

  1. A circle with fill of white - This is the area which will be shown i.e. the radius will be that of the entire gauge.
  2. A circle with a fill of black - This is the area which will be hidden/masked.

This mask should be defined after the arc paths are appended as:

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");

Next we need to add this mask to the needle and the needle center as:

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)");
};

Check this plunker out for a demo of this method. https://plnkr.co/edit/4SQSNO?p=preview

这篇关于如何使用D3.js或C3.js自定义仪表针指针?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆