简体   繁体   中英

HTML input range slider is affecting the wrong D3 chart

I have two D3 edge bundle charts, one on top of the other (CSS grid). For the top chart (id: edgeB) I have a div input style slider that changes the tension (amount of curve) of the node lines. It should affect the top chart only. Currently, the slider associated with the top chart is affecting the bottom most chart (id: edgeBTwo). I've tried including the correct div id but it seems to have no effect. I'm thinking that it is affecting the most recently created D3 chart but I'm not sure how to change this behavior.

Here is all of my code.

<!DOCTYPE html>
<html>
<head>

    <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
    <link rel="icon" type="globe_icon.png">
    <script type='text/javascript' src='https://ajax.googleapis.com/ajax/libs/jquery/2.1.4/jquery.min.js'></script>

    <style type="text/css">

        body {
            padding: 90px;
            margin: 0px;
            height: 100%;
        }
        html,
        .grid-container {
            display: grid;
            grid-template-columns: 1fr;
            grid-template-rows: auto auto;
            background-color: #ffffff;
            padding: 10px;
            grid-row-gap: 10px;
          }
        .grid-item1 {
            background-color: rgb(255, 255, 255);
            border: 5px solid rgba(255, 0, 0, 0.8);
            padding: 15px;
            font-size: 12px;
            text-align: left;
            grid-row-gap: 10px;
            font: 8pt "Helvetica Neue", Arial, Helvetica, sans-serif;
            }
        .grid-item2 {
            background-color: rgb(255, 255, 255);
            border: 5px solid rgba(234, 0, 255, 0.8);
            padding: 15px;
            font-size: 12px;
            text-align: left;
            grid-row-gap: 10px;
            font: 8pt "Helvetica Neue", Arial, Helvetica, sans-serif;
            }
        .wrapword {
            white-space: -moz-pre-wrap !important;  /* Mozilla, since 1999 */
            white-space: -webkit-pre-wrap;          /* Chrome & Safari */ 
            white-space: -pre-wrap;                 /* Opera 4-6 */
            white-space: -o-pre-wrap;               /* Opera 7 */
            white-space: pre-wrap;                  /* CSS3 */
            word-wrap: break-word;                  /* Internet Explorer 5.5+ */
            word-break: break-all;
            white-space: normal;
        }
        path.arc {
            cursor: move;
            fill: #000000;
          }
          .node {
            font: 300 9 "Helvetica Neue", Helvetica, Arial, sans-serif;
            fill: rgb(0, 0, 0);
          }
          .node:hover {
            fill: rgb(132, 236, 255);
          }
          .node:hover,
          .node--source,
          .node--target {
            font-weight: 700;
          }
          .link {
            fill: none;
            stroke: #1f77b4;
            stroke-opacity: .5;
            pointer-events: none;
          }
          .link.source, .link.target {
            stroke-opacity: .8;
            stroke-width: 2px;
          }
          .node.target {
            fill: #d62728 !important;
          }
          .link.source {
            stroke: #d62728;
          }
          .node.source {
            fill: #00ff40;
          }
          .link.target {
            stroke: #00ff40;
          }
    </style>


