类型 'SVGPathSeg' 不能分配给类型"输入元素"。类型 'SVGPathSeg' 中缺少属性'ownerDocument'



我正在尝试使用Angular 5上的D3-NG2服务服务来重现此示例。

组件:

ngoninit代码:

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
}

这起作用,我得到了相当不错的结果:角组件输出

,但我一直通过Angular讲出错误输出:

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提示

指代码的这一部分:

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

我正在努力寻找解决方案,真的不知道是框架问题还是我的某个地方的错误。

tomwanzek在此问题上建议,我尝试用SVGPathElement替换SVGPathSeg,但这会触发一个错误,下面是.attr("d",radial)的两行:

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

我之前使用的是SVGPathSeg,因为它接受了.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>'.

我错过了其他地方的某种类型?

,为了确保代码中的不同部分可以很好地播放,需要利用发电机(分层,树(和链接路径生成器上提供的一些通用物。

为了易于参考,假设您定义:

interface Datum {
  id: string;
}

您的data是类型Datum[]

然后,以下更改将确保使用兼容类型,以防止上述错误。

// ...    
const stratify = d3.stratify<Datum>()
// ...
const tree = d3.tree<Datum>()
// ...
const radial = d3.linkRadial<HierarchyPointLink<Datum>, HierarchyPointNode<Datum>>()

请注意,HierarchyPointLink<Datum>HierarchyPointNode<Datum>是树布局生成器创建的链接和节点类型,在类型Datum的基础数据上使用。

当然,绑定的dom元素类型为 SVGPathElement,即

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

最新更新