frequi_origin/src/components/charts/PlotConfigurator.vue

330 lines
9.1 KiB
Vue
Raw Normal View History

<template>
2020-07-01 18:22:29 +00:00
<div v-if="columns">
2021-06-23 04:56:38 +00:00
<b-form-group label="Plot config name" label-for="idPlotConfigName">
<b-form-input id="idPlotConfigName" v-model="plotConfigNameLoc" size="sm"> </b-form-input>
2021-06-23 04:56:38 +00:00
</b-form-group>
<div class="col-mb-3">
2020-08-01 18:43:14 +00:00
<hr />
2021-06-23 04:56:38 +00:00
<b-form-group label="Target" label-for="FieldSel">
<b-form-select id="FieldSel" v-model="selSubPlot" :options="subplots" :select-size="3">
2020-07-01 18:22:29 +00:00
</b-form-select>
</b-form-group>
</div>
2021-06-23 04:56:38 +00:00
<b-form-group label="Add new plot" label-for="newSubPlot">
2020-08-01 18:43:14 +00:00
<b-input-group size="sm">
2021-06-23 04:56:38 +00:00
<b-form-input id="newSubPlot" v-model="newSubplotName" class="addPlot"></b-form-input>
2020-07-01 18:39:03 +00:00
<b-input-group-append>
2021-11-03 05:51:38 +00:00
<b-button :disabled="!newSubplotName" @click="addSubplot">+</b-button>
2021-06-23 04:56:38 +00:00
<b-button v-if="selSubPlot && selSubPlot != 'main_plot'" @click="delSubplot">-</b-button>
2020-07-01 18:39:03 +00:00
</b-input-group-append>
</b-input-group>
2020-07-01 18:22:29 +00:00
</b-form-group>
2020-07-01 18:39:03 +00:00
<hr />
2021-06-24 05:18:06 +00:00
<div>
<b-form-group label="Used indicators" label-for="selectedIndicators">
2020-08-09 08:50:02 +00:00
<b-form-select
id="selectedIndicators"
v-model="selIndicatorName"
2020-08-09 08:50:02 +00:00
:options="usedColumns"
:select-size="4"
>
</b-form-select>
</b-form-group>
</div>
<div>
<b-button
variant="primary"
title="Add indicator to plot"
2021-06-23 04:45:18 +00:00
size="sm"
2021-11-01 18:53:06 +00:00
:disabled="addNewIndicator"
@click="addNewIndicator = !addNewIndicator"
2021-06-23 04:45:18 +00:00
>
Add new indicator
</b-button>
<b-button
2022-11-01 12:19:13 +00:00
variant="secondary"
title="Remove indicator to plot"
size="sm"
:disabled="!selIndicatorName"
class="ms-1"
@click="removeIndicator"
>
Remove indicator
</b-button>
</div>
2020-07-01 18:22:29 +00:00
<PlotIndicator
2021-11-01 18:53:06 +00:00
v-if="selIndicatorName || addNewIndicator"
v-model="selIndicator"
class="mt-1"
:columns="columns"
:add-new="addNewIndicator"
/>
2020-07-01 18:39:03 +00:00
<hr />
2021-06-23 04:56:38 +00:00
2021-06-24 05:18:06 +00:00
<div>
<b-button class="ms-1" variant="secondary" size="sm" @click="loadPlotConfig">Load</b-button>
<b-button
:disabled="botStore.activeBot.isWebserverMode || !botStore.activeBot.isBotOnline"
class="ms-1"
variant="secondary"
size="sm"
@click="loadPlotConfigFromStrategy"
>
2021-06-23 18:51:27 +00:00
From strategy
</b-button>
<b-button
class="ms-1"
2022-11-01 12:19:13 +00:00
variant="secondary"
size="sm"
title="Load configuration from text box below"
@click="resetConfig"
>Reset</b-button
>
2021-06-22 19:08:03 +00:00
<b-button
id="showButton"
class="ms-1"
2022-11-01 12:19:13 +00:00
variant="secondary"
2021-06-22 19:08:03 +00:00
size="sm"
title="Show configuration for easy transfer to a strategy"
@click="showConfig = !showConfig"
>Show</b-button
2021-06-22 19:08:03 +00:00
>
<b-button
2020-08-08 13:57:36 +00:00
v-if="showConfig"
class="ms-1"
2022-11-01 12:19:13 +00:00
variant="secondary"
size="sm"
title="Load configuration from text box below"
2020-08-08 13:57:36 +00:00
@click="loadConfigFromString"
>Load from String</b-button
>
2022-11-01 12:19:13 +00:00
<b-button
class="ms-1"
2022-11-01 12:19:13 +00:00
variant="primary"
size="sm"
data-toggle="tooltip"
title="Save configuration"
@click="savePlotConfig"
>Save</b-button
>
</div>
<div v-if="showConfig" class="col-mb-5 ms-1 mt-2">
<b-form-textarea
id="TextArea"
v-model="plotConfigJson"
2020-08-08 13:57:36 +00:00
class="textArea"
size="sm"
:state="tempPlotConfigValid"
>
</b-form-textarea>
2020-07-01 18:22:29 +00:00
</div>
</div>
</template>
2022-12-13 05:19:25 +00:00
<script setup lang="ts">
import { PlotConfig, EMPTY_PLOTCONFIG, IndicatorConfig } from '@/types';
2020-08-08 13:57:36 +00:00
import { getCustomPlotConfig } from '@/shared/storage';
import PlotIndicator from '@/components/charts/PlotIndicator.vue';
2022-04-15 16:08:41 +00:00
import { showAlert } from '@/stores/alerts';
2022-12-13 05:19:25 +00:00
import { computed, ref, onMounted } from 'vue';
2022-04-19 04:53:35 +00:00
import { useBotStore } from '@/stores/ftbotwrapper';
2022-11-01 13:10:59 +00:00
import { usePlotConfigStore } from '@/stores/plotConfig';
2022-12-13 05:19:25 +00:00
defineProps({
columns: { required: true, type: Array as () => string[] },
asModal: { required: false, default: true, type: Boolean },
});
2022-04-19 04:53:35 +00:00
2022-12-13 05:19:25 +00:00
const plotStore = usePlotConfigStore();
const botStore = useBotStore();
2022-04-17 07:57:39 +00:00
2022-12-13 05:19:25 +00:00
const plotConfig = ref<PlotConfig>(EMPTY_PLOTCONFIG);
2022-04-17 07:57:39 +00:00
2022-12-13 05:19:25 +00:00
const plotConfigNameLoc = ref('default');
const newSubplotName = ref('');
const selIndicatorName = ref('');
const addNewIndicator = ref(false);
const showConfig = ref(false);
const selSubPlot = ref('main_plot');
const tempPlotConfig = ref<PlotConfig>();
const tempPlotConfigValid = ref(true);
2022-04-17 07:57:39 +00:00
2022-12-13 05:19:25 +00:00
const isMainPlot = computed(() => {
return selSubPlot.value === 'main_plot';
});
2022-04-17 07:57:39 +00:00
2022-12-13 05:19:25 +00:00
const currentPlotConfig = computed(() => {
if (isMainPlot.value) {
return plotConfig.value.main_plot;
}
2022-04-17 07:57:39 +00:00
2022-12-13 05:19:25 +00:00
return plotConfig.value.subplots[selSubPlot.value];
});
const subplots = computed((): string[] => {
// Subplot keys (for selection window)
return ['main_plot', ...Object.keys(plotConfig.value.subplots)];
});
const usedColumns = computed((): string[] => {
if (isMainPlot.value) {
return Object.keys(plotConfig.value.main_plot);
}
if (selSubPlot.value in plotConfig.value.subplots) {
return Object.keys(plotConfig.value.subplots[selSubPlot.value]);
}
return [];
});
2022-04-17 07:57:39 +00:00
2022-12-13 05:19:25 +00:00
const addIndicator = (newIndicator: Record<string, IndicatorConfig>) => {
console.log(plotConfig.value);
2022-04-17 07:57:39 +00:00
2022-12-13 05:19:25 +00:00
// const { plotConfig.value } = this;
const name = Object.keys(newIndicator)[0];
const indicator = newIndicator[name];
if (isMainPlot.value) {
console.log(`Adding ${name} to MainPlot`);
plotConfig.value.main_plot[name] = { ...indicator };
} else {
console.log(`Adding ${name} to ${selSubPlot.value}`);
plotConfig.value.subplots[selSubPlot.value][name] = { ...indicator };
}
2022-12-13 05:19:25 +00:00
plotConfig.value = { ...plotConfig.value };
// Reset random color
addNewIndicator.value = false;
plotStore.setPlotConfig(plotConfig.value);
};
2022-04-17 07:57:39 +00:00
2022-12-13 05:19:25 +00:00
const selIndicator = computed({
get() {
if (addNewIndicator.value) {
return {};
}
if (selIndicatorName.value) {
return {
[selIndicatorName.value]: currentPlotConfig.value[selIndicatorName.value],
};
}
return {};
},
set(newValue: Record<string, IndicatorConfig>) {
// console.log('newValue', newValue);
const name = Object.keys(newValue)[0];
// this.currentPlotConfig[this.selIndicatorName] = { ...newValue[name] };
// this.emitPlotConfig();
if (name && newValue) {
addIndicator(newValue);
} else {
addNewIndicator.value = false;
}
},
});
2022-04-17 07:57:39 +00:00
2022-12-13 05:19:25 +00:00
const plotConfigJson = computed({
get() {
return JSON.stringify(plotConfig.value, null, 2);
},
set(newValue: string) {
try {
tempPlotConfig.value = JSON.parse(newValue);
// TODO: Should Validate schema validity (should be PlotConfig type...)
tempPlotConfigValid.value = true;
} catch (err) {
tempPlotConfigValid.value = false;
}
},
});
2022-04-17 07:57:39 +00:00
2022-12-13 05:19:25 +00:00
const removeIndicator = () => {
console.log(plotConfig.value);
// const { plotConfig } = this;
if (isMainPlot.value) {
console.log(`Removing ${selIndicatorName.value} from MainPlot`);
delete plotConfig.value.main_plot[selIndicatorName.value];
} else {
console.log(`Removing ${selIndicatorName.value} from ${selSubPlot.value}`);
delete plotConfig.value.subplots[selSubPlot.value][selIndicatorName.value];
}
2022-12-13 05:19:25 +00:00
plotConfig.value = { ...plotConfig.value };
console.log(plotConfig.value);
selIndicatorName.value = '';
plotStore.setPlotConfig(plotConfig.value);
};
const addSubplot = () => {
plotConfig.value.subplots = {
...plotConfig.value.subplots,
[newSubplotName.value]: {},
};
selSubPlot.value = newSubplotName.value;
newSubplotName.value = '';
2021-06-23 04:56:38 +00:00
2022-12-13 05:19:25 +00:00
plotStore.setPlotConfig(plotConfig.value);
};
2022-12-13 05:19:25 +00:00
const delSubplot = () => {
delete plotConfig.value.subplots[selSubPlot.value];
plotConfig.value.subplots = { ...plotConfig.value.subplots };
selSubPlot.value = '';
plotStore.setPlotConfig(plotConfig.value);
};
const loadPlotConfig = () => {
plotConfig.value = getCustomPlotConfig(plotConfigNameLoc.value);
console.log(plotConfig.value);
console.log('loading config');
plotStore.setPlotConfig(plotConfig.value);
};
2022-12-13 05:19:25 +00:00
const loadConfigFromString = () => {
// this.plotConfig = JSON.parse();
if (tempPlotConfig.value !== undefined && tempPlotConfigValid.value) {
plotConfig.value = tempPlotConfig.value;
plotStore.setPlotConfig(plotConfig.value);
}
};
const resetConfig = () => {
plotConfig.value = { ...EMPTY_PLOTCONFIG };
};
const loadPlotConfigFromStrategy = async () => {
try {
await botStore.activeBot.getStrategyPlotConfig();
if (botStore.activeBot.strategyPlotConfig) {
plotConfig.value = botStore.activeBot.strategyPlotConfig;
plotStore.setPlotConfig(plotConfig.value);
}
} catch (data) {
//
showAlert('Failed to load Plot configuration from Strategy.');
}
};
2021-06-22 19:08:03 +00:00
2022-12-13 05:19:25 +00:00
const savePlotConfig = () => {
plotStore.saveCustomPlotConfig({ [plotConfigNameLoc.value]: plotConfig.value });
};
2022-04-17 07:57:39 +00:00
2022-12-13 05:19:25 +00:00
onMounted(() => {
// console.log('Config Mounted', props.value);
plotConfig.value = plotStore.plotConfig;
plotConfigNameLoc.value = plotStore.plotConfigName;
2022-04-17 07:57:39 +00:00
});
</script>
2020-07-01 18:22:29 +00:00
<style scoped>
.textArea {
min-height: 250px;
}
2020-08-01 18:43:14 +00:00
.form-group {
margin-bottom: 0.5rem;
}
2022-04-17 07:57:39 +00:00
2020-08-01 18:43:14 +00:00
hr {
margin-bottom: 0.5rem;
margin-top: 0.5rem;
}
</style>