</head>
<body>

    <div class="grid-container"></div>
        <div class="grid-item1" id="edgeB">
            <div id="edgeB" style="position:absolute;bottom: 2%;;font-size:16px;">Tension: <input style="position:relative;top:3px;" type="range" min="0" max="100" value="85"></div>
            <script type="text/javascript" src="//d3js.org/d3.v3.min.js"></script>
            <script type="text/javascript" src="packages.js"></script>
            <script>
            (function chart1(){
                color = d3.scale.category10(); 
                var w = 700,
                    h = 700,
                    rx = w / 2.1,
                    ry = h / 2.1,
                    m0,
                    rotate = 0
                  pi = Math.PI;
            
                var splines = [];
            
                var cluster = d3.layout.cluster()
                    .size([360, ry - 180])
                    .sort(function(a, b) {
                        return d3.ascending(a.key, b.key);
                    });
            
                var bundle = d3.layout.bundle();
            
                var line = d3.svg.line.radial()
                    .interpolate("bundle")
                    .tension(.8)
                    .radius(function(d) {
                        return d.y;
                    })
                    .angle(function(d) {
                        return d.x / 180 * Math.PI;
                    });
            
                // Chrome 15 bug: <http://code.google.com/p/chromium/issues/detail?id=98951>
                var div = d3.select("#edgeB")
                
                    .style("width", w + "px")
                    .style("height", w + "px")
                    .style("position", "relative");
            
                var svg = div.append("svg:svg")
                    .attr("width", 700)
                    .attr("height", 700)
                    .append("svg:g")
                    .attr("transform", "translate(" + rx + "," + ry + ")");
            
                svg.append("svg:path")
                    .attr("class", "arc")
                    .attr("d", d3.svg.arc().outerRadius(ry - 180).innerRadius(0).startAngle(0).endAngle(2 * Math.PI))
                    .on("mousedown", mousedown);
            
                d3.json("flare_year.json", function(classes) {
            
                    var nodes = cluster.nodes(packages.root(classes)),
                        links = packages.imports(nodes),
                        splines = bundle(links);
            
                    var path = svg.selectAll("path.link")
                        .data(links)
                        .enter().append("svg:path")
                        .attr("class", function(d) {
                            return "link source-" + d.source.key + " target-" + d.target.key;
                        })
                        .attr("d", function(d, i) {
                            return line(splines[i]);
                        });
            
                    var groupData = svg.selectAll("g.group")
                        .data(nodes.filter(function(d) {
                          return (d.key == '1970-1979' || d.key == '1980-1989' || d.key == '1990-1999' || d.key == '2000-2009' || d.key == '2010-2019') && d.children;
          
                        }))
                        .enter().append("group")
                        .attr("class", "group");
            
                    var groupArc = d3.svg.arc()
                        .innerRadius(ry - 177)
                        .outerRadius(ry - 157)
                        .startAngle(function(d) {
                            return (findStartAngle(d.__data__.children) - 2.3) * pi / 180;
                        })
                        .endAngle(function(d) {
                            return (findEndAngle(d.__data__.children) + 2.3) * pi / 180;
                        });        
            
                    svg.selectAll("g.arc")
                        .data(groupData[0])
                        .enter().append("svg:path")
                        .attr("d", groupArc)
                        .attr("class", "groupArc")
                        .attr("id", function(d, i) {console.log(d.__data__.key); return d.__data__.key;})
                        .style("fill", function(d, i) {return color(i);})
                        .style("fill-opacity", 0.5)
                        .each(function(d,i) {
            
                            var firstArcSection = /(^.+?)L/;
            
                            var newArc = firstArcSection.exec( d3.select(this).attr("d") )[1];
            
                            newArc = newArc.replace(/,/g , " ");
            
                            svg.append("path")
                                .attr("class", "hiddenArcs")
                                .attr("id", "hidden"+d.__data__.key)
                                .attr("d", newArc)
                                .style("fill", "none");
                        });
    
                    svg.selectAll(".arcText")
                        .data(groupData[0])
                        .enter().append("text")
                        .attr("class", "arcText")
                        .attr("dy", 12)
                        .append("textPath")
                        .attr("startOffset","50%")
                        .style("text-anchor","middle")
                        .attr("xlink:href",function(d,i){return "#hidden" + d.__data__.key;})
                        .text(function(d){return d.__data__.key;});    
            
                    svg.selectAll("g.node")
                        .data(nodes.filter(function(n) {
                            return !n.children;
                        }))
                        .enter().append("svg:g")
                        .attr("class", "node")
                        .attr("id", function(d) {
                            return "node-" + d.key;
                        })
                        .attr("transform", function(d) {
                            return "rotate(" + (d.x - 90) + ")translate(" + d.y + ")";
                        })
                        .append("svg:text")
                        .attr("dx", function(d) {
                            return d.x < 180 ? 25 : -25;
                        })
                        .attr("dy", ".31em")
                        .attr("text-anchor", function(d) {
                            return d.x < 180 ? "start" : "end";
                        })
                        .attr("transform", function(d) {
                            return d.x < 180 ? null : "rotate(180)";
                        })
                        .text(function(d) {
                            return d.key.replace(/_/g, ' ');
                        })
                        .on("mouseover", mouseover)
                        .on("mouseout", mouseout);
            
                    d3.select("input[type=range]").on("change", function() {
                        line.tension(this.value / 100);
                        path.attr("d", function(d, i) {
                            return line(splines[i]);
                        });
                    });
                });
            
                d3.select(window)
                    .on("mousemove", mousemove)
                    .on("mouseup", mouseup);
            
                    function mouse(e) {
                        return [e.pageX - rx, e.pageY - ry];
                      }
                      
                      function mousedown() {
                        m0 = mouse(d3.event);
                        d3.event.preventDefault();
                      }
                      
                      function mousemove() {
                        if (m0) {
                          var m1 = mouse(d3.event),
                              dm = Math.atan2(cross(m0, m1), dot(m0, m1)) * 180 / Math.PI;
                          div.style("-webkit-transform", "translate3d(0," + (ry - rx) + "px,0)rotate3d(0,0,0," + dm + "deg)translate3d(0," + (rx - ry) + "px,0)");
                        }
                      }
                      
                      function mouseup() {
                        if (m0) {
                          var m1 = mouse(d3.event),
                              dm = Math.atan2(cross(m0, m1), dot(m0, m1)) * 180 / Math.PI;
                      
                          rotate += dm;
                          if (rotate > 360) rotate -= 360;
                          else if (rotate < 0) rotate += 360;
                          m0 = null;
                      
                          div.style("-webkit-transform", "rotate3d(0,0,0,0deg)");
                      
                          svg.attr("transform", "translate(" + rx + "," + ry + ")rotate(" + rotate + ")")
                            .selectAll("g.node text")
                              .attr("dx", function(d) { return (d.x + rotate) % 360 < 180 ? 25 : -25; })
                              .attr("text-anchor", function(d) { return (d.x + rotate) % 360 < 180 ? "start" : "end"; })
                              .attr("transform", function(d) { return (d.x + rotate) % 360 < 180 ? null : "rotate(180)"; });
                        }
                      }
            
                function mouseover(d) {
                    svg.selectAll("path.link.target-" + d.key)
                        .classed("target", true)
                        .each(updateNodes("source", true));
            
                    svg.selectAll("path.link.source-" + d.key)
                        .classed("source", true)
                        .each(updateNodes("target", true));
                }
            
                function mouseout(d) {
                    svg.selectAll("path.link.source-" + d.key)
                        .classed("source", false)
                        .each(updateNodes("target", false));
            
                    svg.selectAll("path.link.target-" + d.key)
                        .classed("target", false)
                        .each(updateNodes("source", false));
                }
            
                function updateNodes(name, value) {
                    return function(d) {
                        if (value) this.parentNode.appendChild(this);
                        svg.select("#node-" + d[name].key).classed(name, value);
                    };
                }
            
                function cross(a, b) {
                    return a[0] * b[1] - a[1] * b[0];
                }
            
                function dot(a, b) {
                    return a[0] * b[0] + a[1] * b[1];
                }
            
                function findStartAngle(children) {
                    var min = children[0].x;
                    children.forEach(function(d) {
                        if (d.x < min)
                            min = d.x;
                    });
                    return min;
                }
            
                function findEndAngle(children) {
                    var max = children[0].x;
                    children.forEach(function(d) {
                        if (d.x > max)
                            max = d.x;
                    });
                    return max;
                }}())
            </script>     
        </div>
        <div class="grid-item2" id="edgeBTwo">
            <script type="text/javascript" src="//d3js.org/d3.v3.min.js"></script>
            <script type="text/javascript" src="packages.js"></script>
            <script>
            (function chart2(){
                color = d3.scale.category10(); 
                var w = 700,
                    h = 700,
                    rx = w / 2.1,
                    ry = h / 2.1,
                    m0,
                    rotate = 0
                  pi = Math.PI;
            
                var splines = [];
            
                var cluster = d3.layout.cluster()
                    .size([360, ry - 180])
                    .sort(function(a, b) {
                        return d3.ascending(a.key, b.key);
                    });
            
                var bundle = d3.layout.bundle();
            
                var line = d3.svg.line.radial()
                    .interpolate("bundle")
                    .tension(.8)
                    .radius(function(d) {
                        return d.y;
                    })
                    .angle(function(d) {
                        return d.x / 180 * Math.PI;
                    });
            
                // Chrome 15 bug: <http://code.google.com/p/chromium/issues/detail?id=98951>
                var div = d3.select("#edgeBTwo")
                
                    .style("width", w + "px")
                    .style("height", w + "px")
                    .style("position", "relative");
            
                var svg = div.append("svg:svg")
                    .attr("width", 700)
                    .attr("height", 700)
                    .append("svg:g")
                    .attr("transform", "translate(" + rx + "," + ry + ")");
            
                svg.append("svg:path")
                    .attr("class", "arc")
                    .attr("d", d3.svg.arc().outerRadius(ry - 180).innerRadius(0).startAngle(0).endAngle(2 * Math.PI))
                    .on("mousedown", mousedown);
            
                d3.json("flare_test.json", function(classes) {
            
                    var nodes = cluster.nodes(packages.root(classes)),
                        links = packages.imports(nodes),
                        splines = bundle(links);
            
                    var path = svg.selectAll("path.link")
                        .data(links)
                        .enter().append("svg:path")
                        .attr("class", function(d) {
                            return "link source-" + d.source.key + " target-" + d.target.key;
                        })
                        .attr("d", function(d, i) {
                            return line(splines[i]);
                        });
            
                    var groupData = svg.selectAll("g.group")
                        .data(nodes.filter(function(d) {
                          return (d.key == '1970-1979' || d.key == 'Low' || d.key == 'Medium' || d.key == 'High') && d.children;
          
                        }))
                        .enter().append("group")
                        .attr("class", "group");
            
                    var groupArc = d3.svg.arc()
                        .innerRadius(ry - 177)
                        .outerRadius(ry - 157)
                        .startAngle(function(d) {
                            return (findStartAngle(d.__data__.children) - 2.3) * pi / 180;
                        })
                        .endAngle(function(d) {
                            return (findEndAngle(d.__data__.children) + 2.3) * pi / 180;
                        });        
            
                    svg.selectAll("g.arc")
                        .data(groupData[0])
                        .enter().append("svg:path")
                        .attr("d", groupArc)
                        .attr("class", "groupArc")
                        .attr("id", function(d, i) {console.log(d.__data__.key); return d.__data__.key;})
                        .style("fill", function(d, i) {return color(i);})
                        .style("fill-opacity", 0.5)
                        .each(function(d,i) {
            
                            var firstArcSection = /(^.+?)L/;
            
                            var newArc = firstArcSection.exec( d3.select(this).attr("d") )[1];
            
                            newArc = newArc.replace(/,/g , " ");
            
                            svg.append("path")
                                .attr("class", "hiddenArcs")
                                .attr("id", "hidden"+d.__data__.key)
                                .attr("d", newArc)
                                .style("fill", "none");
                        });
                    svg.selectAll(".arcText")
                        .data(groupData[0])
                        .enter().append("text")
                        .attr("class", "arcText")
                        .attr("dy", 12)
                        .append("textPath")
                        .attr("startOffset","50%")
                        .style("text-anchor","middle")
                        .attr("xlink:href",function(d,i){return "#hidden" + d.__data__.key;})
                        .text(function(d){return d.__data__.key;});    
            
                    svg.selectAll("g.node")
                        .data(nodes.filter(function(n) {
                            return !n.children;
                        }))
                        .enter().append("svg:g")
                        .attr("class", "node")
                        .attr("id", function(d) {
                            return "node-" + d.key;
                        })
                        .attr("transform", function(d) {
                            return "rotate(" + (d.x - 90) + ")translate(" + d.y + ")";
                        })
                        .append("svg:text")
                        .attr("dx", function(d) {
                            return d.x < 180 ? 25 : -25;
                        })
                        .attr("dy", ".31em")
                        .attr("text-anchor", function(d) {
                            return d.x < 180 ? "start" : "end";
                        })
                        .attr("transform", function(d) {
                            return d.x < 180 ? null : "rotate(180)";
                        })
                        .text(function(d) {
                            return d.key.replace(/_/g, ' ');
                        })
                        .on("mouseover", mouseover)
                        .on("mouseout", mouseout);
            
                    d3.select("input[type=range]").on("change", function() {
                        line.tension(this.value / 100);
                        path.attr("d", function(d, i) {
                            return line(splines[i]);
                        });
                    });
                });
            
                d3.select(window)
                    .on("mousemove", mousemove)
                    .on("mouseup", mouseup);
            
                    function mouse(e) {
                        return [e.pageX - rx, e.pageY - ry];
                      }
                      
                      function mousedown() {
                        m0 = mouse(d3.event);
                        d3.event.preventDefault();
                      }
                      
                      function mousemove() {
                        if (m0) {
                          var m1 = mouse(d3.event),
                              dm = Math.atan2(cross(m0, m1), dot(m0, m1)) * 180 / Math.PI;
                          div.style("-webkit-transform", "translate3d(0," + (ry - rx) + "px,0)rotate3d(0,0,0," + dm + "deg)translate3d(0," + (rx - ry) + "px,0)");
                        }
                      }
                      
                      function mouseup() {
                        if (m0) {
                          var m1 = mouse(d3.event),
                              dm = Math.atan2(cross(m0, m1), dot(m0, m1)) * 180 / Math.PI;
                      
                          rotate += dm;
                          if (rotate > 360) rotate -= 360;
                          else if (rotate < 0) rotate += 360;
                          m0 = null;
                      
                          div.style("-webkit-transform", "rotate3d(0,0,0,0deg)");
                      
                          svg.attr("transform", "translate(" + rx + "," + ry + ")rotate(" + rotate + ")")
                            .selectAll("g.node text")
                              .attr("dx", function(d) { return (d.x + rotate) % 360 < 180 ? 25 : -25; })
                              .attr("text-anchor", function(d) { return (d.x + rotate) % 360 < 180 ? "start" : "end"; })
                              .attr("transform", function(d) { return (d.x + rotate) % 360 < 180 ? null : "rotate(180)"; });
                        }
                      }
                function mouseover(d) {
                    svg.selectAll("path.link.target-" + d.key)
                        .classed("target", true)
                        .each(updateNodes("source", true));
            
                    svg.selectAll("path.link.source-" + d.key)
                        .classed("source", true)
                        .each(updateNodes("target", true));
                }
            
                function mouseout(d) {
                    svg.selectAll("path.link.source-" + d.key)
                        .classed("source", false)
                        .each(updateNodes("target", false));
            
                    svg.selectAll("path.link.target-" + d.key)
                        .classed("target", false)
                        .each(updateNodes("source", false));
                }
            
                function updateNodes(name, value) {
                    return function(d) {
                        if (value) this.parentNode.appendChild(this);
                        svg.select("#node-" + d[name].key).classed(name, value);
                    };
                }
                function cross(a, b) {
                    return a[0] * b[1] - a[1] * b[0];
                }
                function dot(a, b) {
                    return a[0] * b[0] + a[1] * b[1];
                }
                function findStartAngle(children) {
                    var min = children[0].x;
                    children.forEach(function(d) {
                        if (d.x < min)
                            min = d.x;
                    });
                    return min;
                }
                function findEndAngle(children) {
                    var max = children[0].x;
                    children.forEach(function(d) {
                        if (d.x > max)
                            max = d.x;
                    });
                    return max;
                }}());
            </script>     
        </div>
