Вычислители
Вычислители позволяют запрашивать данные с сервера. Вычислитель получает определенные входные данные, которые включают в себя разрезы, меры, фильтры, сортировки, переменные и другие данные. Затем эти данные обрабатываются внутри вычислителя в соответствии с его логикой, которая может включать в себя агрегацию, фильтрацию, преобразование данных и другие операции. После обработки входных данных вычислитель возвращает результат, который может быть использован для визуализации данных.
В системе существуют следующие вычислители:
- GeneralCalculator — общий вычислитель с одним лимитом. В большинстве случаев нужно выбирать именно этот вычислитель для работы с данными
- PieCalculator — вычислитель для круговых диаграмм с одним разрезом
- ProcessGraphCalculator — предназначен для обработки данных, используемых для создания карт процесса
- TwoLimitsCalculator — вычислитель с двумя лимитами
- TypeCalculator — вычислитель типа
- HistogramCalculator — вычислитель для гистограммы
Для взаимодействия с вычислителями в свойства виджета передается фабрика вычислителей (свойство calculatorFactory
), которая предоставляет удобный интерфейс для создания и получения экземпляров различных типов вычислителей, необходимых для обработки данных и получения результатов. Это позволяет виджету динамически выбирать и использовать подходящий вычислитель в зависимости от его потребностей и типа данных, с которыми он работает.
Так как GeneralCalculator используется чаще всего, то разберем на примере взаимодействие с ним. Результат будем визуализировать, используя библиотеку ReactJS. Подробнее о всех параметрах, которые принимает метод calculate
вычислителя, можно узнать из интерфейса IGeneralCalculatorInput
в библиотеке @infomaximum/widget-sdk, а информацию о данных, которые возвращает вычислитель — из интерфейса IGeneralCalculatorOutput.
import {
mapMeasuresToInputs,
type ICustomWidgetProps,
mapDimensionsToInputs,
replaceHierarchiesWithDimensions,
type IGeneralCalculatorOutput,
} from "@infomaximum/widget-sdk";
import type { WidgetSettings } from "definition/definition";
import { useState, type FC, useMemo, useEffect } from "react";
export const App: FC<ICustomWidgetProps<WidgetSettings>> = ({
calculatorFactory,
settings,
widgetsContext,
filtration,
placeholder,
}) => {
const { measures, dimensions } = settings;
const filters = filtration.preparedFilterValues;
const [calculatorOutput, setCalculatorOutput] =
useState<IGeneralCalculatorOutput | null>(null);
const generalCalculator = useMemo(
() => calculatorFactory.general(),
[calculatorFactory]
);
useEffect(() => {
if (!measures?.length || !dimensions?.length) {
placeholder.setConfigured(false);
return;
}
(async () => {
try {
const output = await generalCalculator.calculate({
filters,
measures: mapMeasuresToInputs(measures, widgetsContext.variables),
dimensions: mapDimensionsToInputs(
replaceHierarchiesWithDimensions(dimensions, filters),
widgetsContext.variables
),
});
setCalculatorOutput(output);
} catch (error) {
placeholder.setError(error as Error);
}
})();
}, [
dimensions,
filters,
generalCalculator,
measures,
placeholder,
widgetsContext.variables,
]);
console.log(calculatorOutput)
return <div>Hello GeneralCalculator</div>;
};
import {
EControlType,
EWidgetIndicatorType,
type IBaseWidgetSettings,
type IDefinition,
type IGroupSettings,
type IPanelDescription,
type IWidgetDimension,
type IWidgetDimensionHierarchy,
type IWidgetMeasure,
type IWidgetsContext,
} from "@infomaximum/widget-sdk";
export interface WidgetSettings extends IBaseWidgetSettings {
dimensions: (IWidgetDimension | IWidgetDimensionHierarchy)[];
measures: IWidgetMeasure[];
}
export class Definition implements IDefinition<WidgetSettings, IGroupSettings> {
public createPanelDescription(
context: IWidgetsContext,
settings: WidgetSettings
): IPanelDescription<WidgetSettings> {
return {
dataRecords: [],
groupSetDescriptions: {
dimensions: {
accessor: "dimensions",
title: "Разрезы",
maxCount: Infinity,
addButtons: [
{
title: "Добавить разрез",
indicatorType: EWidgetIndicatorType.DIMENSION,
},
],
},
measures: {
accessor: "measures",
title: "Меры",
maxCount: Infinity,
addButtons: [
{
title: "Добавить меру",
indicatorType: EWidgetIndicatorType.MEASURE,
},
],
},
},
};
}
public fillSettings(
settings: Partial<WidgetSettings>,
context: IWidgetsContext
) {
settings.dimensions ??= [];
settings.measures ??= [];
}
}
В данном примере компонент App представляет собой функциональный компонент React, который используется в качестве пользовательского виджета. В данном компоненте происходит взаимодействие с вычислителем для получения данных и их обработки. Данный пример по шагам:
- Компонент импортирует различные функции и типы из библиотеки @infomaximum/widget-sdk, которые помогают разрабатывать виджет.
- Используется хук
useState
для создания состоянияcalculatorOutput
, в котором будет храниться результат работы вычислителя. - Хук
useEffect
используется для выполнения асинхронной операции получения данных с сервера при изменении зависимостей, таких какdimensions
,filters
,generalCalculator
,measures
и другие. - Создается экземпляр вычислителя (
GeneralCalculator
) с помощью фабрики вычислителей, которая предоставляется в свойствах компонента. - Внутри блока
useEffect
вызывается методcalculate
экземпляраGeneralCalculator
, который принимает входные данные, такие как фильтры (filters
), разрезы (dimensions
) и меры (measures
). Эти данные подготавливаются с помощью функцийmapMeasuresToInputs
иmapDimensionsToInputs
. - После успешного выполнения запроса полученный результат сохраняется в состоянии
calculatorOutput
с помощью функцииsetCalculatorOutput
. - Результат работы вычислителя отображается внутри компонента в виде JSON-строки с помощью функции
JSON.stringify
.
Таким образом, этот компонент взаимодействует с вычислителем для получения данных с сервера и их дальнейшей обработки, что позволяет отображать визуализацию данных в пользовательском интерфейсе.
Также c примером работы общего вычислителя и построением линейного графика можно ознакомиться в репозитории на github.
Была ли статья полезна?