我想正確禁止使用d3的縮放行爲縮放和縮放我的d3圖表。我已經將問題簡化爲以下最小的可運行示例。我想讓用戶無法放大,讓他看到y軸上的0線以下。約束縮放和平移d3
通過將translateExtent
設置爲svg的整個高度,樣本可以在非縮放狀態下工作,但當用戶放大一點時,該示例當然會中斷。事實上,你進一步放大,進一步你可以看到負面的地區。
我需要將translateExtent
設置爲?
我在每個縮放事件上重繪線條和軸的原因是,通常我使用的是反應來呈現我的svg並僅使用d3進行calculcations - 但我已經刪除了對反應的依賴性以提供更簡潔例。
const data = [ 0, 15, 30, 32, 44, 57, 60, 60, 85];
// set up dimensions and margins
const full = { w: 200, h: 200 };
const pct = { w: 0.7, h: 0.7 };
const dims = { w: pct.w * full.w, h: pct.h * full.h };
const margin = { w: (full.w - dims.w)/2, h: (full.h - dims.h)/2 };
// scales
const x = d3.scaleLinear()
.rangeRound([0, dims.w])
.domain([0, data.length]);
const y = d3.scaleLinear()
.rangeRound([dims.h, 0])
.domain(d3.extent(data));
// axes
const axes = {
x: d3.axisBottom().scale(x).tickSize(-dims.w),
y: d3.axisLeft().scale(y).tickSize(-dims.h)
}
const g = d3.select('.center');
// actual "charting area"
g
.attr('transform', `translate(${margin.w}, ${margin.h})`)
.attr('width', dims.w)
.attr('height', dims.h)
// x-axis
g.append('g')
.attr('transform', `translate(0, ${dims.h})`)
.attr('class', 'axis x')
.call(axes.x)
// y-axis
g.append('g')
.attr('class', 'axis y')
.call(axes.y)
// generator for the line
const line = d3.line()
.x((_, i) => x(i))
.y(d => y(d));
// the actual data path
const path = g
.append('path')
.attr('class', 'path')
.attr('d', line(data))
.attr('stroke', 'black')
.attr('fill', 'none')
const zoomBehaviour = d3.zoom()
.scaleExtent([1, 10])
.translateExtent([[0,0], [Infinity, full.h]])
.on('zoom', zoom);
d3.select('svg.chart').call(zoomBehaviour);
function zoom() {
const t = d3.event.transform;
const scaledX = t.rescaleX(x);
const scaledY = t.rescaleY(y);
axes.x.scale(scaledX);
axes.y.scale(scaledY);
d3.select('.axis.x').call(axes.x);
d3.select('.axis.y').call(axes.y);
line
.x((_, i) => scaledX(i))
.y(d => scaledY(d));
const scaledPath = path.attr('d', line(data));
}
body {
width: 200px;
height: 200px;
}
svg.chart {
width: 200px;
height: 200px;
border: 1px solid black;
}
.axis line, .axis path {
stroke: grey;
}
<script src="https://d3js.org/d3.v4.js"></script>
<body>
<svg class="chart">
<g class="center"></g>
</svg>
</body>
不幸的是,它產生的行爲與我所需要的不同。在這個例子中,圖像的任何部分都不可見,所以放大實際上是不可能的。如果你在你提供的鏈接中嘗試它,你會注意到你永遠不能放大「進入」樣本圖像。 我希望我的用戶能夠做到這一點,當放大時,他們不應該能夠「放大」圖像,即圖像的一部分必須始終可見。 – DeX3
我的意思並不是將上面的內容作爲你的用例的一個確切的解決方案,更像是在你的appriach中展示了一個額外的步驟,這是't.x'和't.y'的條件變種。也許你可以調整條件,因爲邁克的例子將整個內容限制爲始終可見,而你想限制內容(我想,這是行內容的邊界框)以「包圍」你的視口。只是一個不同的條件(如果我理解你的需求,內容邊界框和視口框與Mike的例子相反)。 –
是的,我能夠使它工作。我會接受你的答案,因爲你最終指出了我的正確方向。如果有人希望看到最終使其工作的代碼,我會將其作爲另一個答案發布。 – DeX3