如何通过单击散点图图例中的按钮隐藏所有图形

How to hide all graphs with one click of a button in a scatterplot graph legend

我在下面有这段代码。 我的原始数据有更多不同类型的数据,这些数据构成了一个包含大量散点图点的大图,图例变得很大,很多时候我需要一个一个地删除select所有图例才能看到一个数据我需要的。我想要一个按钮,它可以一次取消 select 所有方块,然后 select 我需要的时候。那可能吗。我想不通。

    <!DOCTYPE html>
<meta charset="utf-8" http-equiv="X-UA-Compatible" content="IE=edge" />
<style>
body {  font: 10px sans-serif;
     }
.axis path,
.axis line {   fill: none;
               stroke: #000;
               shape-rendering: crispEdges;
           }
.dot { stroke: #000;
       stroke-width: 0px;
     }
div.tooltip {
            position: absolute;
            text-align: center;
            width: 160px;
            height: 28px;
            padding: 2px;
            font: 8px sans-serif;
            background: lightsteelblue;
            border: 0px;
            border-radius: 8px;
            }

</style>
<body>
<script src="d3.js"></script>
<script src="d3.min.js"></script>
<div id="graphContainer1" class="graphContainer1">
</div>
<div id="graphContainer2" class="graphContainer2">
</div>
<script>
if(!(window.console && console.log)) {
  console = {
    log: function(){},
    debug: function(){},
    info: function(){},
    warn: function(){},
    error: function(){}
  };
}
// set start of report (where to filter data on)
var dtReportStart = new Date();
//dtReportStart.setMonth(dtReportStart.getMonth() - 1);  //************************ hour
dtReportStart.setDate(dtReportStart.getDate() - 14);  //  adjusted report to show only 2 weeks for TAR ************************ hour

// Set the dimensions of the canvas / graph
var margin = {top: 30, right: 20, bottom: 100, left: 150},
width = 1800 - margin.left - margin.right,
height = 600 - margin.top - margin.bottom,
legend_delta = 15;
var yScaleSize = 20;

// setup fill color
var cValue = function(d) { return d.jobtype;};
var color = d3.scale.category20b();

// add the tooltip area to the webpage
var tooltip = d3.select("body").select("#graphContainer1" ).append("div")
    .attr("class", "tooltip")
    .style("opacity", 0);

// Parse the date / time           ************************ hour
var parseDate = d3.time.format("%Y-%m-%d %H:%M").parse;

// setup x 
var xValue = function(d) { return d.date_time;}; // data -> value
var xScale = d3.time.scale()
    .range([0, width]);
//    xScale = d3.time.scale.linear().range([0, width]), // value -> display
    xMap = function(d) { return xScale(xValue(d));}, // data -> display
    xAxis = d3.svg.axis().scale(xScale).orient("bottom");

// setup y
var yValue = function(d) { return d.average_jobtime;}, // data -> value
    yScale = d3.scale.linear().range([height, 0]), // value -> display
    yMap = function(d) { return yScale(yValue(d));}, // data -> display
    yAxis = d3.svg.axis().scale(yScale).orient("left");

// Define the axes
var xAxis = d3.svg.axis().scale(xScale)
    .orient("bottom")
    .ticks(d3.time.hour, 12) //************************ hour
    .tickFormat(d3.time.format("%Y-%m-%d %H:%M")); //************************ hour

var yAxis = d3.svg.axis().scale(yScale)
    .orient("left")
    .ticks(10); 

