import { COMPONENT_MODE_EMPTY, COMPONENT_MODE_ERROR, COMPONENT_MODE_INITIAL, COMPONENT_MODE_LOADING, COMPONENT_MODE_OK, ComponentModeWindow, MmuiCommonComponent, MmuiProps, MmuiState, } from './common'; import * as React from 'react'; import vegaEmbed from 'vega-embed'; export interface MmuiChartVegaProps extends MmuiProps { chartId: string; // html element selector of the chart container chartSpec: any; // chart configuration, including selector, xScale, yScale, axis config, etc, could be different for each type of chart chartEmbedOpts: any; payload?: any; // received from the server, includes data, whether data hasError, isInvalidated, etc reportIssueUrl?: string; // url link to report issue when something goes wrong } export class MmuiChartVegaComponent< P extends MmuiChartVegaProps, S extends MmuiState > extends MmuiCommonComponent
{ getChartSpec(fromStore = false) { let chartSpec = this.props.chartSpec; if (fromStore || this.useStore) { chartSpec = this.props.store.component[this.name]?.chartSpec; } return chartSpec; } getChartEmbedOpts(fromStore = false) { let chartEmbedOpts = this.props.chartEmbedOpts; if (fromStore || this.useStore) { chartEmbedOpts = this.props.store.component[this.name]?.chartEmbedOpts; } return chartEmbedOpts; } buildChart(dataArray) { const chartSpec = this.getChartSpec(), chartEmbedOpts = this.getChartEmbedOpts(); chartSpec.data.values = dataArray; vegaEmbed(`#${this.props.chartId}`, chartSpec, chartEmbedOpts); } /** * Extract the dataArray portion of the payload received from the server. * @param payload */ extractDataArray(payload) { let dataArray = []; if (payload && payload.data) { dataArray = payload.data; } return dataArray; } /** * Get Component mode based on data payload */ getComponentMode(payload) { let mode = COMPONENT_MODE_INITIAL, dataArray, hasData = false; if (payload) { if (payload.hasError) { mode = COMPONENT_MODE_ERROR; } else if (payload.isInvalidated) { mode = COMPONENT_MODE_LOADING; } else { dataArray = this.extractDataArray(payload); hasData = dataArray.length > 0; if (hasData) { mode = COMPONENT_MODE_OK; } else { mode = COMPONENT_MODE_EMPTY; } } } return mode; } componentDidMount() { const payload = this.getPayloadData(); const a_la_mode = this.getComponentMode(payload); if (a_la_mode == COMPONENT_MODE_OK) { const dataArray = this.extractDataArray(payload); this.buildChart(dataArray); } } /** * On update to Component props or state */ componentDidUpdate() { const payload = this.getPayloadData(); const a_la_mode = this.getComponentMode(payload); if (a_la_mode == COMPONENT_MODE_OK) { const dataArray = this.extractDataArray(payload); this.buildChart(dataArray); } } /** * Render the Chart Component */ render() { const payload = this.getPayloadData(); const a_la_mode = this.getComponentMode(payload); let chartContent = null; if (a_la_mode == COMPONENT_MODE_OK) { chartContent = (