這是我第一次使用 d3.js,所以請耐心等待。我在 vue.js 檔案中將其作為純 JavaScript 實作。 我正在嘗試製作具有縮放功能的散點圖。到目前為止,我幾乎一切正常,但當我縮放時,我注意到 x 軸未正確縮放,但 y 軸工作正常。例如,在查看原始圖時,某個點可能位於 x 軸上的 625 左右,但放大後同一點將小於 600。 y 軸上不會發生這種情況 - 這些點會正確縮放。我假設縮放函數中 x 軸的縮放有問題,但我只是無法弄清楚。請看一下,如果您能看出我哪裡出錯了,請告訴我。
編輯:我應該要提到這是使用 d3.js 版本 7.4.4
<template> <div id="reg_plot"></div> </template> <script> import * as d3 from 'd3'; export default { name: 'regCamGraph', components: { d3 }, methods: { createSvg() { // dimensions var margin = {top: 20, right: 20, bottom: 30, left: 40}, svg_dx = 1400, svg_dy =1000, chart_dx = svg_dx - margin.right - margin.left, chart_dy = svg_dy - margin.top - margin.bottom; // data var y = d3.randomNormal(400, 100); var x_jitter = d3.randomUniform(-100, 1400); var d = d3.range(1000) .map(function() { return [x_jitter(), y()]; }); // fill var colorScale = d3.scaleLinear() .domain(d3.extent(d, function(d) { return d[1]; })) .range([0, 1]); // y position var yScale = d3.scaleLinear() .domain(d3.extent(d, function(d) { return d[1]; })) .range([chart_dy, margin.top]); // x position var xScale = d3.scaleLinear() .domain(d3.extent(d, function(d) { return d[0]; })) .range([margin.right, chart_dx]); console.log("chart_dy: " + chart_dy); console.log("margin.top: " + margin.top); console.log("chart_dx: " + chart_dx); console.log("margin.right: " + margin.right); // y-axis var yAxis = d3.axisLeft(yScale); // x-axis var xAxis = d3.axisBottom(xScale); // zoom var svg = d3.select("#reg_plot") .append("svg") .attr("width", svg_dx) .attr("height", svg_dy); svg.call(d3.zoom().on("zoom", zoom)); // ref [1] // plot data var circles = svg.append("g") .attr("id", "circles") .attr("transform", "translate(200, 0)") .selectAll("circle") .data(d) .enter() .append("circle") .attr("r", 4) .attr("cx", function(d) { return xScale(d[0]); }) .attr("cy", function(d) { return yScale(d[1]); }) .style("fill", function(d) { var norm_color = colorScale(d[1]); return d3.interpolateInferno(norm_color) }); // add y-axis var y_axis = svg.append("g") .attr("id", "y_axis") .attr("transform", "translate(75,0)") .call(yAxis).style("font-size", "20px") // add x-axis var x_axis = svg.append("g") .attr("id", "x_axis") .attr("transform", `translate(${margin.left}, ${svg_dy - margin.bottom})`) .call(xAxis).style("font-size", "20px") function zoom(e) { // re-scale y axis during zoom y_axis.transition() .duration(50) .call(yAxis.scale(e.transform.rescaleY(yScale))); // re-scale x axis during zoom x_axis.transition() .duration(50) .call(xAxis.scale(e.transform.rescaleX(xScale))); // re-draw circles using new y-axis scale var new_xScale = e.transform.rescaleX(xScale); var new_yScale = e.transform.rescaleY(yScale); console.log(d); x_axis.call(xAxis.scale(new_xScale)); y_axis.call(yAxis.scale(new_yScale)); circles.data(d) .attr('cx', function(d) {return new_xScale(d[0])}) .attr('cy', function(d) {return new_yScale(d[1])}); } } }, mounted() { this.createSvg(); } } </script>
有趣的是,在我設定剪輯區域以防止顯示軸外的點後,問題似乎自行解決了。這就是我創建剪輯路徑的方式:
// clip path var clip = svg.append("defs").append("svg:clipPath") .attr("id", "clip") .append("svg:rect") .attr("id", "clip-rect") .attr("x", "0") .attr("y", "0") .attr('width', chart_dx) .attr('height', chart_dy);
然後,我在繪製資料時將該屬性新增至 svg,如下所示:
svg.append("g").attr("clip-path", "url(#clip)")
使用繪圖資料部分更新了剪輯路徑:
// clip path var clip = svg.append("defs").append("svg:clipPath") .attr("id", "clip") .append("svg:rect") .attr("id", "clip-rect") .attr("x", "0") .attr("y", "0") .attr('width', chart_dx) .attr('height', chart_dy); // plot data var circles = svg.append("g") .attr("id", "circles") .attr("transform", "translate(75, 0)") .attr("clip-path", "url(#clip)") //added here .selectAll("circle") .data(d) .enter() .append("circle") .attr("r", 4) .attr("cx", function(d) { return xScale(d[0]); }) .attr("cy", function(d) { return yScale(d[1]); }) .style("fill", function(d) { var norm_color = colorScale(d[1]); return d3.interpolateInferno(norm_color) });
我最終解決了這個問題。我已經更新了原始帖子以展示對我有用的內容。
基本上,在添加剪輯區域後,一切開始正常工作。