1
私は3軸を独立してズームする必要があるプロジェクトがあります。これを達成するためにスクロールバーを使用していますが、ズームが発生すると軸は再描画されません。D3.js軸でズームする
また、クリップパスが期待どおりに機能していないようです。
最終的には、グラフにパン機能も追加したいと思いますが、どこで開始するのかはわかりません。助けを事前に
感謝。
// cases vs deaths of a disease over time
var data = [
{"year": "1960", "cases":"887", "deaths": "199"},
{"year": "1965", "cases":"218", "deaths": "55"},
{"year": "1993", "cases":"37046", "deaths": "931"},
{"year": "1994", "cases":"38735", "deaths": "118"},
{"year": "1995", "cases":"19903", "deaths": "624"},
{"year": "1997", "cases":"4170", "deaths": "125"},
{"year": "1998", "cases":"10000", "deaths": "0"}
];
data.forEach(function (d) {
d.year = d3.time.format("%Y").parse(d.year.toString());
d.cases = +d.cases;
d.deaths = +d.deaths;
});
var margin = { top: 30, right: 40, bottom: 30, left: 50 },
width = 500 - margin.left - margin.right,
height = 270 - margin.top - margin.bottom;
var xScale = d3.time.scale()
.domain(d3.extent(data, function (d) { return d.year; }))
.range([0, width]);
var yScaleLeft = d3.scale.linear()
.domain([0, d3.max(data, function (d) { return d.cases; })])
.range([height, 0]);
var yScaleRight = d3.scale.linear()
.domain([0, d3.max(data, function (d) { return d.deaths; })])
.range([height, 0]);
var xAxis = d3.svg.axis()
.scale(xScale)
.orient("bottom").ticks(5);
var yAxisLeft = d3.svg.axis()
.scale(yScaleLeft)
.orient("left").ticks(5);
var yAxisRight = d3.svg.axis()
.scale(yScaleRight)
.orient("right").ticks(5);
var lineCases = d3.svg.line()
.x(function (d) { return xScale(d.year); })
.y(function (d) { return yScaleLeft(d.cases); });
var lineDeaths = d3.svg.line()
.x(function (d) { return xScale(d.year); })
.y(function (d) { return yScaleRight(d.deaths); });
var svg = d3.select("#chart").append("svg")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom)
.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
svg.append("g")
.attr("class", "x axis")
.attr("transform", "translate(0," + height + ")")
.call(xAxis);
svg.append("g")
.attr("class", "y axis yleft")
.call(yAxisLeft);
svg.append("g")
.attr("class", "y axis yright")
.call(yAxisRight)
.attr('transform', 'translate(' + width + ',0)');
svg.append("path")
.datum(data)
.attr("class", "line lineLeft")
.style("stroke", "red")
.attr("d", lineCases(data))
.attr("clip", "url(#clip)");
svg.append("path")
.datum(data)
.attr("class", "line lineRight")
.attr("d", lineDeaths(data))
.attr("clip", "url(#clip)");
svg.append("clipPath")
.attr("id", "clip")
.append("rect")
.attr("width", width)
.attr("height", height);
$("#slider-x").slider({
orientation: "horizontal",
range: "min",
min: 1000,
max: 10000, // make max be (maxDate-minDate).Days*1000, so you can zoom to one day
value: 1000,
slide: function(event, ui) {
zoomXWithSlider(ui.value/1000);
}
});
$("#slider-y-left").slider({
orientation: "vertical",
range: "min",
min: 1000,
max: 10000,
value: 1000,
slide: function(event, ui) {
zoomLeftWithSlider(ui.value/1000);
}
});
$("#slider-y-right").slider({
orientation: "vertical",
range: "min",
min: 1000,
max: 10000,
value: 1000,
slide: function(event, ui) {
zoomRightWithSlider(ui.value/1000);
}
});
function zoomXWithSlider(scale) {
// Note: works only on the <g> element and not on the <svg> element
// which is a common mistake
svg.selectAll("path.line").attr("transform", "scale("+scale+", 1)");
svg.select(".x.axis").call(xAxis);
}
function zoomLeftWithSlider(scale) {
svg.select("path.line.lineLeft").attr("transform", "scale(1, "+scale+")");
svg.select(".y.axis.yleft").call(yAxisLeft);
}
function zoomRightWithSlider(scale) {
svg.select("path.line.lineRight").attr("transform", "scale(1, "+scale+")");
svg.select(".y.axis.yright").call(yAxisRight);
}
多くの問題があります。私は今より完全な答えを書くことができます。まず、スライダの変更に反応して軸を再描画するときは、軸の基点となる尺度も変更する必要があります。そうでない場合は、同じものを再描画します(見ているとおり)。例えば、Xでは、軸を再描画する前に 'xScale.range([0、width * scale])'のようなことをするかもしれません。スライダーの値が変化したときに、新しいスケール値をキャプチャして、チャートのすべてまたはほとんどを再描画して、コードの繰り返しを避けるようなものをリファクタリングすることができます。 – meetamit
パンに入ると、影響を受けた範囲の最初の要素(上記の「0」)も変更する必要があります。これが、リファクタリングの理由です。 – meetamit
clipPathが機能しない理由は複数あります。まず、 'clipPath'は' 'セクションの子でなければなりません。 'clip'属性の代わりに、' .attr( "clip-path"、 "url(#clip)");)のように 'clip-path'を指定する必要があります。しかし、スライダーがドラッグされたときに ' 'を拡大すると、clipPathも暗黙的に拡大縮小されるという問題があります。つまり、一定のチャートの幅に基づいてクロップを続行しません。私が何を意味するか見るために、私は意図的にマスクの幅を 'width/2'に設定して、チャートの半分を切り取った。 xスライダをスライドさせたときの動きを見てみましょう。http://jsfiddle.net/tvvcbrob/ –
meetamit