D3在节点上单击,在svg窗口

时间:2018-01-24 15:45:49

标签: javascript html d3.js

我想知道点击节点时是否有可能在svg窗口旁边出现一个表/图像,如下所示:

enter image description here

我是d3的新手,但我尝试在svg周围放置一个div容器并将表添加到此,但这似乎没有用。如果有人知道这样做的方法,我会非常感激。

<!DOCTYPE html>
<meta charset="UTF-8">
<style>
    svg {
        border:1px solid dimgrey;
        background-color: White;
    }
    body {
        background-color: #F9FBFF;

<body>
<script src="https://d3js.org/d3.v4.min.js"></script>
<script>

    // Properties
    var width = 800;
    var height = 800;
    var nominal_stroke = 4;
    var base_node_size = 800;

    // Colour Scheme
    var colour = d3.scaleLinear().domain([1,7]).range(["#4b0868", "#f0f0f0"]);

    // Simulation
    var simulation = d3.forceSimulation()
        .force("link", d3.forceLink().id(function(d) { return d.id; }))
        .force("charge", d3.forceManyBody().strength(-400))
        .force("center", d3.forceCenter(width / 2, height / 2))
        .force('forceX', d3.forceX(0))
        .force('forceY', d3.forceY(0));

    // Create SVG window
    var svg = d3.select("body").append("svg")
        .attr("width", width)
        .attr("height", height);

    var g = svg.append("g");
    svg.style("cursor", "move");


    // Load JSON data
    d3.json("./network.json", function(error, graph) {
        console.log(graph);
        if (error) throw error;

        // Draw links
        var link = g.selectAll(".link")
            .data(graph.links)
            .enter().append("line")
            .attr("class", "link")
            .style("stroke-width", nominal_stroke)
            .style("stroke", "#999")
            .style("stroke-opacity", 0.6);

        // Draw nodes
        var node = g.selectAll(".node")
            .data(graph.nodes)
            .enter().append("g")
            .attr("class", "node")
            .call(d3.drag()
                .on("start", dragstarted)
                .on("drag", dragged)
                .on("end", dragended))
            .on("click.node", connectedNodes)
            .on("dblclick.rect",openLink())
            .on("mouseover.node", onMouseover)
            .on("mouseout.node", onMouseout);


        // Setup node properties
        var circle = node.append("path")
            .attr("d", d3.symbol()
            .type(function (d) {
                if
                (d.shape === "rect") {
                    return d3.symbolSquare;
                } else if
                (d.shape === "circle") {
                    return d3.symbolCircle;
                }
            })
                .size(circleSize))
        .style("stroke", "#998")
        .style("stroke-opacity", 0.6)
        .style("stroke-width", 1)
        .style("fill", circleColour);


    // Add titles
        node.append("title")
            .text(function (d) {return d.name});

        // Start Simulation
        simulation
            .nodes(graph.nodes)
            .on("tick", ticked);

        simulation.force("link")
            .links(graph.links);

        // Refresh page
        function ticked() {
            link
                .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; });
            node
                .attr("transform", function(d) {
                return "translate(" + d.x + "," + d.y + ")";
            });
        }

        // Zoom handler
        svg.call(d3.zoom()
            .scaleExtent([1 / 2, 8])
            .on("zoom", zoomed))
            .on("dblclick.zoom", null);

        function zoomed() {
            g.attr("transform", d3.event.transform);
        }

        //Toggle stores whether the highlighting is on
        var toggle = 0;

        //Create an array logging what is connected to what
        var linkedByIndex = {};
        for (i = 0; i < graph.nodes.length; i++) {
            linkedByIndex[i + "," + i] = 1;
        };
        graph.links.forEach(function (d) {
            linkedByIndex[d.source.index + "," + d.target.index] = 1;
        });

         //This function looks up whether a pair are neighbours
        function neighboring(a, b) {
            return linkedByIndex[a.index + "," + b.index];
        }

        function connectedNodes() {

            if (toggle === 0) {
                //Reduce the opacity of all but the neighbouring nodes
                d = d3.select(this).node().__data__;
                node.style("opacity", function (o) {
                    return neighboring(d, o) | neighboring(o, d) ? 1 : 0.1;
                });

                link.style("opacity", function (o) {
                    return d.index===o.source.index | d.index===o.target.index ? 1 : 0.1;
                });

                //Reduce the op

                toggle = 1;
            } else {
                //Put them back to opacity=1
                node.style("opacity", 1);
                link.style("opacity", 1);
                toggle = 0;
            }
        }

    });

    // Functions

    function dragstarted(d) {
        if (!d3.event.active) simulation.alphaTarget(0.3).restart();
        d.fx = d.x;
        d.fy = d.y;
    }

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

    function dragended(d) {
        if (!d3.event.active) simulation.alphaTarget(0);
        d.fx = d.x;
        d.fy = d.y;
    }

    function openLink() {
        return function (d) {
            var url = "";
            if (d.url !== "") {
                url = d.url;
                window.open(url)
            }
        }
    }

    function circleColour(d) {
        if(d.colour === 0) {
            return "#6ac6ee";
        }

        if(d.colour > 0 && d.colour <10) {
            return colour(d.colour);
        }

        else {
            return "green";
        }

    }

    function circleSize(d) {
        if (d.group === 0) {
            return base_node_size;
        }
        if (d.group >= 2) {
            return (d.group)*100;
        }
        if (d.group === 1) {
            return (d.size)*50;
        }
        else {
            return base_node_size;
        }
    }

    function onMouseover(d){
        //Mouse event
        d3.select(this)
            .transition()
            .duration(500)
            .style("cursor", "pointer");
    }

    function onMouseout(d){
        d3.select(this)
            .transition()
            .duration(500)
            .style("cursor", "normal")
            .attr("width", 40);
    }

</script>
</body>

1 个答案:

答案 0 :(得分:0)

我已经想出了如何做到这一点。如果有人有兴趣,我会添加一个示例代码。

我使用了这些例子的组合: