8

I am trying to use D3 v4 with Angular 2 (Typescript). I am currently looking into D3 v4. I was able to follow some of the answers here in stackoverflow with similar issues with no success. I have imported most of the D3 libraries and its typings ( I am using TS 2.0) and in my component file I require import * as d3 from 'd3';. This issue to me might be Angular 2, Typescript and 3rd party libraries... so far a mess.

In my component file I have some code like this:

        let arc = d3.arc()
            .outerRadius(chartHeight / 2)
            .innerRadius(chartHeight / 4)
            .padAngle(0.03)
            .cornerRadius(8);

        let pieG = chartLayer.selectAll("g")
            .data([data])
            .enter()
            .append("g")
            .attr("transform", "translate(" + [chartWidth / 2, chartHeight / 2] + ")");

        let block = pieG.selectAll(".arc")
            .data(arcs);

        let newBlock = block.enter().append("g").classed("arc", true);

        newBlock.append("path")
            .attr("d", arc)
            .attr("id", function (d, i) {
                return "arc-" + i
            })
            .attr("stroke", "gray")
            .attr("fill", function (d, i) {
                return d3.interpolateCool(Math.random())
            });

As you can see I have defined arc on the first line and using it in line 19 but I get an error:

[at-loader] src\piechart\piechart.component.ts:19:28
    Argument of type 'Arc<any, DefaultArcObject>' is not assignable to      parameter of type '(this: BaseType, datum: PieArcDatum<number | { valueOf():    number; }>, index: num
  ber, groups: Base...'.
  Types of parameters 'd' and 'datum' are incompatible.
    Type 'PieArcDatum<number | { valueOf(): number; }>' is not assignable to type 'DefaultArcObject'.
      Property 'innerRadius' is missing in type 'PieArcDatum<number | { valueOf(): number; }>'.

The Arch and arc seem to be defined in the d3-shape types and also in the d3-path types.

Anyone that can help me... I have spent days trying to do a POC with angular 2, TS and D3 v4 and so far no luck... I have seen all the articles online about it and most of them have older version or not working. It seems too me that this is a typing issue. Angular 2 and third party libraries are a nightmare.

