d3.event在缩放回调(角度)中未定义

时间:2019-03-18 20:18:46

标签: javascript angular d3.js

我正在努力使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

感谢您的见解;)

1 个答案:

答案 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似乎没有“缩放”方法。

谢谢