# Class: IMCSDiagramEditor

## IMCSDiagramEditor(settings)

#### new IMCSDiagramEditor(settings)

Creates a new JavaScript graphical diagram editor with layout capabilities.
Currently the diagram editor has the following restrictions:

- only orthogonal lines are supported;
- no inner boxes (box-in-a-box);
- only one diagram per HTML page;
- several canvas are used, however, canvas size is limited to the visible area, while the diagram can be much larger.

The built-in default layout manager is activated by default, thus, the diagram is adjusted automatically in such a way that boxes and lines do not overlap. The default layout manager can be replaced by a user-defined layout manager or even switched off for manual mode (where the diagram is not adjusted).

To minimize diagram adjustments and repaintings, the diagram IS NOT refreshed after any single operation such as addBox, addLine, updateBoxLocation, updateLineLocation, etc. Multiple modifications should to be performed in bulk, and then the refresh() function has to be called explicitly.

Instead of just adjusting the diagram, it can be re-arranged from scratch by calling resetLayout.

##### Parameters:

Name | Type | Description
--- | --- | ---
`settings` | object | a JavaScript/JSON object contatining configuration settings for the diagram. The fields are:
diagramDiv | HTML div element id, where to put the diagram
readOnly | a boolean value denoting where the diagram is read-only or editable
backgroundColor | background color of the diagram, e.g. "#f0f8ff"
paletteElements | an array of palette elements in the format: `{ reference: <a number representing the id of this palette element>, className: "PaletteBox" or "PaletteLine", picture: "a/path/relative/to/<script-folder>/images" }`
onNewBox | an function to be called when a new box is being created from a palette element; this box has to be explicitly added to the diagram via addBox (or ingored, e.g., if this box is not allowed) `function (palette_element_reference, x, y, width, height)`
onNewLine | an function to be called when a new line is being created from a palette element; this line has to be explicitly added to the diagram via addLine (or ignored, e.g., if this line is not allowed) `function(palette_element_reference, source_box_reference, target_box_reference, points)` points is an array in the form [{x:x1, y:y1},{x:x2,y:y2},{x:xN,y:yN}]
onElementsMoved | an function to be called when some boxes and/or lines changed their positions `function(rElementsArr)` each element in the array is in the format: `{ reference: <a number representing the id of this diagram element>, location: "width;height;left;top" for a box or "N\x1,y1\x2,y2\xN,yN" for lines TODO!: className, width, height, left, top, points }`
onElementsSelected | an function to be called when the set of selected boxes and lines changes `function(rElementsArr)` each element in the array is in the format: `{ reference: <a number representing the id of this diagram element>, }`
onElementDoubleClick | an function to be called when a double click is performed on an element `function(reference)` reference is a number representing the id of the clicked diagram element
onElementRightClick | an function to be called when a right click is performed on an element `function(reference)` reference is a number representing the id of the clicked diagram element
onDiagramRightClick | an function to be called when a right click is performed somewhere on a diagram, but not on an element `function()`
onceReady | a function to be called when the diagram loading has been finished and the initial layout has been performed `function()`
showPleaseWait | a function to be called when the diagram needs to display some message and block user input (e.g., to inform the used to wait while the diagram is being re-arranged) `function(message)`
hidePleaseWait | a function to be called when the "please, wait" message is not needed any more `function()`

### Methods

#### addBox(obj)

Adds (or updates) a box to (in) this diagram editor. Call refresh() after finishing adding boxes and lines to adjust (incrementally) the diagram.

##### Parameters:

Name | Type | Description
--- | --- | ---
`obj` | object | a JS (a repository) object representing a box. The fields are:
reference | a number representing the id of this box
location | box dimensions and coordinates in the form "width;height;left;top" //TODO!
style | box style in the form { fillColor:, lineColor:, lineWidth:, shape: "Rectangle" or "RoundRectangle" or "Package" or "Note" or "Circle" or "Triangle" or "HorizontalLine" or "VerticalLine", dashLength:, dashBreakLength, } Alternatively, style value can be a string in legacy AZ node style encoding.
compartment | an array of compartments, where each compartment is in the form: `{ reference: <compartment id>, input: "compartment text", style: { alignment: "left" or "center" or "right", fontColor:, fontFamily:, fontSize: <number in pt> fontWeight: "bold" or "italic" or "normal", lineWidth:, isVisible:, } // alternatively, the style can be a string in legacy AZ compartment style encoding }`
elemType | undefined or [{caption:"HorizontalFork" or "VerticalFork"}] for specifying a fork

#### addLine(obj)

Adds (or updates) a line to (in) this diagram editor. Call refresh() after finishing adding boxes and lines to adjust the diagram.

##### Parameters:

