gpt4 book ai didi

d3.js - 将缩放行为从v3更新到v5

转载 作者:行者123 更新时间:2023-12-04 03:02:55 52 4
gpt4 key购买 nike

我面临的问题是由于版本不匹配,我无法在我的代码中编写以下函数。
代码是

var zoom = d3.behavior.zoom()
.x(x)
.y(y)
.scaleExtent([1, 10])
.on("zoom", zoomed);

我已经尝试过这种方式
  const zoom = d3.zoom()
.scaleExtent([1, 4])
.x(this.xScale)
.on('zoom', () => {})

但这对我不起作用。

如何在d3版本5中编写相同的函数?我想使用d3版本5使折线图在y轴为固定位置的x轴上滚动

这是我的实现基本代码
    private createLineChart() {
this.width = 2000 - this.margin.left - this.margin.right;
this.height = 600 - this.margin.top - this.margin.bottom;

// X AXIS
this.xScale = d3.scaleBand()
.domain(this.dataset[0].fluencyData.map((data) => {
return new Date(data.date);
}))
.range([0, this.width]);

// Y AXIS
this.yScale = d3.scaleLinear()
.domain([0, 110])
.range([this.height, 0]);

// Line Generator
this.line = d3.line()
.x((data) => this.xScale(new Date(data.date)))
.y((data) => this.yScale(data.wcpm));
// .curve(d3.curveMonotoneX);

// Add SVG to Div
this.svg = d3.select('#displayChart').append('svg')
.attr('preserveAspectRatio', 'xMinYMin meet')
.attr(
'viewBox',
'0 0 ' +
(this.width + this.margin.left + this.margin.right) +
' ' +
(this.height + this.margin.top + this.margin.bottom))
// .attr('width', this.width + this.margin.left + this.margin.right)
// .attr('height', this.height + this.margin.top + this.margin.bottom)
.append('g')
.attr('transform', 'translate(' + this.margin.left + ',' + this.margin.top + ')');

// Define the div for the tooltip
this.toolTipDiv = d3.select('#displayChart').append('div')
.attr('class', 'tooltip')
.style('opacity', 0);

// Append XAXIS to the SVG
this.svg.append('g')
.attr('class', 'xAxis')
.attr('transform', 'translate(0,' + this.height + ')')
.call(d3.axisBottom(this.xScale).tickSizeOuter(0).tickFormat(d3.timeFormat('%b %d')));

const zoom = d3.zoom()
.scaleExtent([1, 4])
.extent([100, 100], [this.width - 100, this.height - 100])
.x(this.xScale)
.on('zoom', () => {
console.log(d3.event.transform);
// this.svg.select('#displayChart').attr('d', this.line);
});
this.svg.call(zoom);

// Append YAXIS to SVG
this.svg.append('g')
.attr('class', 'yAxis')
.call(d3.axisLeft(this.yScale).tickSize(-this.width)
);

// Make a Path for Dataset
this.svg.append('path')
.datum(this.dataset[0].fluencyData)
.attr('class', 'line')
.attr('d', this.line)
.attr('transform', 'translate(' + this.margin.left + ',0)');

// Text Heading of DATE in chart
this.svg.append('text')
.attr('transform', 'translate(' + (-20) + ',' + (this.height + 13) + ')')
.attr('dy', '.35em')
.attr('class', ' xAxis')
.text('Date');
}
}

我得到的错误是
LineChartComponent_Host.ngfactory.js? [sm]:1 ERROR TypeError: d3__WEBPACK_IMPORTED_MODULE_2__.zoom(...).scaleExtent(...).x is not a function
at LineChartComponent.push../src/app/line-chart/line-chart.component.ts

最佳答案

使用d3v3及更早版本,缩放可以跟踪缩放比例的状态。在文档中,scale.x():“指定一个x比例尺,在缩放时应自动调整其域。” (docs)。这将修改原始比例。

D3v4 +没有zoom.x或zoom.y方法。

使用d3v4 +,缩放不会跟踪或修改d3比例尺的状态。实际上,对于d3v4 +,缩放行为甚至无法跟踪当前的缩放状态:“缩放行为不再在内部存储事件的缩放变换(即可见区域;缩放和平移)。现在,缩放变换存储在任何缩放行为已应用到的元素。(change log)”。

在此过程中,更重要的是,“缩放行为不再取决于比例,而是可以使用transform.rescaleX,transform.rescaleY,transform.invertX或transform.invertY来转换比例域(change log)”。

因此,我们需要自己完成此操作,而不是让缩放更新d3比例尺。最常见的方法是通过一个不变的引用比例,以及一个我们应用缩放变换的比例:

var zoom = d3.zoom()
.on("zoom",zoomed)

var x = d3.scaleLinear().... // working scale
var x2 = x.copy(); // reference scale.

function zoomed() {
x = d3.event.transform.rescaleX(x2) // update the working scale.
// do something...
}

因此,如下所示:

var x = d3.scale.linear()
.domain([0,1])
.range([0,500]);

var zoom = d3.behavior.zoom()
.x(x)
.scaleExtent([1, 10])
.on("zoom", zoomed);

var svg = d3.select("svg")
.call(zoom);

var axis = d3.svg.axis()
.orient("bottom")
.scale(x);

var axisG = svg.append("g")
.attr("transform", "translate(0,30)")
.call(axis);

function zoomed() {
axisG.call(axis);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.17/d3.min.js"></script>

<svg width="500" height="200"></svg>


变成这样的东西:

var x = d3.scaleLinear()
.domain([0,1])
.range([0,500]);
var x2 = x.copy(); // reference.

var zoom = d3.zoom()
.scaleExtent([1, 10])
.on("zoom", zoomed);

var svg = d3.select("svg")
.call(zoom);

var axis = d3.axisBottom().scale(x)

var axisG = svg.append("g")
.attr("transform", "translate(0,30)")
.call(axis);

function zoomed() {
x = d3.event.transform.rescaleX(x2)
axis.scale(x);
axisG.call(axis);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>

<svg width="500" height="200"></svg>


请注意,d3.event.transform.rescaleX用于连续刻度-您有序带刻度,因此我们需要对带刻度和/或点刻度使用稍微修改的方法:

var x = d3.scaleBand()
.domain(d3.range(10).map(function(d) { return d/10; }))
.range([0,500]);
var x2 = x.copy(); // reference.

var zoom = d3.zoom()
.scaleExtent([1, 10])
.on("zoom", zoomed);

var svg = d3.select("svg")
.call(zoom);

var axis = d3.axisBottom().scale(x)

var axisG = svg.append("g")
.attr("transform", "translate(0,30)")
.call(axis);

function zoomed() {
// Rescale the range of x using the reference range of x2.
x.range(x2.range().map(function(d) {
return d3.event.transform.applyX(d);
}))
axisG.call(axis);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>

<svg width="500" height="200"></svg>


这是基于 this issue和Bostock提出的解决方案的带/点比例解决方案

关于d3.js - 将缩放行为从v3更新到v5,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55376779/

52 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com