ঠিক আছে, সুতরাং আমার এটি আরও একবার গিয়েছিল - যেমনটি আমার পূর্ববর্তী উত্তরে উল্লিখিত হয়েছে , আপনার যে সবচেয়ে বড় সমস্যাটি কাটিয়ে উঠতে হবে তা হ'ল ডি 3-জুম কেবল প্রতিসম স্কেলিংয়ের অনুমতি দেয়। এটি এমন একটি বিষয় যা ব্যাপকভাবে আলোচিত হয়েছে এবং আমি বিশ্বাস করি যে মাইক বোস্টক পরবর্তী প্রকাশে এটি সম্বোধন করছেন।
সুতরাং, সমস্যাটি কাটিয়ে উঠতে আপনার একাধিক জুম ব্যবহার করা উচিত। আমি একটি চার্ট তৈরি করেছি যাতে প্রতিটি অক্ষের জন্য একটি এবং প্লটের ক্ষেত্রের জন্য একটি থাকে। এক্স ও ওয়াই জুম আচরণগুলি অক্ষকে স্কেল করতে ব্যবহৃত হয়। যখনই কোনও জুম ইভেন্ট এক্স ও ওয়াই জুম আচরণগুলি দ্বারা উত্থাপিত হয় তখন তাদের অনুবাদ মানগুলি প্লট অঞ্চলে অনুলিপি করা হয়। তেমনিভাবে, যখন প্লট এলাকায় অনুবাদ অনুবাদ হয়, তখন এক্স ও ওয়াই উপাদানগুলি সংশ্লিষ্ট অক্ষ আচরণে অনুলিপি করা হয়।
আমাদের দিক অনুপাত বজায় রাখার জন্য প্লটের ক্ষেত্রের স্কেলিংটি আরও কিছুটা জটিল। এটি অর্জনের জন্য আমি পূর্ববর্তী জুম ট্রান্সফর্মটি সঞ্চয় করি এবং এক্স ও ওয়াই জুম আচরণগুলিতে প্রয়োগ করতে উপযুক্ত স্কেলটি ব্যবহার করতে স্কেল ডেল্টা ব্যবহার করি।
সুবিধার জন্য, আমি এই সমস্তগুলি একটি চার্টের উপাদানগুলিতে গুটিয়ে রেখেছি:
const interactiveChart = (xScale, yScale) => {
const zoom = d3.zoom();
const xZoom = d3.zoom();
const yZoom = d3.zoom();
const chart = fc.chartCartesian(xScale, yScale).decorate(sel => {
const plotAreaNode = sel.select(".plot-area").node();
const xAxisNode = sel.select(".x-axis").node();
const yAxisNode = sel.select(".y-axis").node();
const applyTransform = () => {
// apply the zoom transform from the x-scale
xScale.domain(
d3
.zoomTransform(xAxisNode)
.rescaleX(xScaleOriginal)
.domain()
);
// apply the zoom transform from the y-scale
yScale.domain(
d3
.zoomTransform(yAxisNode)
.rescaleY(yScaleOriginal)
.domain()
);
sel.node().requestRedraw();
};
zoom.on("zoom", () => {
// compute how much the user has zoomed since the last event
const factor = (plotAreaNode.__zoom.k - plotAreaNode.__zoomOld.k) / plotAreaNode.__zoomOld.k;
plotAreaNode.__zoomOld = plotAreaNode.__zoom;
// apply scale to the x & y axis, maintaining their aspect ratio
xAxisNode.__zoom.k = xAxisNode.__zoom.k * (1 + factor);
yAxisNode.__zoom.k = yAxisNode.__zoom.k * (1 + factor);
// apply transform
xAxisNode.__zoom.x = d3.zoomTransform(plotAreaNode).x;
yAxisNode.__zoom.y = d3.zoomTransform(plotAreaNode).y;
applyTransform();
});
xZoom.on("zoom", () => {
plotAreaNode.__zoom.x = d3.zoomTransform(xAxisNode).x;
applyTransform();
});
yZoom.on("zoom", () => {
plotAreaNode.__zoom.y = d3.zoomTransform(yAxisNode).y;
applyTransform();
});
sel
.enter()
.select(".plot-area")
.on("measure.range", () => {
xScaleOriginal.range([0, d3.event.detail.width]);
yScaleOriginal.range([d3.event.detail.height, 0]);
})
.call(zoom);
plotAreaNode.__zoomOld = plotAreaNode.__zoom;
// cannot use enter selection as this pulls data through
sel.selectAll(".y-axis").call(yZoom);
sel.selectAll(".x-axis").call(xZoom);
decorate(sel);
});
let xScaleOriginal = xScale.copy(),
yScaleOriginal = yScale.copy();
let decorate = () => {};
const instance = selection => chart(selection);
// property setters not show
return instance;
};
এখানে কাজের উদাহরণ সহ একটি কলম দেওয়া হয়েছে:
https://codepen.io/colineberhardt-the-bashful/pen/qBOEEGJ