Skip to content

Commit

Permalink
implement support for custom colors in sankey diagram
Browse files Browse the repository at this point in the history
  • Loading branch information
ishubin committed Feb 6, 2025
1 parent 760203e commit 9d67bef
Show file tree
Hide file tree
Showing 6 changed files with 62 additions and 7 deletions.
2 changes: 1 addition & 1 deletion assets/templates/diagrams/sankey.json

Large diffs are not rendered by default.

3 changes: 2 additions & 1 deletion assets/templates/diagrams/sankey.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ args:
}
colorTheme: {group: "Theme & Colors", type: "choice", value: "default",
options: [
"default", "light", "dark", "air-force-blue", "gray"
"default", "light", "dark", "air-force-blue", "gray", "custom"
],
name: "Color theme"
}
Expand Down Expand Up @@ -65,6 +65,7 @@ handlers:
area: onAreaUpdate(itemId, item, area)
text: onTextUpdate(itemId, item, text)
delete: onDeleteItem(itemId, item)
shapeProps: onShapePropsUpdate(itemId, item, name, value)

controls:
- $-foreach: {source: "allConnections", it: "c"}
Expand Down
25 changes: 22 additions & 3 deletions assets/templates/diagrams/src/sankey.sch
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ func encodeNodes(nodes) {
if (result != '') {
result += '|'
}
result += `${n.id};x=${n.x};y=${n.y}`
result += `${n.id};x=${n.x};y=${n.y};c=${n.color}`
})
result
}
Expand All @@ -97,6 +97,8 @@ func decodeNodesData(text) {
node.x = value
} else if (name == 'y') {
node.y = value
} else if (name == 'c') {
node.color = value
}
}
}
Expand Down Expand Up @@ -139,6 +141,9 @@ func parseConnections(text, nodesData) {
if (nData) {
node.x = nData.x
node.y = nData.y
if (nData.color) {
node.color = nData.color
}
}
node
}
Expand Down Expand Up @@ -320,8 +325,9 @@ func buildNodeItems(levels) {
node.position = levelPosition
node.offset = currentY
local hashCode = Strings.hashCode(node.name)
node.color = colorPalette.get(abs(hashCode) % colorPalette.size)

if (colorTheme != 'custom') {
node.color = colorPalette.get(abs(hashCode) % colorPalette.size)
}

local nodeItem = Item('n-' + node.id, node.name, 'rect')
nodeItem.w = node.width
Expand All @@ -331,7 +337,9 @@ func buildNodeItems(levels) {
nodeItem.shapeProps.set('strokeSize', nodeStrokeSize)
nodeItem.shapeProps.set('strokeColor', nodeStrokeColor)
nodeItem.shapeProps.set('cornerRadius', nodeCornerRadius)

nodeItem.shapeProps.set('fill', Fill.solid(node.color))

nodeItem.args.set('tplArea', 'movable')
nodeItem.args.set('tplConnector', 'off')
nodeItem.args.set('tplRotation', 'off')
Expand Down Expand Up @@ -941,6 +949,17 @@ func addNewNodeForNode(nodeId, isDst) {
}
}

func onShapePropsUpdate(itemId, item, name, value) {
if (itemId.startsWith('n-') && name == 'fill' && value.type == 'solid') {
local nodeId = itemId.substring(2)
local node = allNodes.find(n => { n.id == nodeId })
if (node) {
node.color = value.color
nodesData = encodeNodes(nodesById)
}
}
}


local nodesDataById = decodeNodesData(nodesData)

Expand Down
33 changes: 32 additions & 1 deletion src/ui/components/SchemeEditor.vue
Original file line number Diff line number Diff line change
Expand Up @@ -186,6 +186,7 @@
:item="floatingHelperPanel.item"
:schemeContainer="schemeContainer"
@item-updated="onItemUpdatedInFloatingHelperPanel"
@item-shape-prop-updated="onItemShapePropdUpdatedInFloatingHelperPanel"
@edit-path-requested="onEditPathRequested"
@image-crop-requested="startCroppingImage"
@close="floatingHelperPanel.shown = false"
Expand Down Expand Up @@ -2164,6 +2165,26 @@ export default {
EditorEventBus.textSlot.moved.$emit(this.editorId, item, slotName, anotherSlotName);
},


/**
* @param {Item} item
* @param {String} name
* @param {Object} value
*/
triggerShapePropsUpdateTemplateHandler(item, name, value) {
const rootItem = this.schemeContainer.findItemById(item.meta.templateRootId);
if (!rootItem || !rootItem.meta.templateRef) {
return;
}

this.schemeContainer.getTemplate(rootItem.meta.templateRef)
.then(template => {
const templateArgs = template.onShapePropsUpdate(rootItem, item.args.templatedId, item, name, value);
this.schemeContainer.regenerateTemplatedItem(rootItem, template, templateArgs, rootItem.area.w, rootItem.area.h);
});
},


// triggered from ItemProperties or QuickHelperPanel components
onItemShapePropChanged(name, type, value) {
//TODO move it to another script (to simplify this script)
Expand All @@ -2182,6 +2203,10 @@ export default {
EditorEventBus.item.changed.specific.$emit(this.editorId, item.id, `shapeProps.${name}`);
});

if (item.meta && item.meta.templated) {
this.triggerShapePropsUpdateTemplateHandler(item, name, value);
}

itemIds += item.id;
recentPropsChanges.registerItemShapeProp(item.shape, name, value);
}
Expand Down Expand Up @@ -2295,6 +2320,13 @@ export default {

},

onItemShapePropdUpdatedInFloatingHelperPanel(item, name, value) {
this.schemeContainer.updateItemClones(item);
if (item.meta && item.meta.templated) {
this.triggerShapePropsUpdateTemplateHandler(item, name, value);
}
},

onItemUpdatedInFloatingHelperPanel(item) {
this.schemeContainer.updateItemClones(item);
},
Expand All @@ -2319,7 +2351,6 @@ export default {
onEditBoxTemplateRebuildRequested(originItemId, template, templateArgs) {
// storing ids of selected items so that we can restore the selection after the regeneration
this.rebuildTemplate(originItemId, template, templateArgs);
this.schemeContainer.updateEditBox();
},

onEditBoxTemplatePropertiesUpdateRequested() {
Expand Down
2 changes: 1 addition & 1 deletion src/ui/components/editor/FloatingHelperPanel.vue
Original file line number Diff line number Diff line change
Expand Up @@ -199,7 +199,7 @@ export default {
this.schemeContainer.updateItem(this.item.id, `shapeProps.${name}`, item => {
item.shapeProps[name] = value;
});
this.$emit('item-updated', this.item);
this.$emit('item-shape-prop-updated', this.item, name, value);
EditorEventBus.item.changed.specific.$emit(this.editorId, this.item.id, `shapeProps.${name}`);
EditorEventBus.schemeChangeCommitted.$emit(this.editorId, `item.${this.item.id}.shapeProps.${name}`);
},
Expand Down
4 changes: 4 additions & 0 deletions src/ui/components/editor/items/ItemTemplate.js
Original file line number Diff line number Diff line change
Expand Up @@ -256,6 +256,10 @@ export function compileItemTemplate(editorId, template, templateRef) {
return this.triggerTemplateEvent(rootItem, 'text', {itemId, item, text});
},

onShapePropsUpdate(rootItem, itemId, item, name, value) {
return this.triggerTemplateEvent(rootItem, 'shapeProps', {itemId, item, name, value});
},

buildItem : (args, width, height, postBuild) => {
if (postBuild) {
return itemPostBuilder({
Expand Down

0 comments on commit 9d67bef

Please sign in to comment.