function do_graph(graph_title,filetoUse,gcid) {

console.log ('doing graph')

// Adds the svg canvas
var svg = d3.select("body").select("#graphContainer" + gcid )
    .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("text")
        .attr("x", (width / 2))             
        .attr("y", 0 - (margin.top / 2))
        .attr("text-anchor", "middle")  
        .style("font-size", "20px") 
        .style("font-weight", "bold")  
        .text(graph_title + " - average job duration per hour" );    //************************ hour

// Get the data
console.log (filetoUse)
d3.csv(filetoUse, function(error, data) {
  data=data.filter(function(row) {
       return parseDate(row['date_time']) >= dtReportStart; 
    })
  data.forEach(function(d) {
    d.average_jobtime = +d.average_jobtime;
    d.jobtype = d.jobtype;
    d.date_time = parseDate(d.date_time);
  });

   // Scale the range of the data
    xScale.domain(d3.extent(data, function(d) { return d.date_time; }));
    xScale.nice(d3.time.hour, 12); //************************ hour
    //yScale.domain([0,1+d3.max(data, function(d) { return d.average_jobtime; })]);
    yScale.domain([0,yScaleSize]);    
    //console.log("test :" + d3.max(data, function(d) { return d.average_jobtime; }) )
    // Add the X Axis
    svg.append("g")
        .attr("class", "x axis")
        .attr("transform", "translate(0," + height + ")")
        .call(xAxis);
    svg.append("text")
        .attr("class", "label")
        .attr("x", width)
        .attr("y", height-6)
        .style("text-anchor", "end")
        .text("Time");

    svg.select(".x.axis")
       .selectAll("text")
       .attr("transform"," translate(-13,50) rotate(-90)"); // To rotate the texts on x axis. Translate y position a little bit to prevent overlapping on axis line.

    // Add the Y Axis
    svg.append("g")
        .attr("class", "y axis")
        .call(yAxis);
    svg.append("text")
        .attr("class", "label")
        .attr("transform", "rotate(-90)")
        .attr("y", 6)
        .attr("dy", ".71em")
        .style("text-anchor", "end")
        .text("average_jobtime (seconds)");          

    svg.selectAll(".dot" )
      .data(data)
      .enter().append("circle")
      .attr("class", "dot")
      .attr("r", 2)
      .attr("id" , function(d) { return d.jobtype; } ) 
      .attr("cx", xMap )
      .attr("cy", yMap )
      .style("fill", function(d) { return color(cValue(d));}) 
      .on("mouseover", function(d) {
          tooltip.transition()
               .duration(50)
               .style("opacity", 0);
          tooltip.transition()
               .duration(20)
               .style("opacity", .9);
          tooltip.html(d.jobtype + ": " + yValue(d) +"<br/> (" + xValue(d) + ")")
               .style("left", (d3.event.pageX + 5) + "px")
               .style("top", (d3.event.pageY - 28) + "px");
      });

  // draw legend
  var legend = svg.selectAll(".legend")
      .data(color.domain())
      .enter()
      .append("g")
      .attr("class", "legend")
      .attr("transform", function(d, i) { return "translate(-1680," + i * legend_delta + ")"; })
     // .attr("transform", function(d, i) { return "translate(0," + i * 20 + ")"; });
      ;

  // draw legend empty rectangles 
  legend.append("rect")
      .attr("x", width - legend_delta-2)
      .attr("width", legend_delta-2 )
      .attr("height", legend_delta-2)
      .attr("border", 1)
      .style("stroke", 'black')
      .style("stroke-width", 1)
      .style("fill", 'white')
      ;

   // draw legend colored rectangles
  legend.append("rect")
      .attr("class", "fade_rectangle" ) 
      .attr("x", width - legend_delta-2)
      .attr("id" , function(d) { return d; } ) 
      .attr("width", legend_delta-2)
      .attr("height", legend_delta-2)
      .style("fill", color)
      .style("stroke", 'black')
      .style("stroke-width", 1)
      .style("opacity", 1)
      .on("click", function (d, i) {
                      // register on click event
                      console.log ('opacity:' + this.style.opacity  );
                      var lVisibility = this.style.opacity 
                      console.log ('lVisibility:' + lVisibility  );
                      filterGraph(d, lVisibility);
                   });

  // draw legend text
  legend.append("text")
      .attr("x", width - 24)
      .attr("y", 9)
      .attr("dy", ".35em")
      .style("text-anchor", "end")
      .text(function(d) { return d;})
      ;
});
    // Method to filter graph
    function filterGraph( aType, aVisibility) {
        console.log( "jobtype :" + aType + ",vis:" + aVisibility   );
        // change lthe visibility of the node
        // if all the links with that node are invisibile, the node should also be invisible
        // otherwise if any link related to that node is visibile, the node should be visible
          newOpacity = 1 - aVisibility ;
        console.log( "newOpacity :" + newOpacity);
        // Hide or show the elements
        d3.selectAll("#" + aType).style("opacity", newOpacity);         
    }
}
console.log ('start')
do_graph('PILOT 0' ,'test.csv','1');  

console.log ('end')
</script>
</body>

test.csv:

20150723_080028,xxxMio,0,12246,Job finished JobReport,369,60736,61106
20150723_080136,pppMio,1,12331,Job finished JobReport,773,44959,45733
20150723_080141,tttMio,0,12421,Job finished JobReport,570,46836,47407
20150723_080238,fffMio,1,12531,Job finished JobReport,427,53571,53999
20150723_080304,xxxMio,0,12596,Job finished JobReport,257,52017,52275
20150723_080355,pppMio,1,12681,Job finished JobReport,777,43932,44710
20150723_080358,tttMio,0,12771,Job finished JobReport,569,43565,44135

假设我有一个 ID 为 toggle 的按钮:

<button id="toggle">Toggle All</button>

那么代码就很简单了:

d3.select('#toggle')
    .on("click", function(d){
      var o = d3.select('.fade_rectangle').style('opacity') === "1" ? "0" : "1";
      d3.selectAll('.dot')
        .style('opacity', o);
      d3.selectAll('.fade_rectangle')
        .style('opacity', o);
    });

这将使用第一个图例项来确定所有元素的状态。

工作example