refactor(graph): async process elements

* process elements in chunks of 50 per ms to avoid blocking main thread

Signed-off-by: Braks <78412429+bcakmakoglu@users.noreply.github.com>

refactor(flow): deferr initial loading to Renderer.vue component
This commit is contained in:
Braks
2021-11-25 19:29:13 +01:00
parent 50fc0f2fd8
commit 4408ca1eb7
3 changed files with 15 additions and 12 deletions
+6 -2
View File
@@ -11,6 +11,7 @@ import {
getSourceTargetNodes, getSourceTargetNodes,
isEdge, isEdge,
parseElements, parseElements,
processElements,
} from '~/utils' } from '~/utils'
const pinia = createPinia() const pinia = createPinia()
@@ -84,9 +85,11 @@ export default (id: string, preloadedState: FlowState) => {
}, },
}, },
actions: { actions: {
setElements(elements) { async setElements(elements) {
const { nodes, edges } = parseElements(elements, this.elements, this.nodeExtent) const { nodes, edges } = parseElements(elements, this.elements, this.nodeExtent)
this.elements = [...nodes, ...edges] await processElements([...nodes, ...edges], (processed) => {
this.elements = [...this.elements, ...processed]
})
}, },
setUserSelection(mousePos) { setUserSelection(mousePos) {
this.selectionActive = true this.selectionActive = true
@@ -179,6 +182,7 @@ export default (id: string, preloadedState: FlowState) => {
this.elements = [...this.elements, ...nodes, ...edges] this.elements = [...this.elements, ...nodes, ...edges]
}, },
setState(state) { setState(state) {
if (typeof state.loading !== 'undefined') this.loading = state.loading
if (typeof state.panOnScroll !== 'undefined') this.panOnScroll = state.panOnScroll if (typeof state.panOnScroll !== 'undefined') this.panOnScroll = state.panOnScroll
if (typeof state.panOnScrollMode !== 'undefined') this.panOnScrollMode = state.panOnScrollMode if (typeof state.panOnScrollMode !== 'undefined') this.panOnScrollMode = state.panOnScrollMode
if (typeof state.panOnScrollSpeed !== 'undefined') this.panOnScrollSpeed = state.panOnScrollSpeed if (typeof state.panOnScrollSpeed !== 'undefined') this.panOnScrollSpeed = state.panOnScrollSpeed
+1 -1
View File
@@ -73,7 +73,7 @@ export interface FlowState extends Omit<FlowOptions, 'elements'> {
} }
export interface FlowActions { export interface FlowActions {
setElements: (elements: Elements) => void setElements: (elements: Elements) => Promise<void>
setUserSelection: (mousePos: XYPosition) => void setUserSelection: (mousePos: XYPosition) => void
updateUserSelection: (mousePos: XYPosition) => void updateUserSelection: (mousePos: XYPosition) => void
unsetUserSelection: () => void unsetUserSelection: () => void
+8 -9
View File
@@ -313,19 +313,18 @@ export const getTransformForBounds = (
return [x, y, clampedZoom] return [x, y, clampedZoom]
} }
export const processElements = (elements: Elements, fn: (element: Node | Edge) => void) => { export const processElements = (elements: FlowElements, fn: (elements: FlowElements) => void) => {
return new Promise((resolve) => { return new Promise((resolve) => {
const chunk = 50 const chunk = 50
let index = 0 let index = 0
function doChunk() { function doChunk() {
let cnt = chunk const chunkPos = chunk * index
while (cnt-- && index < elements.length) { const lastChunk = elements.length - chunkPos < chunkPos
fn(elements[index]) const cnt = !lastChunk ? chunk : elements.length - chunkPos
++index fn(elements.slice(chunkPos, chunkPos + cnt))
} index++
if (index < elements.length) { if (!lastChunk) {
// set Timeout for async iteration setTimeout(doChunk, 1)
nextTick(doChunk)
} else { } else {
resolve(true) resolve(true)
} }