首页 > 解决方案 > 使用本地 JSON 文件运行 d3.js

问题描述

我正在尝试使用本地 JSON 文件运行附加代码。到目前为止,数据在 HTML 中并且按预期工作。我尝试了 stackoverflow 的几种解决方案。我最近的尝试是加载但没有任何数据或 d3 代码的可视代码扩展“实时服务器”。此外,我的 Firefox 设置允许外部文件导入以及 chrome。还是行不通。:/

显然我做错了。如果有人可以指导我,我将不胜感激。

{
  "nodes": [
      { "id": 0, "active": true, "state": "on" },
      { "id": 1, "active": true, "state": "on" },
      { "id": 2, "active": true, "state": "on" },
      { "id": 3, "active": true, "state": "on" },
      { "id": 4, "active": true, "state": "on" },
      { "id": 5, "active": true, "state": "on" },
      { "id": 6, "active": true, "state": "on" },
      { "id": 7, "active": true, "state": "on" },
      { "id": 8, "active": true, "state": "on" }
  ],
  "links": [
      { "source": 0, "target": 1},
      { "source": 0, "target": 2},
      { "source": 0, "target": 3},
      { "source": 1, "target": 7},
      { "source": 1, "target": 6},
      { "source": 1, "target": 8},
      { "source": 2, "target": 4},
      { "source": 2, "target": 5}
  ]
}
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <title>stackoverflow demo</title>
    <script src="https://d3js.org/d3.v6.min.js"></script>
</head>

<style>
    body {
        background-color: #e6e7ee;
    }

    circle {
        stroke: black;
        stroke-width: 1px;
        cursor: pointer;
    }
</style>

