2
我有一個條形圖,根據下拉選擇而變化。下拉選擇過濾我的數據文件。d3.js條形圖 - 在圖例點擊上顯示/隱藏條形圖。如何正確過濾?
然後,當點擊相應的圖例項目時,我顯示/隱藏圖表中的小節。顯示/隱藏正在工作。問題在於年份數據未被正確過濾。點擊圖例項目時,忽略從下拉列表中選擇年份時發生的數據過濾。我不知道爲什麼。
如何解決此問題?
我的代碼的下方,這裏是一個Plunker:https://plnkr.co/edit/gMa09b2jO9shxCbXDaFD?p=preview
HTML:
<!DOCTYPE html>
<meta charset="utf-8">
<link rel="stylesheet" type="text/css" href="style.css">
<body>
<script src="https://d3js.org/d3.v3.min.js"></script>
<script src="//code.jquery.com/jquery-1.10.2.js"></script>
<div id="dropdown">
<div class="ccms_form_element cfdiv_custom" id="indSelectors">
<label>Dimension:</label>
<select size="1" id="dimensions" class=" validate['required']" title="" type="select" name="style">
<option value="">-Select-</option>
<option value="Fruit">Fruit</option>
<option value="Vegetables">Vegetables</option>
</select>
<div class="clear"></div>
<div id="error-message-style"></div>
</div>
<div id="secondaryDrop">
<div id="Fruit" class="style-sub-1" style="display: none;" name="stylesub1">
<label>Fruit</label>
<select class="inds">
<option value="">- Select -</option>
<option value="apples">apples</option>
<option value="pears">pears</option>
</select>
</div>
<div id="Vegetables" class="style-sub-1" style="display: none;" name="stylesub1">
<label>Vegetables</label>
<select class="inds">
<option value="">- Select -</option>
<option value="tomatoes">tomatoes</option>
</select>
</div>
</div>
<div class="clear"></div>
<div id="error-message-style-sub-1"></div>
</div>
<div id="tertiaryDrop">
<div id="apples" class="style-sub-2" style="display: none;" name="stylesub2">
<label>Year</label>
<select class="years">
<option value="">- Select a Year -</option>
<option value="1950">1950</option>
<option value="2000">2000</option>
</select>
</div>
<div id="pears" class="style-sub-2" style="display: none;" name="stylesub2">
<label>Year</label>
<select class="years">
<option value="">- Select a Year -</option>
<option value="1900">1900</option>
<option value="2015">2015</option>
</select>
</div>
<div id="tomatoes" class="style-sub-2" style="display: none;" name="stylesub2">
<label>Year</label>
<select class="years">
<option value="">- Select a Year -</option>
<option value="2000">2000</option>
<option value="2015">2015</option>
</select>
</div>
<div class="clear"></div>
<div id="error-message-style-sub-2"></div>
</div>
</div>
<div id="legendContainer" class="legendContainer">
<svg id="legend"></svg>
</div>
<div id="tooltip" class="hidden">
<p><span id="state"></span></p>
</div>
<script src="script.js"></script>
JS:
$("#dimensions").change (function() {
var targID = $(this).val();
$("div.style-sub-1").hide();
$('#' + targID).show();
});
$(".inds").change (function() {
var targID = $(this).val();
$("div.style-sub-2").hide();
$('#' + targID).show();
});
function filterJSON(json, key, value) {
var result = [];
for (var foo in json) {
if (json[foo][key] === value) {
result.push(json[foo]);
}
}
return result;
}
var margin = {top: 20, right: 20, bottom: 130, left: 160},
width = 1200 - margin.left - margin.right,
height = 500 - margin.top - margin.bottom,
padding = 0.25;
var x = d3.scale.ordinal()
.rangeRoundBands([0, width - margin.left - margin.right], padding);
var y = d3.scale.linear()
.range([height, 0]);
var xAxis = d3.svg.axis()
.scale(x)
.orient("bottom");
var yAxis = d3.svg.axis()
.scale(y)
.orient("left")
.ticks(10);
var svg = d3.select("body").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 + ")");
d3.json("data.json", function(error, json) {
if (error) throw error;
json.forEach(function(d) {
d.year = +d.year;
d.value = +d.value;
});
var yr;
$('.inds')
.on("change", function() {
var prod = $(this).val();
console.log("prod:", prod);
data = filterJSON(json, 'produce', prod);
console.log("data: ", data);
updateGraph(data);
$('.years')
.on("change", function() {
var yr = $(this).val();
yr = +yr;
data1 = filterJSON(data, 'year', yr);
updateGraph(data1, yr);
});
});
// data = filterJSON(json, 'produce', 'apples');
// data1 = filterJSON(data, 'year', 2015);
// updateGraph(data1);
});
function updateGraph(data1, yr) {
console.log("year: ", yr);
console.log("data1: ", data1);
data1.sort(function(a,b) {return a.value-b.value;});
x.domain(data1.map(function(d) { return d.state; }));
y.domain([0, d3.max(data1, function(d) { return d.value; })]);
var result = data1.filter(function(d){
return $("." + d.state.replace(/\s|\(|\)|\'|\,+/g, '')).attr("fill") != "#cccccc"
// matching the data with selector status
})
console.log("result: ", result);
var bars = svg.selectAll(".bar")
.data(result, function(d){return d.state.replace(/\s|\(|\)|\'|\,+/g, '')});
bars.enter().append("rect")
.attr("class", "bar")
.on("mouseover", function(d) {
//Get this bar's x/y values, then augment for the tooltip
var xPosition = parseFloat(d3.select(this).attr("x")) + x.rangeBand() + 5;
var yPosition = parseFloat(d3.select(this).attr("y"))/2 + height/2;
//Update the tooltip position and value
d3.select("#tooltip")
.style("left", xPosition + "px")
.style("top", yPosition + "px")
.select("#state")
.text(d.state + ": " + d.produce + ": " + d.year + ": " + d.value);
d3.select("#tooltip").classed("hidden", false);
})
.on("mouseout", function() {
d3.select("#tooltip").classed("hidden", true);
});
bars.transition()
.attr("id", function(d){ return 'tag'+d.state.replace(/\s|\(|\)|\'|\,+/g, '');})
.attr("x", function(d) { return x(d.state); })
.attr("width", x.rangeBand())
.attr("y", function(d) {return y(d.value); })
.attr("height", function(d) { return height - y(d.value); });
bars.exit().remove();
// LEGEND GROUPS
var legendGroups = d3.select("#legend")
.selectAll(".legendGroup")
.data(data1, function(d){
return d.state; // always try and use a key function to uniquely identify
});
var enterGroups = legendGroups
.enter()
.append("g")
.attr("class","legendGroup");
legendGroups
.exit()
.remove();
legendGroups
.attr("transform",function(d,i){
return "translate(10," + (10 + i* 15) + ")"; // position the whole group
});
enterGroups.append("text")
.text(function(d){return d.state;})
.attr("x", 15)
.attr("y", 10);
enterGroups
.append("rect")
.attr("width", 10)
.attr("height", 10)
.attr("fill",function(d) {
return "#0000ff";
})
.attr("class", function(d,i){return "legendcheckbox " + d.state.replace(/\s|\(|\)|\'|\,|\.+/g, '')})
.on("click", function(d){
d.active = !d.active;
d3.select(this).attr("fill", function(d){
if(d3.select(this).attr("fill") == "#cccccc"){
return "#0000ff";
}else {
return "#cccccc";
}
})
var result = data1.filter(function(d, yr){
return $("." + d.state.replace(/\s|\(|\)|\'|\,+/g, '')).attr("fill") != "#cccccc"
})
console.log("data1 after legend click", data1);
console.log("result after legend click: ", result);
x.domain(result.map(function(d) { return d.state; }));
y.domain([0, d3.max(result, function(d) { return d.value; })]);
svg.select(".x.axis")
.transition()
.call(xAxis);
svg.selectAll(".bar")
.data(result, function(d){return d.state.replace(/\s|\(|\)|\'|\,|\.+/g, '')})
.enter()
.append("rect")
.attr("class", "bar")
.on("mouseover", function(d) {
var xPosition = parseFloat(d3.select(this).attr("x")) + x.rangeBand() + 5;
var yPosition = parseFloat(d3.select(this).attr("y"))/2 + height/2;
d3.select("#tooltip")
.style("left", xPosition + "px")
.style("top", yPosition + "px")
.select("#state")
.text(d.state + ": " + d.produce + ": " + d.year + ": " + d.value);
d3.select("#tooltip").classed("hidden", false);
})
.on("mouseout", function() {
d3.select("#tooltip").classed("hidden", true);
});
svg.selectAll(".bar")
.transition()
.attr("x", function(d) { return x(d.state); })
.attr("width", x.rangeBand())
.attr("y", function(d) {return y(d.value); })
.attr("height", function(d) { return height - y(d.value); });
svg.selectAll(".bar").data(result, function(d){return d.state.replace(/\s|\(|\)|\'|\,|\.+/g, '')}).exit().remove()
}); // end on click
svg.selectAll(".axis").remove();
svg.append("g")
.attr("class", "y axis")
.call(yAxis)
.append("text")
.attr("transform", "rotate(-90)")
.attr("y", 6)
.attr("dy", ".71em")
.style("text-anchor", "end")
.text("value");
};
數據(以.json文件)格式如下:
[{
"state":"Maine",
"produce":"apples",
"year":1900,
"value":"131"
},
{
"state":"Maine",
"produce":"apples",
"year":1950,
"value":"231"
},
{
"state":"Maine",
"produce":"apples",
"year":2000,
"value":"191"
}...
完整的數據文件可以在Plunker中看到。在傳說中點擊
var currentData = [];
//set the currentData in the update
function updateGraph(data1, yr) {
currentData = data1;
然後做CURRENTDATA過濾:
真棒,精美的作品。非常感謝您的幫助! – sprucegoose