</body>
</html>

Here is my packages.js file and both data files needed to run the above code:

packages.js

(function() {
  packages = {

    // Lazily construct the package hierarchy from class names.
    root: function(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 map[""];
    },

    // Return a list of imports for the given array of nodes.
    imports: function(nodes) {
      var map = {},
          imports = [];

      // Compute a map from name to node.
      nodes.forEach(function(d) {
        map[d.name] = d;
      });

      // For each import, construct a link from the source to target node.
      nodes.forEach(function(d) {
        if (d.imports) d.imports.forEach(function(i) {
          imports.push({source: map[d.name], target: map[i]});
        });
      });

      return imports;
    }

  };
})();

flare_year.json

[
    {
        "name": "root.2010-2019.A",
        "imports": [
            "root.1990-1999.B",
        ]
    },
    {
        "name": "root.1990-1999.B",
        "imports": [
            "root.2010-2019.A",
        ]
    }
]

flare_test.json

[
    {
        "name": "root.High.A",
        "imports": [
            "root.Medium.F",
        ]
    },
    {
        "name": "root.Medium.F",
        "imports": [
            "root.High.A",
        ]
    }
]

It was a simple issue but took me some time to figure out.

What you are doing wrong is that you are assigning the onChange Event Handler on (input[type="range"]) in chart1 and again assigning it in chart2 on the same node. Event Listener assigned later will always be called.

