[英]D3: Y axis prints won't update with new data
I'm working with the D3 library and I have a Y-axis only that I want to update when my new data is updated. 我正在使用D3库,并且只有Y轴,因此我想在更新新数据时进行更新。 The new data is updated when the slider changes numbers and that works fine.
当滑块更改数字时,新数据将更新,并且效果很好。 The problem is that the new axis prints over the old one.
问题在于新轴将在旧轴上打印。 I need the old ones to be removed obviously and the new ones replacing it when the data is changed.
当数据更改时,我需要明显地删除旧的文件,而新的文件将其替换。 Would appreciate any help on this, thanks.
希望对此有所帮助,谢谢。
<script type="text/javascript">
var myYear = 2006;
//Width and height
var w = 1000;
var h = 500;
var barPadding = 20;
var myNames = ["Pedestrian", "Bicycle", "Motorbike", "Car", "Other"];
//Original data
var dataset = [
[
{ y: 20 }, //male
{ y: 4 },
{ y: 16},
{ y: 53},
{ y: 15 }
],
[
{ y: 12 }, //female
{ y: 4 },
{ y: 3 },
{ y: 36 },
{ y: 2 }
],
];
console.log(dataset);
//Set up stack method
var stack = d3.layout.stack();
//Data, stacked
stack(dataset);
//Set up scales
var xScale = d3.scale.ordinal()
.domain(d3.range(dataset[0].length))
.rangeRoundBands([30, w], 0.05);
var yScale = d3.scale.linear()
.domain([0,
d3.max(dataset, function(d) {
return d3.max(d, function(d) {
return d.y0 + d.y;
});
})
])
.range([0, h]);
yScale2 = d3.scale.linear() //for Y axis
.domain([0,
d3.max(dataset, function(d) {
return d3.max(d, function(d) {
return d.y0 + d.y;
});
})
])
.range([h-10, 0]);
//Easy colors accessible via a 10-step ordinal scale
// var colors = d3.scale.category20c();
var color = d3.scale.ordinal()
.domain(["Male", "Female"])
.range(["#00B2EE", "#FF69B4"]);
//Create SVG element
var svg = d3.select("body")
.append("svg")
.attr("width", w)
.attr("height", h);
// Add a group for each row of data
var groups = svg.selectAll("g")
.data(dataset)
.enter()
.append("g")
.style("fill", function(d, i) {
return color(i);
});
//Define X axis
var xAxis = d3.svg.axis()
.scale(xScale)
.orient("bottom")
.ticks(5);
//Define Y axis
var yAxis = d3.svg.axis()
.scale(yScale2)
.orient("left")
.ticks(5);
// Add a rect for each data value
groups.selectAll("rect")
.data(function(d) { return d; })
.enter()
.append("rect")
.attr("x", function(d, i) {
return xScale(i)
})
.attr("width", xScale.rangeBand())
.attr("y", function(d) {
return h - yScale(d.y0) - yScale(d.y) -20
})
.attr("height", function(d) {
return yScale(d.y)
})
.on("mouseover", function(d) {
//Get this bar's x/y values, then augment for the tooltip
d3.select(this)
.attr("stroke", "white")
.attr("stroke-width", "3px")
var xPosition = parseFloat(d3.select(this).attr("x")) + xScale.rangeBand() / 2; var yPosition = parseFloat(d3.select(this).attr("y")) / 2 + h / 2;
//Update the tooltip position and value
d3.select("#tooltip")
.style("left", xPosition + "px")
.style("top", yPosition + "px")
.select(".deathCount")
.text(d.y);
//Show the tooltip
d3.select("#tooltip").classed("hidden", false);
})
.on("mouseout", function(d) {
//Hide the tooltip
d3.select("#tooltip").classed("hidden", true);
d3.select(this)
.transition()
.duration(2000)
.attr("stroke", "none")
// .attr("fill", "rgb(0, 0, " + (d * 1) + ")");
});
///////// MOUSE CLICK TO CHANGE DATA //////////////////////////////
function data2012() {
dataset = [
[
{ y: 20 }, //male
{ y: 4 },
{ y: 16},
{ y: 53},
{ y: 15 }
],
[
{ y: 12 }, //female
{ y: 4 },
{ y: 3 },
{ y: 36 },
{ y: 2 }
],
];
}
function data2011() {
dataset = [
[
{ y: 33 }, //male
{ y: 9 },
{ y: 17},
{ y: 57},
{ y: 14 }
],
[
{ y: 14 }, //female
{ y: 0 },
{ y: 1 },
{ y: 38 },
{ y: 3 }
],
];
}
function data2010() {
dataset = [
[
{ y: 26 }, //male
{ y: 7 },
{ y: 25},
{ y: 106},
{ y: 18 }
],
[
{ y: 14 }, //female
{ y: 0 },
{ y: 0 },
{ y: 40 },
{ y: 2 }
],
];
}
function data2009() {
dataset = [
[
{ y: 31 }, //male
{ y: 11 },
{ y: 28},
{ y: 102},
{ y: 27 }
],
[
{ y: 17 }, //female
{ y: 2 },
{ y: 1 },
{ y: 55 },
{ y: 0 }
],
];
}
function updateData() {
// RE-SET SCALES AND LAYOUT
d3.select("g").selectAll("svg").remove();
//Data, stacked
stack(dataset);
//Set up scales
xScale = d3.scale.ordinal()
.domain(d3.range(dataset[0].length))
.rangeRoundBands([30, w], 0.05);
yScale = d3.scale.linear()
.domain([0,
d3.max(dataset, function(d) {
return d3.max(d, function(d) {
return d.y0 + d.y;
});
})
])
.range([0, h]);
// d3.selectAll(yAxis).remove(); //new stuff
groups = svg.selectAll("g")
.data(dataset)
//Update all rects
var gas = groups.selectAll("rect")
.data(function(d) {return d;});
gas
.exit
.remove;
gas
.transition()
.duration(750)
.ease("linear")
.attr("width", xScale.rangeBand())
.attr("y", function(d) {
return h - yScale(d.y0) - yScale(d.y) - 20
})
.attr("height", function(d) {
return yScale(d.y)
})
.attr("x", function(d, i) {
return xScale(i);
});
// d3.select(yAxis).remove();
//REDRAW Y AXIS
yScale2 = d3.scale.linear()
.domain([0,
d3.max(dataset, function(d) {
return d3.max(d, function(d) {
return d.y0 + d.y;
});
})
])
.range([h-10, 0]);
yAxis = d3.svg.axis()
.scale(yScale2)
.orient("left")
.ticks(5);
svg.append("g")
.attr("class", "axis")
.attr("transform", "translate(" + 30 + ",-10)")
.transition()
.duration(500)
.call(yAxis)
}
//SLIDER STUFF
xAxis = d3.svg.axis()
.scale(xScale)
.orient("bottom")
.ticks(5)
.tickFormat(function(d) {
return myNames[d];
});
//Create Y axis
svg.append("g")
.attr("class", "axis")
.attr("transform", "translate(" + 30 + ",-10)")
// .call(yAxis);
svg.append("g")
.attr("class", "axis")
.attr("transform", "translate(0," + (h - barPadding ) + ")")
.transition()
.duration(500)
.call(xAxis)
</script>
<script> //Jquery slider
$(function() {
$( "#slider" ).slider({
value:2012,
min: 2009,
max: 2012,
step: 1,
slide: function( event, ui ) {
$( "#amount" ).val( ui.value );
myYear = ui.value;
console.log(myYear);
if (myYear == 2012){
data2012();
}
if (myYear == 2011){
data2011();
}
if (myYear == 2010){
data2010();
}
if (myYear == 2009){
data2009();
}
updateData();
// console.log(myYear);
}
});
In your updateData()
function don't re-append the axis. 在您的
updateData()
函数中,不要重新附加轴。 Do it once on initial and then update it. 首先执行一次,然后更新。 This is consistent with d3's enter, update, and exit pattern.
这与d3的输入,更新和退出模式一致。
function updateData(){
...
yScale2 = d3.scale.linear()
.domain([0,
d3.max(dataset, function(d) {
return d3.max(d, function(d) {
return d.y0 + d.y;
});
})
])
.range([h - 10, 0]);
// set scale
yAxis.scale(yScale2);
// redraw it
d3.select('.yaxis').call(yAxis);
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.