d3 v4如何将转换应用于在转换中存活的子元素

时间:2017-08-09 11:24:00

标签: javascript d3.js

如果你看一下整页的例子(忽略疯狂的线,那是不相关的),你会看到在加载时,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>

0 个答案:

没有答案