You need to have seperate inputs for range and corresponding handlers or if you want to assign a same handler, add a dropdown to select which chart to change and get value of that dropdown in the event handler.

Your fixed code below:

 (function() { packages = { // Lazily construct the package hierarchy from class names. root: function(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 map[""]; }, // Return a list of imports for the given array of nodes. imports: function(nodes) { var map = {}, imports = []; // Compute a map from name to node. nodes.forEach(function(d) { map[d.name] = d; }); // For each import, construct a link from the source to target node. nodes.forEach(function(d) { if (d.imports) d.imports.forEach(function(i) { imports.push({ source: map[d.name], target: map[i] }); }); }); return imports; } }; })(); (function chart1() { color = d3.scale.category10(); let w = 700, h = 700, rx = w / 2.1, ry = h / 2.1, m0, rotate = 0 pi = Math.PI; let splines = []; let cluster = d3.layout.cluster() .size([360, ry - 180]) .sort(function(a, b) { return d3.ascending(a.key, b.key); }); let bundle = d3.layout.bundle(); let line = d3.svg.line.radial() .interpolate("bundle") .tension(.8) .radius(function(d) { return dy; }) .angle(function(d) { return dx / 180 * Math.PI; }); // Chrome 15 bug: <http://code.google.com/p/chromium/issues/detail?id=98951> let div = d3.select("#edgeB") .style("width", w + "px") .style("height", w + "px") .style("position", "relative"); let svg = div.append("svg:svg") .attr("width", 700) .attr("height", 700) .append("svg:g") .attr("transform", "translate(" + rx + "," + ry + ")"); svg.append("svg:path") .attr("class", "arc") .attr("d", d3.svg.arc().outerRadius(ry - 180).innerRadius(0).startAngle(0).endAngle(2 * Math.PI)) .on("mousedown", mousedown); { let classes = [{ "name": "root.2010-2019.A", "imports": [ "root.1990-1999.B", ] }, { "name": "root.1990-1999.B", "imports": [ "root.2010-2019.A", ] } ]; let nodes = cluster.nodes(packages.root(classes)), links = packages.imports(nodes), splines = bundle(links); let path = svg.selectAll("path.link") .data(links) .enter().append("svg:path") .attr("class", function(d) { return "link source-" + d.source.key + " target-" + d.target.key; }) .attr("d", function(d, i) { return line(splines[i]); }); let groupData = svg.selectAll("g.group") .data(nodes.filter(function(d) { return (d.key == '1970-1979' || d.key == '1980-1989' || d.key == '1990-1999' || d.key == '2000-2009' || d.key == '2010-2019') && d.children; })) .enter().append("group") .attr("class", "group"); let groupArc = d3.svg.arc() .innerRadius(ry - 177) .outerRadius(ry - 157) .startAngle(function(d) { return (findStartAngle(d.__data__.children) - 2.3) * pi / 180; }) .endAngle(function(d) { return (findEndAngle(d.__data__.children) + 2.3) * pi / 180; }); svg.selectAll("g.arc") .data(groupData[0]) .enter().append("svg:path") .attr("d", groupArc) .attr("class", "groupArc") .attr("id", function(d, i) { console.log(d.__data__.key); return d.__data__.key; }) .style("fill", function(d, i) { return color(i); }) .style("fill-opacity", 0.5) .each(function(d, i) { let firstArcSection = /(^.+?)L/; let newArc = firstArcSection.exec(d3.select(this).attr("d"))[1]; newArc = newArc.replace(/,/g, " "); svg.append("path") .attr("class", "hiddenArcs") .attr("id", "hidden" + d.__data__.key) .attr("d", newArc) .style("fill", "none"); }); svg.selectAll(".arcText") .data(groupData[0]) .enter().append("text") .attr("class", "arcText") .attr("dy", 12) .append("textPath") .attr("startOffset", "50%") .style("text-anchor", "middle") .attr("xlink:href", function(d, i) { return "#hidden" + d.__data__.key; }) .text(function(d) { return d.__data__.key; }); svg.selectAll("g.node") .data(nodes.filter(function(n) { return !n.children; })) .enter().append("svg:g") .attr("class", "node") .attr("id", function(d) { return "node-" + d.key; }) .attr("transform", function(d) { return "rotate(" + (dx - 90) + ")translate(" + dy + ")"; }) .append("svg:text") .attr("dx", function(d) { return dx < 180 ? 25 : -25; }) .attr("dy", ".31em") .attr("text-anchor", function(d) { return dx < 180 ? "start" : "end"; }) .attr("transform", function(d) { return dx < 180 ? null : "rotate(180)"; }) .text(function(d) { return d.key.replace(/_/g, ' '); }) .on("mouseover", mouseover) .on("mouseout", mouseout); d3.select("input[type=range]").on("change", function() { console.log(line); line.tension(this.value / 100); path.attr("d", function(d, i) { return line(splines[i]); }); }); }; d3.select(window) .on("mousemove", mousemove) .on("mouseup", mouseup); function mouse(e) { return [e.pageX - rx, e.pageY - ry]; } function mousedown() { m0 = mouse(d3.event); d3.event.preventDefault(); } function mousemove() { if (m0) { var m1 = mouse(d3.event), dm = Math.atan2(cross(m0, m1), dot(m0, m1)) * 180 / Math.PI; div.style("-webkit-transform", "translate3d(0," + (ry - rx) + "px,0)rotate3d(0,0,0," + dm + "deg)translate3d(0," + (rx - ry) + "px,0)"); } } function mouseup() { if (m0) { var m1 = mouse(d3.event), dm = Math.atan2(cross(m0, m1), dot(m0, m1)) * 180 / Math.PI; rotate += dm; if (rotate > 360) rotate -= 360; else if (rotate < 0) rotate += 360; m0 = null; div.style("-webkit-transform", "rotate3d(0,0,0,0deg)"); svg.attr("transform", "translate(" + rx + "," + ry + ")rotate(" + rotate + ")") .selectAll("g.node text") .attr("dx", function(d) { return (dx + rotate) % 360 < 180 ? 25 : -25; }) .attr("text-anchor", function(d) { return (dx + rotate) % 360 < 180 ? "start" : "end"; }) .attr("transform", function(d) { return (dx + rotate) % 360 < 180 ? null : "rotate(180)"; }); } } function mouseover(d) { svg.selectAll("path.link.target-" + d.key) .classed("target", true) .each(updateNodes("source", true)); svg.selectAll("path.link.source-" + d.key) .classed("source", true) .each(updateNodes("target", true)); } function mouseout(d) { svg.selectAll("path.link.source-" + d.key) .classed("source", false) .each(updateNodes("target", false)); svg.selectAll("path.link.target-" + d.key) .classed("target", false) .each(updateNodes("source", false)); } function updateNodes(name, value) { return function(d) { if (value) this.parentNode.appendChild(this); svg.select("#node-" + d[name].key).classed(name, value); }; } function cross(a, b) { return a[0] * b[1] - a[1] * b[0]; } function dot(a, b) { return a[0] * b[0] + a[1] * b[1]; } function findStartAngle(children) { var min = children[0].x; children.forEach(function(d) { if (dx < min) min = dx; }); return min; } function findEndAngle(children) { var max = children[0].x; children.forEach(function(d) { if (dx > max) max = dx; }); return max; } }()); (function chart2() { color = d3.scale.category10(); var w = 700, h = 700, rx = w / 2.1, ry = h / 2.1, m0, rotate = 0 pi = Math.PI; var splines = []; var cluster = d3.layout.cluster() .size([360, ry - 180]) .sort(function(a, b) { return d3.ascending(a.key, b.key); }); var bundle = d3.layout.bundle(); var line = d3.svg.line.radial() .interpolate("bundle") .tension(.8) .radius(function(d) { return dy; }) .angle(function(d) { return dx / 180 * Math.PI; }); // Chrome 15 bug: <http://code.google.com/p/chromium/issues/detail?id=98951> var div = d3.select("#edgeBTwo") .style("width", w + "px") .style("height", w + "px") .style("position", "relative"); var svg = div.append("svg:svg") .attr("width", 700) .attr("height", 700) .append("svg:g") .attr("transform", "translate(" + rx + "," + ry + ")"); svg.append("svg:path") .attr("class", "arc") .attr("d", d3.svg.arc().outerRadius(ry - 180).innerRadius(0).startAngle(0).endAngle(2 * Math.PI)) .on("mousedown", mousedown); { let classes = [ { "name": "root.High.A", "imports": [ "root.Medium.F", ] }, { "name": "root.Medium.F", "imports": [ "root.High.A", ] } ]; var nodes = cluster.nodes(packages.root(classes)), links = packages.imports(nodes), splines = bundle(links); var path = svg.selectAll("path.link") .data(links) .enter().append("svg:path") .attr("class", function(d) { return "link source-" + d.source.key + " target-" + d.target.key; }) .attr("d", function(d, i) { return line(splines[i]); }); var groupData = svg.selectAll("g.group") .data(nodes.filter(function(d) { return (d.key == '1970-1979' || d.key == 'Low' || d.key == 'Medium' || d.key == 'High') && d.children; })) .enter().append("group") .attr("class", "group"); var groupArc = d3.svg.arc() .innerRadius(ry - 177) .outerRadius(ry - 157) .startAngle(function(d) { return (findStartAngle(d.__data__.children) - 2.3) * pi / 180; }) .endAngle(function(d) { return (findEndAngle(d.__data__.children) + 2.3) * pi / 180; }); svg.selectAll("g.arc") .data(groupData[0]) .enter().append("svg:path") .attr("d", groupArc) .attr("class", "groupArc") .attr("id", function(d, i) { console.log(d.__data__.key); return d.__data__.key; }) .style("fill", function(d, i) { return color(i); }) .style("fill-opacity", 0.5) .each(function(d, i) { var firstArcSection = /(^.+?)L/; var newArc = firstArcSection.exec(d3.select(this).attr("d"))[1]; newArc = newArc.replace(/,/g, " "); svg.append("path") .attr("class", "hiddenArcs") .attr("id", "hidden" + d.__data__.key) .attr("d", newArc) .style("fill", "none"); }); svg.selectAll(".arcText") .data(groupData[0]) .enter().append("text") .attr("class", "arcText") .attr("dy", 12) .append("textPath") .attr("startOffset", "50%") .style("text-anchor", "middle") .attr("xlink:href", function(d, i) { return "#hidden" + d.__data__.key; }) .text(function(d) { return d.__data__.key; }); svg.selectAll("g.node") .data(nodes.filter(function(n) { return !n.children; })) .enter().append("svg:g") .attr("class", "node") .attr("id", function(d) { return "node-" + d.key; }) .attr("transform", function(d) { return "rotate(" + (dx - 90) + ")translate(" + dy + ")"; }) .append("svg:text") .attr("dx", function(d) { return dx < 180 ? 25 : -25; }) .attr("dy", ".31em") .attr("text-anchor", function(d) { return dx < 180 ? "start" : "end"; }) .attr("transform", function(d) { return dx < 180 ? null : "rotate(180)"; }) .text(function(d) { return d.key.replace(/_/g, ' '); }) .on("mouseover", mouseover) .on("mouseout", mouseout); d3.select("input#inputEdgesec").on("change", function() { line.tension(this.value / 100); path.attr("d", function(d, i) { return line(splines[i]); }); }); }; d3.select(window) .on("mousemove", mousemove) .on("mouseup", mouseup); function mouse(e) { return [e.pageX - rx, e.pageY - ry]; } function mousedown() { m0 = mouse(d3.event); d3.event.preventDefault(); } function mousemove() { if (m0) { var m1 = mouse(d3.event), dm = Math.atan2(cross(m0, m1), dot(m0, m1)) * 180 / Math.PI; div.style("-webkit-transform", "translate3d(0," + (ry - rx) + "px,0)rotate3d(0,0,0," + dm + "deg)translate3d(0," + (rx - ry) + "px,0)"); } } function mouseup() { if (m0) { var m1 = mouse(d3.event), dm = Math.atan2(cross(m0, m1), dot(m0, m1)) * 180 / Math.PI; rotate += dm; if (rotate > 360) rotate -= 360; else if (rotate < 0) rotate += 360; m0 = null; div.style("-webkit-transform", "rotate3d(0,0,0,0deg)"); svg.attr("transform", "translate(" + rx + "," + ry + ")rotate(" + rotate + ")") .selectAll("g.node text") .attr("dx", function(d) { return (dx + rotate) % 360 < 180 ? 25 : -25; }) .attr("text-anchor", function(d) { return (dx + rotate) % 360 < 180 ? "start" : "end"; }) .attr("transform", function(d) { return (dx + rotate) % 360 < 180 ? null : "rotate(180)"; }); } } function mouseover(d) { svg.selectAll("path.link.target-" + d.key) .classed("target", true) .each(updateNodes("source", true)); svg.selectAll("path.link.source-" + d.key) .classed("source", true) .each(updateNodes("target", true)); } function mouseout(d) { svg.selectAll("path.link.source-" + d.key) .classed("source", false) .each(updateNodes("target", false)); svg.selectAll("path.link.target-" + d.key) .classed("target", false) .each(updateNodes("source", false)); } function updateNodes(name, value) { return function(d) { if (value) this.parentNode.appendChild(this); svg.select("#node-" + d[name].key).classed(name, value); }; } function cross(a, b) { return a[0] * b[1] - a[1] * b[0]; } function dot(a, b) { return a[0] * b[0] + a[1] * b[1]; } function findStartAngle(children) { var min = children[0].x; children.forEach(function(d) { if (dx < min) min = dx; }); return min; } function findEndAngle(children) { var max = children[0].x; children.forEach(function(d) { if (dx > max) max = dx; }); return max; } }());
 body { padding: 90px; margin: 0px; height: 100%; } html, .grid-container { display: grid; grid-template-columns: 1fr; grid-template-rows: auto auto; background-color: #ffffff; padding: 10px; grid-row-gap: 10px; } .grid-item1 { background-color: rgb(255, 255, 255); border: 5px solid rgba(255, 0, 0, 0.8); padding: 15px; font-size: 12px; text-align: left; grid-row-gap: 10px; font: 8pt "Helvetica Neue", Arial, Helvetica, sans-serif; } .grid-item2 { background-color: rgb(255, 255, 255); border: 5px solid rgba(234, 0, 255, 0.8); padding: 15px; font-size: 12px; text-align: left; grid-row-gap: 10px; font: 8pt "Helvetica Neue", Arial, Helvetica, sans-serif; } .wrapword { white-space: -moz-pre-wrap !important; /* Mozilla, since 1999 */ white-space: -webkit-pre-wrap; /* Chrome & Safari */ white-space: -pre-wrap; /* Opera 4-6 */ white-space: -o-pre-wrap; /* Opera 7 */ white-space: pre-wrap; /* CSS3 */ word-wrap: break-word; /* Internet Explorer 5.5+ */ word-break: break-all; white-space: normal; } path.arc { cursor: move; fill: #000000; } .node { font: 300 9 "Helvetica Neue", Helvetica, Arial, sans-serif; fill: rgb(0, 0, 0); } .node:hover { fill: rgb(132, 236, 255); } .node:hover, .node--source, .node--target { font-weight: 700; } .link { fill: none; stroke: #1f77b4; stroke-opacity: .5; pointer-events: none; } .link.source, .link.target { stroke-opacity: .8; stroke-width: 2px; } .node.target { fill: #d62728 !important; } .link.source { stroke: #d62728; } .node.source { fill: #00ff40; } .link.target { stroke: #00ff40; } .sliderContainer { display:flex; flex-direction:column; }
 <!DOCTYPE html> <html> <head> <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no"> <link rel="icon" type="globe_icon.png"> <script type='text/javascript' src='https://ajax.googleapis.com/ajax/libs/jquery/2.1.4/jquery.min.js'></script> </head> <body> <div class="grid-container"></div> <div class="grid-item1" id="edgeB"> <div id="edgeB" style="position:absolute;bottom: 2%;;font-size:16px;"><div class="sliderContainer">Tension: <input style="position:relative;top:3px;" type="range" min="0" max="100" value="85"> Tension for second <input id="inputEdgesec" style="position:relative;top:3px;" type="range" min="0" max="100" value="85"> </div> </div> <script type="text/javascript" src="//d3js.org/d3.v3.min.js"></script> </script> </div> <div class="grid-item2" id="edgeBTwo"> </div> <script type="text/javascript" src="//d3js.org/d3.v3.min.js"></script> <script type="text/javascript" src="packages.js"></script> </body> </html>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM