Skip to content Skip to sidebar Skip to footer

D3 Animate Path By Arc

I started to work with d3. And have a question, how can I animate properly triangle along the filling path? I created a base for the gauge chart and animated it. The question is,

Solution 1:

I'd use SVG transform: rotate, because it allows you to specify relative to what you should rotate, and because you can chain transformations. In this case, I transform the angle to the centre of the arc, then rotate it into the right direction, and then move it up a little bit more than the outer radius so it follows the line smoothly.

It's not pixel perfect, which I think is because the triangle is not a whole number of pixels wide.

var chart = d3.select("#speedometer");

const arc = d3
    .arc()
    .outerRadius(120)
    .innerRadius(90)
    .startAngle(-Math.PI / 2);

chart
    .append("path")
    .datum({
        endAngle: Math.PI / 2
    })
    .attr("transform", "translate(160, 180)")
    .attr("class", "background")
    .style("fill", "#495270")
    .attr("d", arc);

const triangle = chart
  .append('g')
  .datum({ endAngle: -Math.PI / 2 })
  .style('width', '100%')
  .append("path").attr("d", "M3.937,0,7.873,14H0Z");

const newAngle = (70 / 100) * Math.PI - Math.PI / 2;

const foreground = chart
    .append("path")
    .datum({ endAngle: -Math.PI / 2 })
    .style("fill", "rgb(50, 188, 228)")
    .attr("transform", "translate(160, 180)")
    .attr("d", arc);

foreground
    .transition()
    .duration(3000)
    .attrTween("d", function (d) {
        const interpolate = d3.interpolate(d.endAngle, newAngle);
        returnfunction (t) {
            d.endAngle = interpolate(t);
            returnarc(d);
        };
    });

triangle
    .transition()
    .duration(3000)
    .attrTween("transform", function (d) {
        const interpolate = d3.interpolate(d.endAngle, newAngle);
        returnfunction (t) {
          const angleRadians = interpolate(t);
          const angleDegrees = 360 * angleRadians / (2 * Math.PI);
          return`
            translate(158 176)
            rotate(${angleDegrees + 180} 3.5 7)
            translate(0 132)
          `;
        };
    });

functionpathTween(path) {
    const length = path.node().getTotalLength(); // Get the length of the pathconst r = d3.interpolate(0, length); // Set up interpolation from 0 to the path lengthreturnfunction (t) {
        const point = path.node().getPointAtLength(r(t)); // Get the next point along the path
        d3
            .select(this) // Select the circle
            .attr("transform", `translate(${point.x}, ${point.y})`);
    };
}
.main-wrapper{
  max-width: 80%;
  margin: 20px auto;
}

.element{
  display: flex;
  flex-flow: column nowrap;
  margin-bottom: 20px;
    border: 1px solid rgba(0,0,0,.4);
    padding: 20px;
    border-radius: 6px;
}

.title{
  margin-bottom: 4px;
  font-weight: 500;
}
.description{
  margin-bottom: 10px;
  color: rgba(0,0,0,.4);
}

#speedometer {
    width: 300px;
    height: 300px;
}

canvas{
    width: 100%;
    height: 100%;
}
<scriptsrc="https://cdnjs.cloudflare.com/ajax/libs/d3/6.2.0/d3.min.js"></script><divclass="main-wrapper"><sectionclass="ui-section"><divclass="element"><divclass="title">
        Speedometr
      </div><divclass="content"><svgid="speedometer"viewbox="0 0 300 300"></svg></div></div></section></div>

Post a Comment for "D3 Animate Path By Arc"