Using Dynamic Business Data as Label Text
Tips & TricksSummary
Description
A custom label style lets you easily use business data, for example, from the label tag as text, instead of the value of label.text. This makes it possible to let the graph render dynamically changing data without having to update the respective label items.
Style Implementation
For general advice on label style implementation, please follow the Custom Styles Tutorial.
To render data from the label tag, use the corresponding data in createVisual and updateVisual. For example, if you have an object with a name property stored in the label tag, your code could look like this:
createVisual(context) {
const textElement = window.document.createElementNS("http://www.w3.org/2000/svg", "text");
textElement.textContent = this.label.tag ? this.label.tag.name : "Empty Label";
return new SvgVisual(textElement);
}
You might also have to adjust the getPreferredSize method to use the text from the business data instead of the label text for label measurement.
Adjusting Interactive Label Editing
To adjust label editing so that it modifies the business data instead of the label text, you need a custom IEditLabelHelper implementation.
class MyEditLabelHelper extends EditLabelHelper {
onLabelEditing(evt) {
if (evt.owner === null || evt.owner.labels.count === 0) {
return;
}
let listener = null;
let canceledListener = null;
const label = evt.owner.labels.first();
const labelText = MyEditLabelHelper.$getLabelText(label);
// create a dummy label
const dummyLabel = new SimpleLabel(label.owner, labelText, label.layoutParameter);
dummyLabel.preferredSize = label.preferredSize;
dummyLabel.style = label.style;
const editorMode = evt.context.canvasComponent.inputMode;
if (editorMode && editorMode instanceof GraphEditorInputMode) {
listener = (evt) => {
// write edited label back to label tag
const newText = evt.item.text;
MyEditLabelHelper.$setLabelText(label, newText);
// adjust the label size
evt.context.canvasComponent.graph.adjustLabelPreferredSize(label);
// deregister listeners
editorMode.removeEventListener("label-text-changed", listener);
editorMode.removeEventListener("label-text-editing-canceled", canceledListener);
};
canceledListener = (evt) => {
// deregister listeners
editorMode.removeEventListener("label-text-changed", listener);
editorMode.removeEventListener("label-text-editing-canceled", canceledListener);
};
setTimeout(function() {
// start editing
editorMode.startLabelEditing(dummyLabel);
editorMode.addEventListener("label-text-changed", listener);
editorMode.addEventListener("label-text-editing-canceled", canceledListener);
}, 10);
}
}
static $getLabelText(label) {
// return desired business data here
return label.tag.name;
}
static $setLabelText(label, text) {
// modify business data here
return label.tag.name = text;
}
}
You can put this EditLabelHelper implementation in the label's lookup. One way to do this is by overriding lookup in a custom style.
lookup(label, type) {
if (type === IEditLabelHelper) {
return new MyEditLabelHelper();
}
return super.lookup(label, type);
}
Another option is to add the class to the lookup using GraphDecorator.
const decorator = graphComponent.graph.decorator;
decorator.labels.editLabelHelper.addConstant(new MyEditLabelHelper());