Графики сравнения

Библиотека Graphs/comparison представлена двумя контролами:

  1. Graphs/comparison:View — базовый график сравнения периодов;
  2. Graphs/comparison:TreeView — график с таблицей детализации.

Graphs/comparison:View

Graphs/comparison:View - контрол, который позволяет отобразить графики каких-либо числовых значений, а также их сумму, во временном периоде и просчитать линию прогнозируемых значений на основе имеющихся данных.

Справочные материалы и ресурсы

Руководство разработчика по конфигурации контрола

Чтобы добавить контрол на страницу, необходимо выполнить следующие действия:

  1. Добавить контрол Graphs/comparison:View в шаблон страницы;
  2. Сконфигурировать контрол при помощи опций, которые описаны в документации;
  3. При изменении периода через переключатель происходит событие periodsChanged.
    WML:
<Graphs.comparison:View
  ...
  on:periodsChanged="_periodsChangedHandler()">
</Graphs.comparison:View>

TS:

protected _periodsChanged(e: SyntheticEvent<MouseEvent>, periods: IPeriods): void {
   this._periods = periods;
}

Далее рассмотрим пример конфигурации контрола.

WML:

<Graphs.comparison:View
   firstPeriodData="{{ _firstPeriodData }}"
   secondPeriodData="{{ _secondPeriodData }}"
   forecastData="{{ _forecastData }}"
   summaryData="{{ _summaryData }}"
   availablePeriodTypes="{{ _availablePeriodTypes }}"
   periods="{{ _periods }}"
   on:periodsChanged="_periodsChangedHandler()">
   <ws:selectorsLeftContentTemplate>
      <Controls.heading:Title
         caption="Продажи"
         fontColorStyle="primary"
         fontSize="3xl"
      />
   </ws:selectorsLeftContentTemplate>
   <ws:selectorsRightContentTemplate>
      <div>Контентная область</div>
   </ws:selectorsRightContentTemplate>
   <ws:dataLeftContentTemplate>
      <div>Контентная область</div>
   </ws:dataLeftContentTemplate>
   <ws:dataRightContentTemplate>
      <div>Контентная область</div>
   </ws:dataRightContentTemplate>
</Graphs.comparison:View>

TS:

...
protected _beforeMount(): void {
   this._periods = {
      selectedPeriodType: 'year',
      firstPeriodStart: new Date(2015, 0 1),
      secondPeriodStart: new Date(2017, 0, 1)    
   };
   this._availablePeriodTypes = ['year', 'halfyear', 'quarter', 'month', 'day'];
   this._summaryData = {
      current: {
         first: 5473900,
         second: 89484700
      },
      total: {
         first: 8477393890088000,
         second: 12477393890088000
      }
   };
   this._firstPeriodData = [
      [0, 180],
      [31, 130],
      [59, 300],
      [90, 200],
      [120, 40],
      [151, 80],
      [181, 100]
   ];
   this._secondPeriodData = [
      [0, 60],
      [31, 200],
      [59, 300],
      [90, 150],
      [95, 100]
   ];
   this._forecastData = [
      [95, 100],
      [120, 40],
      [151, 80],
      [181, 60]
   ]
}
 
protected _periodsChanged(e: SyntheticEvent<MouseEvent>, periods: IPeriods): void {
   this._periods = periods;
}
...

В результате получим изображение графика сравнения.

Дополнительные возможности контрола

График в режиме "Статистика"

Одной из возможностей контрола является отображение графика в режиме "Статистика". При таком варианте не отображается столбчатый график.

Для того, чтобы включить режим, после выполнения основных этапов конфигурации контрола необходимо установить опцию mode в значение stat. Также в этом режиме отличается формат опции summaryData:

...
protected _beforeMount(): void {
   this._mode = 'stat';
    
   this._summaryData = {
      start: {
         first: 10020803,
         second: 20100399
      }, 
      current: {
         first: 2019309890,
         second: 3818923878
      }        
   }
}
...

График в режиме "Тенденция"

В таком режиме отображается только процентное соотношение, а также нет подсказки при наведении на точку графика и подписи по оси Y.

