+
- Run #{{ index + 1 }}
+ {{ run.isLiveRun ? 'Live run' : `Run #${index}` }}
-
-
@@ -189,19 +155,20 @@
:icon="run.visible ? 'pi pi-eye' : 'pi pi-eye-slash'"
:severity="run.visible ? 'info' : 'secondary'"
text size="small"
- :title="(run.visible ? 'Hide' : 'Show') + ' run'"
+ :title="`${run.visible ? 'Hide' : 'Show'} ${run.isLiveRun ? 'live run' : 'run'}`"
@click="onToggleRun(index)"
/>
-
+
+
There are no (additional) runs.
Click "Add run" to add one.
@@ -250,6 +217,7 @@ interface ISimulationRun {
data: IGraphPanelData[];
color: string;
tooltip: string;
+ isLiveRun: boolean;
}
const props = defineProps<{
@@ -411,14 +379,20 @@ const interactiveShowInput = vue.ref
(
interactiveModeAvailable.value ? props.uiJson.input.map((input: locApi.IUiJsonInput) => input.visible ?? 'true') : []
);
const interactiveIdToInfo: Record = {};
-const interactiveRuns = vue.ref([]);
-const interactiveLiveRunColor = vue.ref(DefaultGraphPanelWidgetColor);
-const interactiveLiveRunVisible = vue.ref(true);
-const interactiveLiveRunColorPopover = vue.ref();
+const interactiveRuns = vue.ref([
+ {
+ inputParameters: {},
+ visible: true,
+ data: [],
+ color: DefaultGraphPanelWidgetColor,
+ tooltip: '',
+ isLiveRun: true
+ }
+]);
const interactiveRunColorPopoverIndex = vue.ref(-1);
-const interactiveRunPopoverRefs = vue.ref>({});
+const interactiveRunColorPopoverRefs = vue.ref>({});
const interactiveCompData = vue.computed(() => {
- // Combine the live data with the data from the visible runs.
+ // Combine the live data with the data from the additional runs.
const res: IGraphPanelData[] = [];
@@ -427,36 +401,31 @@ const interactiveCompData = vue.computed(() => {
interactiveDataIndex < (interactiveData.value.length || 0);
++interactiveDataIndex
) {
- const traces: IGraphPanelPlotTrace[] = interactiveLiveRunVisible.value
- ? (interactiveData.value[interactiveDataIndex]?.traces ?? []).map((trace, traceIndex) => {
- return {
- ...trace,
- name: trace.name + (interactiveRuns.value.length ? ` [Live]` : ''),
- color:
- GraphPanelWidgetPalette[
- (GraphPanelWidgetPalette.indexOf(interactiveLiveRunColor.value) + traceIndex) %
- GraphPanelWidgetPalette.length
- ] ?? DefaultGraphPanelWidgetColor,
- zorder: 1
- };
- })
- : [];
+ const traces: IGraphPanelPlotTrace[] = [];
interactiveRuns.value.forEach((interactiveRun: ISimulationRun, runIndex: number) => {
- if (interactiveRun.visible) {
- const runTraces = (interactiveRun.data[interactiveDataIndex]?.traces ?? []).map((trace, traceIndex) => {
- return {
- ...trace,
- name: trace.name + (interactiveRuns.value.length ? ` [#${runIndex + 1}]` : ''),
- color:
- GraphPanelWidgetPalette[
- (GraphPanelWidgetPalette.indexOf(interactiveRun.color) + traceIndex) % GraphPanelWidgetPalette.length
- ] ?? DefaultGraphPanelWidgetColor
- };
- });
-
- traces.push(...runTraces);
+ if (!interactiveRun.visible) {
+ return;
}
+
+ const data = interactiveRun.isLiveRun
+ ? interactiveData.value[interactiveDataIndex]
+ : interactiveRun.data[interactiveDataIndex];
+ const runTraces = (data?.traces ?? []).map((trace, traceIndex) => {
+ return {
+ ...trace,
+ name:
+ trace.name +
+ (interactiveRuns.value.length === 1 ? '' : interactiveRun.isLiveRun ? ' [Live]' : ` [#${runIndex}]`),
+ color:
+ GraphPanelWidgetPalette[
+ (GraphPanelWidgetPalette.indexOf(interactiveRun.color) + traceIndex) % GraphPanelWidgetPalette.length
+ ] ?? DefaultGraphPanelWidgetColor,
+ zorder: interactiveRun.isLiveRun ? 1 : undefined
+ };
+ });
+
+ traces.push(...runTraces);
});
res.push({
@@ -693,9 +662,8 @@ function onAddRun(): void {
// Determine the colour (of the first trace) by using the next unused colour in the palette unless all the colours
// have already been used.
- const usedColors = new Set([interactiveLiveRunColor.value, ...interactiveRuns.value.map((run) => run.color)]);
- const interactiveRun = interactiveRuns.value.length ? interactiveRuns.value[interactiveRuns.value.length - 1] : null;
- const lastColor = interactiveRun ? interactiveRun.color : interactiveLiveRunColor.value;
+ const usedColors = new Set(interactiveRuns.value.map((run) => run.color));
+ const lastColor = interactiveRuns.value[interactiveRuns.value.length - 1]?.color ?? DefaultGraphPanelWidgetColor;
const lastColorIndex = GraphPanelWidgetPalette.indexOf(lastColor);
let color: string = DefaultGraphPanelWidgetColor;
@@ -716,7 +684,8 @@ function onAddRun(): void {
visible: true,
data: interactiveData.value,
color,
- tooltip
+ tooltip,
+ isLiveRun: false
});
}
@@ -727,9 +696,9 @@ function onRemoveRun(index: number): void {
}
function onRemoveAllRuns(): void {
- // Remove all the runs.
+ // Remove all the runs except the live run.
- interactiveRuns.value = [];
+ interactiveRuns.value.splice(1);
}
function onToggleRun(index: number): void {
@@ -742,40 +711,25 @@ function onToggleRun(index: number): void {
}
}
-function onLiveRunColorChange(color: string) {
- interactiveLiveRunColor.value = color;
-
- interactiveLiveRunColorPopover.value.hide();
-}
-
function onRunColorChange(index: number, color: string) {
const interactiveRun = interactiveRuns.value[index];
if (interactiveRun) {
interactiveRun.color = color;
-
- closeRunColorPopover(index);
}
}
function onToggleRunColorPopover(index: number, event: MouseEvent) {
- if (interactiveRunColorPopoverIndex.value === index) {
- closeRunColorPopover(index);
- } else {
- interactiveRunColorPopoverIndex.value = index;
+ // Note: interactiveRunColorPopoverIndex is only used to ensure that the active popover gets properly hidden when the
+ // window loses focus as a result of switching tabs (see onMounted below).
- vue.nextTick(() => {
- // Note: we do this in a next tick to ensure that the reference is available.
+ interactiveRunColorPopoverIndex.value = index;
- interactiveRunPopoverRefs.value[index]?.toggle(event);
- });
- }
-}
-
-function closeRunColorPopover(index: number) {
- interactiveRunPopoverRefs.value[index]?.hide();
+ vue.nextTick(() => {
+ // Note: we do this in a next tick to ensure that the reference is available.
- interactiveRunColorPopoverIndex.value = -1;
+ interactiveRunColorPopoverRefs.value[index]?.toggle(event);
+ });
}
// "Initialise" our standard and/or interactive modes.
@@ -839,16 +793,16 @@ vue.onMounted(() => {
mutationObserver.observe(document.documentElement, { attributes: true, attributeFilter: ['style'] });
- // Close popovers when the window loses focus.
+ // Make sure that our active popover gets hidden when the window loses focus.
vue.watch(
() => windowIsFocused.value,
(isFocused) => {
if (!isFocused) {
- interactiveLiveRunColorPopover.value?.hide();
-
if (interactiveRunColorPopoverIndex.value !== -1) {
- closeRunColorPopover(interactiveRunColorPopoverIndex.value);
+ interactiveRunColorPopoverRefs.value[interactiveRunColorPopoverIndex.value]?.hide();
+
+ interactiveRunColorPopoverIndex.value = -1;
}
}
}
@@ -931,4 +885,8 @@ if (common.isDesktop()) {
.run {
border-color: var(--p-content-border-color);
}
+
+.selected-color {
+ outline: 3px solid var(--p-text-color);
+}