我正在尝试使用this example约束松弛来生成散点图。 这是我的semi-working Plunker。
我遇到的麻烦是我想在蓝线上绘制点。相反,它们沿着y轴反转。
示例中的原始代码实际上已经翻转了轴:
var y = d3.scale.linear()
.domain([6.6, d3.max(data, function (d) {
return d[1] + 0 ;
})])
.range([0, height]); //flip y
我这样解开了它:
.range([height, 0]); //flip y
这使得蓝线图正确,但不是点。我希望点(和标签)按照my Plunker中显示的蓝线进行绘制。我该如何解决这个问题?
答案 0 :(得分:1)
我的方法是使用这两个尺度简化所有x / y计算:
var xext = d3.extent(data, d => d[0]);
var sx = d3.scale.linear()
.domain(xext)
.range([0, width])
.nice();
var yext = d3.extent(data, d => d[1]);
var sy = d3.scale.linear()
.domain(yext)
.range([height, 0]) // flip y-axis
.nice();
然后可以从原始数据创建新的dataPoints数组,如下所示:
var lastYear = 2016;
var dataPoints = data.map(function(d, i) {
dx = sx(d[0]);
dy = sy(d[1]);
return {
x: dx,
y: dy,
label: lastYear - i,
labelX: dx + 5,
labelY: dy - 5
};
});
console.log(dataPoints);
从这个增强的数据结构中,所有的线条,点和标签都放在图表区域中......
// begin of drawing lines
var line = d3.svg.line()
.x(d => d.x)
.y(d => d.y)
.interpolate("linear");
g.append("path")
.attr("d", line(dataPoints))
.attr("transform", "translate(0,0)")
.style("stroke-width", 2)
.style("stroke", "steelblue")
.style("opacity", 0.7)
.style("fill", "none");
// Place the points
var viewPoints = points.selectAll("point").data(dataPoints);
viewPoints.enter()
.append("circle")
.attr({
class: "point",
cx: d => d.x,
cy: d => d.y,
r: 2
});
// Place the labels
var viewLabels = labels.selectAll("label").data(dataPoints);
viewLabels.enter()
.append("text")
.text(d => d.label)
.attr({
class: "label",
x: d => d.labelX,
y: d => d.labelY
});
// Place the lines. Lines use the point position
// for the x1,y1 and the label position for the x2,y2.
var viewLines = lines.selectAll("line").data(dataPoints);
viewLines.enter()
.append("line")
.attr({
class: "line",
x1: d => d.x,
y1: d => d.y,
x2: d => d.labelX,
y2: d => d.labelY
});
我没有改变任何松弛功能代码,但其中一些可以使用类似的技术进行简化。