mirror of
https://github.com/MrUnknownDE/VRCX.git
synced 2026-05-06 22:46:06 +02:00
Persist layout settings (#1532)
This commit is contained in:
@@ -111,11 +111,13 @@
|
|||||||
import { useI18n } from 'vue-i18n';
|
import { useI18n } from 'vue-i18n';
|
||||||
|
|
||||||
import { useAppearanceSettingsStore, useChartsStore, useFriendStore, useUserStore } from '../../../stores';
|
import { useAppearanceSettingsStore, useChartsStore, useFriendStore, useUserStore } from '../../../stores';
|
||||||
import { computeForceOptions, useMutualGraphChart } from '../composables/useMutualGraphChart';
|
import { applyForceOverrides, computeForceOptions, useMutualGraphChart } from '../composables/useMutualGraphChart';
|
||||||
import { createRateLimiter, executeWithBackoff } from '../../../shared/utils';
|
import { createRateLimiter, executeWithBackoff } from '../../../shared/utils';
|
||||||
import { database } from '../../../service/database';
|
import { database } from '../../../service/database';
|
||||||
import { userRequest } from '../../../api';
|
import { userRequest } from '../../../api';
|
||||||
|
|
||||||
|
import configRepository from '../../../service/config';
|
||||||
|
|
||||||
import * as echarts from 'echarts';
|
import * as echarts from 'echarts';
|
||||||
|
|
||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
||||||
@@ -179,12 +181,14 @@
|
|||||||
|
|
||||||
const isForceDialogVisible = ref(false);
|
const isForceDialogVisible = ref(false);
|
||||||
const forceOverrides = ref(null);
|
const forceOverrides = ref(null);
|
||||||
|
const persistedForce = ref(null);
|
||||||
const forceForm = reactive({
|
const forceForm = reactive({
|
||||||
repulsion: null,
|
repulsion: null,
|
||||||
edgeLengthMin: null,
|
edgeLengthMin: null,
|
||||||
edgeLengthMax: null,
|
edgeLengthMax: null,
|
||||||
gravity: null
|
gravity: null
|
||||||
});
|
});
|
||||||
|
const forceConfigKey = 'VRCX_MutualGraphForce';
|
||||||
|
|
||||||
const parseForceField = (value, { min = 0, max = Infinity, decimals = 0 } = {}) => {
|
const parseForceField = (value, { min = 0, max = Infinity, decimals = 0 } = {}) => {
|
||||||
if (value === '' || value === null || value === undefined) {
|
if (value === '' || value === null || value === undefined) {
|
||||||
@@ -250,11 +254,22 @@
|
|||||||
(tab) => {
|
(tab) => {
|
||||||
if (tab === 'mutual') {
|
if (tab === 'mutual') {
|
||||||
loadGraphFromDatabase();
|
loadGraphFromDatabase();
|
||||||
|
loadForceOverridesFromConfig();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{ immediate: true }
|
{ immediate: true }
|
||||||
);
|
);
|
||||||
|
|
||||||
|
watch(
|
||||||
|
graphReady,
|
||||||
|
(ready) => {
|
||||||
|
if (ready && forceOverrides.value) {
|
||||||
|
updateChart(graphPayload.value);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{ immediate: false }
|
||||||
|
);
|
||||||
|
|
||||||
function showStatusMessage(message, type = 'info') {
|
function showStatusMessage(message, type = 'info') {
|
||||||
if (!message) {
|
if (!message) {
|
||||||
return;
|
return;
|
||||||
@@ -530,7 +545,10 @@
|
|||||||
if (!chartInstance) {
|
if (!chartInstance) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
chartInstance.setOption(createChartOption(payload, forceOverrides.value));
|
const forceOption =
|
||||||
|
persistedForce.value ||
|
||||||
|
applyForceOverrides(computeForceOptions(nodes, payload?.links ?? []), forceOverrides.value);
|
||||||
|
chartInstance.setOption(createChartOption(payload, forceOption));
|
||||||
nextTick(() => chartInstance?.resize());
|
nextTick(() => chartInstance?.resize());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -590,16 +608,59 @@
|
|||||||
gravity: gravity.value === null ? defaults.gravity : gravity.value,
|
gravity: gravity.value === null ? defaults.gravity : gravity.value,
|
||||||
layoutAnimation: defaults.layoutAnimation
|
layoutAnimation: defaults.layoutAnimation
|
||||||
};
|
};
|
||||||
|
persistedForce.value = applyForceOverrides(defaults, forceOverrides.value);
|
||||||
|
persistForceOverrides();
|
||||||
updateChart(graphPayload.value);
|
updateChart(graphPayload.value);
|
||||||
isForceDialogVisible.value = false;
|
isForceDialogVisible.value = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
function resetForceSettings() {
|
function resetForceSettings() {
|
||||||
forceOverrides.value = null;
|
forceOverrides.value = null;
|
||||||
|
persistedForce.value = null;
|
||||||
syncForceForm(forceDefaults.value);
|
syncForceForm(forceDefaults.value);
|
||||||
if (hasGraphData.value) {
|
if (hasGraphData.value) {
|
||||||
updateChart(graphPayload.value);
|
updateChart(graphPayload.value);
|
||||||
}
|
}
|
||||||
|
clearForceOverrides();
|
||||||
|
}
|
||||||
|
|
||||||
|
async function loadForceOverridesFromConfig() {
|
||||||
|
try {
|
||||||
|
const saved = await configRepository.getObject(forceConfigKey, null);
|
||||||
|
if (!saved || typeof saved !== 'object') {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
forceOverrides.value = saved.overrides || null;
|
||||||
|
persistedForce.value = saved.force || null;
|
||||||
|
if (forceOverrides.value) {
|
||||||
|
syncForceForm(forceOverrides.value);
|
||||||
|
}
|
||||||
|
if (graphReady.value) {
|
||||||
|
updateChart(graphPayload.value);
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
console.warn('[MutualNetworkGraph] Failed to load force settings', err);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function persistForceOverrides() {
|
||||||
|
if (!forceOverrides.value) {
|
||||||
|
clearForceOverrides();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const payload = {
|
||||||
|
overrides: forceOverrides.value,
|
||||||
|
force: persistedForce.value
|
||||||
|
};
|
||||||
|
configRepository.setObject(forceConfigKey, payload).catch((err) => {
|
||||||
|
console.warn('[MutualNetworkGraph] Failed to save force settings', err);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function clearForceOverrides() {
|
||||||
|
configRepository.remove(forceConfigKey).catch((err) => {
|
||||||
|
console.warn('[MutualNetworkGraph] Failed to clear force settings', err);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|||||||
@@ -55,7 +55,7 @@ export function computeForceOptions(nodes, links) {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
function applyForceOverrides(force, forceOverrides) {
|
export function applyForceOverrides(force, forceOverrides) {
|
||||||
if (!forceOverrides) {
|
if (!forceOverrides) {
|
||||||
return force;
|
return force;
|
||||||
}
|
}
|
||||||
@@ -181,13 +181,10 @@ export function useMutualGraphChart({ cachedUsers, graphPayload }) {
|
|||||||
updateChart?.(graphPayload.value);
|
updateChart?.(graphPayload.value);
|
||||||
}
|
}
|
||||||
|
|
||||||
function createChartOption(payload, forceOverrides) {
|
function createChartOption(payload, force) {
|
||||||
const nodes = payload?.nodes ?? [];
|
const nodes = payload?.nodes ?? [];
|
||||||
const links = payload?.links ?? [];
|
const links = payload?.links ?? [];
|
||||||
const force = applyForceOverrides(
|
const resolvedForce = force || computeForceOptions(nodes, links);
|
||||||
computeForceOptions(nodes, links),
|
|
||||||
forceOverrides
|
|
||||||
);
|
|
||||||
const labelMap = Object.create(null);
|
const labelMap = Object.create(null);
|
||||||
nodes.forEach((node) => {
|
nodes.forEach((node) => {
|
||||||
if (node?.id) {
|
if (node?.id) {
|
||||||
|
|||||||
Reference in New Issue
Block a user