Home > OS >  D3.js edge bundle chart will not display inside a CSS grid position
D3.js edge bundle chart will not display inside a CSS grid position

Time:06-07

I'm using css-grid to create a 4 row (1 column) grid layout. I have items inside the first 3 rows and this works fine. Those items are a leaflet map, a table, and a D3 plot. My fourth item (a D3 edge bundle chart) will not display inside the 4th row, it seems to display underneath it (outside of the overall grid container).

Here is a scaled down version of my code:

css..

.grid-container {
        display: grid;
        grid-template-columns: 1fr;
        background-color: #ffffff;
        padding: 10px;
        grid-template-rows: auto auto auto auto;
        grid-row-gap: 10px;
        }
.grid-item1 {
        background-color: rgba(255, 255, 255, 0.8);
        border: 1px solid rgba(160, 160, 160, 0.8);
        padding: 15px;
        font-size: 13px;
        text-align: left;
        grid-row-gap: 10px;
        }
.grid-item2 {
        background-color: rgba(255, 255, 255, 0.8);
        border: 1px solid rgba(160, 160, 160, 0.8);
        padding: 15px;
        font-size: 13px;
        text-align: left;
        grid-row-gap: 10px;
        }
.grid-item3 {
        background-color: rgba(255, 255, 255, 0.8);
        border: 1px solid rgba(160, 160, 160, 0.8);
        padding: 15px;
        font-size: 13px;
        text-align: left;
        grid-row-gap: 10px;
        }
.grid-item4 {
        background-color: rgba(255, 255, 255, 0.8);
        border: 1px solid rgba(210, 3, 3, 0.8);
        padding: 15px;
        font-size: 13px;
        text-align: left;
        grid-row-gap: 10px;
        }

HTML/JS..

<body>
    <div ></div>

        <div  id="map"></div>

        <div >
            <script>
            DATATABLE CODE HERE
            </script>
        </div>
        <div  id="my_plot">
            <script>
                D3 PLOT CODE HERE
             </script>
        </div>
        <div  id="edgeB">
            test
            <script>
                var diameter = 760,
                radius = diameter / 2;
                innerRadius = radius - 160;
            
                var cluster = d3.cluster()
                    .size([360, innerRadius]);
                
                var line = d3.radialLine()
                    .curve(d3.curveBundle.beta(0.85))
                    .radius(function(d) { return d.y; })
                    .angle(function(d) { return d.x / 180 * Math.PI; });
                
                var svg = d3.select("body").append("svg")
                    .attr("width", diameter)
                    .attr("height", diameter)
                .append("g")
                    .attr("transform", "translate("   radius   ","   radius   ")");
                
                var link = svg.append("g").selectAll(".link"),
                    node = svg.append("g").selectAll(".node");
                
                d3.json("flare.json", function(error, classes) {
                if (error) throw error;
                
                var root = packageHierarchy(classes)
                    .sum(function(d) { return d.size; });
                
                cluster(root);
                
                link = link
                    .data(packageImports(root.leaves()))
                    .enter().append("path")
                    .each(function(d) { d.source = d[0], d.target = d[d.length - 1]; })
                    .attr("class", "link")
                    .attr("d", line);
                
                node = node
                    .data(root.leaves())
                    .enter().append("text")
                    .attr("class", "node")
                    .attr("dy", "0.31em")
                    .attr("transform", function(d) { return "rotate("   (d.x - 90)   ")translate("   (d.y   8)   ",0)"   (d.x < 180 ? "" : "rotate(180)"); })
                    .attr("text-anchor", function(d) { return d.x < 180 ? "start" : "end"; })
                    .text(function(d) { return d.data.key; })
                    .on("mouseover", mouseovered)
                    .on("mouseout", mouseouted);
                });
                
                function mouseovered(d) {
                node
                    .each(function(n) { n.target = n.source = false; });
                
                link
                    .classed("link--target", function(l) { if (l.target === d) return l.source.source = true; })
                    .classed("link--source", function(l) { if (l.source === d) return l.target.target = true; })
                    .filter(function(l) { return l.target === d || l.source === d; })
                    .raise();
                
                node
                    .classed("node--target", function(n) { return n.target; })
                    .classed("node--source", function(n) { return n.source; });
                }
                
                function mouseouted(d) {
                link
                    .classed("link--target", false)
                    .classed("link--source", false);
                
                node
                    .classed("node--target", false)
                    .classed("node--source", false);
                }
                
                // Lazily construct the package hierarchy from class names.
                function packageHierarchy(classes) {
                var map = {};
                
                function find(name, data) {
                    var node = map[name], i;
                    if (!node) {
                    node = map[name] = data || {name: name, children: []};
                    if (name.length) {
                        node.parent = find(name.substring(0, i = name.lastIndexOf(".")));
                        node.parent.children.push(node);
                        node.key = name.substring(i   1);
                    }
                    }
                    return node;
                }
                
                classes.forEach(function(d) {
                    find(d.name, d);
                });
                
                return d3.hierarchy(map[""]);
                }
                
                // Return a list of imports for the given array of nodes.
                function packageImports(nodes) {
                var map = {},
                    imports = [];
                
                // Compute a map from name to node.
                nodes.forEach(function(d) {
                    map[d.data.name] = d;
                });
                
                // For each import, construct a link from the source to target node.
                nodes.forEach(function(d) {
                    if (d.data.imports) d.data.imports.forEach(function(i) {
                    imports.push(map[d.data.name].path(map[i]));
                    });
                });
                
                return imports;
                }  
            </script>     
        </div>
