How to Make My Custom Style Serializable
Tips & TricksSummary
Description
Making the Style Serializable
If your style contains a parameterless constructor and all properties have a public getter and setter, your style is already serializable. If not, you can write a MarkupExtension. The MarkupExtension should have all the necessary public properties that are needed to create the style instance.
Your style could look like this:
yfiles.module("my.module", function(exports) {
exports.MyNodeStyle = new yfiles.ClassDefinition(function() {
return {
'$extends': yfiles.drawing.SimpleAbstractNodeStyle,
'constructor': function(color, cornerRounding) {
yfiles.drawing.SimpleAbstractNodeStyle.call(this, yfiles.drawing.DefaultVisual.$class);
this.color = color;
this.cornerRounding = cornerRounding;
},
'createVisual': function(node, context) { /*...*/ }
};
})
});
This style is not serializable by default, since it does not have a parameterless constructor and the color and cornerRounding are not publicly accessible. Create a MarkupExtension for the style.
yfiles.module("my.module", function(exports) {
exports.MyNodeStyleExtension = new yfiles.ClassDefinition(function() {
return {
'$extends': yfiles.system.MarkupExtension,
'colorField': null,
'cornerRoundingField': null,
'color': {
'get': function() { return this.colorField; }
'set': function(value) { this.colorField = value; }
},
'cornerRounding': {
'get': function() { return this.cornerRoundingField; }
'set': function(value) { this.cornerRoundingField = value; }
},
'provideValue ': function(serviceProvider) {
return new my.module.MyNodeStyle(this.color, this.cornerRounding);
}
};
})
});
Now register a serialization handler that calls the MarkupExtension for instances of MyNodeStyle.
var graphMLIOHandler = graphControl.getGraphMLIOHandler();
graphMLIOHandler.addHandleSerializationListener(function(s, arg){
if (arg.item instanceof my.module.MyNodeStyle){
arg.replaceItem(arg.item.createMarkupExtension(), yfiles.system.MarkupExtension.$class);
arg.handled = true;
}
})
Also add the createMarkupExtension method to the style implementation.
yfiles.module("my.module", function(exports) {
exports.MyNodeStyle = new yfiles.ClassDefinition(function() {
return {
'$extends': yfiles.drawing.SimpleAbstractNodeStyle,
'constructor': function(color, cornerRounding) {
yfiles.drawing.SimpleAbstractNodeStyle.call(this, yfiles.drawing.DefaultVisual.$class);
this.color = color;
this.cornerRounding = cornerRounding;
},
'createVisual': function(node, context) { /*...*/ },
'createMarkupExtension': function() {
var extension = new my.module.MyNodeStyleExtension();
extension.color = this.color;
extension.cornerRounding = this.cornerRounding;
return extension;
}
};
})
});
Adding a Namespace Definition
Use the XmlnsDefinitionAttribute and XmlnsPrefixAttribute to add symbolic names for your module names.
yfiles.module("my.module", function (exports) {
exports.$meta = function () {
return [
yfiles.system.XmlnsDefinitionAttribute("http://www.my.url/my/application", "my.module"),
yfiles.system.XmlnsPrefixAttribute("http://www.my.url/my/application", "myName")];
};
// ...
});
This will result in nice output in the GraphML file.
<myName:MyNodeStyle xmlns:myName="http://www.my.url/my/application"/>