Skip to content

Commit

Permalink
Merge pull request #2 from yWorks/dev
Browse files Browse the repository at this point in the history
Fix concurrent layouts applying obsolete node sizes.
  • Loading branch information
yNiedworok authored Apr 15, 2024
2 parents 309799b + 48c9951 commit 2648fe7
Show file tree
Hide file tree
Showing 4 changed files with 68 additions and 33 deletions.
9 changes: 6 additions & 3 deletions examples/src/examples/custom-item-style/index.css
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
.item-name {
margin-top: 10px;
margin-left: 20px;
margin-right: 20px;
font-family: Arial, Helvetica, sans-serif;
font-size: 20px;
font-weight: bold;
Expand All @@ -9,17 +10,19 @@
.item-price {
margin-top: 10px;
margin-left: 20px;
margin-right: 20px;
font-family: Arial, Helvetica, sans-serif;
font-size: 16px;
}

.item-summary {
display: grid;
display: flex;
justify-content: center;
align-items: center;
text-align: center;
height: 100%;
margin-left: 20px;
font-family: Arial, Helvetica, sans-serif;
font-size: 42px;
font-size: 30px;
font-weight: bold;
}

Expand Down
16 changes: 11 additions & 5 deletions examples/src/examples/custom-item-style/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,20 +8,26 @@ import {

import './index.css'

type MetalItem = UserSupplyChainItem & { price: string }
type MetalItem = UserSupplyChainItem & { name: string; price: string }

const data = {
items: [
{ name: 'Copper', id: 1, price: 'USD 8500/t', className: 'copper', width: 180, height: 70 },
{ name: 'Zinc', id: 2, price: 'USD 2500/t', className: 'zinc', width: 180, height: 70 },
{ name: 'Brass', id: 3, price: 'USD 6500/t', className: 'brass', width: 180, height: 70 }
{ name: 'Copper', id: 1, price: 'USD 8500/t', className: 'copper' },
{ name: 'Zinc', id: 2, price: 'USD 2500/t', className: 'zinc' },
{ name: 'Brass', id: 3, price: 'USD 6500/t', className: 'brass' }
],
connections: [
{ sourceId: 1, targetId: 3 },
{ sourceId: 2, targetId: 3 }
]
} satisfies SupplyChainData<MetalItem, UserSupplyChainConnection>

const abbreviations = new Map<string, string>([
['Copper', 'Cu'],
['Zinc', 'Zn'],
['Brass', 'Brass']
])

export function CustomSupplyChainItem({
dataItem,
detail,
Expand Down Expand Up @@ -53,7 +59,7 @@ export function CustomSupplyChainItem({
<div className="item-price">{customSupplyChainItem.price}</div>
</div>
) : (
<div className="item-summary">{customSupplyChainItem.name}</div>
<div className="item-summary">{abbreviations.get(customSupplyChainItem.name)}</div>
)}
</div>
)
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@yworks/react-yfiles-supply-chain",
"version": "1.0.0",
"version": "1.0.1",
"author": {
"name": "yFiles for HTML team @ yWorks GmbH",
"email": "[email protected]"
Expand Down
74 changes: 50 additions & 24 deletions src/core/LayoutSupport.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,8 @@ import {
PartitionCellId,
PartitionGrid,
PartitionGridData,
PolylineEdgeStyle
PolylineEdgeStyle,
Rect
} from 'yfiles'
import {
GridPositioningFunction,
Expand All @@ -37,7 +38,8 @@ export class LayoutSupport<TSupplyChainItem extends SupplyChainItem> {
this.workerPromise = null
}
}
private executor: LayoutExecutorAsync | null = null
private executorAsync: LayoutExecutorAsync | null = null
private executor: LayoutExecutor | null = null

private hiddenEdgeStyle = new PolylineEdgeStyle({ stroke: 'transparent' })
private hiddenLabelStyle = new DefaultLabelStyle({
Expand Down Expand Up @@ -182,28 +184,53 @@ export class LayoutSupport<TSupplyChainItem extends SupplyChainItem> {
}
}

private createLayoutExecutor(
/**
* When a layout animation is already running, it might have started
* with now obsolete node sizes - stop the running animation and restore
* the latest measured node sizes.
*/
private async maybeCancel() {
const syncRunning = this.executor && this.executor.running
const asyncRunning = this.executorAsync && this.executorAsync.running
if (syncRunning || asyncRunning) {
const layouts = new Map<INode, Rect>()
for (const node of this.graphComponent.graph.nodes) {
layouts.set(node, node.layout.toRect())
}
await this.executor?.stop()
await this.executorAsync?.cancel()
for (const node of this.graphComponent.graph.nodes) {
if (layouts.has(node)) {
this.graphComponent.graph.setNodeLayout(node, layouts.get(node)!)
}
}
}
}

private async createLayoutExecutor(
incremental: boolean,
incrementalNodes: INode[],
fixedNode: INode | null = null,
fitViewport: boolean
): Promise<LayoutExecutor> {
return Promise.resolve(
new LayoutExecutor({
graphComponent: this.graphComponent,
layout: createLayout(incremental, this.layoutOptions),
layoutData: this.createLayoutData(
this.graphComponent.graph,
incremental,
incrementalNodes,
fixedNode
),
duration: '300ms',
animateViewport: fitViewport,
updateContentRect: true,
targetBoundsInsets: defaultGraphFitInsets
})
)
await this.maybeCancel()

this.executor = new LayoutExecutor({
graphComponent: this.graphComponent,
layout: createLayout(incremental, this.layoutOptions),
layoutData: this.createLayoutData(
this.graphComponent.graph,
incremental,
incrementalNodes,
fixedNode
),
duration: '300ms',
animateViewport: fitViewport,
updateContentRect: true,
targetBoundsInsets: defaultGraphFitInsets
})

return Promise.resolve(this.executor)
}

private async createLayoutExecutorAsync(
Expand All @@ -212,9 +239,8 @@ export class LayoutSupport<TSupplyChainItem extends SupplyChainItem> {
fixedNode: INode | null = null,
fitViewport: boolean
): Promise<LayoutExecutorAsync> {
if (this.executor) {
await this.executor.cancel()
}
await this.maybeCancel()

const worker = await this.workerPromise!

// helper function that performs the actual message passing to the web worker
Expand All @@ -239,7 +265,7 @@ export class LayoutSupport<TSupplyChainItem extends SupplyChainItem> {
})
}

this.executor = new LayoutExecutorAsync({
this.executorAsync = new LayoutExecutorAsync({
messageHandler: webWorkerMessageHandler,
graphComponent: this.graphComponent,
layoutData: this.createLayoutData(
Expand All @@ -253,6 +279,6 @@ export class LayoutSupport<TSupplyChainItem extends SupplyChainItem> {
updateContentRect: true,
targetBoundsInsets: defaultGraphFitInsets
})
return this.executor
return this.executorAsync
}
}

0 comments on commit 2648fe7

Please sign in to comment.