简体   繁体   English

HTML 输入范围滑块影响了错误的 D3 图表

[英]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).我有两个 D3 边缘捆绑图,一个在另一个之上(CSS 网格)。 For the top chart (id: edgeB) I have a div input style slider that changes the tension (amount of curve) of the node lines.对于顶部图表(id:edgeB),我有一个 div 输入样式滑块,可以改变节点线的张力(曲线量)。 It should affect the top chart only.它应该只影响顶部图表。 Currently, the slider associated with the top chart is affecting the bottom most chart (id: edgeBTwo).目前,与顶部图表关联的滑块正在影响最底部的图表(id:edgeBTwo)。 I've tried including the correct div id but it seems to have no effect.我试过包括正确的 div id,但它似乎没有效果。 I'm thinking that it is affecting the most recently created D3 chart but I'm not sure how to change this behavior.我认为它正在影响最近创建的 D3 图表,但我不确定如何更改此行为。

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 文件和运行上述代码所需的两个数据文件:

packages.js包.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耀斑年.json

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

flare_test.json耀斑测试.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.你做错了什么是你在chart1中的(input [type =“range”])上分配onChange事件处理程序,并再次在同一节点上的chart2中分配它。 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>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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