d3 js Uncaught TypeError: Cannot read property 'select' of null

84
16 апреля 2022, 06:50

Всем привет! Я использую d3 js первый раз для отрисовки агрегационного графика, и мне нужно в нем обновить данные по нажатию на кнопку. Для отрисовки графики я использую синтаксис классов и вызываю и метод первоначальной отрисовки и далее метод обновления данных.

И при первом нажатии на кнопку все отлично, данные обновляются, но если повторно нажать на кнопку и вызвать этот же метод появляется данная ошибка в консоли Uncaught TypeError: Cannot read property 'select' of null

Опытным путем выяснил, что переменная this.svg после первого обновления данных становиться null, не могу разобраться в чем причина.

Благодарю за помощь!

import * as d3 from 'd3';
import { brush} from 'd3';
export default class AggregationChart {
  margin: Record<string, any>;
  w: Number;
  h: Number;
  width: Number;
  height: Number;
  from: Number;
  to: Number;
  data: Array<Object>;
  svg: any;
  x: any;
  y: any;
  brush: any;
  g: any;
  labelL: any;
  labelR: any;
  brushg: any;
  gBrush: any;
  handle: any;
  xBrush: any;
  constructor(data: any) {
    this.margin = { top: 30, right: 2, bottom: 0, left: 0 };
    this.w = 800;
    this.h = 85;
    this.width = this.w - this.margin.left - this.margin.right;
    this.height = this.h - this.margin.top - this.margin.bottom;
    this.from = 0;
    this.to = 365;
    this.data = data;
    this.svg = null;
    this.x = d3.scaleTime().range([0, this.width]);
    this.y = d3.scaleLinear().range([this.h, 0]);
    this.brush = null;
    this.g = null;
    this.labelL = null;
    this.labelR = null;
    this.gBrush = null;
    this.handle = null;
    this.xBrush = null;
  }
  showChart() {
    var x = this.x;
    var y = this.y;
    var area = d3
      .area()
      .x(function (d) {
        return x(d.x);
      })
      .y0(this.h)
      .y1(function (d) {
        return y(d.y);
      });
    this.svg = d3
      .select('#area')
      .append('svg')
      .attr('width', this.w)
      .attr('height', this.h + 30)
      .append('g')
      .attr(
        'transform',
        'translate(' + this.margin.left + ',' + this.margin.top + ')'
      );
 
    x.domain(
      d3.extent(this.data, function (d) {
        return d.x;
      })
    );
    y.domain([
      0,
      d3.max(this.data, function (d) {
        return d.y;
      }),
    ]);

    this.svg
      .append('path')
      .data([this.data])
      .attr('class', 'area filled')
      .attr('id', 'areafield')
      .attr('d', area);
    // gradient for back chart
    var svgDefs = this.svg.append('defs');
    var mainGradient = svgDefs
      .append('linearGradient')
      .attr('id', 'mainGradient');
    mainGradient.append('stop').attr('class', 'stop-left').attr('offset', '0');
    mainGradient
      .append('stop')
      .attr('class', 'stop-right')
      .attr('offset', '100%');
    this.svg.selectAll('#mainGradient').attr('gradientTransform', 'rotate(90)');
    this.drawBrush(50, 80);
  }
  updateDataChart(data) {
    console.log('update chart');
    console.log(data);
    var x = this.x;
    var y = this.y;
    var svg = d3
      .select('#area')
      .select('#svgarea')
      .attr('width', this.w)
      .attr('height', this.h + 30)
      .select('#gselect')
      .attr(
        'transform',
        'translate(' + this.margin.left + ',' + this.margin.top + ')'
      );
    // define the area
    var area = d3
      .area()
      .x(function (d) {
        return x(d.x);
      })
      .y0(this.h)
      .y1(function (d) {
        return y(d.y);
      });
    // scale the range of the data
    x.domain(
      d3.extent(data, function (d) {
        return d.x;
      })
    );
    y.domain([
      0,
      d3.max(data, function (d) {
        return d.y;
      }),
    ]);
    this.svg = svg;
    // update the area
    svg.select('#areafield').data([data]).attr('d', area);
  }

Ответ, найден код отредактирован, всем спасибо!

READ ALSO
Javascript как передать ссылку на HTML элемент в функцию

Javascript как передать ссылку на HTML элемент в функцию

У меня есть таблица, в которой есть кнопка "Удалить" в каждой строки, при нажатии на которую выставляется дата удаленияТеперь я хочу...

138
Вывод объектов с помощью метода

Вывод объектов с помощью метода

Нужно вывести 3 карточки товараЗадание: Создать класс, позволяющий создавать карточку товара

124