Load real GraphFX serialized examples
This commit is contained in:
4
graphfx-ui/.gitignore
vendored
4
graphfx-ui/.gitignore
vendored
@@ -22,7 +22,3 @@ dist-ssr
|
|||||||
*.njsproj
|
*.njsproj
|
||||||
*.sln
|
*.sln
|
||||||
*.sw?
|
*.sw?
|
||||||
examples/*
|
|
||||||
|
|
||||||
# Local graph examples
|
|
||||||
examples/*
|
|
||||||
|
|||||||
1
graphfx-ui/examples/api.json
Normal file
1
graphfx-ui/examples/api.json
Normal file
File diff suppressed because one or more lines are too long
@@ -10,6 +10,7 @@ import GraphFxNode from './components/GraphFxNode.vue'
|
|||||||
import { countSavedPositions, graphFxToVueFlow, parseGraphFxJson, type GraphFxFlowWarning, type GraphFxSerializedGraph } from './lib/graphfxToVueFlow'
|
import { countSavedPositions, graphFxToVueFlow, parseGraphFxJson, type GraphFxFlowWarning, type GraphFxSerializedGraph } from './lib/graphfxToVueFlow'
|
||||||
import { layoutGraph } from './lib/layout'
|
import { layoutGraph } from './lib/layout'
|
||||||
import { sampleGraph } from './lib/sampleGraph'
|
import { sampleGraph } from './lib/sampleGraph'
|
||||||
|
import apiExampleJson from '../examples/api.json?raw'
|
||||||
|
|
||||||
const editorText = ref(JSON.stringify(sampleGraph, null, 2))
|
const editorText = ref(JSON.stringify(sampleGraph, null, 2))
|
||||||
const parseError = ref<string | null>(null)
|
const parseError = ref<string | null>(null)
|
||||||
@@ -18,7 +19,7 @@ const nodes = ref<Node[]>([])
|
|||||||
const edges = ref<Edge[]>([])
|
const edges = ref<Edge[]>([])
|
||||||
const warnings = ref<GraphFxFlowWarning[]>([])
|
const warnings = ref<GraphFxFlowWarning[]>([])
|
||||||
const layoutDirection = ref<'LR' | 'TB'>('LR')
|
const layoutDirection = ref<'LR' | 'TB'>('LR')
|
||||||
const preferSavedPositions = ref(false)
|
const preferSavedPositions = ref(true)
|
||||||
const selectedSaveSlot = ref(localStorage.getItem('GRAPHFX_UI_SELECTED_SAVE_SLOT') || 'My first graph')
|
const selectedSaveSlot = ref(localStorage.getItem('GRAPHFX_UI_SELECTED_SAVE_SLOT') || 'My first graph')
|
||||||
const fileInput = ref<HTMLInputElement | null>(null)
|
const fileInput = ref<HTMLInputElement | null>(null)
|
||||||
const { fitView } = useVueFlow()
|
const { fitView } = useVueFlow()
|
||||||
@@ -53,6 +54,12 @@ function loadSample() {
|
|||||||
refreshFlow()
|
refreshFlow()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function loadApiExample() {
|
||||||
|
editorText.value = JSON.stringify(parseGraphFxJson(apiExampleJson), null, 2)
|
||||||
|
selectedSaveSlot.value = 'api'
|
||||||
|
refreshFlow()
|
||||||
|
}
|
||||||
|
|
||||||
function saveSlotKey(name = selectedSaveSlot.value) {
|
function saveSlotKey(name = selectedSaveSlot.value) {
|
||||||
return `GRAPHFX_UI_SAVE_${name}`
|
return `GRAPHFX_UI_SAVE_${name}`
|
||||||
}
|
}
|
||||||
@@ -129,6 +136,7 @@ refreshFlow()
|
|||||||
<div class="toolbar">
|
<div class="toolbar">
|
||||||
<button type="button" @click="refreshFlow">Render JSON</button>
|
<button type="button" @click="refreshFlow">Render JSON</button>
|
||||||
<button type="button" class="secondary" @click="loadSample">Load sample</button>
|
<button type="button" class="secondary" @click="loadSample">Load sample</button>
|
||||||
|
<button type="button" class="secondary" @click="loadApiExample">Load api.json</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="savebar">
|
<div class="savebar">
|
||||||
@@ -150,7 +158,7 @@ refreshFlow()
|
|||||||
</label>
|
</label>
|
||||||
<label class="checkbox-row">
|
<label class="checkbox-row">
|
||||||
<input v-model="preferSavedPositions" type="checkbox" />
|
<input v-model="preferSavedPositions" type="checkbox" />
|
||||||
Prefer saved x/y when every node has coordinates
|
Use saved x/y when every node has coordinates
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
@@ -66,6 +66,15 @@ export function getOutputHandleId(nodeId: string, outputName: string) {
|
|||||||
return `${nodeId}:out:${outputName}`
|
return `${nodeId}:out:${outputName}`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function serializedOutputIds(nodeId: string, outputName: string) {
|
||||||
|
return [
|
||||||
|
// GraphFX Output.id is `${outputsSet.id}-${name}` and Outputs.id is `${node.id}-out`.
|
||||||
|
`${nodeId}-out-${outputName}`,
|
||||||
|
// Keep accepting early graphfx-ui/sample shorthand.
|
||||||
|
`${nodeId}-${outputName}`,
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
const ioTypeColors: Record<GraphFxIoType, string> = {
|
const ioTypeColors: Record<GraphFxIoType, string> = {
|
||||||
Image: '#4dd7ff',
|
Image: '#4dd7ff',
|
||||||
Number: '#f6c85f',
|
Number: '#f6c85f',
|
||||||
@@ -117,7 +126,7 @@ export function graphFxToVueFlow(graph: GraphFxSerializedGraph): GraphFxFlowMode
|
|||||||
nodeIds.add(item.node.id)
|
nodeIds.add(item.node.id)
|
||||||
|
|
||||||
for (const outputName of Object.keys(item.node.options?.out || {})) {
|
for (const outputName of Object.keys(item.node.options?.out || {})) {
|
||||||
const serializedOutputId = `${item.node.id}-${outputName}`
|
const [serializedOutputId, ...aliases] = serializedOutputIds(item.node.id, outputName)
|
||||||
if (outputBySerializedId.has(serializedOutputId)) {
|
if (outputBySerializedId.has(serializedOutputId)) {
|
||||||
warnings.push({
|
warnings.push({
|
||||||
type: 'duplicate-output',
|
type: 'duplicate-output',
|
||||||
@@ -128,6 +137,11 @@ export function graphFxToVueFlow(graph: GraphFxSerializedGraph): GraphFxFlowMode
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
outputBySerializedId.set(serializedOutputId, { nodeId: item.node.id, outputName })
|
outputBySerializedId.set(serializedOutputId, { nodeId: item.node.id, outputName })
|
||||||
|
for (const alias of aliases) {
|
||||||
|
if (!outputBySerializedId.has(alias)) {
|
||||||
|
outputBySerializedId.set(alias, { nodeId: item.node.id, outputName })
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -108,8 +108,17 @@ code {
|
|||||||
|
|
||||||
.toolbar {
|
.toolbar {
|
||||||
display: grid;
|
display: grid;
|
||||||
grid-template-columns: 1fr 1fr;
|
grid-template-columns: repeat(2, minmax(0, 1fr));
|
||||||
gap: 0.7rem;
|
gap: 0.55rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.toolbar button {
|
||||||
|
padding-inline: 0.68rem;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
.toolbar button:first-child {
|
||||||
|
grid-column: 1 / -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
.savebar {
|
.savebar {
|
||||||
|
|||||||
Reference in New Issue
Block a user