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:
- 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.
- 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