1

解決:

私はこれを調べるのに少し時間を費やし、まともな解決策を思いつきました。Lars の言うとおりです。d3.js は、私が望んでいたことを実際には許可していませんが、少しレイヤー化するだけでうまくいきました。基本的に、軸のみを含む新しい SVG を作成し、それを実際のグラフに重ねて、2 つのズーム スケールを結び付けました。コードは次のとおりです。

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

元の質問:

X 軸に沿ってスケールを表示し、ズームインおよびズームアウトすると適切に更新される D3js のグラフがあります。ただし、グラフの下部全体を目盛りにするのではなく、地図上の距離目盛りのように、目盛りを凡例として表示したいと思います (例: http://2012books.lardbucket.org/books /地理情報システムの要点/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