Диаграмма складывается, когда ось х установлена ​​в формат даты и времени - PullRequest
0 голосов
/ 22 апреля 2020

У меня есть angular компонент диаграммы, который dr aws диаграмм для данных временных рядов. Код здесь:

  ChangeDetectionStrategy,
  Component,
  ElementRef,
  Input,
  OnDestroy,
  ViewChild,
  ViewEncapsulation,
} from '@angular/core';
import { notNullFilter } from '@app/lib/rxjs-not-null-filter';
import { AnychartCartesian } from '@app/shared/anychart/anychart.module';
import { ResizeObserver } from 'resize-observer';
import { combineLatest, BehaviorSubject, Subject } from 'rxjs';
import { takeUntil } from 'rxjs/operators';

/**
 * Компонент для построения графиков с использованием anychart.
 */
@Component({
  selector: 'app-anychart',
  templateUrl: './anychart.component.html',
  styleUrls: ['./anychart.component.scss'],
  changeDetection: ChangeDetectionStrategy.OnPush,
  encapsulation: ViewEncapsulation.None,
})
export class AppAnychartComponent implements OnDestroy {
  constructor() {
    combineLatest([
      this.elementRef$,
      this.anychartCartesian$,
      this.height$.pipe(notNullFilter()),
    ])
      .pipe(
        takeUntil(this.destroy$),
      )
      .subscribe(([ref, chart, height]) => {
        this.destroyPrevAnychart();
        if (ref !== null && chart !== null) {
          const el = ref.nativeElement;
          this.resizeObserver.observe(el);
          chart.height(height);
          chart.xScale('date-time'); // it makes chart stacked
          chart.credits().enabled(false);
          chart.container(el);
          chart.draw();
          this.prevChart = chart;
        }
      });
  }

  private readonly resizeObserver = new ResizeObserver(entries => {
    const chart = this.anychartCartesian$.getValue();
    if (chart === null) { return; }
    const widthPx: number = entries.reduce((acc, entry) => entry.contentRect.width || acc, 0);
    console.log('TODO: resize chart:', widthPx); // TODO: resize chart
  });

  private readonly elementRef$ = new BehaviorSubject<ElementRef<HTMLDivElement> | null>(null);
  @ViewChild('elRef') set elementRef(ref: ElementRef<HTMLDivElement> | undefined) {
    this.elementRef$.next(ref || null);
  }

  private readonly anychartCartesian$ = new BehaviorSubject<AnychartCartesian | null>(null);
  @Input() set chart(chart: AnychartCartesian) {
    this.anychartCartesian$.next(chart);
  }

  public readonly height$ = new BehaviorSubject<string | null>(null);
  @Input() set height(height: string) {
    this.height$.next(height);
  }

  private prevChart: AnychartCartesian | null = null;

  private readonly destroy$ = new Subject<void>();

  /**
   * @inheritDoc
   */
  public ngOnDestroy(): void {
    this.resizeObserver.disconnect();
    this.destroy$.next();
    this.destroy$.complete();
    this.destroyPrevAnychart();
  }

  private destroyPrevAnychart(): void {
    if (this.prevChart !== null) {
      this.prevChart.dispose();
      this.prevChart = null;

      // ensure clean up previous svg
      const ref = this.elementRef$.getValue();
      if (ref !== null) {
        const el = ref.nativeElement;
        while (el.firstChild) {
          el.removeChild(el.firstChild);
        }
      }
    }
  }
}

Если я комментирую строку chart.xScale('date-time'); график выглядит следующим образом normal bar chart

Если я раскомментирую эту строку, график становится таким stacked bar chart

Я прочитал документы, но понятия не имею, почему это происходит. Вопрос в том, как с форматом даты и времени по шкале х сделать нормальную гистограмму, как на первом скриншоте? Заранее спасибо!

UPD1. Когда я изменил код с

const series1 = chart.colum(mapping1);

на

const series1 = chart.line(mapping1);`

, как было предложено в ответе, я получил диаграмму, которая выглядит так:

line chart

1 Ответ

0 голосов
/ 23 апреля 2020

Это ожидаемое поведение и режим не в стеке. Позволь мне объяснить. Каждая серия имеет балл за 1 марта (например, 2020-03-01). Если шкала Ordinal (первый снимок экрана), она создает категорию с именем «1 марта». Если масштаб dateTime, он становится линейным (не порядковым, 2-й снимок экрана). В этом случае каждый бар размещается строго в соответствии с его отметкой времени. Но все бары имеют одинаковую дату и время "2020-03-01". Итак, в результате все они размещаются в одной позиции. И выглядит как сложено, но это не так. Высота полосы не является суммой всех значений ряда в этой координате X. Есть несколько доступных вариантов, чтобы избежать этого:

  1. Использовать Порядковую шкалу, которая является значением по умолчанию
  2. Использовать шкалу dateTime, но переключать ряд столбцов в линию или сплайн, это повысит читабельность
  3. Используйте масштаб даты и времени, но создавайте эти серии на отдельных графиках.
...