Passing Diagram options using JSON

We have a way for a parent document to pass options to our application in an iframe using postMessage(). For example the parent document can pass JSON like this to configure the Diagram.

{
   "diagramOptions":{
      "scale":1.0,
      "grid.visible":false,
      "initialAutoScale":go.Diagram.Uniform
   }
}

In the above example, scale and grid.visible work just fine, but I can’t figure how to get initialAutoScale to work since the value is an object and JSON.parse() in our app fails. I’ve also tried putting quotes around the value but then the Diagram doesn’t like it.

Is there any way to pass Diagram options as JSON when the value is an object like go.Diagram.Uniform. Of course eval() would probably work but we don’t want to do that!

I think you’re going to have to preprocess the data before sending it and process it upon arrival before calling Diagram.setProperties.

Do you have any suggestions on how to preprocess the data in the parent document, then process it in the iframe so Diagram likes it? Since the parent document will be sending data to our app in the iframe, we don’t want to do eval().

It would be easy if Diagram.Uniform was a string, but debugging it’s an actual object.

This is an older version of our product, and using GoJS 1.8 if that matters.

Well, if the property value is an instanceof go.EnumValue, you can get its name property and then substitute that property value with an Object that you will check for at the receiving end, where you can substitute it back with the corresponding EnumValue.

That’s basically what Model.toJson and Model.fromJson do when handling an EnumValue. Of course you’re dealing with a few Diagram properties, not a whole Model.

I’m guessing that Model.toJson and fromJson have a lot more logic than simple JSON calls, and why JSON.stringify(diagramOptions) in the parent document and JSON.parse(input) doesn’t work. It creates an object in the iframe, but not a GoJS class.

Are there public methods I can call that will do the equivalent of Model.toJson and fromJson do? What I’m passing are Diagram options and not model data.

Yes, that’s right – Diagram options are not model data.

Well, I told you about the EnumValue.name property. There is also an internal function for finding a particular EnumValue for a class given a name, but it is minified. Sorry.

I suggest that you just write the code to convert particular names to their corresponding appropriate EnumValues. Just put them into a Map<string, EnumValue>.

We currently allow any property of Diagram, so it’s unfortunately more than just EnumValues. It could be Spot, Point, etc., plus all of the options of nested objects. This is what the customer is trying to do.

"diagramOptions":{
  "commandHandler.defaultScale":1.0,
  "autoScale":"go.Diagram.Uniform",
  "grid.visible":true
}

Is there an alternative way to do the autoScale Uniform that doesn’t require a GoJS class?

But what are you going to do about event handlers and DiagramEvent listeners? You cannot reliably serialize functions.

I think you should not try to expose the Diagram API in your data, but I don’t understand what your real requirements are.

We aren’t supporting events or functions. The main reason for this functionality is to allow customizing of the Diagram, which has worked great for primitives, but now we have a customer trying to do a GoJS class.

"autoScale":"go.Diagram.Uniform"

Maybe the answer is we only support customization using primitives.

OK. But you could support specific properties if you handle ones such as Diagram.autoScale specially.