admin管理员组

文章数量:1420310

I'm trying to understand how to use the function attrTween in D3. I'm trying to implement a pie-chart from the following example: .

I'm having issues however when I arrive to the transition part.

  private populateGauge(): void {
    const innerRadius = this.radius - 50;
    const outerRadius = this.radius - 10;
    const arc = d3
      .arc()
      .innerRadius(innerRadius)
      .outerRadius(outerRadius)
      .startAngle(0);

    const background = this.svg
      .append('path')
      .datum({ endAngle: this.tau })
      .style('fill', '#ddd')
      .attr('d', arc);
    this.myEndAngle = { endAngle: (this.gaugeData.value / 100) * this.tau };
    const foreground = this.svg
      .append('path')
      .datum(this.myEndAngle)
      .style('fill', 'orange')
      .attr('d', arc);

    foreground
      .transition()
      .duration(1500)
      .attrTween('d', function(newAngle) {
        return function(d) {
          const interpolate = d3.interpolate(d.endAngle, newAngle);
          return function(t) {
            d.endAngle = interpolate(t);
            return arc(d);
          };
        };
      });
    }

I've been trying to use easy base cases and just using 0's in the interpolate function but I cant get rid of a final error, which the last return statement is throwing (return arc(d));

Argument of type 'number' is not assignable to parameter of type 'DefaultArcObject'.

How do I get arround these problems? Let me know if you need more information provided.

I'm trying to understand how to use the function attrTween in D3. I'm trying to implement a pie-chart from the following example: http://bl.ocks/mbostock/5100636 .

I'm having issues however when I arrive to the transition part.

  private populateGauge(): void {
    const innerRadius = this.radius - 50;
    const outerRadius = this.radius - 10;
    const arc = d3
      .arc()
      .innerRadius(innerRadius)
      .outerRadius(outerRadius)
      .startAngle(0);

    const background = this.svg
      .append('path')
      .datum({ endAngle: this.tau })
      .style('fill', '#ddd')
      .attr('d', arc);
    this.myEndAngle = { endAngle: (this.gaugeData.value / 100) * this.tau };
    const foreground = this.svg
      .append('path')
      .datum(this.myEndAngle)
      .style('fill', 'orange')
      .attr('d', arc);

    foreground
      .transition()
      .duration(1500)
      .attrTween('d', function(newAngle) {
        return function(d) {
          const interpolate = d3.interpolate(d.endAngle, newAngle);
          return function(t) {
            d.endAngle = interpolate(t);
            return arc(d);
          };
        };
      });
    }

I've been trying to use easy base cases and just using 0's in the interpolate function but I cant get rid of a final error, which the last return statement is throwing (return arc(d));

Argument of type 'number' is not assignable to parameter of type 'DefaultArcObject'.

How do I get arround these problems? Let me know if you need more information provided.

Share Improve this question asked Feb 24, 2019 at 14:18 maacmaac 4993 gold badges7 silver badges18 bronze badges 1
  • 1 I assume this runs fine. You just want to silent the TypeScript warning? Getting the types right with D3 and TypeScript can be a pain. – Reactgular Commented Feb 24, 2019 at 14:36
Add a ment  | 

1 Answer 1

Reset to default 6

attrTween('d',...) takes a single function that returns another function. You pass it a function that gets called with the current datum, index and current node as the parameters. This function should return the interpolation function which gets called with a time value.

When I look at your source code. You have 3 nested functions, and that's not correct.

You need to have the start and end angles as values of the datum, and should not mutate the datum from inside a tween function.

I prefer to create an arc function outside the tween function, and then use that for my interpolation. Which is more effective since you're not creating a new arc function every time.

const myArc = d3.arc();
// ^^^ call methods of arc() to configure settings that won't animate.

foreground
  .transition()
  .duration(1500)
  .attrTween('d', (d) => {
      return (t) => {
        const angle = d3.interpolate(d.endAngle, d.newAngle)(t);
        // ^^^ interpolate datum values using time.
        myArc.startAngle(angle);
        // ^^^ call methods of arc() to configure what you need.
        return myArc(null);
        // ^^^ call arc function to render "d" attribute.
      };
    };
  });

I find it easier to use the node package "@types/d3"

npm install @types/d3 --save-dev

You can then import these types into the TypeScript file

import * as d3 from 'd3';

If you have an IDE like WebStorm. You can CTRL+CLICK on a D3 function and see the type definitions and ments.

本文标签: javascriptAngular D3 understanding attrTween functionStack Overflow