D3-Sankey 错误:缺少:(节点名)

Posted

技术标签:

【中文标题】D3-Sankey 错误:缺少:(节点名)【英文标题】:D3-Sankey Error: Missing: (nodename) 【发布时间】:2018-02-24 16:49:18 【问题描述】:
import React,  Component  from 'react';

import  json  from 'd3-request';
import  rgb  from 'd3-color';
import  interpolateHcl  from 'd3-interpolate';
import  scaleLinear, scaleOrdinal  from 'd3-scale';
import  arc, line, pie, curveMonotoneX  from 'd3-shape';
import  format  from 'd3-format';
import  min, max  from 'd3-array';
import  select  from 'd3-selection';
import  sankey as sankeyGraph, sankeyLinkHorizontal  from 'd3-sankey';

class Graph extends React.Component 
    constructor(props) 
        super(props);

        this.createLineGraph = this.createLineGraph.bind(this);
        this.createBarChart = this.createBarChart.bind(this);
        this.createPieChart = this.createPieChart.bind(this);
        this.createSankeyGraph = this.createSankeyGraph.bind(this);
        // this.createRadialChart = this.createRadialChart.bind(this);

        this.createTheGraphs = this.createTheGraphs.bind(this);

        this.state = 
            loading: false
        ;
    

    getDimensions() 
        const margin = top: 20, right: 20, bottom: 20, left: 20,
            padding = top: 40, right: 40, bottom: 40, left: 40,
            outerWidth = parseInt(this.props.size[0]),
            outerHeight = parseInt(this.props.size[1]),
            innerWidth = outerWidth - margin.left - margin.right,
            innerHeight = outerHeight - margin.top - margin.bottom,
            width = innerWidth - padding.left - padding.right,
            height = innerHeight - padding.top - padding.botto,
            radius = parseInt(min([innerWidth, innerHeight]) / 2),
            donutHole = this.props.type === "DONUT" ? radius / 2 : 0,
            color = scaleLinear()
                .domain([1, this.props.data.length])
                .interpolate(interpolateHcl)
                .range([rgb("#AF2192"), rgb("#98D719")]);

        // DON'T DO DATA MAPPING ON SANKEY GRAPH SINCE DATA STRUCTURE IS DIFFERENT
        if (this.props.type !== "SANKEY") 

            // HIGHEST VALUE OF ITEMS IN DATA ARRAY
            const dataMax = max(this.props.data.map(item => item.value)),
                dataSpread = (innerWidth / this.props.data.length),
                // DEPEND SCALE OF ITEMS ON THE Y AXIS BASED ON HIGHEST VALUE
                yScale = scaleLinear()
                    .domain([0, dataMax])
                    .range([0, innerHeight]),
                // GENERATE THE LINE USING THE TOTAL SPACE AVAILABLE FROM THE SIZE PROP DIVIDED BY THE LENGTH OF THE DATA ARRAY
                lineGen = line()
                    .x((d, i) => i * dataSpread)
                    .y(d => innerHeight - yScale(d))
                    // CURVEMONOTONEX GAVE THE BEST RESULTS
                    .curve(curveMonotoneX);

            dimensions = margin, padding, outerWidth, outerHeight, innerWidth, innerHeight, radius, donutHole, color, dataMax, dataSpread, yScale, lineGen;

         else 

            dimensions = margin, padding, outerWidth, outerHeight, innerWidth, innerHeight, radius, donutHole, color;

        

    

    createSankeyGraph(data) 
        const sankeyNode = this.node;

        let graphData = this.props.data;

        // console.log(graphData);
        // console.log(graphData.links);
        // console.log(graphData.nodes);

        // console.log(dimensions.outerWidth, dimensions.outerHeight);

        // GET DIMENSIONS IN A GLOBAL-VAR-LIKE WAY
        this.getDimensions();

        const formatNumber = format('.1f');
        const formatted = function(d) return formatNumber(d) + " Potential Guests";
        const color = scaleLinear()
            .domain([1, 3])
            .interpolate(interpolateHcl)
            .range([rgb('#126382'), rgb('#417685')]);

        var sankey = sankeyGraph()
            .nodeWidth(15)
            .nodePadding(10)
            .extent([1, 1], [parseInt(dimensions.outerWidth) - 1, parseInt(dimensions.outerHeight) - 6]);

        var SVG = select(sankeyNode)
            .append('g')
            .attr('transform', 'translate(' + dimensions.margin.left + ',' + dimensions.margin.top +')');

        var link = SVG.append('g')
            .attr('class', 'links')
            .attr("fill", "none")
            .attr("stroke", "#000")
            .attr("stroke-opacity", 0.2)
            .selectAll('path')

        var node = SVG.append('g')
            .attr('class', 'nodes')
            .attr("font-family", "sans-serif")
            .attr("font-size", 10)
            .selectAll('g')

        // json('https://api.myjson.com/bins/15xgsd', function(error, graphData)

            sankey(graphData);

            // console.log(graphData.nodes, graphData.links);

            link = link
                .data(graphData.links)
                .enter()
                .append('path')
                .attr('d', sankeyLinkHorizontal())
                .attr('stroke-width', function(d)  return Math.max(1, d.width); );

            link.append('title')
                .text(function(d)  return d.source.name + " → " + d.target.name + "\n" + formatted(d.value); );

            node = node
                .data(graphData.nodes)
                .enter()
                .append('g')

            node.append('rect')
                .attr('x', function(d)  return d.x0; ) 
                .attr('y', function(d)  return d.y0; ) 
                .attr('height', function(d)  return d.y1 - d.y0) 
                .attr('width', function(d)  return d.x1 - d.x0) 
                .attr("fill", function(d, i)  return color(i); )
                .attr('stroke', 'black');

            node.append('text')
                .attr('x', function(d) return d.x0 - 6)
                .attr('y', function(d) return (d.y1 + d.y0) / 2)
                .attr('dy', '.35em')
                .attr('text-anchor', 'end')
                .text(function(d)  return d.name; )
                .filter(function(d)  return d.x0 < dimensions.innerWidth / 2; )
                .attr('x', function(d)  return d.x1 + 6; )
                .attr('text-anchor', 'start');

            node.append('title')
                .text(d => d.name + "\n" + formatted(d.value));

        // );

    

    createTheGraphs() 
        (this.props.type === "LINE") ? this.createLineGraph() : "";
        (this.props.type === "BAR") ? this.createBarChart() : "";
        (this.props.type === "PIE" || this.props.type === "DONUT") ? this.createPieChart() : "";
        (this.props.type === "SANKEY") ? this.createSankeyGraph() : "";
        (this.props.type === "RADIAL") ? this.createRadialChart() : "";
    

    componentWillMount() 
        this.setState( loading: true );
    

    componentDidMount() 
        this.createTheGraphs();
    

    componentDidUpdate() 
        this.createTheGraphs();
    

    render() 
        return(
            <div className="Graph">
                <svg className='Graph_Container' ref=node => this.node = node></svg>
                <h2>this.props.type Placeholder</h2>
            </div>
        );
    


