解决方案:
我花了一点时间研究这个问题,并提出了一个不错的解决方案。Lars 是对的,d3.js 并没有真正实现我想要的,但是通过一点分层,它就成功了。基本上,我创建了一个仅包含轴的新 SVG,将其覆盖在实际图形上并将两个缩放比例绑定在一起。这是代码:
var x = d3.scale.linear()
.nice()
.domain([-1, 1])
.range([0, w]);
var xScale = d3.scale.linear()
.nice()
.domain([0, 1])
.range([0, 230]);
var xAxis = d3.svg.axis()
.scale(xScale)
.ticks(3)
.tickSize(7);
var y = d3.scale.linear()
.nice()
.domain([1, -1])
.range([h, 0]);
/* Control panning and zooming */
var zoom = function() {
if( d3.event ) {
zm.scale(d3.event.scale).translate(d3.event.translate);
za.scale(d3.event.scale); // don't translate so the axis is fixed
}
/* Do other zoom/pan related translations for chart */
// Update x-axis on pan and zoom
vis2.select(".xaxis")
.transition()
.ease("sin-in-out")
.call(xAxis);
vis.selectAll("line.link")
.attr("x1", function(d) { return x(parseFloat(d.source.x)); })
.attr("y1", function(d) { return y(parseFloat(d.source.y)); })
.attr("x2", function(d) { return x(parseFloat(d.target.x)); })
.attr("y2", function(d) { return y(parseFloat(d.target.y)); });
};
var zm = d3.behavior.zoom().x(x).y(y).scaleExtent([-Infinity, Infinity]).on("zoom", zoom);
var za = d3.behavior.zoom().x(xScale).scaleExtent([-Infinity, Infinity]).on("zoom", zoom);
force = d3.layout.force()
.gravity(0)
.charge(-5)
.alpha(-20)
.size([w, h]);
nodes = force.nodes();
links = force.links();
vis = d3.select(CHART).append("svg:svg")
.attr("width", w)
.attr("height", h)
.call(zm);
vis.append("rect")
.attr("class", "overlay")
.attr("width", "100%")
.attr("height", "100%");
vis2 = vis.append("svg:svg")
.attr("width", 300)
.attr("height", 30)
.call(za);
vis2.append("svg:g")
.attr("class", "xaxis")
.attr("transform", "translate(20,10)")
.call(xAxis);
vis2.append("rect")
.attr("class", "overlay")
.attr("width", "100%")
.attr("height", "100%");
force.on("tick", zoom);
结果(当然还有一些额外的 CSS)看起来像这样,当用户放大和缩小时,比例会自动调整:http: //i.imgur.com/TVYVp4M.png
原始问题:
我在 D3js 中有一个图表,它沿 X 轴显示一个比例,并在我放大和缩小时适当更新。但是,我不想让图表的整个底部成为比例尺,而是将比例尺显示为更多的图例,就像地图上的距离比例尺(例如http://2012books.lardbucket.org/books /essentials-of-geographic-information-systems/section_06/91302d9e3ef560ae47c25d02a32a629a.jpg)。这可能吗?
相关代码片段:
var x = d3.scale.linear()
.nice()
.domain([-1, 1])
.range([0, w]);
var xAxis = d3.svg.axis()
.scale(x);
var zoom = function() {
vis.selectAll("g.node")
.attr("transform", function(d) {
return "translate(" + x(parseFloat(d.x)) + "," + y(parseFloat(d.y)) + ")";
});
// Update x-axis on pan and zoom
vis.select(".xaxis")
.transition()
.ease("sin-in-out")
.call(xAxis);
};