<body>
    <script>

        /*
      var graph = {
          "nodes": [
              { "id": 0, "active": true, "state": "on" },
              { "id": 1, "active": true, "state": "on" },
              { "id": 2, "active": true, "state": "on" },
              { "id": 3, "active": true, "state": "on" },
              { "id": 4, "active": true, "state": "on" },
              { "id": 5, "active": true, "state": "on" },
              { "id": 6, "active": true, "state": "on" },
              { "id": 7, "active": true, "state": "on" },
              { "id": 8, "active": true, "state": "on" },
          ],
          "links": [
              { "source": 0, "target": 1},
              { "source": 0, "target": 2},
              { "source": 0, "target": 3},
              { "source": 1, "target": 7},
              { "source": 1, "target": 6},
              { "source": 1, "target": 8},
              { "source": 2, "target": 4},
              { "source": 2, "target": 5},
          ]
      }
      */

        d3.json("data.json", function (error, graph) {
            if (error) throw error


            var svg = d3.select("body").append("svg")
                .attr("width", window.innerWidth)
                .attr("height", window.innerHeight)
                .attr("class", "svg")
                .call(d3.zoom().on("zoom", function (event) {
                    svg.attr("transform", event.transform)
                }))
                .append("g")

            d3.select("svg").on("dblclick.zoom", null)


            // append markers to svg
            svg.append("defs").append("marker")
                .attr("id", "arrowhead")
                .attr("viewBox", "-0 -5 10 10")
                .attr("refX", 6)
                .attr("refY", 0)
                .attr("orient", "auto")
                .attr("markerWidth", 100)
                .attr("markerHeight", 100)
                .attr("xoverflow", "visible")
                .append("svg:path")
                .attr("d", "M 0,-1 L 2 ,0 L 0,1")
                .attr("fill", "red")
                .style("stroke", "none")

            var linkContainer = svg.append("g").attr("class", "linkContainer")
            var nodeContainer = svg.append("g").attr("class", "nodeContainer")




            var forceLayout = d3.forceSimulation()
                .force("link", d3.forceLink().id(function (d) {
                    return d.id;
                }).distance(125))
                .force("charge", d3.forceManyBody().strength(-1250))
                .force("center", d3.forceCenter(window.innerWidth / 2, window.innerHeight / 2))
                .force("collision", d3.forceCollide().radius(50))


            //###############################################
            //################## initialize #################
            //###############################################

            function init() {

                links = linkContainer.selectAll(".link")
                    .data(graph.links)
                    .join("line")
                    .attr("class", "link")
                    .attr('marker-end', 'url(#arrowhead)')
                    .style("stroke", "black")

                nodes = nodeContainer.selectAll(".node")
                    .data(graph.nodes, function (d) { return d.id; })
                    .join("g")
                    .attr("class", "node")
                    .attr("id", function (d) { return "node" + d.id; })
                    .call(d3.drag()
                        .on("start", dragStarted)
                        .on("drag", dragged)
                        .on("end", dragEnded)
                    )

                nodes.selectAll("circle")
                    .data(d => [d])
                    .join("circle")
                    .attr("r", 40)
                    .style("fill", setColor)
                    .on("click", switchState)


                nodes.selectAll("text")
                    .data(d => [d])
                    .join("text")
                    .attr("dominant-baseline", "central")
                    .attr("text-anchor", "middle")
                    .attr("id", function (d) { return "text" + d.id })
                    .attr("pointer-events", "none")
                    .text(function (d) {
                        return d.id + " - " + d.state
                    })


                forceLayout
                    .nodes(graph.nodes)
                    .on("tick", outerTick)

                forceLayout
                    .force("link")
                    .links(graph.links)
            }

            //###############################################
            //##### set color in relation of the state ######
            //###############################################

            function setColor(d) {
                switch (d.state) {
                    case "on":
                        return "greenyellow"
                    case "limited":
                        return "yellow"
                    case "error":
                        return "red"
                    case "off":
                        return "grey"
                    default:
                        return "greenyellow"
                }
            }


            //###############################################
            //######## switch state - turn off & on #########
            //###############################################

            function switchState(event, d) {
                if (d.active == true) {
                    d.active = false
                    d.state = "off"
                } else if (d.active == false) {
                    d.active = true
                    d.state = "on"
                }
            }


            function outerTick() {
                links
                    .attr("x1", function (d) {
                        return d.source.x;
                    })
                    .attr("y1", function (d) {
                        return d.source.y;
                    })
                    .attr("x2", function (d) {
                        return d.target.x;
                    })
                    .attr("y2", function (d) {
                        return d.target.y;
                    });

                nodes.attr("transform", function (d) {
                    return "translate(" + d.x + "," + d.y + ")";
                });
            }


            function dragStarted(event, d) {
                if (!event.active) forceLayout.alphaTarget(0.3).restart();

                d.fx = d.x;
                d.fy = d.y;
            }

            function dragged(event, d) {
                d.fx = event.x;
                d.fy = event.y;
            }

            function dragEnded(event, d) {
                if (!event.active) forceLayout.alphaTarget(0);

                d.fx = undefined;
                d.fy = undefined;
            }
        })
    </script>
</body>

</html>

标签: javascriptjsond3.js

解决方案


在 D3 V6 中,该d3.json函数应用作 Promise:

d3.json(url).then(onLoad).catch(err => console.log(err));

请参阅下面的片段:

const url = "https://api.jsonbin.io/b/60a62c6265d5d77ffc89cdca";