</body>
</html>

The part I can't understand is that the "test" text I have in grid-item4 does correctly appear in the grid-item4 area, it's specifically my D3.js chart that will not display there, it displays underneath. The only thing I can think of try is to play around with various div opening and closing tags but that did not make any difference.

Thanks

CodePudding user response:

Though I was not able to run your code I found the issue. d3.js requires you to append the svg element to another dom element. You selected the body element to append the svg element to.

var svg = d3.select("body").append("svg")

If you want the chart to be appended to the correct grid cell use the id selector for that specific cell instead of body.

 var svg = d3.select("#edgeB").append("svg")

CodePudding user response:

please replace the d3.select("body") with d3.select("#edgeB")

so the chart will appear with in the container. I attached a demo below. I hope it will solve your problem.

.grid-container {
    display: grid;
    grid-template-columns: 1fr;
    background-color: #ffffff;
    padding: 10px;
    grid-template-rows: auto auto auto auto;
    grid-row-gap: 10px;
}

.grid-item1 {
    background-color: rgba(255, 255, 255, 0.8);
    border: 1px solid rgba(160, 160, 160, 0.8);
    padding: 15px;
    font-size: 13px;
    text-align: left;
    grid-row-gap: 10px;
}

.grid-item2 {
    background-color: rgba(255, 255, 255, 0.8);
    border: 1px solid rgba(160, 160, 160, 0.8);
    padding: 15px;
    font-size: 13px;
    text-align: left;
    grid-row-gap: 10px;
}

.grid-item3 {
    background-color: rgba(255, 255, 255, 0.8);
    border: 1px solid rgba(160, 160, 160, 0.8);
    padding: 15px;
    font-size: 13px;
    text-align: left;
    grid-row-gap: 10px;
}

.grid-item4 {
    background-color: rgba(255, 255, 255, 0.8);
    border: 1px solid rgba(210, 3, 3, 0.8);
    padding: 15px;
    font-size: 13px;
    text-align: left;
    grid-row-gap: 10px;
}

.node {
    font: 300 11px "Helvetica Neue", Helvetica, Arial, sans-serif;
    fill: #bbb;
}

.node:hover {
    fill: #000;
}

.link {
    stroke: steelblue;
    stroke-opacity: 0.4;
    fill: none;
    pointer-events: none;
}

.node:hover,
.node--source,
.node--target {
    font-weight: 700;
}

.node--source {
    fill: #2ca02c;
}

.node--target {
    fill: #d62728;
}

.link--source,
.link--target {
    stroke-opacity: 1;
    stroke-width: 2px;
}

.link--source {
    stroke: #d62728;
}

