Skip to content

Commit

Permalink
In the ExtraCalc result you can now add a custom subtitle using the v…
Browse files Browse the repository at this point in the history
…ariables.
  • Loading branch information
juliarobles committed Oct 29, 2024
1 parent 8132752 commit da14716
Show file tree
Hide file tree
Showing 5 changed files with 89 additions and 82 deletions.
96 changes: 49 additions & 47 deletions src/components/editors/extraCalcForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -215,53 +215,55 @@ export const ExtraCalcForm: React.FC<Props> = ({ extraCalc, updateFunction, dele
<br />&nbsp;&nbsp; · Text: string in single quotes
<br />&nbsp;&nbsp; · Date: string in single quotes formatted as YYYY-MM-DD
</Alert>
<InlineField label="Initial tag" labelWidth={17} grow required disabled={disabled}>
<Input {...register("tag")} value={currentCalc.tag} disabled={disabled} onChange={handleOnChangeCalc} required />
</InlineField>
<InlineField label="Calculation" labelWidth={17} required disabled={disabled}>
<InputControl
render={({ field }) =>
<Select
value={selectedCalc}
options={calcOptions}
onChange={(v) => setSelectedCalc(v)}
disabled={disabled}
defaultValue={calcOptions[0]}
/>
}
control={control}
name="calc"
/>
</InlineField>
<InlineField label="Value to consider" labelWidth={17} grow required disabled={disabled}>
<Input {...register("calcValue")} value={currentCalc.calcValue} disabled={disabled} onChange={handleOnChangeCalc} required />
</InlineField>
<InlineField label="Execute until" labelWidth={17} grow required disabled={disabled}>
<Input {...register("until")} value={currentCalc.until} disabled={disabled} onChange={handleOnChangeCalc} required />
</InlineField>
</Collapse>
<Collapse label="Result processing" collapsible={false} isOpen={true} className={css({ color: useTheme2().colors.text.primary })}>
<Alert title="Info" severity='info'>
$res = number of iterations
</Alert>
<InlineField label="Format" labelWidth={17} grow required disabled={disabled}>
<InputControl
render={({ field }) =>
<Select
value={selectedFormat}
options={formatOptions}
onChange={(v) => setSelectedFormat(v)}
disabled={disabled}
defaultValue={formatOptions[0]}
/>
}
control={control}
name="resFormat"
/>
</InlineField>
<InlineField label="Result processing" labelWidth={17} grow hidden={selectedFormat.value === ExtraCalcFormat.raw} required={selectedFormat.value === ExtraCalcFormat.process} disabled={disabled}>
<Input {...register("resProcess")} value={currentCalc.resProcess} disabled={disabled} onChange={handleOnChangeCalc} required={selectedFormat.value === ExtraCalcFormat.process} />
</InlineField>
<Collapse label="Iterations" collapsible={false} isOpen={true} className={css({ color: useTheme2().colors.text.primary })}>
<InlineField label="Initial tag" labelWidth={17} grow required disabled={disabled}>
<Input {...register("tag")} value={currentCalc.tag} disabled={disabled} onChange={handleOnChangeCalc} required />
</InlineField>
<InlineField label="Calculation" labelWidth={17} required disabled={disabled}>
<InputControl
render={({ field }) =>
<Select
value={selectedCalc}
options={calcOptions}
onChange={(v) => setSelectedCalc(v)}
disabled={disabled}
defaultValue={calcOptions[0]}
/>
}
control={control}
name="calc"
/>
</InlineField>
<InlineField label="Value to consider" labelWidth={17} grow required disabled={disabled}>
<Input {...register("calcValue")} value={currentCalc.calcValue} disabled={disabled} onChange={handleOnChangeCalc} required />
</InlineField>
<InlineField label="Execute until" labelWidth={17} grow required disabled={disabled}>
<Input {...register("until")} value={currentCalc.until} disabled={disabled} onChange={handleOnChangeCalc} required />
</InlineField>
</Collapse>
<Collapse label="Final result" collapsible={false} isOpen={true} className={css({ color: useTheme2().colors.text.primary })}>
<InlineField label="Value" labelWidth={17} grow required disabled={disabled}>
<Input {...register("resValue")} value={currentCalc.resValue} disabled={disabled} onChange={handleOnChangeCalc} required/>
</InlineField>
<InlineField label="Format" labelWidth={17} grow required disabled={disabled}>
<InputControl
render={({ field }) =>
<Select
value={selectedFormat}
options={formatOptions}
onChange={(v) => setSelectedFormat(v)}
disabled={disabled}
defaultValue={formatOptions[0]}
/>
}
control={control}
name="resFormat"
/>
</InlineField>
<InlineField label="Subtitle" labelWidth={17} grow disabled={disabled}>
<Input {...register("resSubtitle")} value={currentCalc.resSubtitle} disabled={disabled} onChange={handleOnChangeCalc} />
</InlineField>
</Collapse>
</Collapse>
</div>
)
Expand Down
10 changes: 5 additions & 5 deletions src/components/step4_PredictModel.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { Button, DatePickerWithInput, HorizontalGroup, IconButton, InlineLabel, Input, Modal, Pagination, Spinner, useTheme2, VerticalGroup } from '@grafana/ui'
import React, { Fragment, useContext, useEffect, useState } from 'react'
import { Context, dateTimeLocalToString, getMean, round, groupBy, dateToString, stringToDate } from 'utils/utils'
import { IData, IDataCollection, IModel, IntervalTypeEnum, IResult, ITag, DateRes, IDynamicField, TypeDynamicField } from 'utils/types'
import { IData, IDataCollection, IModel, IntervalTypeEnum, IResult, ITag, IDynamicField, TypeDynamicField } from 'utils/types'
import { idDefault, idNew, Steps } from 'utils/constants'
import { predictAllCollections } from 'utils/datasources/predictions'
import Plot from 'react-plotly.js'
Expand Down Expand Up @@ -328,12 +328,12 @@ export const PredictModel: React.FC<Props> = ({ model, collections, updateCollec
if (col.conclusionExtraCalc !== undefined) {
return <div className='horizontal-item-1' style={{ backgroundColor: theme.colors.background.secondary, padding: '10px', width: '100%' }}>
<p style={{ color: theme.colors.text.secondary, paddingBottom: '0px', marginBottom: '2px' }}>{msgs.resultCalc}</p>
{(col.conclusionExtraCalc instanceof DateRes) ?
{(col.conclusionExtraCalc.subtitle !== undefined && col.conclusionExtraCalc.subtitle.trim() !== '') ?
<div>
<h3 style={{ textAlign: 'center', marginBottom: '0px' }}>{col.conclusionExtraCalc.dateString}</h3>
<p style={{ textAlign: 'center', marginTop: '5px' }}>Remaining days: {col.conclusionExtraCalc.days}</p>
<h3 style={{ textAlign: 'center', marginBottom: '0px' }}>{col.conclusionExtraCalc.title}</h3>
<p style={{ textAlign: 'center', marginTop: '5px' }}>{col.conclusionExtraCalc.subtitle}</p>
</div>
: <h1 style={{ textAlign: 'center' }}>{col.conclusionExtraCalc}</h1>
: <h1 style={{ textAlign: 'center' }}>{col.conclusionExtraCalc.title}</h1>
}
</div>
}
Expand Down
39 changes: 21 additions & 18 deletions src/utils/datasources/extraCalc.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import { Calc, DateRes, ExtraCalcFormat, IDataCollection, IDataPred, IModel, IResult, ITag, PostChangeIDataPred, TypeDynamicField, WhenApplyEnum } from "utils/types"
import { Calc, ConclusionRes, ExtraCalcFormat, IDataCollection, IDataPred, IModel, IResult, ITag, PostChangeIDataPred, TypeDynamicField, WhenApplyEnum } from "utils/types"
import { getListValuesFromNew, newDataToObject, predictResults, prepareAndPredictResults, prepareToPredict } from "./predictions"
import vm from 'vm'
import { dateToString, deepCopy, getMean } from "utils/utils"
import { dateTime, DateTime } from "@grafana/data"

const replaceVariables = (model: IModel, col: IDataCollection, text: string, data: IDataPred, dyn?: string[], lastResult?: number, iter?: number) => {
const replaceVariables = (model: IModel, col: IDataCollection, text: string, data: IDataPred, dyn?: string[], lastResult?: number|string, iter?: number) => {
// $out
if (lastResult !== undefined) text = text.replace(/\$out/g, lastResult.toString())

Expand Down Expand Up @@ -68,19 +68,15 @@ const applyCalcValue = (first: number, second: number, calc: Calc): number => {
}
}

const applyFormatToRes = (res: number, format: ExtraCalcFormat, selectedDate?: DateTime, process?: string): string|DateRes => {
if (format !== ExtraCalcFormat.raw) {
if (process) {
const code = process.replace(/\$res/g, res.toString())
res = executeString(code) as number
}
if (format === ExtraCalcFormat.addDays && selectedDate) {
let copyDate = dateTime(selectedDate)
let dateString = copyDate.add(res, 'days').toDate().toLocaleDateString('en-EN', { year: 'numeric', month: 'long', day: 'numeric' })
return new DateRes(dateString, res)
}
const applyFormatToRes = (res: string, format: ExtraCalcFormat, selectedDate?: DateTime): string => {
if (format === ExtraCalcFormat.addDays && selectedDate) {
console.log('res', res)
const num = Number(res)
console.log('num', num)
let copyDate = dateTime(selectedDate)
return copyDate.add(num, 'days').toDate().toLocaleDateString('en-EN', { year: 'numeric', month: 'long', day: 'numeric' })
}
return res.toString()
return res
}

const createRequests = (iniRes: IResult, num: number, calcValue: number, data: IDataPred, tag: string, calc: Calc, idNumber: number, isProcessed = false): PostChangeIDataPred => {
Expand Down Expand Up @@ -111,7 +107,7 @@ const createRequests = (iniRes: IResult, num: number, calcValue: number, data: I
}

const check = (r: IResult, model: IModel, col: IDataCollection, isAfter: boolean, dyn?: string[], iter?: number) => {
if(r.result && model.extraCalc && typeof r.result === 'number') {
if(r.result && model.extraCalc) {
let condition = ""
if(isAfter && r.processedData) {
condition = replaceVariables(model, col, model.extraCalc.until, r.processedData, dyn, r.result, iter)
Expand Down Expand Up @@ -172,11 +168,18 @@ export const extraCalcCollection = async (model: IModel, col: IDataCollection, d
}

res = [...res, ...results.slice(0, idxFin)]

if(res.length === 0) res = [results[0]]
col.resultsExtraCalc = res
col.conclusionExtraCalc = applyFormatToRes(res.length-1, model.extraCalc.resFormat, col.dateTime, model.extraCalc.resProcess)

const finalResult = res[res.length-1]
console.log("finalResult", finalResult)
const finalDataPred = (isAfter && finalResult.processedData && finalResult.result) ? finalResult.processedData : finalResult.data
let processedRes = executeString(replaceVariables(model, col, model.extraCalc.resValue, finalDataPred, dyn, finalResult.result, res.length-1))
processedRes = applyFormatToRes(processedRes, model.extraCalc.resFormat, col.dateTime)
let subtitleRes = (model.extraCalc.resSubtitle) ? executeString(replaceVariables(model, col, model.extraCalc.resSubtitle, finalDataPred, dyn, finalResult.result, res.length-1)) : ''
col.conclusionExtraCalc = new ConclusionRes(processedRes, subtitleRes)
} else {
col.conclusionExtraCalc = "ERROR"
col.conclusionExtraCalc = new ConclusionRes("ERROR","")
}
console.log("Result col extra calc", col)
return col
Expand Down
5 changes: 3 additions & 2 deletions src/utils/default.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,12 @@ export const ExtraCalcDefault: IExtraCalc = {
calc: Calc.sum,
calcValue: "",
until: "",
resProcess: "$res",
resValue: "$res",
maxIterations: 1000,
resFormat: ExtraCalcFormat.raw,
numRequests: 10,
whenApply: WhenApplyEnum.afterPreprocess
whenApply: WhenApplyEnum.afterPreprocess,
resSubtitle: ''
}

export const ModelDefault: IModel = {
Expand Down
21 changes: 11 additions & 10 deletions src/utils/types.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ export enum Calc {

export enum ExtraCalcFormat {
raw = "Raw",
process = "Number processed",
addDays = "Add as days to selected date"
}

Expand Down Expand Up @@ -87,7 +86,7 @@ export interface IDataCollection {
results?: IResult[]
extraInfo?: { [key: string]: any },
resultsExtraCalc?: IResult[],
conclusionExtraCalc?: string|DateRes
conclusionExtraCalc?: ConclusionRes
}

export interface IData {
Expand Down Expand Up @@ -165,26 +164,28 @@ export interface IExtraCalc {
calc: Calc,
calcValue: string,
until: string,
resProcess: string,
resValue: string,
maxIterations: number,
resFormat: ExtraCalcFormat,
numRequests: number,
whenApply: WhenApplyEnum
whenApply: WhenApplyEnum,
resSubtitle?: string
}

export interface PostChangeIDataPred {
newData: IDataPred[],
newResults: IResult[]
}

export class DateRes {
dateString: string;
days: number;
export class ConclusionRes {
title: string;
subtitle?: string;

constructor(dateString: string, days: number) {
this.dateString = dateString
this.days = days
constructor(title: string, subtitle: string) {
this.title = title
this.subtitle = subtitle
}

}

export interface IScaler {
Expand Down

0 comments on commit da14716

Please sign in to comment.