如何通过单击散点图图例中的按钮隐藏所有图形
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。
我在下面有这段代码。 我的原始数据有更多不同类型的数据,这些数据构成了一个包含大量散点图点的大图,图例变得很大,很多时候我需要一个一个地删除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。