codeepic codeepic - 5 months ago 131
Javascript Question

Compilation errors when drawing a piechart using D3.js, TypeScript and Angular

I am trying to display a pie chart and it's actually working, even though I get TypeScript compilation errors:

Argument of type '(d: any) => {}' is not assignable to parameter of type 'datum: Arc<number>, index: number, outerIndex: number) => number | string | boolean'. Type '{}' is not assignable to type 'number | string | boolean'. Type '{}' is not assignable to type 'boolean'.


I've been using TypeScript for the last 2 years, but the line above makes me dizzy. I have no idea what is going on, I tried few things but nothing worked so far.

This is the code that actually draws the pie chart:

function drawChart(){
var width = 960,
height = 500,
radius = Math.min(width, height) / 2;

var colourValues = d3.scale.ordinal().range(d3.values(that.ColoursService.colours));

var arc = d3.svg.arc()
.outerRadius(radius - 10)
.innerRadius(radius - 70);

var pie = d3.layout.pie()
.sort(null)
.value(function(d: any) {return d.quantity});

var svg = d3.select('.pie-chart').append('svg')
.attr('width', width)
.attr('height', height)
.append('g')
.attr('transform', 'translate(' + width / 2 + ',' + height/2 + ')');

var g = svg.selectAll('.arc')
.data(pie(data))
.enter().append('g')
.attr('class', 'arc');

g.append('path')
.attr('d', <any>arc)
.attr('fill', function(d: any) {
return colourValues(d.data.category);
});
}


This is where the typescript highlights the error, the squiggly line appears below "function" word. I need to make the TypeScript compilator pass, but I don't know how.

Answer

Alright I figured out what is happening, although I don't fully understand how D3 works with TypeScript. There are essentially two solutions:

First one, where I set specific interface on datum parameter and return values (either string, number or boolean) and then typecast the return value to string - it is too wordy.

g.append('path')
    .attr('d', <any>arc)
    .attr('fill', function (datum: d3.layout.pie.Arc<any>): number | string | boolean {
        return <string>colourValues(datum.data.category); 
  });

Second solution is easier on the eye. I only added :any as a return type from the function.

g.append('path')
    .attr('d', <any>arc)
    .attr('fill', function (d: any): any {
        return colourValues(d.data.category); 
    });

I still don't fully understand how to interface my data models I interact with in D3 - every time I try to use the interface that is already implemented in successful promise resolution via angular.IPromise<interfaceNameOfTheReturnData> in D3 functions wrapped inside angular directive's link function, I encounter TypeScript compilation errors and have to use any type.

Comments