Name | Type | Description
--- | --- | ---
`obj` | object | a JS (a repository) object representing a line. The fields are:
reference | a number representing the id of this line
location | line coordinates in the form "N\x1,y1\x2,y2\xN,yN" //TODO!
start | [box-object] or [{className:"Node",reference:<id>,elemType:undefined or [{caption:"HorizontalFork" or "VerticalFork"}]}] //TODO! startNode
end | [box-object] or [{className:"Node",reference:<id>,elemType:undefined or [{caption:"HorizontalFork" or "VerticalFork"}]}] //TODO! startNode
style | line style in the form { lineColor:, lineWidth:, startStyle:{ shape: "None" or "Triangle" or "Diamond" or "Triangle" or "Arrow", lineColor: lineWidth: fillColor: } endStyle:{...}, dashLength:, dashBreakLength, } Alternatively, style value can be a string in legacy AZ edge style encoding.
compartment | an array of compartments, where each compartment is in the form: `{ reference: <compartment id>, input: "compartment text", style: { fontColor:, fontFamily:, fontSize: <number in pt> fontWeight: "bold" or "italic" or "normal", placement: "start-left" or "start-right" or "end-left" or "end-right" or "middle-left" or "middle-right", lineWidth:, isVisible:, } // alternatively, the style can be a string in legacy AZ compartment style encoding }`

#### getBoxesSet() → {set-of-references}

##### Returns:

the set of box ids in this diagram editor; the set is in the form { <box-reference1>: true, <box-reference2>: true, ...}

Type
  set-of-references

#### getLinesSet() → {set-of-references}

##### Returns:

the set of line ids in this diagram editor; the set is in the form { <line-reference1>: true, <line-reference2>: true, ...}

Type
  set-of-references

#### lineExists(reference) → {boolean}

Checks whether the line has already been added to this diagram editor.

##### Parameters:

Name | Type | Description
--- | --- | ---
`reference` | number | line id

##### Returns:

whether a line with the given id exists

Type
  boolean

#### refresh(fAfter)

Re-arranges and repaints the diagram (asynchronously). In manual mode (when no layout manager is preset) the diagram is just repainted.

##### Parameters:

Name | Type | Description
--- | --- | ---
`fAfter` | function | a function to be called after the diagram is repainted

#### removeBox(reference)

Removes the given box from the diagram (and from internal layout structures). You may wish to call refresh() after deletions to adjust the diagram.

##### Parameters:

Name | Type | Description
--- | --- | ---
`reference` | number | box id

#### removeLine(reference)

Removes the given line from the diagram (and from internal layout structures). You may wish to call refresh() after deletions to re-arrange the diagram.

##### Parameters:

Name | Type | Description
--- | --- | ---
`reference` | number | line id

#### resetLayout(name)

Re-arrange the diagram from scratch using the given arrangment name. Call refresh() then to repaint the diagram.

##### Parameters:

Name | Type | Description
--- | --- | ---
`name` | string | “UNIVERSAL”, “SYMMETRIC”, “VERTICAL” (for an edge a→b the layout algorithm will return y_max[a]≤y_min[b]), “INVERSE_VERTICAL”, “HORIZONTAL”, or “INVERSE_HORIZONTAL”; if name not specified, the diagram is only adjusted incrementally.

#### selectElements(arr)

Visually selects the given diagram elements.

##### Parameters:

Name | Type | Description
--- | --- | ---
`arr` | array | array of boxes and/or lines to be selected; each array element must have the reference attribute

#### setDefaultLayoutManager(skipAdd)

Sets the built-in default layout manager. Useful from switching back from the manual mode to the semi-automatic mode, where the diagram is automatically re-arranged on refresh.

##### Parameters:

Name | Type | Description
--- | --- | ---
`skipAdd` | boolean | whether to skip adding existing boxes and lines to the default layout manager (they are added by default); perhaps, this option is only useful when other coordinates will be assigned to existing boxes and lines right away

#### setLayoutManager(layout, skipAdd)

Sets user-defined layout manager or switches to the manual mode (if no manager is specified). In manual mode, diagram won't be re-arranged on refresh; boxes and line may overlap.

##### Parameters:

Name | Type | Description
--- | --- | ---
`layout` | object | user-defined layout manager implementing the same API as ICMSDiagramLayout or null for the manual mode
`skipAdd` | boolean | whether to skip adding existing boxes and lines to the user-defined layout manager (they are added by default); this option is useful if the user-defined layout manager has been already initialized with the existing boxes and lines

#### updateBoxLocation(reference, x, y, w, h)

Updates location of the given box. Call refresh() after updating all box and line locations to adjust the diagram.

##### Parameters:

Name | Type | Description
--- | --- | ---
`reference` | number | box id
`x` | number | new left coordinate
`y` | number | new top coordinate
`w` | number | new width
`h` | number | new height

#### updateLineLabelLocation(reference, x, y, w, h)

Temporarily changes location of the given line label (=line compartment) on the screen until the next refresh (since adjusting the diagram moves line labels).

##### Parameters:

Name | Type | Description
--- | --- | ---
`reference` | number | box id
`x` | number | new left coordinate
`y` | number | new top coordinate
`w` | number | new width
`h` | number | new height

#### updateLineLocation(reference, points)

Sets points for the given line. Call refresh() after updating all box and line locations to adjust the diagram.

##### Parameters:

Name | Type | Description
--- | --- | ---
`reference` | number | line id
`points` | array | array in the form [{x:x1,y:y1}, {x:x2,y:y2}, {x:xN,y:yN}]