tomwanzek / d3-ng2-service

A D3 service for use with Angular.
MIT License
205 stars 42 forks source link

Type 'SVGPathSeg' is not assignable to type 'EnterElement'. Property 'ownerDocument' is missing in type 'SVGPathSeg'. #114

Closed stockmind closed 6 years ago

stockmind commented 6 years ago

Hi!

I'm trying to reproduce this example using your d3 service. ngOnInit code:

let d3 = this.d3;
let d3ParentElement: Selection<HTMLElement, any, null, undefined>;
let d3Svg: Selection<SVGSVGElement, any, null, undefined>;
let d3G: Selection<SVGGElement, any, null, undefined>;
let width: number;
let height: number;

if (this.parentNativeElement !== null) {

    d3ParentElement = d3.select(this.parentNativeElement);
    d3Svg = this.d3Svg = d3ParentElement.select<SVGSVGElement>('svg');

    width = +d3Svg.attr('width');
    height = +d3Svg.attr('height');

    d3G = d3Svg.append<SVGGElement>("g")
        .attr("transform", "translate(" + (width / 2 + 40) + "," + (height / 2 + 90) + ")");

    let stratify = d3.stratify()
        .parentId(function (d) {
            return d["id"].substring(0, d["id"].lastIndexOf("."));
        });

    let tree = d3.tree()
        .size([2 * Math.PI, 500])
        .separation(function (a, b) {
            return (a["parent"] == b["parent"] ? 1 : 2) / a["depth"];
        });

    //let data = this.gruppi;
    let data = [
        {id: "flare"},
        {id: "flare.analytics"},
        {id: "flare.analytics.cluster"},
        {id: "flare.analytics.cluster.AgglomerativeCluster"},
        {id: "flare.analytics.cluster.CommunityStructure"},
        {id: "flare.analytics.cluster.HierarchicalCluster"},
        {id: "flare.analytics.cluster.MergeEdge"},
        {id: "flare.analytics.graph"},
        {id: "flare.analytics.graph.BetweennessCentrality"},
        {id: "flare.analytics.graph.LinkDistance"},
        {id: "flare.analytics.graph.MaxFlowMinCut"},
        {id: "flare.analytics.graph.ShortestPaths"},
        {id: "flare.analytics.graph.SpanningTree"},
        {id: "flare.analytics.optimization"},
        {id: "flare.analytics.optimization.AspectRatioBanker"},
        {id: "flare.animate"},
        {id: "flare.animate.Easing"},
        {id: "flare.animate.FunctionSequence"},
        {id: "flare.animate.interpolate"},
        {id: "flare.animate.interpolate.ArrayInterpolator"},
        {id: "flare.animate.interpolate.ColorInterpolator"},
        {id: "flare.animate.interpolate.DateInterpolator"},
        {id: "flare.animate.interpolate.Interpolator"},
        {id: "flare.animate.interpolate.MatrixInterpolator"},
        {id: "flare.animate.interpolate.NumberInterpolator"},
        {id: "flare.animate.interpolate.ObjectInterpolator"},
        {id: "flare.animate.interpolate.PointInterpolator"},
        {id: "flare.animate.interpolate.RectangleInterpolator"},
        {id: "flare.animate.ISchedulable"},
        {id: "flare.animate.Parallel"},
        {id: "flare.animate.Pause"},
        {id: "flare.animate.Scheduler"},
        {id: "flare.animate.Sequence"},
        {id: "flare.animate.Transition"},
        {id: "flare.animate.Transitioner"},
        {id: "flare.animate.TransitionEvent"},
        {id: "flare.animate.Tween"},
        {id: "flare.data"},
        {id: "flare.data.converters"},
        {id: "flare.data.converters.Converters"},
        {id: "flare.data.converters.DelimitedTextConverter"},
        {id: "flare.data.converters.GraphMLConverter"},
        {id: "flare.data.converters.IDataConverter"},
        {id: "flare.data.converters.JSONConverter"},
        {id: "flare.data.DataField"},
        {id: "flare.data.DataSchema"},
        {id: "flare.data.DataSet"},
        {id: "flare.data.DataSource"},
        {id: "flare.data.DataTable"},
        {id: "flare.data.DataUtil"},
        {id: "flare.display"},
        {id: "flare.display.DirtySprite"},
        {id: "flare.display.LineSprite"},
        {id: "flare.display.RectSprite"},
        {id: "flare.display.TextSprite"},
        {id: "flare.flex"},
        {id: "flare.flex.FlareVis"},
        {id: "flare.physics"},
        {id: "flare.physics.DragForce"},
        {id: "flare.physics.GravityForce"},
        {id: "flare.physics.IForce"},
        {id: "flare.physics.NBodyForce"},
        {id: "flare.physics.Particle"},
        {id: "flare.physics.Simulation"},
        {id: "flare.physics.Spring"},
        {id: "flare.physics.SpringForce"},
        {id: "flare.query"},
        {id: "flare.query.AggregateExpression"},
        {id: "flare.query.And"},
        {id: "flare.query.Arithmetic"},
        {id: "flare.query.Average"},
        {id: "flare.query.BinaryExpression"},
        {id: "flare.query.Comparison"},
        {id: "flare.query.CompositeExpression"},
        {id: "flare.query.Count"},
        {id: "flare.query.DateUtil"},
        {id: "flare.query.Distinct"},
        {id: "flare.query.Expression"},
        {id: "flare.query.ExpressionIterator"},
        {id: "flare.query.Fn"},
        {id: "flare.query.If"},
        {id: "flare.query.IsA"}
    ];

    let root = tree(stratify(data));

    let radial = d3.linkRadial()
        .angle(function(d){ return d["x"];})
        .radius(function(d){ return d["y"];});

    let link = d3G.selectAll<SVGElement, any>(".link")
        .data(root.links())
        .enter()
        .append<SVGPathSeg>("path")
        .attr("class", "link")
        .attr("d",radial);

    let radialPoint = function(x, y) {
        return [(y = +y) * Math.cos(x -= Math.PI / 2), y * Math.sin(x)];
    };

    let node = d3G.selectAll<SVGElement, any>(".node")
        .data(root.descendants())
        .enter()
        .append<SVGGElement>("g")
        .attr("class", function (d) {
            return "node" + (d["children"] ? " node--internal" : " node--leaf");
        })
        .attr("transform", function (d) {
            return "translate(" + radialPoint(d["x"], d["y"]) + ")";
        });

    node.append<SVGCircleElement>("circle")
        .attr("r", 2.5);

    node.append<SVGTextElement>("text")
        .attr("dy", "0.31em")
        .attr("x", function (d) {
            return d["x"] < Math.PI === !d["children"] ? 6 : -6;
        })
        .attr("text-anchor", function (d) {
            return d["x"] < Math.PI === !d["children"] ? "start" : "end";
        })
        .attr("transform", function (d) {
            return "rotate(" + (d["x"] < Math.PI ? d["x"] - Math.PI / 2 : d["x"] + Math.PI / 2) * 180 / Math.PI + ")";
        })
        .text(function (d) {
            return d["id"].substring(d["id"].lastIndexOf(".") + 1);
        });
    // Do more D3 things
}

