我正在努力使D3.js / Angular中的缩放工作正常。更具体地说:缩放有效,但轴也得到缩放,这不是我想要的。
下面的代码应该可以解决此缩放问题,但是它不起作用:d3.event为我提供了“未定义”值:
import { Injectable } from '@angular/core';
import * as d3 from 'd3';
import {event as currentEvent} from 'd3-selection';
import * as d3Array from 'd3-array';
import { ClosedTrade } from '../models/closed-trade.model';
@Injectable({
providedIn: 'root'
})
export class TmpChartService {
svg: any;
xAxis: any;
xScale: any;
yAxis: any;
yScale: any;
constructor() { }
drawGraph() {
// Use the margin convention practice
const margin = { top: 100, right: 100, bottom: 100, left: 100 };
const width = window.innerWidth - margin.left - margin.right; // Use the window's width
const height = window.innerHeight - margin.top - margin.bottom; // Use the window's height
// An array of objects of length N. Each object has key -> value pair, the key being 'y' and the value is a random number
const dataset = d3.range(10).map(function (d) {
return { 'y': d3.randomUniform(1)() };
});
const zoom = d3.zoom()
.scaleExtent([1, 10])
.on('zoom', () => {
console.log(d3.event.translate);
// doesn't work => d3.event.translate is undefined!
d3.select('svg').attr('transform', 'translate(' + d3.event.translate + ')scale(' + d3.event.scale + ')');
// d3.select('svg').attr('transform', d3.event.transform); // zooms but the axis are zoomed too which I want to avoid
// d3.select('svg').attr('transform', 'translate('
// + currentEvent.translate + ')scale(' + currentEvent.scale + ')'); // currentEvent is also undefined
});
// X scale will use the index of our data
this.xScale = d3.scaleLinear()
.domain([0, dataset.length]) // input
.range([0, width]); // output
// Y scale will use the randomly generate number
this.yScale = d3.scaleLinear()
.domain([
d3Array.min(dataset.map(d => d.y)),
d3Array.max(dataset.map(d => d.y))
]) // input
.range([height, 0]); // output
// d3's line generator
const line = d3.line<any>()
.x((d, i) => this.xScale(i)) // set the x values for the line generator
.y((d) => this.yScale(d.y)) // set the y values for the line generator
.curve(d3.curveMonotoneX); // apply smoothing to the line
this.svg = d3.select('body').append('svg')
.attr('width', width + margin.left + margin.right)
.attr('height', height + margin.top + margin.bottom)
.call(zoom);
this.xAxis = this.svg.append('g')
.attr('class', 'x axis')
.attr('transform', 'translate(0,' + height + ')')
.call(d3.axisBottom(this.xScale)); // Create an axis component with d3.axisBottom
// Call the y axis in a group tag
this.yAxis = this.svg.append('g')
.attr('class', 'y axis')
.call(d3.axisLeft(this.yScale)); // Create an axis component with d3.axisLeft
// Append the path, bind the data, and call the line generator
this.svg.append('path')
.datum(dataset) // Binds data to the line
.attr('class', 'line') // Assign a class for styling
.attr('d', line); // Calls the line generator
}
}
因此,d3.event.translate => d3.event行是未定义的,而我尝试过的另一种方法也是:currentEvent也未定义。
这是结果的屏幕,调试器工具显示错误: d3.event is undefined
感谢您的见解;)
答案 0 :(得分:0)
对不起,不清楚。我在网上找到的“解决方案”是这样的:
const zoom = d3.zoom()
.scaleExtent([1, 10])
.on('zoom', () => {
d3.select('svg').attr('transform', d3.event.transform); // zooms but the axis are zoomed too which I want to avoid
this.xAxis.call(this.xScale.scale(d3.event.transform.rescaleX(this.xScale)));
this.yAxis.call(this.yScale.scale(d3.event.transform.rescaleY(this.yScale)));
});
但是,this.xScale似乎没有“缩放”方法。
谢谢