如果你看一下整页的例子(忽略疯狂的线,那是不相关的),你会看到在加载时,X轴的最后一个标记是10,通过改变过渡属性来“捏造”。
但是,当您单击“更新”按钮以运行XAxis数据的更新和转换时,尽管重新应用了“捏造”,但数据将被替换并且最后一个刻度的“捏造”位置将丢失在更新中触发的customXAxis
函数中。
我怀疑这与过渡生命周期有关吗?
是否可以在父母转换之前对某些元素进行子元素(例如.remove()
)所需的定位更改?
var update = document.getElementById("update");
update.addEventListener(
"click",
function() {
updateFunc();
},
false
);
var data = [
{
date: 1,
amount: 58.13
},
{
date: 30,
amount: 53.98
},
{
date: 27,
amount: 67.0
},
{
date: 26,
amount: 89.7
},
{
date: 25,
amount: 99.0
},
{
date: 24,
amount: 130.28
},
{
date: 23,
amount: 166.7
},
{
date: 20,
amount: 234.98
},
{
date: 19,
amount: 345.44
},
{
date: 18,
amount: 443.34
},
{
date: 17,
amount: 543.7
},
{
date: 16,
amount: 580.13
},
{
date: 13,
amount: 605.23
},
{
date: 12,
amount: 622.77
},
{
date: 11,
amount: 626.2
},
{
date: 10,
amount: 628.44
},
{
date: 9,
amount: 636.23
},
{
date: 5,
amount: 633.68
},
{
date: 4,
amount: 624.31
},
{
date: 3,
amount: 629.32
},
{
date: 2,
amount: 618.63
},
{
date: 30,
amount: 599.55
},
{
date: 29,
amount: 609.86
},
{
date: 28,
amount: 617.62
},
{
date: 27,
amount: 614.48
},
{
date: 26,
amount: 606.98
}
];
// set the dimensions and margins of the graph
var margin = { top: 20, right: 20, bottom: 30, left: 50 },
width = 960 - margin.left - margin.right,
height = 500 - margin.top - margin.bottom;
// set the ranges
var x = d3.scaleLinear().range([0, width]);
var y = d3.scaleLinear().range([height, 0]);
// define the line
var valueline = d3
.line()
.x(function(d) {
return x(d.date);
})
.y(function(d) {
return y(d.amount);
});
// append the svg obgect to the body of the page
// appends a 'group' element to 'svg'
// moves the 'group' element to the top left margin
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 + ")");
// Get the data
// format the data
data.forEach(function(d) {
d.date = +d.date;
d.amount = +d.amount;
});
// Scale the range of the data
x.domain(
d3.extent(data, function(d) {
return d.date;
})
);
y.domain([
0,
d3.max(data, function(d) {
return d.amount;
})
]);
// Add the valueline path.
svg.append("path").data([data]).attr("class", "line").attr("d", valueline);
// Add the X Axis
svg
.append("g")
.attr("transform", "translate(0," + height + ")")
.classed("XAxis", true)
.call(customXAxis);
function customXAxis(g) {
g.call(d3.axisBottom(x));
var firstTicksTransform = svg
.selectAll(".XAxis .tick:first-of-type")
.attr("transform");
var translate = firstTicksTransform
.substring(
firstTicksTransform.indexOf("(") + 1,
firstTicksTransform.indexOf(")")
)
.split(",");
svg
.selectAll("XAxis .tick:first-of-type")
.attr("transform", "translate(" + (parseFloat(translate[0]) + 10) + ", 0)");
var lastTicksTransform = svg.selectAll(".XAxis .tick:last-of-type").attr("transform");
var translateLast = lastTicksTransform
.substring(
lastTicksTransform.indexOf("(") + 1,
lastTicksTransform.indexOf(")")
)
.split(",");
svg
.selectAll(".XAxis .tick:last-of-type")
.attr(
"transform",
"translate(" + (parseFloat(translateLast[0]) - 10) + ", 0)"
);
}
// Add the Y Axis
svg.append("g").classed("YAxis", true).call(d3.axisLeft(y));
var updateFunc = function() {
var svg = d3.select("body svg").transition();
data.forEach(function(d) {
d.date = d.date + 5;
d.amount = +d.amount;
});
x.domain(
d3.extent(data, function(d) {
return d.date;
})
);
svg.select(".XAxis").duration(750).call(customXAxis);
};
.line {
fill: none;
stroke: steelblue;
stroke-width: 2px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.10.0/d3.min.js"></script>
<button id="update">Update</button>