This works and i get a pretty decent result: Angular component output

But i keep getting an error output by angular telling:

ERROR in src/app/grafo/grafo.component.ts(262,25): error TS2344: Type 'SVGPathSeg' does not satisfy the constraint 'BaseType'.
  Type 'SVGPathSeg' is not assignable to type 'EnterElement'.
    Property 'ownerDocument' is missing in type 'SVGPathSeg'.

PhpStorm hint

That refer to this part of code:

let link = d3G.selectAll<SVGElement, any>(".link")
                .data(root.links())
                .enter()
                .append<SVGPathSeg>("path")
                .attr("class", "link")
                .attr("d",radial);

I'm struggling to find a fix for that and really don't know if is a framework issue or an error of mine somewhere.

Can you help me?

tomwanzek commented 6 years ago

@stockmind This should be readily addressable by using append<SVGPathElement>("path"), and you're ready to roll...:smile:

stockmind commented 6 years ago

Sorry, didn't mention that, but if use SVGPathElement i get this from .attr("d", radial);:

let link = d3G.selectAll<SVGElement, any>(".link")
                .data(root.links())
                .enter()
                .append<SVGPathSeg>("path")
                .attr("class", "link")
                .attr("d",radial);

Two lines below. I was using SVGPathSeg because it accepted the .attr("d", radial).

https://ibb.co/g5CN0S

TS2345: Argument of type 'LinkRadial<any, DefaultLinkObject, [number,number]>' is not assignable to parameter of type 'ValueFn<SVGPathElement, HierarchyPointLink<{}>, string | number | boolean>'.

I've missed some type somewhere else?

tomwanzek commented 6 years ago

@stockmind As this is not a bug with the service, could you kindly open it up on StackOverflow and then cross-reference it here. I will answer on SO for future reference not just by yourself, but others. Thanks in advance.

stockmind commented 6 years ago

@tomwanzek Thanks, i've opened a question on StackOverflow: https://stackoverflow.com/questions/49581045/type-svgpathseg-is-not-assignable-to-type-enterelement-property-ownerdocum

tomwanzek commented 6 years ago

Answered on SO.