import loglevel from 'loglevel' import { ComponentModel } from './cykLang' import { onUnmounted, Ref, ref } from 'vue' import { componentModelParameter, NamedComponent } from './cykReact' import { ObjectData, PrimitiveData, Variables } from '@cyklang/core' import { AlertException } from './cykRun' const logger = loglevel.getLogger('Chart') logger.setLevel('debug') const parseOptions = (optionsObject: ObjectData): { labels: string[], datasets: { label: string, data: number[] }[] } => { const labels: string[] = ['T1', 'Q2', 'Q3', 'Q4']; const datasets: { label: string, data: number[] }[] = [ { label: 'Commercial A', data: [45000, 48000, 52000, 49000] }, { label: 'Commercial B', data: [38000, 42000, 45000, 47000] }, { label: 'Commercial C', data: [52000, 55000, 58000, 61000] } ] return { labels, datasets } } const delay = (ms: number) => new Promise(res => setTimeout(res, ms)); export function useCykChart(props: { componentArg: ComponentModel | undefined }) { const isLoading = ref(true) const visible = componentModelParameter(props.componentArg, "visible", true) const optionsObject = props.componentArg?.model?.data as ObjectData; const refType = ref('bar') const refLabels: Ref = ref(null) const refDatasets: Ref<{ label: string, data: number[] }[] | null> = ref(null) const runQuery = async () => { try { if (!props.componentArg?.model?.data) throw `missing chart_model` if (!props.componentArg.model.data.type.isObject()) throw `chart_model is not an object`; const functionData = (props.componentArg.model.data as ObjectData).variables.getFunction('query') if (!functionData) throw `query is not defined` if (!props.componentArg.objectData) throw `props.componentArg.objectData undefined` const params = new Variables() const data = await functionData.callFunction(params, props.componentArg.objectData.scope) if (!data?.type.isObject()) throw `query should return an object` const objData = data as ObjectData refType.value = objData.variables.getString('type') || 'bar' const labels: string[] = []; const p_labels = objData.variables.getVariable('labels') if (!p_labels?.data?.type.isObject()) throw `labels object option is missing` const objLabels = p_labels.data as ObjectData for (let ind = 0; ind < objLabels.variables.length(); ind++) { const namedVariable = objLabels.variables.at(ind) if (namedVariable !== undefined) { const { variable } = namedVariable labels.push(variable.getString()) } } const datasets: { label: string, data: number[] }[] = [] const p_datasets = objData.variables.getVariable('datasets') if (!p_datasets?.data?.type.isObject()) throw `datasets object option is missing` const objDatasets = p_datasets.data as ObjectData for (let indi = 0; indi < objDatasets.variables.length(); indi++) { const namedVariable = objDatasets.variables.at(indi) if (namedVariable === undefined) continue const { variable } = namedVariable if (! variable.data?.type.isObject()) throw `datasets should contain objects` const objData = variable.data as ObjectData const dataset: { label: string, data: number[] } = { label: '', data: []} dataset.label = objData.variables.getString('label') || '' const varData = objData.variables.getVariable('data') if (!varData?.data?.type.isObject()) throw `dataset data should be an object` const dataObject = varData.data as ObjectData for (let indj = 0; indj < dataObject.variables.length(); indj++) { const namedVariable = dataObject.variables.at(indj) if (namedVariable === undefined) continue const { variable: varNumber } = namedVariable if (! varNumber.data?.type.isPrimitive()) throw `data should contain only numbers` dataset.data.push(Number((varNumber.data as PrimitiveData).value)) } datasets.push(dataset) } // const datasets: { label: string, data: number[] }[] = [ // { label: 'Commercial A', data: [45000, 48000, 52000, 49000] }, // { label: 'Commercial B', data: [38000, 42000, 45000, 47000] }, // { label: 'Commercial C', data: [52000, 55000, 58000, 61000] } // ] refLabels.value = labels refDatasets.value = datasets isLoading.value = false; } catch (err) { AlertException(err) } } runQuery(); const reload = () => { if (isLoading.value) return isLoading.value = true; runQuery(); }; // ready to accept reload event let namedComponent: NamedComponent; if (props.componentArg?.objectData?.tag.attributes.NAME !== undefined) { namedComponent = new NamedComponent( props.componentArg?.objectData.tag.attributes.NAME, (event: string) => { if (event === 'reload') { reload(); } else { throw Error( 'TableView ' + props.componentArg?.objectData?.tag.attributes.NAME + ' has no event named ' + event ); } } ); try { props.componentArg.variableReact?.addNamedComponent(namedComponent); } catch (err) { AlertException(err) } } onUnmounted(() => { if ( props.componentArg?.variableReact !== undefined && namedComponent !== undefined ) { props.componentArg.variableReact.removeNamedComponent(namedComponent); } props.componentArg?.objectData?.destroy() }); return { isLoading, visible, refType, refLabels, refDatasets } }