Для того, чтобы включить режим, после выполнения основных этапов конфигурации контрола необходимо установить опцию mode в значение trend.

...
protected _beforeMount(): void {
   this._mode = 'trend';
}
...

График в режиме "Динамика данных"

В этом режиме на линейном графике отображаются данные только за текущий период, а также нет столбчатого графика с суммарными данными.

Для того, чтобы включить режим, не нужно устанавливать поле firstPeriodStart в опцию periods.

...
protected _beforeMount(): void {
   this._periods = {
      selectedPeriodType: 'year',
      secondPeriodStart: new Date(2017, 0, 1)    
   }
}
...

График с произвольным периодом

Тип графика позволяет установить любой диапазон через переключатель периодов.

Для того, чтобы включить режим, после выполнения основных этапов конфигурации контрола необходимо добавить в массив опции availablePeriodTypes типы периода day и custom.

...
protected _beforeMount(): void {
   this._periods = {
      selectedPeriodType: 'years',
      firstPeriodStart: new Date(2015, 0 1),
      firstPeriodEnd: new Date(2016, 11, 31),           
      secondPeriodStart: new Date(2017, 0, 1),
      secondPeridoEnd: new Date(2018, 11, 31)   
   }
   this._availablePeriodTypes = ['year', 'day', 'custom'];
}
...

Тип периода day включает контрол "Большой выбор периода". Только в нем можно выбрать произвольный диапазон, за что отвечает тип custom.

Заглушка на пустые данные

При отсутствии данных за выбранный период контрол имеет возможность отображать заглушку.

Пустыми данными принято считать значения, отличные от null.

Ноль не считается пустым значением. При нулевом значении отобразится сплошная линия по оси Y.

Для этого следует передавать пустые массивы в опции firstPeriodStart, secondPeriodStart, forecastPeriodStart. Если хотя бы в одной из них будут значения, отличные от 0, заглушка не отобразится.

...
protected _beforeMount(): void {
   this._firstPeriodData = [];
   this._secondPeriodData = [];
   this._forecastData = [];
}
...

Graphs/comparison:TreeView

Graphs/comparison:TreeView - контрол представляет собой стандартный контрол сравнения периодов с возможностью вывода таблицы с детализированными данными по периодам.

Справочные материалы и ресурсы

Руководство разработчика по конфигурации контрола

Чтобы добавить контрол на страницу, необходимо выполнить следующие действия:

  1. Добавить контрол Graphs/comparison:TreeView в шаблон страницы;
  2. Сконфигурировать контрол при помощи опций, которые описаны в документации;
  3. При изменении периода через переключатель происходит событие periodsChanged.
    WML:
<Graphs.comparison:TreeView
  ...
  on:periodsChanged="_periodsChangedHandler()">
</Graphs.comparison:TreeView>

TS:

protected _periodsChanged(e: SyntheticEvent<MouseEvent>, periods: IPeriods): void {
   this._periods = periods;
}

Далее рассмотрим пример конфигурации контрола.

WML:

<Graphs.comparison:TreeView
   firstPeriodData="{{ _firstPeriodData }}"
   secondPeriodData="{{ _secondPeriodData }}"
   forecastData="{{ _forecastData }}"
   summaryData="{{ _summaryData }}"
   periods="{{ _periods }}"
   on:periodsChanged="_periodsChangedHandler()"
   tableConfig="{{ _tableConfig }}">
   <ws:tableContentTemplate>
      <Controls.scroll:Container>
         <Controls.list:DataContainer
            source="{{ _options.source }}"
            displayProperty="title"
            keyProperty="id">
            <Controls.operations:Controller
               bind:selectedKeys="_selectedKeys"
               bind:excludedKeys="_excludedKeys">
               <Controls.list:Container>
                  <Controls.explorer:View
                        bind:root="_root"
                        multiSelectVisibility="{{true}}"
                        keyProperty="id"
                        parentProperty="parent"
                        nodeProperty="type"
                        columns="{{ _columns }}"
                        header="{{ _options.headerTemplate }}" />
               </Controls.list:Container>
            </Controls.operations:Controller>
         </Controls.list:DataContainer>
      </Controls.scroll:Container>
   </ws:tableContentTemplate>
