1

解决方案:

我花了一点时间研究这个问题,并提出了一个不错的解决方案。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);
};
4

0 回答 0