3

ズーム機能を可能にする簡単なチャートを作成しようとしています。これまでに見つけた例では、軸と目盛りを手動で生成しています:http: //bl.ocks.org/1182434

しかし、私が使用したのは組み込みの軸オブジェクトであり、これを機能させるためにスケールを変換する方法がわかりません-何かアイデアはありますか?

var xScale = d3.scale.linear().
    domain([0, 80]). // your data minimum and maximum
    range([0, width]); // the pixels to map to, e.g., the width of the diagram.

var yScale = d3.scale.linear().
    domain([100, 0]). 
    range([0, height]); 

var xAxis = d3.svg.axis().orient("bottom").scale(xScale).ticks(10, d3.format(",d")),
    yAxis = d3.svg.axis().orient("left").scale(yScale);


var chart = d3.select("#chart").append("svg")
    .attr("class", "chart")
    .attr("width", width + margin.left + margin.right)
    .attr("height", height + margin.top + margin.bottom)
    .attr("pointer-events", "all")
    .append("g")
    .attr("transform", "translate(" + margin.left + "," + margin.top + ")")
    .call(d3.behavior.zoom().on("zoom", redraw))
    .append("g")

chart.append('svg:rect')
    .attr('width', width)
    .attr('height', height)
    .attr('fill', 'white');

// x-axis
var xaxis = chart.append("g")
    .attr("class", "x axis")
    .attr("transform", "translate(0," + height + ")")
    .call(xAxis);

// y-axis
var yaxis = chart.append("g")
    .attr("class", "y axis")
    .call(yAxis);

// omitted code to draw the path, it's just a path object that uses a line and passes data to it

function redraw() 
{
    console.log("here", d3.event.translate, d3.event.scale);
    path.attr("transform", "translate(" + d3.event.translate + ")" + " scale(" + d3.event.scale + ")");

    // d3.event.transform(xScale, yScale);
    // HERE is where I need to figure out how to scale the x and y axes!    

    xAxis.scale(xScale);
    yAxis.scale(yScale);

    xaxis.call(xAxis);
    yaxis.call(yAxis);
}
4

3 に答える 3

4

誰かが興味を持った場合に備えて、これが私がそれをやった方法です:

function redraw() 
{

    console.log("here", d3.event.translate, d3.event.scale);
    path.attr("transform", "translate(" + d3.event.translate + ")" + " scale(" + d3.event.scale + ")");     

    var xoffset = (xMax + xMin) / 2;
    var yoffset = (yMax + yMin) / 2;

    var xTemp = [(0 - xoffset) * (1/d3.event.scale), (0 + xoffset) * (1/d3.event.scale)];
    var yTemp = [(0 - yoffset) * (1/d3.event.scale), (0 + yoffset) * (1/d3.event.scale)];

    xMin = xTemp[0] + xoffset;
    xMax = xTemp[1] + xoffset;
    yMin = yTemp[0] + yoffset;
    yMax = yTemp[1] + yoffset;

    console.log("", xMin, xMax, yMin, yMax);

    xScale.domain([xMin, xMax]);
    yScale.domain([yMax, yMin]);

    xaxis.call(xAxis);
    yaxis.call(yAxis);

    path.attr("d", line)
        .attr("transform", null)
        .transition()       
        .ease("linear")     
        ;
}

スケール制限も設定する必要があることに注意してください。

var chart = d3.select("#chart").append("svg")
.attr("class", "chart")
.attr("width", width + margin.left + margin.right)
    .attr("height", height + margin.top + margin.bottom)
.attr("pointer-events", "all")
.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")")
.call(d3.behavior.zoom().scaleExtent([0.2, 5]).on("zoom", redraw))
.append("g");
于 2012-05-04T16:12:51.270 に答える
4

別のグラフを使用して、ズーム機能を含むチャートを確認できます。同じことが、既存のグラフを拡大する場合にも機能します。チャートはhttp://bl.ocks.org/1962173で入手できます。

ズームする方法は次のとおりです。

var rects, labels
  , minExtent = d3.time.day(brush.extent()[0])
  , maxExtent = d3.time.day(brush.extent()[1])
  , visItems = items.filter(function (d) { return d.start < maxExtent && d.end > minExtent});

mini.select('.brush').call(brush.extent([minExtent, maxExtent]));       

    // modify the domain (this is what actually does the 'zoom')
x1.domain([minExtent, maxExtent]);

// then redraw the updated axis which are based on the modified domain
main.select('.main.axis.date').call(x1DateAxis);
main.select('.main.axis.month').call(x1MonthAxis)
    .selectAll('text')
        .attr('dx', 5)
        .attr('dy', 12);

// upate the item rects that are visible
rects = itemRects.selectAll('rect')
    .data(visItems, function (d) { return d.id; })
    .attr('x', function(d) { return x1(d.start); })
    .attr('width', function(d) { return x1(d.end) - x1(d.start); });

    // append any new data that is now in view
rects.enter().append('rect')
    .attr('x', function(d) { return x1(d.start); })
    .attr('y', function(d) { return y1(d.lane) + .1 * y1(1) + 0.5; })
    .attr('width', function(d) { return x1(d.end) - x1(d.start); })
    .attr('height', function(d) { return .8 * y1(1); })
    .attr('class', function(d) { return 'mainItem ' + d.class; });

    // remove any data that is no longer in view
rects.exit().remove();

すべてのコードは、上記のリンクから入手できます。

于 2012-05-04T17:54:02.630 に答える
1

機密性の高いイベント領域を使用してグラフを追加できます(最後の追加である必要があります):

var rect = svg.append("svg:rect")
    .attr("class", "pane")
    .attr("width", w)
    .attr("height", h);

AFTER(含まない)この領域にイベント管理を追加する

rect.call(d3.behavior.zoom().x(x).scaleExtent([0.5, 4]).on("zoom", draw));

次のような描画関数を追加します

function draw() {
    svg.select("g.x.axis").call(xAxis);
    svg.select("g.y.axis").call(yAxis);
    svg.select("path.area").attr("d", area);
    svg.select("path.line").attr("d", line);
}

この例を参照してください: https://groups.google.com/forum/?fromgroups =#!topic / d3-js / 6p7Lbnz-jRQ%5B1-25-false%5D

于 2013-02-17T23:01:01.333 に答える