</Graphs.comparison:TreeView>

TS:

...
import {
   detailValueCellTemplate,
   partCellTemplate,
   percentCellTemplate
} from 'Graphs/comparison';
...
protected _columns: object[] = null;
protected _root: number | string = null;
protected _selectedKeys: number[] | string[] = [];
protected _excludedKeys: number[] | string[] = [];
 
protected _beforeMount(options: IOptions): void {
   const { columnsWidth, source }: IOptions = options;
   this._periods = {
      selectedPeriodType: 'year',
      firstPeriodStart: new Date(2015, 0 1),
      secondPeriodStart: new Date(2017, 0, 1)    
   };
   this._availablePeriodTypes = ['year', 'halfyear', 'quarter', 'month', 'day'];
   this._summaryData = {
      current: {
         first: 5473900,
         second: 89484700
      },
      total: {
         first: 8477393890088000,
         second: 12477393890088000
      }
   };
   this._firstPeriodData = [
      [0, 180],
      [31, 130],
      [59, 300],
      [90, 200],
      [120, 40],
      [151, 80],
      [181, 100]
   ];
   this._secondPeriodData = [
      [0, 60],
      [31, 200],
      [59, 300],
      [90, 150],
      [95, 100]
   ];
   this._forecastData = [
      [95, 100],
      [120, 40],
      [151, 80],
      [181, 60]
   ]
   const data = this._getData(source);
   const {
      detailValuePast,
      partValuePast,
      detailValueCurrent,
      partValueCurrent,
      percentValue
   }: IData = data;
   
   this._columns = [{
      displayProperty: 'title'
   }, {
      width: columnsWidth.second,
      template: detailValueCellTemplate,
      value: data.detailValuePast
   }, {
      width: columnsWidth.third,
      template: partCellTemplate,
      value: data.partValuePast
   }, {
      width: columnsWidth.fourth,
      template: detailValueCellTemplate,
      value: data.detailValueCurrent
   }, {
      width: columnsWidth.fifth,
      template: partCellTemplate,
      value: data.partValueCurrent
   }, {
      width: columnsWidth.sixth,
      template: percentCellTemplate,
      value: data.percentValue
   }];
}
 
protected _periodsChanged(e: SyntheticEvent<MouseEvent>, periods: IPeriods): void {
   this._periods = periods;
}
...

Дополнительные возможности контрола

Прикладной разработчик имеет возможность заполнить контентные области, которые предоставляет контрол.

Подробнее остановимся на tableContentTemplate. Опция предназначена для настройки и отображения детализированной таблицы с помощью любого из возможных табличных контролов (например, Controls/treeGrid:View, Controls/explorer:View). Такое решение было принято для упрощения взаимодействия с таблицей. В данное табличное представление проксируется объект columnsWidth с шириной для каждой колонки и шапка таблицы в headerTemplate.

Если в таблице установлено иерархическое дерево (Controls/explorer:View), хлебные крошки по умолчанию располагаются в шапке в первой колонке. За это отвечает headerTemplate.

Опцию columns для контрола с табличным представлением следует формировать в прикладном коде в TS. При конфигурации отдельной колонки обязательным требованием является:

  • Передача значения в опцию value;
  • Указании ширины в опцию width из объекта columnsWidth;
  • Указание шаблона ячейки в опцию template. Шаблон ячейки приводит данные в нужный формат и отображает, согласно стандарту.

Для отображения ячейки в колонке из библиотеки Graphs.comparison доступны шаблоны:

  • detailValueCellTemplate (вторая и четвертая колонки),
  • partCellTemplate (3 и 5 колонки).
  • percentCellTemplate (6 колонка).

Также контрол поддерживает дополнительную прикладную 7 колонку. Для корректного выравнивания инфоблока необходимо знать ширину этой колонки. Для указания ширины нужно использовать опцию lastColumnWidth.