const onLoad = graph => {
        console.log('G: ', graph);

            var svg = d3.select("svg")
                .call(d3.zoom().on("zoom", function (event) {
                    svg.attr("transform", event.transform)
                }))
                .append("g")

            d3.select("svg").on("dblclick.zoom", null)


            // append markers to svg
            svg.append("defs").append("marker")
                .attr("id", "arrowhead")
                .attr("viewBox", "-0 -5 10 10")
                .attr("refX", 6)
                .attr("refY", 0)
                .attr("orient", "auto")
                .attr("markerWidth", 100)
                .attr("markerHeight", 100)
                .attr("xoverflow", "visible")
                .append("svg:path")
                .attr("d", "M 0,-1 L 2 ,0 L 0,1")
                .attr("fill", "red")
                .style("stroke", "none")

            var linkContainer = svg.append("g").attr("class", "linkContainer")
            var nodeContainer = svg.append("g").attr("class", "nodeContainer")




            var forceLayout = d3.forceSimulation()
                .force("link", d3.forceLink().id(function (d) {
                    return d.id;
                }).distance(125))
                .force("charge", d3.forceManyBody().strength(-1250))
                .force("center", d3.forceCenter(window.innerWidth / 2, window.innerHeight / 2))
                .force("collision", d3.forceCollide().radius(50))

  init();

            //###############################################
            //################## initialize #################
            //###############################################

            function init() {

                links = linkContainer.selectAll(".link")
                    .data(graph.links)
                    .join("line")
                    .attr("class", "link")
                    .attr('marker-end', 'url(#arrowhead)')
                    .style("stroke", "black")

                nodes = nodeContainer.selectAll(".node")
                    .data(graph.nodes, function (d) { return d.id; })
                    .join("g")
                    .attr("class", "node")
                    .attr("id", function (d) { return "node" + d.id; })
                    .call(d3.drag()
                        .on("start", dragStarted)
                        .on("drag", dragged)
                        .on("end", dragEnded)
                    )

                nodes.selectAll("circle")
                    .data(d => [d])
                    .join("circle")
                    .attr("r", 40)
                    .style("fill", setColor)
                    .on("click", switchState)


                nodes.selectAll("text")
                    .data(d => [d])
                    .join("text")
                    .attr("dominant-baseline", "central")
                    .attr("text-anchor", "middle")
                    .attr("id", function (d) { return "text" + d.id })
                    .attr("pointer-events", "none")
                    .text(function (d) {
                        return d.id + " - " + d.state
                    })


                forceLayout
                    .nodes(graph.nodes)
                    .on("tick", outerTick)

                forceLayout
                    .force("link")
                    .links(graph.links)
            }

            //###############################################
            //##### set color in relation of the state ######
            //###############################################

            function setColor(d) {
                switch (d.state) {
                    case "on":
                        return "greenyellow"
                    case "limited":
                        return "yellow"
                    case "error":
                        return "red"
                    case "off":
                        return "grey"
                    default:
                        return "greenyellow"
                }
            }


            //###############################################
            //######## switch state - turn off & on #########
            //###############################################

            function switchState(event, d) {
                if (d.active == true) {
                    d.active = false
                    d.state = "off"
                } else if (d.active == false) {
                    d.active = true
                    d.state = "on"
                }
            }


            function outerTick() {
                links
                    .attr("x1", function (d) {
                        return d.source.x;
                    })
                    .attr("y1", function (d) {
                        return d.source.y;
                    })
                    .attr("x2", function (d) {
                        return d.target.x;
                    })
                    .attr("y2", function (d) {
                        return d.target.y;
                    });

                nodes.attr("transform", function (d) {
                    return "translate(" + d.x + "," + d.y + ")";
                });
            }


            function dragStarted(event, d) {
                if (!event.active) forceLayout.alphaTarget(0.3).restart();

                d.fx = d.x;
                d.fy = d.y;
            }

            function dragged(event, d) {
                d.fx = event.x;
                d.fy = event.y;
            }

            function dragEnded(event, d) {
                if (!event.active) forceLayout.alphaTarget(0);

                d.fx = undefined;
                d.fy = undefined;
            }
        };

d3.json(url).then(onLoad).catch(err => console.log(err));
    body {
        background-color: #e6e7ee;
    }

    circle {
        stroke: black;
        stroke-width: 1px;
        cursor: pointer;
    }
<script src="https://d3js.org/d3.v6.min.js"></script>

<svg width="1000" height="1000" />


推荐阅读