如何在 d3 中创建图表之间的交互

How to create an interaction between charts in d3

我想让两个图表交互。图表的代码可以在以下链接中找到:https://github.com/irbp005/d3SankeyAndLineInteraction

图表的直观表示如下:

线条代表节点A、B、C的趋势值

我想要做的是,当鼠标悬停在 A、B 和 C 节点上时,折线图中的相应线条会突出显示,反之亦然,当鼠标悬停在折线图中的线条上时,桑基图中的节点会突出显示突出显示。

关于如何实现这种互动的任何想法。

谢谢

这里有一些快速修改以实现您的目标:

<!DOCTYPE html>
<meta charset="utf-8">
<title>SANKEY Static Sankey Visualization</title>
<style>
 .node rect {
   cursor: move;
   fill-opacity: .9;
   shape-rendering: crispEdges;
 }
 .node text {
   pointer-events: none;
   text-shadow: 0 1px 0 #fff;
 }
 .link {
   fill: none;
   stroke: #000;
   stroke-opacity: .2;
 }
 .link:hover {
   stroke-opacity: .5;
 }
 .axis path,
 .axis line{
   fill: none;
   stroke: black;
 }
 
 #A{
   fill: none;
   stroke: rgb(15, 58, 88);
   stroke-width: 5px;
 }
 
 #B{
   fill: none;
   stroke: rgb(85, 97, 113);
   stroke-width: 5px;
 }
 
 #C{
   fill: none;
   stroke: rgb(124, 62, 6);
   stroke-width: 5px;
 }
 .tick text{
   font-size: 12px;
 }
 .tick line{
   opacity: 0.2;
 }
</style>
<body>

<p id="chartSankey"></p>
<p id="chartLine"></p>

<script src="http://d3js.org/d3.v3.min.js"></script>
<script src="https://rawgit.com/d3/d3-plugins/master/sankey/sankey.js"></script>

<script> 
// ## Datasets for Sankey visualization
var graph = 
 {
 "nodes":[
 {"node":0,"name":"A"},
 {"node":1,"name":"B"},
 {"node":2,"name":"C"},
 {"node":3,"name":"D"},
 {"node":4,"name":"E"},
 {"node":4,"name":"F"}
 ],
 "links":[
 {"source":0,"target":3,"value":200},
 {"source":0,"target":4,"value":300},
 {"source":0,"target":5,"value":500},
 {"source":1,"target":3,"value":400},
 {"source":1,"target":4,"value":600},
 {"source":1,"target":5,"value":1000},
 {"source":2,"target":3,"value":600},
 {"source":2,"target":4,"value":900},
 {"source":2,"target":5,"value":1500}
 ]};
// ## Datasets for linechart 
var dataset = [
  {x: 0, y: 0},
  {x: 1, y: 28},
  {x: 2, y: 131},
  {x: 3, y: 152},
  {x: 4, y: 187},
  {x: 5, y: 245},
  {x: 6, y: 345},
  {x: 7, y: 481},
  {x: 8, y: 559},
  {x: 9, y: 632},
  {x: 10, y: 820},
  {x: 11, y: 800},
  {x: 12, y: 1000}
];
var dataset2 = [
  {x: 0, y: 0},
  {x: 1, y: 74},
  {x: 2, y: 174},
  {x: 3, y: 393},
  {x: 4, y: 593},
  {x: 5, y: 814},
  {x: 6, y: 1038},
  {x: 7, y: 1276},
  {x: 8, y: 1529},
  {x: 9, y: 1756},
  {x: 10, y: 1860},
  {x: 11, y: 1900},
  {x: 12, y: 2000}
];
var dataset3 = [
  {x: 0, y: 0},
  {x: 1, y: 95},
  {x: 2, y: 295},
  {x: 3, y: 406},
  {x: 4, y: 518},
  {x: 5, y: 869},
  {x: 6, y: 1282},
  {x: 7, y: 1403},
  {x: 8, y: 1504},
  {x: 9, y: 1840},
  {x: 10, y: 2050},
  {x: 11, y: 2500},
  {x: 12, y: 3000}
];
 
</script>

<script>
// ## Original source for Sankey https://gist.github.com/d3noob/c2637e28b79fb3bfea13
// ## Option to move nodes eliminated
// ## Order of nodes disabled on sankey.js (//nodes.sort(ascendingDepth);) to maintain the order of data, which is alphabetical and prevent for the nodes to be ordered by size 
// ## Codigo inicial adquirido para el Sankey https://gist.github.com/d3noob/c2637e28b79fb3bfea13
// ## La posibilidad de mover los nodos se ha eliminado
// ## La ordenacion en el archivo sankey.js se ha desbilitado (//nodes.sort(ascendingDepth);) para mantener el ordenen de los datos y evitar que los nodos se ordenen por tama~o 
var units = "$";
var margin = {top: 10, right: 10, bottom: 40, left: 20},
    width = 700 - margin.left - margin.right,
    height = 300 - margin.top - margin.bottom;
var formatNumber = d3.format(",.0f"),    // zero decimal places
    format = function(d) { return formatNumber(d) + " " + units; },
    color = d3.scale.category20();
