I’m playing around with ( https://gist.github.com/1499279 ) a custom gauge using d3js by Tomer. In his code, he calls updateGauges() gauges[key].redraw(30 + 50 * Math.random() - 30 * Math.random()); to generate random numbers for the pointer to animate to. I changed it to gauges[key].redraw(80); so that the pointer does not re-render.
During the initial load, the pointer follows a shortest path in getting to its destination instead of animating in an arched trajectory (clock wise like how real gauges operate). When 80 is passed in as parameter, the pointer animates anti clockwise from 0. Instead, it should always follow an arched trajectory.
What do you guys think should be modified/added?
*Soln Update:
this.drawPointer = function(value)
{
var delta = this.config.range / 13;
var n=value/2;
var head = this.valueToPoint(n, 0.85);
var head1 = this.valueToPoint(n - delta, 0.12);
var head2 = this.valueToPoint(n + delta, 0.12);
var headlast = this.valueToPoint(value, 0.85);
var head1last = this.valueToPoint(value - delta, 0.12);
var head2last = this.valueToPoint(value + delta, 0.12);
var tailValue = n - (this.config.range * (1/(270/360)) / 2);
var tail = this.valueToPoint(tailValue, 0.28);
var tail1 = this.valueToPoint(tailValue - delta, 0.12);
var tail2 = this.valueToPoint(tailValue + delta, 0.12);
var tailValuelast = value - (this.config.range * (1/(270/360)) / 2);
var taillast = this.valueToPoint(tailValuelast, 0.28);
var tail1last = this.valueToPoint(tailValuelast - delta, 0.12);
var tail2last = this.valueToPoint(tailValuelast + delta, 0.12);
var data = [head, head1, tail2, tail, tail1, head2, head];
var line = d3.svg.line()
.x(function(d) { return d.x })
.y(function(d) { return d.y })
.interpolate("basis");
var pointerContainer = this.body.select(".pointerContainer");
var pointer = pointerContainer.selectAll("path").data([data])
pointer.enter()
.append("svg:path")
.attr("d", line)
.style("fill", "#dc3912")
.style("stroke", "#c63310")
.style("fill-opacity", 0.7)
pointer.transition()
.attr("d", line)
.each("end", function () {
if (value!=0) {
var head = headlast;
var head1 = head1last;
var head2 = head2last;
var tailValue = tailValuelast;
var tail = taillast;
var tail1 = tail1last;
var tail2 = tail2last;
var data = [head, head1, tail2, tail, tail1, head2, head];
var line = d3.svg.line()
.x(function(d) { return d.x })
.y(function(d) { return d.y })
.interpolate("basis");
var pointer = pointerContainer.selectAll("path").data([data])
pointer.enter()
.append("svg:path")
.attr("d", line)
.style("fill", "#dc3912")
.style("stroke", "#c63310")
.style("fill-opacity", 0.7)
pointer.transition()
.attr("d", line)
.ease("bounce")
.duration(600);
}
}
)
.duration(200);
var fontSize = Math.round(this.config.size / 10);
pointerContainer.selectAll("text")
.data([value])
.text(Math.round(value))
.enter()
.append("svg:text")
.attr("x", this.config.cx)
.attr("y", this.config.size - this.config.cy / 4 - fontSize)
.attr("dy", fontSize / 2)
.attr("text-anchor", "middle")
.text(Math.round(value))
.style("font-size", fontSize + "px")
.style("fill", "#000")
.style("stroke-width", "0px");
}
Regards,
Viswesh
I am also new to D3, but here is my humble understanding (please correct me if I am wrong):
Here interpolate simply change x and y value from current value to target value.
In your case, the y value needs to change from current value -> highest point(which is 100) -> to the target value.
One of the solution i can think of is add control point.