Graph.propTypes = 

;

export default Graph;

发生了什么事?嗯,基本上控制台在输出

Error: missing: Peter  modules.js:54276:20
find http://localhost:3000/packages/modules.js:54276:20
computeNodeLinks/< http://localhost:3000/packages/modules.js:54353:62
forEach self-hosted:267:13
computeNodeLinks http://localhost:3000/packages/modules.js:54350:5
sankey http://localhost:3000/packages/modules.js:54292:5
createSankeyGraph http://localhost:3000/app/app.js:554:13
createSankeyGraph self-hosted:941:17
createTheGraphs http://localhost:3000/app/app.js:598:44
createTheGraphs self-hosted:941:17
componentDidMount http://localhost:3000/app/app.js:617:13
mountComponent/</< http://localhost:3000/packages/modules.js:17838:20
measureLifeCyclePerf http://localhost:3000/packages/modules.js:17649:12
mountComponent/< http://localhost:3000/packages/modules.js:17837:11
notifyAll http://localhost:3000/packages/modules.js:10464:9
close http://localhost:3000/packages/modules.js:20865:5
closeAll http://localhost:3000/packages/modules.js:11623:11
perform http://localhost:3000/packages/modules.js:11570:11
batchedMountComponentIntoNode http://localhost:3000/packages/modules.js:22897:3
perform http://localhost:3000/packages/modules.js:11557:13
batchedUpdates http://localhost:3000/packages/modules.js:20563:14
batchedUpdates http://localhost:3000/packages/modules.js:10225:10
_renderNewRootComponent http://localhost:3000/packages/modules.js:23090:5
_renderSubtreeIntoContainer http://localhost:3000/packages/modules.js:23172:21
render http://localhost:3000/packages/modules.js:23193:12
routes.js/< http://localhost:3000/app/app.js:1504:3
maybeReady http://localhost:3000/packages/meteor.js:821:6
loadingCompleted http://localhost:3000/packages/meteor.js:833:5

这会导致图表不渲染它需要作为线(路径)基础的节点。我得到的唯一 html 是:

<svg class="Graph_Container">
    <g transform="translate(20,20)">
        <g class="links" fill="none" stroke="#000" stroke-opacity="0.2"></g>
        <g class="nodes" font-family="sans-serif" font-size="10"></g>
    </g>
</svg>

“g.nodes”中没有节点,因此“g.links”中没有链接。该图应处理的数据结构如下所示:

<Graph type="SANKEY"
data=
    nodes: [
        name: "Peter",
        name: "Test.com",
        name: "Thing.com",
        name: "AnotherName"
    ], links: [
        source: "Peter", target: "Test.com", value: 50,
        source: "Peter", target: "Thing.com", value: 50,
        source: "Test.com", target: "AnotherName", value: 50,
        source: "Thing.com", target: "AnotherName", value: 50
    ]

size=[500, 500] />

我不知道从这里去哪里。有了这个包,我从一个问题跳到另一个问题,逐行更改代码。最初的问题看起来像this。

【问题讨论】:

【参考方案1】:

如果使用sourcetarget 名称(即字符串)而不是节点索引指定链接,则解决方案是指定nodeId 映射函数:

d3.sankey()
  .nodeId(d => d.name) // Needed to avoid "Error: Missing: myNode"

当然可能需要调整函数d =&gt; d.name以对应实际数据。

【讨论】:

以上是关于D3-Sankey 错误:缺少:(节点名)的主要内容,如果未能解决你的问题,请参考以下文章

HTTP 错误 500.19 - Internal Server Error 无法读取配置节 system.serviceModel 因为它缺少节声明

cdnbest自定义错误显示节点名教程

Android Smack XMPP 节侦听器:缺少节属性

CHEF 服务器--错误:网络错误:getaddrinfo:提供节点名或服务名,或未知

android中smack的消息节中缺少自定义属性

php artisan migrate 错误:提供或不知道节点名或服务名