Skip to main content

Property Mapping

Property mapping allows you to match specific values for a given property/properties to a set of config options - it's related to the concept of UI States, but it's a "pull" rather than "push": when you update the model, the UI figures out what config to apply for a given object, rather than you having to tell it.

note

This functionality is available only for edges. We are investigating options for how this could be usefully extended to nodes, groups and ports.

Example​

This example is drawn from the Flowchart starter app's source code:


import { ArrowOverlay } from "@visuallyjs/browser-ui"

const ARROW_WIDTH = 5
const ARROW_LENGTH = 10
const CLASS_DASHED_EDGE = "some-css-class"

const PROPERTY_LINE_STYLE = "lineStyle"

const EDGE_TYPE_SOURCE_ARROW = "source"
const EDGE_TYPE_TARGET_ARROW = "target"
const EDGE_TYPE_PLAIN = "plain"
const EDGE_TYPE_DASHED = "dashed"

const edgeMappings = [
{
property:PROPERTY_LINE_STYLE,
mappings:{
[EDGE_TYPE_SOURCE_ARROW]:{
overlays:[
{
type:ArrowOverlay.type,
options:{
location:0,
direction:-1,
width:ARROW_WIDTH,
Length:ARROW_LENGTH
}
} ]
},
[EDGE_TYPE_TARGET_ARROW]:{
overlays:[
{
type:ArrowOverlay.type,
options:{
location:1,
width:ARROW_WIDTH,
length:ARROW_LENGTH
}
}
]
},
[EDGE_TYPE_PLAIN]:{},
[EDGE_TYPE_DASHED]:{
cssClass:CLASS_DASHED_EDGE
}
}
}
]

Each mapping consists of a property name (or list of names - see below) and a map of values to configs (the specific type of these configs is EdgeMapping). Here we have declared a set of mappings for the property lineStyle in the backing data for an edge:

{
property:PROPERTY_LINE_STYLE,
mappings: {
[EDGE_TYPE_SOURCE_ARROW] : {
...
}
...
}
}

So if you had an edge with this definition:

{
source: "1",
target: "2",
data:{
lineStyle:"source"
}
}

Then the corresponding connection would have an Arrow overlay at location 0.

Updating data​

When an edge is updated, the property mappings are inspected. Any that are no longer valid are removed, and any that are now valid are added:

model.updateEdge(someEdge, {
lineStyle:EDGE_TYPE_DASHED
})

This would result in the arrow overlay being removed, and "some-css-class" being added to the connection's class list, because there is a mapping for EDGE_TYPE_DASHED:

mappings:{

...

[EDGE_TYPE_DASHED]:{
cssClass:CLASS_DASHED_EDGE
}
}

Wildcard mappings​

You can use "*" or WILDCARD from @visuallyjs/browser-ui as the value for some property, which will instruct the UI that the given config should be applied regardless of the value of the mapped property (as long as it is present, not null):

import { WILDCARD } from "@visuallyjs/browser-ui"

{
property:"label",
mappings:{
[WILDCARD]:{
overlays:[
{
type:LabelOverlay.type,
options:{
label:"{{label}}",
location:0.5,
cssClass:"some-label"
}
}
]
}
}
}

Here, we have instructed VisuallyJs to show a label whenever an edge's backing data has a label property. Incidentally, this specific requirement can actually be neatly handled by Edge labels.

Multiple properties​

You can map multiple properties instead of just a single property if you need the extra flexibility. For example, these are property mappings for an edge in a conceptual ERD, in which edges between entities and relationships show cardinality, but only at one end. We can model that with two properties:

propertyMappings: [
{
property: ["cardinality", "terminus"],
mappings:{
"one source": {
sourceMarker: OneOverlay.type
},
"one target": {
targetMarker: OneOverlay.type
}
}
}
]

Then in our dataset we might have edges like this:

[
{ source:"1", target:"2", data:{ cardinality:"one", terminus:"source" }},
{ source:"2", target:"3", data:{ cardinality:"many", terminus:"target" }}
]

The important point to note in the example mapping above is that the order of the keys must be reflected in the mapping keys: we declare ["cardiinality", "terminus"] as our properties, and our mapping keys are "one source" and "one target", ie. the values to match are in the same order as the property keys.