.link--target {
    stroke: #2ca02c;
}
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <script src="https://d3js.org/d3.v4.min.js"></script>

    <div ></div>

        <div  id="map"></div>

        <div >
            <script>
            // DATATABLE CODE HERE
            </script>
        </div>
        <div  id="my_plot">
            <script>
            // D3 PLOT CODE HERE
            var data = [10, 5, 10, 12, 15];

            var width = 600,
                height = 250,
                scaleFactor = 20,
                barWidth = 40;
                barGap = 2.5;

            var svg = d3.select("#my_plot")
                .append("svg")
                .attr("width", width)
                .attr("height", height);

            var g = svg.append("g")
                .attr("transform", "translate("   20   ","   20   ")");

            g.append("path")
                .datum(data)
                .attr("class", "line")
                .attr("fill", "none")
                .attr("stroke", "steelblue")
                .attr("d", d3.line()
                    .x(function(d, i) { return i * barWidth * barGap; })
                    .y(function(d) { return d3.max(data) * scaleFactor - d * scaleFactor; })
                );

            </script>
        </div>
        <div  id="edgeB">
            test
            <script>
                var diameter = 760,
                radius = diameter / 2;
                innerRadius = radius - 160;
            
                var cluster = d3.cluster()
                    .size([360, innerRadius]);
                
                var line = d3.radialLine()
                    .curve(d3.curveBundle.beta(0.85))
                    .radius(function(d) { return d.y; })
                    .angle(function(d) { return d.x / 180 * Math.PI; });
                
                var svg = d3.select("#edgeB").append("svg")
                    .attr("width", diameter)
                    .attr("height", diameter)
                .append("g")
                    .attr("transform", "translate("   radius   ","   radius   ")");
                
                var link = svg.append("g").selectAll(".link"),
                    node = svg.append("g").selectAll(".node");
                
                d3.json("https://atikur-rabbi.github.io/d3-edge/flare.json", function(error, classes) {
                if (error) throw error;
                
                var root = packageHierarchy(classes)
                    .sum(function(d) { return d.size; });
                
                cluster(root);
                
                link = link
                    .data(packageImports(root.leaves()))
                    .enter().append("path")
                    .each(function(d) { d.source = d[0], d.target = d[d.length - 1]; })
                    .attr("class", "link")
                    .attr("d", line);
                
                node = node
                    .data(root.leaves())
                    .enter().append("text")
                    .attr("class", "node")
                    .attr("dy", "0.31em")
                    .attr("transform", function(d) { return "rotate("   (d.x - 90)   ")translate("   (d.y   8)   ",0)"   (d.x < 180 ? "" : "rotate(180)"); })
                    .attr("text-anchor", function(d) { return d.x < 180 ? "start" : "end"; })
                    .text(function(d) { return d.data.key; })
                    .on("mouseover", mouseovered)
                    .on("mouseout", mouseouted);
                });
                
                function mouseovered(d) {
                node
                    .each(function(n) { n.target = n.source = false; });
                
                link
                    .classed("link--target", function(l) { if (l.target === d) return l.source.source = true; })
                    .classed("link--source", function(l) { if (l.source === d) return l.target.target = true; })
                    .filter(function(l) { return l.target === d || l.source === d; })
                    .raise();
                
                node
                    .classed("node--target", function(n) { return n.target; })
                    .classed("node--source", function(n) { return n.source; });
                }
                
                function mouseouted(d) {
                link
                    .classed("link--target", false)
                    .classed("link--source", false);
                
                node
                    .classed("node--target", false)
                    .classed("node--source", false);
                }
                
                // Lazily construct the package hierarchy from class names.
                function packageHierarchy(classes) {
                var map = {};
                
                function find(name, data) {
                    var node = map[name], i;
                    if (!node) {
                    node = map[name] = data || {name: name, children: []};
                    if (name.length) {
                        node.parent = find(name.substring(0, i = name.lastIndexOf(".")));
                        node.parent.children.push(node);
                        node.key = name.substring(i   1);
                    }
                    }
                    return node;
                }
                
                classes.forEach(function(d) {
                    find(d.name, d);
                });
                
                return d3.hierarchy(map[""]);
                }
                
                // Return a list of imports for the given array of nodes.
                function packageImports(nodes) {
                var map = {},
                    imports = [];
                
                // Compute a map from name to node.
                nodes.forEach(function(d) {
                    map[d.data.name] = d;
                });
                
                // For each import, construct a link from the source to target node.
                nodes.forEach(function(d) {
                    if (d.data.imports) d.data.imports.forEach(function(i) {
                    imports.push(map[d.data.name].path(map[i]));
                    });
                });
                
                return imports;
                }  
            </script>     
        </div>
</body>
</html>

  • Related