// append the svg canvas to the page
var svg = d3.select("#chartSankey").append("svg")
    .attr("width", width + margin.left + margin.right)
    .attr("height", height + margin.top + margin.bottom)
  .append("g")
    .attr("transform", 
          "translate(" + margin.left + "," + margin.top + ")");
// Set the sankey diagram properties
var sankey = d3.sankey()
    .nodeWidth(36)
    .nodePadding(40)
    .size([width, height]);
var path = sankey.link();
  sankey
      .nodes(graph.nodes)
      .links(graph.links)
      .layout(32);
// add in the links
  var link = svg.append("g").selectAll(".link")
      .data(graph.links)
    .enter().append("path")
      .attr("class", function(d){
         return "link " + d.source.name;
      })
      .attr("d", path)
      .style("stroke-width", function(d) { return Math.max(1, d.dy); })
      .sort(function(a, b) { return b.dy - a.dy; })
      .on("mouseover", function(d){
        var s = d.source.name;
        d3.selectAll(".line").style('opacity', .1);
        d3.select("#" + s).style('opacity',  1);
      })
      .on("mouseout", function(d){
        d3.selectAll(".line").style('opacity', 1);
      });
      
      
      
// add the link titles
  link.append("title")
        .text(function(d) {
      return d.source.name + " → " + 
                d.target.name + "\n" + format(d.value); });
// add in the nodes
  var node = svg.append("g").selectAll(".node")
      .data(graph.nodes)
    .enter().append("g")
      .attr("class", "node")
      .attr("transform", function(d) { 
    return "translate(" + d.x + "," + d.y + ")"; })
// add the rectangles for the nodes
  node.append("rect")
      .attr("height", function(d) { return d.dy; })
      .attr("width", sankey.nodeWidth())
      .style("fill", function(d) { 
    return d.color = color(d.name.replace(/ .*/, "")); })
      .style("stroke", function(d) { 
    return d3.rgb(d.color).darker(2); })
    .on("mouseover", function(d){
        var s = d.name;
        d3.selectAll(".line").style('opacity', .1);
        d3.select("#" + s).style('opacity',  1);
      })
      .on("mouseout", function(d){
        d3.selectAll(".line").style('opacity', 1);
      });
    
    node.append("title")
      .text(function(d) { 
    return d.name + "\n" + format(d.value); });
// add in the title for the nodes
  node.append("text")
      .attr("x", -6)
      .attr("y", function(d) { return d.dy / 2; })
      .attr("dy", ".35em")
      .attr("text-anchor", "end")
      .attr("transform", null)
      .text(function(d) { return d.name; })
    .filter(function(d) { return d.x < width / 2; })
      .attr("x", 6 + sankey.nodeWidth())
      .attr("text-anchor", "start");
   
</script>

<script>
var margin = {top: 10, right: 10, bottom: 40, left: 40},
    width = 700 - margin.left - margin.right,
    height = 300 - margin.top - margin.bottom;
 
var xScale = d3.scale.linear()
    .domain([0, d3.max(dataset3, function(d){ return d.x; })])
    .range([0, width]);
var yScale = d3.scale.linear()
    .domain([0, d3.max(dataset3, function(d){ return d.y; })])
    .range([height, 0]);
var xAxis = d3.svg.axis()
    .scale(xScale)
    .tickSize(-height);
var yAxis = d3.svg.axis()
    .scale(yScale)
 .orient("left")
    .ticks(10);
 
var line = d3.svg.line()
    .x(function(d) { return xScale(d.x); })
    .y(function(d) { return yScale(d.y); });
 
var line2 = d3.svg.line()
    .x(function(d) { return xScale(d.x); })
    .y(function(d) { return yScale(d.y); });
var line2 = d3.svg.line()
    .x(function(d) { return xScale(d.x); })
    .y(function(d) { return yScale(d.y); });
 
var svg = d3.select("#chartLine").append("svg")
    .attr("width", width + margin.left + margin.right)
    .attr("height", height + margin.top + margin.bottom)
  .append("g")
    .attr("transform", "translate(" + margin.left + "," + margin.top + ")");
  svg.append("g")
      .attr("class", "x axis")
      .attr("transform", "translate(0," + height + ")")
      .call(xAxis)
  svg.append("g")
      .attr("class", "y axis")
      .call(yAxis)
  svg.append("path")
      .data([dataset])
      .attr("class", "line")
      .attr("d", line)
      .attr("id", "A")
      .on("mouseover", highlight)
      .on("mouseout", function(){ d3.selectAll(".link").style('opacity', 1);   });
  svg.append("path")
      .data([dataset2])
      .attr("class", "line")
      .attr("d", line)
      .attr("id", "B")
      .on("mouseover", highlight)
      .on("mouseout", function(){ d3.selectAll(".link").style('opacity', 1);   });
  svg.append("path")
      .data([dataset3])
      .attr("class", "line")
      .attr("d", line)
      .attr("id", "C")
      .on("mouseover", highlight)
      .on("mouseout", function(){ d3.selectAll(".link").style('opacity', 1);   });
      
  function highlight(){
    var id = this.id;
    d3.selectAll(".link").style('opacity', 0.1);
    d3.selectAll("." + id).style('opacity', 1);
  }
   
</script>

</body>
</html>