4
  • Change .attr("d", arc) to .attr("d", function(d) { console.log(d); arc(d); } update your question with the output of that console.log...
    – Mark
    Commented Dec 2, 2016 at 2:17
  • newBlock.append("path") .attr("d", (d) => { console.log(d); arc(d); }) .attr("id", (d, i) => { return "arc-" + i }) I get two ts errors ... and the 4 logs like below: Log: {"data":{"name":"hoge","value":100},"index":0,"value":100,"startAngle":0,"endAngle":0.7075659129706742,"padAngle":0}
    – coderdark
    Commented Dec 2, 2016 at 2:44
  • Trying to replicate your issue here without success. I'm unsure how plunker compiles typescript, though :(
    – Mark
    Commented Dec 2, 2016 at 16:27
  • Thanks Mark. This is frustrating. I switched to d3 v3.5.5 and the latest types for this version is 3.5.36. When using this code: ` let pie = d3.layout.pie() .sort(null) .value((d) => { return d.population; }); ` I get an error: [at-loader] src/piechart/piechart.component.ts:39:26 Property 'population' does not exist on type 'number'. But if I just add a type to 'd' (inside value) of any it works. I think the issue is with typings or I am doing something wrong but cant figure it out.
    – coderdark
    Commented Dec 2, 2016 at 21:59

5 Answers 5

17

Just need to cast arc as any. So it should be .attr("d", <any>arc)

1
  • 2
    This can be a temporary workaround, but I guess this should be solved in a proper way, maybe is a bug on typescript definitions?
    – Braulio
    Commented Feb 25, 2020 at 10:26
7

You just need to add a type when you create the arc. Try something like this:

interface Datum {
  key: string;
  value: number;
}

const pieData = d3.pie<Datum>()
  .value(d => d.value)(data);

const arc = d3.arc<d3.PieArcDatum<Datum>>();

d3.select('#pie')
  .data(pieData)
  .enter()
  .append('path')
  .attr('d', arc);

2

I added the import statement in my Angular 2 project and kept getting errors in development. I'm using angular-cli and d3 v4.

In addition to import * as d3 from "d3"; add the code below to your typings.d.ts file:

declare module 'd3' {
  export * from 'd3-array';
  export * from 'd3-axis';
  export * from 'd3-brush';
  export * from 'd3-chord';
  export * from 'd3-collection';
  export * from 'd3-color';
  export * from 'd3-dispatch';
  export * from 'd3-drag';
  export * from 'd3-dsv';
  export * from 'd3-ease';
  export * from 'd3-force';
  export * from 'd3-format';
  export * from 'd3-geo';
  export * from 'd3-hierarchy';
  export * from 'd3-interpolate';
  export * from 'd3-path';
  export * from 'd3-polygon';
  export * from 'd3-quadtree';
  export * from 'd3-queue';
  export * from 'd3-random';
  export * from 'd3-request';
  export * from 'd3-scale';
  export * from 'd3-selection';
  export * from 'd3-shape';
  export * from 'd3-time';
  export * from 'd3-time-format';
  export * from 'd3-timer';
  export * from 'd3-transition';
  export * from 'd3-voronoi';
  export * from 'd3-zoom';
}

Any errors I was getting (and seeing them only in development) went away when I included this code. Hope this helps you rule out typings errors and gets you closer to a solution!

1
  • Thank you Bruce. I have tried that before posting the question but I was still getting errors. I switched to d3 3.5.5, unfortunately the typings version is 3.3.6. I am still getting errors for example: let _data: any = d3.layout.pie().sort(null).value(function (d: any) { return d.value; })(data); if I do not declare d as any, the typescript transpiler throws out an error saying that "Property 'value' does not exist on type 'number'. ". To fix it I need to add a type of any to d. Typings are supposed to be optional but that is not the real case.
    – coderdark
    Commented Dec 5, 2016 at 1:13
0

Try this when appending the path:

newBlock.append("path")
    .attr("d", arc())
    .attr("id", function (d, i) {
        return "arc-" + i
    })
    .attr("stroke", "gray")
    .attr("fill", function (d, i) {
        return d3.interpolateCool(Math.random())
    });

According to the d3 API, after constructing an arc generator using let arc = d3.arc(), you have to call arc() in order to generate the actual arc.

2
  • I tried what you told me but now I get this error: [at-loader] src\piechart\piechart.component.ts:19:28 Supplied parameters do not match any signature of call target. I think the typings are bad.
    – coderdark
    Commented Dec 1, 2016 at 23:53
  • If you also include a startAngle and endAngle when constructing the arc generator (for example .startAngle(0).endAngle(Math.PI / 2)), you will still get that error when calling arc(), but at least it will return a string which you can pass to the path. Commented Dec 2, 2016 at 7:11
0

The following code draws one arc. You may supply more items to arcData:

import * as d3 from "d3";

export function run() {
  const chartLayer = d3.select('svg');

  let chartHeight = 500;
  let chartWidth = 500;
  let data = null;

  let arcData = [{
          innerRadius: 0,
          outerRadius: 100,
          startAngle: 0,
          endAngle: Math.PI / 2,
          padAngle: 1
       }];

  let arc = d3.arc();

  let pieG = chartLayer 
      .selectAll("g").data([data]).enter()
      .append("g")
      .attr("transform", "translate(" + [chartWidth / 2, chartHeight / 2] + ")");

  let block = pieG.selectAll(".arc")
      .data(arcData);

  let newBlock = block.enter().append("g").classed("arc", true);

  newBlock.append("path")
      .attr("d", function (d) { return arc(d) })
      .attr("id", function (d, i) {
          return "arc-" + i
      })
      .attr("stroke", "gray")
      .attr("fill", function (d, i) {
          return d3.interpolateCool(Math.random())
      });
}

Btw, my guess is that you do not need the line

.selectAll("g").data([data]).enter()

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.