updates to js syntax
parent
fc98630dad
commit
8ed2f25c20
|
@ -3,7 +3,7 @@
|
||||||
* Copyright (c) 2006-2018, Gaudenz Alder
|
* Copyright (c) 2006-2018, Gaudenz Alder
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import mxRectangle from "FIXME";
|
import mxRectangle from "../util/mxRectangle";
|
||||||
import mxDictionary from "FIXME";
|
import mxDictionary from "FIXME";
|
||||||
|
|
||||||
class mxGraphLayout {
|
class mxGraphLayout {
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
* Copyright (c) 2006-2015, Gaudenz Alder
|
* Copyright (c) 2006-2015, Gaudenz Alder
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import mxRectangle from "FIXME";
|
import mxRectangle from "../util/mxRectangle";
|
||||||
|
|
||||||
class mxPartitionLayout extends mxGraphLayout {
|
class mxPartitionLayout extends mxGraphLayout {
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import mxPoint from "FIXME";
|
import mxPoint from "FIXME";
|
||||||
import mxRectangle from "FIXME";
|
import mxRectangle from "../util/mxRectangle";
|
||||||
|
|
||||||
class mxGeometry extends mxRectangle {
|
class mxGeometry extends mxRectangle {
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
* Copyright (c) 2006-2015, Gaudenz Alder
|
* Copyright (c) 2006-2015, Gaudenz Alder
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import mxRectangle from "FIXME";
|
import mxRectangle from "../util/mxRectangle";
|
||||||
|
|
||||||
class mxDoubleEllipse extends mxShape {
|
class mxDoubleEllipse extends mxShape {
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
* Copyright (c) 2006-2015, Gaudenz Alder
|
* Copyright (c) 2006-2015, Gaudenz Alder
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import mxRectangle from "FIXME";
|
import mxRectangle from "../util/mxRectangle";
|
||||||
import mxConnectionConstraint from "FIXME";
|
import mxConnectionConstraint from "FIXME";
|
||||||
|
|
||||||
class mxStencil extends mxShape {
|
class mxStencil extends mxShape {
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -2,91 +2,86 @@
|
||||||
* Copyright (c) 2006-2015, JGraph Ltd
|
* Copyright (c) 2006-2015, JGraph Ltd
|
||||||
* Copyright (c) 2006-2015, Gaudenz Alder
|
* Copyright (c) 2006-2015, Gaudenz Alder
|
||||||
*/
|
*/
|
||||||
/**
|
import mxUtils from "./mxUtils";
|
||||||
*
|
import mxEventSource from "./mxEventSource";
|
||||||
* Class: mxAnimation
|
import mxEventObject from "./mxEventObject";
|
||||||
*
|
|
||||||
* Implements a basic animation in JavaScript.
|
|
||||||
*
|
|
||||||
* Constructor: mxAnimation
|
|
||||||
*
|
|
||||||
* Constructs an animation.
|
|
||||||
*
|
|
||||||
* Parameters:
|
|
||||||
*
|
|
||||||
* graph - Reference to the enclosing <mxGraph>.
|
|
||||||
*/
|
|
||||||
function mxAnimation(delay)
|
|
||||||
{
|
|
||||||
this.delay = (delay != null) ? delay : 20;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
class mxAnimation extends mxEventSource {
|
||||||
* Extends mxEventSource.
|
/**
|
||||||
*/
|
* Variable: delay
|
||||||
mxAnimation.prototype = new mxEventSource();
|
*
|
||||||
constructor = mxAnimation;
|
* Specifies the delay between the animation steps. Defaul is 30ms.
|
||||||
|
*/
|
||||||
|
delay = null;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Variable: delay
|
* Variable: thread
|
||||||
*
|
*
|
||||||
* Specifies the delay between the animation steps. Defaul is 30ms.
|
* Reference to the thread while the animation is running.
|
||||||
*/
|
*/
|
||||||
delay = null;
|
thread = null;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Variable: thread
|
*
|
||||||
*
|
* Class: mxAnimation
|
||||||
* Reference to the thread while the animation is running.
|
*
|
||||||
*/
|
* Implements a basic animation in JavaScript.
|
||||||
thread = null;
|
*
|
||||||
|
* Constructor: mxAnimation
|
||||||
|
*
|
||||||
|
* Constructs an animation.
|
||||||
|
*
|
||||||
|
* Parameters:
|
||||||
|
*
|
||||||
|
* graph - Reference to the enclosing <mxGraph>.
|
||||||
|
*/
|
||||||
|
constructor(delay) {
|
||||||
|
this.delay = (delay != null) ? delay : 20;
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function: isRunning
|
* Function: isRunning
|
||||||
*
|
*
|
||||||
* Returns true if the animation is running.
|
* Returns true if the animation is running.
|
||||||
*/
|
*/
|
||||||
isRunning = ()=>
|
isRunning = () => {
|
||||||
{
|
return this.thread != null;
|
||||||
return this.thread != null;
|
};
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function: startAnimation
|
* Function: startAnimation
|
||||||
*
|
*
|
||||||
* Starts the animation by repeatedly invoking updateAnimation.
|
* Starts the animation by repeatedly invoking updateAnimation.
|
||||||
*/
|
*/
|
||||||
startAnimation = ()=>
|
startAnimation = () => {
|
||||||
{
|
if (this.thread == null) {
|
||||||
if (this.thread == null)
|
this.thread = window.setInterval(mxUtils.bind(this, this.updateAnimation), this.delay);
|
||||||
{
|
}
|
||||||
this.thread = window.setInterval(mxUtils.bind(this, this.updateAnimation), this.delay);
|
};
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function: updateAnimation
|
* Function: updateAnimation
|
||||||
*
|
*
|
||||||
* Hook for subclassers to implement the animation. Invoke stopAnimation
|
* Hook for subclassers to implement the animation. Invoke stopAnimation
|
||||||
* when finished, startAnimation to resume. This is called whenever the
|
* when finished, startAnimation to resume. This is called whenever the
|
||||||
* timer fires and fires an mxEvent.EXECUTE event with no properties.
|
* timer fires and fires an mxEvent.EXECUTE event with no properties.
|
||||||
*/
|
*/
|
||||||
updateAnimation = ()=>
|
updateAnimation = () => {
|
||||||
{
|
this.fireEvent(new mxEventObject(mxEvent.EXECUTE));
|
||||||
this.fireEvent(new mxEventObject(mxEvent.EXECUTE));
|
};
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function: stopAnimation
|
* Function: stopAnimation
|
||||||
*
|
*
|
||||||
* Stops the animation by deleting the timer and fires an <mxEvent.DONE>.
|
* Stops the animation by deleting the timer and fires an <mxEvent.DONE>.
|
||||||
*/
|
*/
|
||||||
stopAnimation = ()=>
|
stopAnimation = () => {
|
||||||
{
|
if (this.thread != null) {
|
||||||
if (this.thread != null)
|
window.clearInterval(this.thread);
|
||||||
{
|
this.thread = null;
|
||||||
window.clearInterval(this.thread);
|
this.fireEvent(new mxEventObject(mxEvent.DONE));
|
||||||
this.thread = null;
|
}
|
||||||
this.fireEvent(new mxEventObject(mxEvent.DONE));
|
};
|
||||||
}
|
}
|
||||||
};
|
|
||||||
|
export default mxAnimation;
|
||||||
|
|
|
@ -2,212 +2,198 @@
|
||||||
* Copyright (c) 2006-2015, JGraph Ltd
|
* Copyright (c) 2006-2015, JGraph Ltd
|
||||||
* Copyright (c) 2006-2015, Gaudenz Alder
|
* Copyright (c) 2006-2015, Gaudenz Alder
|
||||||
*/
|
*/
|
||||||
/**
|
import mxEventSource from "./mxEventSource";
|
||||||
* Class: mxAutoSaveManager
|
import mxUtils from "./mxUtils";
|
||||||
*
|
|
||||||
* Manager for automatically saving diagrams. The <save> hook must be
|
class mxAutoSaveManager extends mxEventSource {
|
||||||
* implemented.
|
/**
|
||||||
*
|
* Variable: graph
|
||||||
* Example:
|
*
|
||||||
*
|
* Reference to the enclosing <mxGraph>.
|
||||||
* (code)
|
*/
|
||||||
* var mgr = new mxAutoSaveManager(editor.graph);
|
graph = null;
|
||||||
* mgr.save = ()=>
|
|
||||||
* {
|
/**
|
||||||
* mxLog.show();
|
* Variable: autoSaveDelay
|
||||||
* mxLog.debug('save');
|
*
|
||||||
* };
|
* Minimum amount of seconds between two consecutive autosaves. Eg. a
|
||||||
* (end)
|
* value of 1 (s) means the graph is not stored more than once per second.
|
||||||
*
|
* Default is 10.
|
||||||
* Constructor: mxAutoSaveManager
|
*/
|
||||||
*
|
autoSaveDelay = 10;
|
||||||
* Constructs a new automatic layout for the given graph.
|
|
||||||
*
|
/**
|
||||||
* Arguments:
|
* Variable: autoSaveThrottle
|
||||||
*
|
*
|
||||||
* graph - Reference to the enclosing graph.
|
* Minimum amount of seconds between two consecutive autosaves triggered by
|
||||||
*/
|
* more than <autoSaveThreshhold> changes within a timespan of less than
|
||||||
function mxAutoSaveManager(graph)
|
* <autoSaveDelay> seconds. Eg. a value of 1 (s) means the graph is not
|
||||||
{
|
* stored more than once per second even if there are more than
|
||||||
// Notifies the manager of a change
|
* <autoSaveThreshold> changes within that timespan. Default is 2.
|
||||||
this.changeHandler = mxUtils.bind(this, (sender, evt)=>
|
*/
|
||||||
{
|
autoSaveThrottle = 2;
|
||||||
if (this.isEnabled())
|
|
||||||
{
|
/**
|
||||||
this.graphModelChanged(evt.getProperty('edit').changes);
|
* Variable: autoSaveThreshold
|
||||||
|
*
|
||||||
|
* Minimum amount of ignored changes before an autosave. Eg. a value of 2
|
||||||
|
* means after 2 change of the graph model the autosave will trigger if the
|
||||||
|
* condition below is true. Default is 5.
|
||||||
|
*/
|
||||||
|
autoSaveThreshold = 5;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Variable: ignoredChanges
|
||||||
|
*
|
||||||
|
* Counter for ignored changes in autosave.
|
||||||
|
*/
|
||||||
|
ignoredChanges = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Variable: lastSnapshot
|
||||||
|
*
|
||||||
|
* Used for autosaving. See <autosave>.
|
||||||
|
*/
|
||||||
|
lastSnapshot = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Variable: enabled
|
||||||
|
*
|
||||||
|
* Specifies if event handling is enabled. Default is true.
|
||||||
|
*/
|
||||||
|
enabled = true;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Variable: changeHandler
|
||||||
|
*
|
||||||
|
* Holds the function that handles graph model changes.
|
||||||
|
*/
|
||||||
|
changeHandler = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class: mxAutoSaveManager
|
||||||
|
*
|
||||||
|
* Manager for automatically saving diagrams. The <save> hook must be
|
||||||
|
* implemented.
|
||||||
|
*
|
||||||
|
* Example:
|
||||||
|
*
|
||||||
|
* (code)
|
||||||
|
* var mgr = new mxAutoSaveManager(editor.graph);
|
||||||
|
* mgr.save = ()=>
|
||||||
|
* {
|
||||||
|
* mxLog.show();
|
||||||
|
* mxLog.debug('save');
|
||||||
|
* };
|
||||||
|
* (end)
|
||||||
|
*
|
||||||
|
* Constructor: mxAutoSaveManager
|
||||||
|
*
|
||||||
|
* Constructs a new automatic layout for the given graph.
|
||||||
|
*
|
||||||
|
* Arguments:
|
||||||
|
*
|
||||||
|
* graph - Reference to the enclosing graph.
|
||||||
|
*/
|
||||||
|
constructor(graph) {
|
||||||
|
// Notifies the manager of a change
|
||||||
|
this.changeHandler = mxUtils.bind(this, (sender, evt) => {
|
||||||
|
if (this.isEnabled()) {
|
||||||
|
this.graphModelChanged(evt.getProperty('edit').changes);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
this.setGraph(graph);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function: isEnabled
|
||||||
|
*
|
||||||
|
* Returns true if events are handled. This implementation
|
||||||
|
* returns <enabled>.
|
||||||
|
*/
|
||||||
|
isEnabled = () => {
|
||||||
|
return this.enabled;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function: setEnabled
|
||||||
|
*
|
||||||
|
* Enables or disables event handling. This implementation
|
||||||
|
* updates <enabled>.
|
||||||
|
*
|
||||||
|
* Parameters:
|
||||||
|
*
|
||||||
|
* enabled - Boolean that specifies the new enabled state.
|
||||||
|
*/
|
||||||
|
setEnabled = (value) => {
|
||||||
|
this.enabled = value;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function: setGraph
|
||||||
|
*
|
||||||
|
* Sets the graph that the layouts operate on.
|
||||||
|
*/
|
||||||
|
setGraph = (graph) => {
|
||||||
|
if (this.graph != null) {
|
||||||
|
this.graph.getModel().removeListener(this.changeHandler);
|
||||||
}
|
}
|
||||||
});
|
|
||||||
|
|
||||||
this.setGraph(graph);
|
this.graph = graph;
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
if (this.graph != null) {
|
||||||
* Extends mxEventSource.
|
this.graph.getModel().addListener(mxEvent.CHANGE, this.changeHandler);
|
||||||
*/
|
}
|
||||||
mxAutoSaveManager.prototype = new mxEventSource();
|
};
|
||||||
constructor = mxAutoSaveManager;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Variable: graph
|
* Function: save
|
||||||
*
|
*
|
||||||
* Reference to the enclosing <mxGraph>.
|
* Empty hook that is called if the graph should be saved.
|
||||||
*/
|
*/
|
||||||
graph = null;
|
save = () => {
|
||||||
|
// empty
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Variable: autoSaveDelay
|
* Function: graphModelChanged
|
||||||
*
|
*
|
||||||
* Minimum amount of seconds between two consecutive autosaves. Eg. a
|
* Invoked when the graph model has changed.
|
||||||
* value of 1 (s) means the graph is not stored more than once per second.
|
*/
|
||||||
* Default is 10.
|
graphModelChanged = (changes) => {
|
||||||
*/
|
var now = new Date().getTime();
|
||||||
autoSaveDelay = 10;
|
var dt = (now - this.lastSnapshot) / 1000;
|
||||||
|
|
||||||
/**
|
if (dt > this.autoSaveDelay ||
|
||||||
* Variable: autoSaveThrottle
|
(this.ignoredChanges >= this.autoSaveThreshold &&
|
||||||
*
|
dt > this.autoSaveThrottle)) {
|
||||||
* Minimum amount of seconds between two consecutive autosaves triggered by
|
this.save();
|
||||||
* more than <autoSaveThreshhold> changes within a timespan of less than
|
this.reset();
|
||||||
* <autoSaveDelay> seconds. Eg. a value of 1 (s) means the graph is not
|
} else {
|
||||||
* stored more than once per second even if there are more than
|
// Increments the number of ignored changes
|
||||||
* <autoSaveThreshold> changes within that timespan. Default is 2.
|
this.ignoredChanges++;
|
||||||
*/
|
}
|
||||||
autoSaveThrottle = 2;
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Variable: autoSaveThreshold
|
* Function: reset
|
||||||
*
|
*
|
||||||
* Minimum amount of ignored changes before an autosave. Eg. a value of 2
|
* Resets all counters.
|
||||||
* means after 2 change of the graph model the autosave will trigger if the
|
*/
|
||||||
* condition below is true. Default is 5.
|
reset = () => {
|
||||||
*/
|
this.lastSnapshot = new Date().getTime();
|
||||||
autoSaveThreshold = 5;
|
this.ignoredChanges = 0;
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Variable: ignoredChanges
|
* Function: destroy
|
||||||
*
|
*
|
||||||
* Counter for ignored changes in autosave.
|
* Removes all handlers from the <graph> and deletes the reference to it.
|
||||||
*/
|
*/
|
||||||
ignoredChanges = 0;
|
destroy = () => {
|
||||||
|
this.setGraph(null);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
export default mxAutoSaveManager;
|
||||||
* Variable: lastSnapshot
|
|
||||||
*
|
|
||||||
* Used for autosaving. See <autosave>.
|
|
||||||
*/
|
|
||||||
lastSnapshot = 0;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Variable: enabled
|
|
||||||
*
|
|
||||||
* Specifies if event handling is enabled. Default is true.
|
|
||||||
*/
|
|
||||||
enabled = true;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Variable: changeHandler
|
|
||||||
*
|
|
||||||
* Holds the function that handles graph model changes.
|
|
||||||
*/
|
|
||||||
changeHandler = null;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Function: isEnabled
|
|
||||||
*
|
|
||||||
* Returns true if events are handled. This implementation
|
|
||||||
* returns <enabled>.
|
|
||||||
*/
|
|
||||||
isEnabled = ()=>
|
|
||||||
{
|
|
||||||
return this.enabled;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Function: setEnabled
|
|
||||||
*
|
|
||||||
* Enables or disables event handling. This implementation
|
|
||||||
* updates <enabled>.
|
|
||||||
*
|
|
||||||
* Parameters:
|
|
||||||
*
|
|
||||||
* enabled - Boolean that specifies the new enabled state.
|
|
||||||
*/
|
|
||||||
setEnabled = (value)=>
|
|
||||||
{
|
|
||||||
this.enabled = value;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Function: setGraph
|
|
||||||
*
|
|
||||||
* Sets the graph that the layouts operate on.
|
|
||||||
*/
|
|
||||||
setGraph = (graph)=>
|
|
||||||
{
|
|
||||||
if (this.graph != null)
|
|
||||||
{
|
|
||||||
this.graph.getModel().removeListener(this.changeHandler);
|
|
||||||
}
|
|
||||||
|
|
||||||
this.graph = graph;
|
|
||||||
|
|
||||||
if (this.graph != null)
|
|
||||||
{
|
|
||||||
this.graph.getModel().addListener(mxEvent.CHANGE, this.changeHandler);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Function: save
|
|
||||||
*
|
|
||||||
* Empty hook that is called if the graph should be saved.
|
|
||||||
*/
|
|
||||||
save = ()=>
|
|
||||||
{
|
|
||||||
// empty
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Function: graphModelChanged
|
|
||||||
*
|
|
||||||
* Invoked when the graph model has changed.
|
|
||||||
*/
|
|
||||||
graphModelChanged = (changes)=>
|
|
||||||
{
|
|
||||||
var now = new Date().getTime();
|
|
||||||
var dt = (now - this.lastSnapshot) / 1000;
|
|
||||||
|
|
||||||
if (dt > this.autoSaveDelay ||
|
|
||||||
(this.ignoredChanges >= this.autoSaveThreshold &&
|
|
||||||
dt > this.autoSaveThrottle))
|
|
||||||
{
|
|
||||||
this.save();
|
|
||||||
this.reset();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// Increments the number of ignored changes
|
|
||||||
this.ignoredChanges++;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Function: reset
|
|
||||||
*
|
|
||||||
* Resets all counters.
|
|
||||||
*/
|
|
||||||
reset = ()=>
|
|
||||||
{
|
|
||||||
this.lastSnapshot = new Date().getTime();
|
|
||||||
this.ignoredChanges = 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Function: destroy
|
|
||||||
*
|
|
||||||
* Removes all handlers from the <graph> and deletes the reference to it.
|
|
||||||
*/
|
|
||||||
destroy = ()=>
|
|
||||||
{
|
|
||||||
this.setGraph(null);
|
|
||||||
};
|
|
||||||
|
|
|
@ -2,8 +2,7 @@
|
||||||
* Copyright (c) 2006-2015, JGraph Ltd
|
* Copyright (c) 2006-2015, JGraph Ltd
|
||||||
* Copyright (c) 2006-2015, Gaudenz Alder
|
* Copyright (c) 2006-2015, Gaudenz Alder
|
||||||
*/
|
*/
|
||||||
var mxClipboard =
|
var mxClipboard = {
|
||||||
{
|
|
||||||
/**
|
/**
|
||||||
* Class: mxClipboard
|
* Class: mxClipboard
|
||||||
*
|
*
|
||||||
|
@ -217,5 +216,6 @@ var mxClipboard =
|
||||||
|
|
||||||
return cells;
|
return cells;
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export default mxClipboard;
|
||||||
|
|
|
@ -2,8 +2,8 @@
|
||||||
* Copyright (c) 2006-2015, JGraph Ltd
|
* Copyright (c) 2006-2015, JGraph Ltd
|
||||||
* Copyright (c) 2006-2015, Gaudenz Alder
|
* Copyright (c) 2006-2015, Gaudenz Alder
|
||||||
*/
|
*/
|
||||||
var mxConstants =
|
|
||||||
{
|
var mxConstants = {
|
||||||
/**
|
/**
|
||||||
* Class: mxConstants
|
* Class: mxConstants
|
||||||
*
|
*
|
||||||
|
@ -2336,3 +2336,5 @@
|
||||||
*/
|
*/
|
||||||
PERIMETER_TRIANGLE: 'trianglePerimeter'
|
PERIMETER_TRIANGLE: 'trianglePerimeter'
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export default mxConstants;
|
||||||
|
|
|
@ -12,119 +12,113 @@
|
||||||
*
|
*
|
||||||
* Constructs a new dictionary which allows object to be used as keys.
|
* Constructs a new dictionary which allows object to be used as keys.
|
||||||
*/
|
*/
|
||||||
function mxDictionary()
|
|
||||||
{
|
|
||||||
this.clear();
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
class mxDictionary {
|
||||||
* Function: map
|
constructor() {
|
||||||
*
|
this.clear();
|
||||||
* Stores the (key, value) pairs in this dictionary.
|
};
|
||||||
*/
|
|
||||||
map = null;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function: clear
|
* Function: map
|
||||||
*
|
*
|
||||||
* Clears the dictionary.
|
* Stores the (key, value) pairs in this dictionary.
|
||||||
*/
|
*/
|
||||||
clear = ()=>
|
map = null;
|
||||||
{
|
|
||||||
this.map = {};
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function: get
|
* Function: clear
|
||||||
*
|
*
|
||||||
* Returns the value for the given key.
|
* Clears the dictionary.
|
||||||
*/
|
*/
|
||||||
get = (key)=>
|
clear = () => {
|
||||||
{
|
this.map = {};
|
||||||
var id = mxObjectIdentity.get(key);
|
};
|
||||||
|
|
||||||
return this.map[id];
|
/**
|
||||||
};
|
* Function: get
|
||||||
|
*
|
||||||
|
* Returns the value for the given key.
|
||||||
|
*/
|
||||||
|
get = (key) => {
|
||||||
|
var id = mxObjectIdentity.get(key);
|
||||||
|
|
||||||
/**
|
return this.map[id];
|
||||||
* Function: put
|
};
|
||||||
*
|
|
||||||
* Stores the value under the given key and returns the previous
|
|
||||||
* value for that key.
|
|
||||||
*/
|
|
||||||
put = (key, value)=>
|
|
||||||
{
|
|
||||||
var id = mxObjectIdentity.get(key);
|
|
||||||
var previous = this.map[id];
|
|
||||||
this.map[id] = value;
|
|
||||||
|
|
||||||
return previous;
|
/**
|
||||||
};
|
* Function: put
|
||||||
|
*
|
||||||
|
* Stores the value under the given key and returns the previous
|
||||||
|
* value for that key.
|
||||||
|
*/
|
||||||
|
put = (key, value) => {
|
||||||
|
var id = mxObjectIdentity.get(key);
|
||||||
|
var previous = this.map[id];
|
||||||
|
this.map[id] = value;
|
||||||
|
|
||||||
/**
|
return previous;
|
||||||
* Function: remove
|
};
|
||||||
*
|
|
||||||
* Removes the value for the given key and returns the value that
|
|
||||||
* has been removed.
|
|
||||||
*/
|
|
||||||
remove = (key)=>
|
|
||||||
{
|
|
||||||
var id = mxObjectIdentity.get(key);
|
|
||||||
var previous = this.map[id];
|
|
||||||
delete this.map[id];
|
|
||||||
|
|
||||||
return previous;
|
/**
|
||||||
};
|
* Function: remove
|
||||||
|
*
|
||||||
|
* Removes the value for the given key and returns the value that
|
||||||
|
* has been removed.
|
||||||
|
*/
|
||||||
|
remove = (key) => {
|
||||||
|
var id = mxObjectIdentity.get(key);
|
||||||
|
var previous = this.map[id];
|
||||||
|
delete this.map[id];
|
||||||
|
|
||||||
/**
|
return previous;
|
||||||
* Function: getKeys
|
};
|
||||||
*
|
|
||||||
* Returns all keys as an array.
|
|
||||||
*/
|
|
||||||
getKeys = ()=>
|
|
||||||
{
|
|
||||||
var result = [];
|
|
||||||
|
|
||||||
for (var key in this.map)
|
/**
|
||||||
{
|
* Function: getKeys
|
||||||
result.push(key);
|
*
|
||||||
}
|
* Returns all keys as an array.
|
||||||
|
*/
|
||||||
|
getKeys = () => {
|
||||||
|
var result = [];
|
||||||
|
|
||||||
return result;
|
for (var key in this.map) {
|
||||||
};
|
result.push(key);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
return result;
|
||||||
* Function: getValues
|
};
|
||||||
*
|
|
||||||
* Returns all values as an array.
|
|
||||||
*/
|
|
||||||
getValues = ()=>
|
|
||||||
{
|
|
||||||
var result = [];
|
|
||||||
|
|
||||||
for (var key in this.map)
|
/**
|
||||||
{
|
* Function: getValues
|
||||||
result.push(this.map[key]);
|
*
|
||||||
}
|
* Returns all values as an array.
|
||||||
|
*/
|
||||||
|
getValues = () => {
|
||||||
|
var result = [];
|
||||||
|
|
||||||
return result;
|
for (var key in this.map) {
|
||||||
};
|
result.push(this.map[key]);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
return result;
|
||||||
* Function: visit
|
};
|
||||||
*
|
|
||||||
* Visits all entries in the dictionary using the given function with the
|
/**
|
||||||
* following signature: (key, value)=> where key is a string and
|
* Function: visit
|
||||||
* value is an object.
|
*
|
||||||
*
|
* Visits all entries in the dictionary using the given function with the
|
||||||
* Parameters:
|
* following signature: (key, value)=> where key is a string and
|
||||||
*
|
* value is an object.
|
||||||
* visitor - A function that takes the key and value as arguments.
|
*
|
||||||
*/
|
* Parameters:
|
||||||
visit = (visitor)=>
|
*
|
||||||
{
|
* visitor - A function that takes the key and value as arguments.
|
||||||
for (var key in this.map)
|
*/
|
||||||
{
|
visit = (visitor) => {
|
||||||
visitor(key, this.map[key]);
|
for (var key in this.map) {
|
||||||
}
|
visitor(key, this.map[key]);
|
||||||
};
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export default mxDictionary;
|
||||||
|
|
|
@ -37,115 +37,108 @@
|
||||||
* container - Optional Container that contains the div. Default is the
|
* container - Optional Container that contains the div. Default is the
|
||||||
* window.
|
* window.
|
||||||
*/
|
*/
|
||||||
function mxDivResizer(div, container)
|
class mxDivResizer {
|
||||||
{
|
constructor(div, container) {
|
||||||
if (div.nodeName.toLowerCase() == 'div')
|
if (div.nodeName.toLowerCase() == 'div') {
|
||||||
{
|
if (container == null) {
|
||||||
if (container == null)
|
container = window;
|
||||||
{
|
}
|
||||||
container = window;
|
|
||||||
|
this.div = div;
|
||||||
|
var style = mxUtils.getCurrentStyle(div);
|
||||||
|
|
||||||
|
if (style != null) {
|
||||||
|
this.resizeWidth = style.width == 'auto';
|
||||||
|
this.resizeHeight = style.height == 'auto';
|
||||||
|
}
|
||||||
|
|
||||||
|
mxEvent.addListener(container, 'resize',
|
||||||
|
mxUtils.bind(this, (evt) => {
|
||||||
|
if (!this.handlingResize) {
|
||||||
|
this.handlingResize = true;
|
||||||
|
this.resize();
|
||||||
|
this.handlingResize = false;
|
||||||
|
}
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|
||||||
|
this.resize();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function: resizeWidth
|
||||||
|
*
|
||||||
|
* Boolean specifying if the width should be updated.
|
||||||
|
*/
|
||||||
|
resizeWidth = true;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function: resizeHeight
|
||||||
|
*
|
||||||
|
* Boolean specifying if the height should be updated.
|
||||||
|
*/
|
||||||
|
resizeHeight = true;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function: handlingResize
|
||||||
|
*
|
||||||
|
* Boolean specifying if the width should be updated.
|
||||||
|
*/
|
||||||
|
handlingResize = false;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function: resize
|
||||||
|
*
|
||||||
|
* Updates the style of the DIV after the window has been resized.
|
||||||
|
*/
|
||||||
|
resize = () => {
|
||||||
|
var w = this.getDocumentWidth();
|
||||||
|
var h = this.getDocumentHeight();
|
||||||
|
|
||||||
|
var l = parseInt(this.div.style.left);
|
||||||
|
var r = parseInt(this.div.style.right);
|
||||||
|
var t = parseInt(this.div.style.top);
|
||||||
|
var b = parseInt(this.div.style.bottom);
|
||||||
|
|
||||||
|
if (this.resizeWidth &&
|
||||||
|
!isNaN(l) &&
|
||||||
|
!isNaN(r) &&
|
||||||
|
l >= 0 &&
|
||||||
|
r >= 0 &&
|
||||||
|
w - r - l > 0) {
|
||||||
|
this.div.style.width = (w - r - l) + 'px';
|
||||||
}
|
}
|
||||||
|
|
||||||
this.div = div;
|
if (this.resizeHeight &&
|
||||||
var style = mxUtils.getCurrentStyle(div);
|
!isNaN(t) &&
|
||||||
|
!isNaN(b) &&
|
||||||
if (style != null)
|
t >= 0 &&
|
||||||
{
|
b >= 0 &&
|
||||||
this.resizeWidth = style.width == 'auto';
|
h - t - b > 0) {
|
||||||
this.resizeHeight = style.height == 'auto';
|
this.div.style.height = (h - t - b) + 'px';
|
||||||
}
|
}
|
||||||
|
};
|
||||||
mxEvent.addListener(container, 'resize',
|
|
||||||
mxUtils.bind(this, (evt)=>
|
|
||||||
{
|
|
||||||
if (!this.handlingResize)
|
|
||||||
{
|
|
||||||
this.handlingResize = true;
|
|
||||||
this.resize();
|
|
||||||
this.handlingResize = false;
|
|
||||||
}
|
|
||||||
})
|
|
||||||
);
|
|
||||||
|
|
||||||
this.resize();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function: resizeWidth
|
* Function: getDocumentWidth
|
||||||
*
|
*
|
||||||
* Boolean specifying if the width should be updated.
|
* Hook for subclassers to return the width of the document (without
|
||||||
*/
|
* scrollbars).
|
||||||
resizeWidth = true;
|
*/
|
||||||
|
getDocumentWidth = () => {
|
||||||
|
return document.body.clientWidth;
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function: resizeHeight
|
* Function: getDocumentHeight
|
||||||
*
|
*
|
||||||
* Boolean specifying if the height should be updated.
|
* Hook for subclassers to return the height of the document (without
|
||||||
*/
|
* scrollbars).
|
||||||
resizeHeight = true;
|
*/
|
||||||
|
getDocumentHeight = () => {
|
||||||
|
return document.body.clientHeight;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
export default mxDivResizer;
|
||||||
* Function: handlingResize
|
|
||||||
*
|
|
||||||
* Boolean specifying if the width should be updated.
|
|
||||||
*/
|
|
||||||
handlingResize = false;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Function: resize
|
|
||||||
*
|
|
||||||
* Updates the style of the DIV after the window has been resized.
|
|
||||||
*/
|
|
||||||
resize = ()=>
|
|
||||||
{
|
|
||||||
var w = this.getDocumentWidth();
|
|
||||||
var h = this.getDocumentHeight();
|
|
||||||
|
|
||||||
var l = parseInt(this.div.style.left);
|
|
||||||
var r = parseInt(this.div.style.right);
|
|
||||||
var t = parseInt(this.div.style.top);
|
|
||||||
var b = parseInt(this.div.style.bottom);
|
|
||||||
|
|
||||||
if (this.resizeWidth &&
|
|
||||||
!isNaN(l) &&
|
|
||||||
!isNaN(r) &&
|
|
||||||
l >= 0 &&
|
|
||||||
r >= 0 &&
|
|
||||||
w - r - l > 0)
|
|
||||||
{
|
|
||||||
this.div.style.width = (w - r - l)+'px';
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this.resizeHeight &&
|
|
||||||
!isNaN(t) &&
|
|
||||||
!isNaN(b) &&
|
|
||||||
t >= 0 &&
|
|
||||||
b >= 0 &&
|
|
||||||
h - t - b > 0)
|
|
||||||
{
|
|
||||||
this.div.style.height = (h - t - b)+'px';
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Function: getDocumentWidth
|
|
||||||
*
|
|
||||||
* Hook for subclassers to return the width of the document (without
|
|
||||||
* scrollbars).
|
|
||||||
*/
|
|
||||||
getDocumentWidth = ()=>
|
|
||||||
{
|
|
||||||
return document.body.clientWidth;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Function: getDocumentHeight
|
|
||||||
*
|
|
||||||
* Hook for subclassers to return the height of the document (without
|
|
||||||
* scrollbars).
|
|
||||||
*/
|
|
||||||
getDocumentHeight = ()=>
|
|
||||||
{
|
|
||||||
return document.body.clientHeight;
|
|
||||||
};
|
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -2,97 +2,84 @@
|
||||||
* Copyright (c) 2006-2015, JGraph Ltd
|
* Copyright (c) 2006-2015, JGraph Ltd
|
||||||
* Copyright (c) 2006-2015, Gaudenz Alder
|
* Copyright (c) 2006-2015, Gaudenz Alder
|
||||||
*/
|
*/
|
||||||
var mxEffects =
|
var mxEffects = {
|
||||||
{
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class: mxEffects
|
* Class: mxEffects
|
||||||
*
|
*
|
||||||
* Provides animation effects.
|
* Provides animation effects.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function: animateChanges
|
* Function: animateChanges
|
||||||
*
|
*
|
||||||
* Asynchronous animated move operation. See also: <mxMorphing>.
|
* Asynchronous animated move operation. See also: <mxMorphing>.
|
||||||
*
|
*
|
||||||
* Example:
|
* Example:
|
||||||
*
|
*
|
||||||
* (code)
|
* (code)
|
||||||
* graph.model.addListener(mxEvent.CHANGE, (sender, evt)=>
|
* graph.model.addListener(mxEvent.CHANGE, (sender, evt)=>
|
||||||
* {
|
* {
|
||||||
* var changes = evt.getProperty('edit').changes;
|
* var changes = evt.getProperty('edit').changes;
|
||||||
*
|
*
|
||||||
* if (changes.length < 10)
|
* if (changes.length < 10)
|
||||||
* {
|
* {
|
||||||
* mxEffects.animateChanges(graph, changes);
|
* mxEffects.animateChanges(graph, changes);
|
||||||
* }
|
* }
|
||||||
* });
|
* });
|
||||||
* (end)
|
* (end)
|
||||||
*
|
*
|
||||||
* Parameters:
|
* Parameters:
|
||||||
*
|
*
|
||||||
* graph - <mxGraph> that received the changes.
|
* graph - <mxGraph> that received the changes.
|
||||||
* changes - Array of changes to be animated.
|
* changes - Array of changes to be animated.
|
||||||
* done - Optional function argument that is invoked after the
|
* done - Optional function argument that is invoked after the
|
||||||
* last step of the animation.
|
* last step of the animation.
|
||||||
*/
|
*/
|
||||||
animateChanges: (graph, changes, done)=>
|
animateChanges: (graph, changes, done) => {
|
||||||
{
|
|
||||||
var maxStep = 10;
|
var maxStep = 10;
|
||||||
var step = 0;
|
var step = 0;
|
||||||
|
|
||||||
var animate = ()=>
|
var animate = () => {
|
||||||
{
|
|
||||||
var isRequired = false;
|
var isRequired = false;
|
||||||
|
|
||||||
for (var i = 0; i < changes.length; i++)
|
for (var i = 0; i < changes.length; i++) {
|
||||||
{
|
|
||||||
var change = changes[i];
|
var change = changes[i];
|
||||||
|
|
||||||
if (change instanceof mxGeometryChange ||
|
if (change instanceof mxGeometryChange ||
|
||||||
change instanceof mxTerminalChange ||
|
change instanceof mxTerminalChange ||
|
||||||
change instanceof mxValueChange ||
|
change instanceof mxValueChange ||
|
||||||
change instanceof mxChildChange ||
|
change instanceof mxChildChange ||
|
||||||
change instanceof mxStyleChange)
|
change instanceof mxStyleChange) {
|
||||||
{
|
|
||||||
var state = graph.getView().getState(change.cell || change.child, false);
|
var state = graph.getView().getState(change.cell || change.child, false);
|
||||||
|
|
||||||
if (state != null)
|
if (state != null) {
|
||||||
{
|
|
||||||
isRequired = true;
|
isRequired = true;
|
||||||
|
|
||||||
if (change.constructor != mxGeometryChange || graph.model.isEdge(change.cell))
|
if (change.constructor != mxGeometryChange || graph.model.isEdge(change.cell)) {
|
||||||
{
|
|
||||||
mxUtils.setOpacity(state.shape.node, 100 * step / maxStep);
|
mxUtils.setOpacity(state.shape.node, 100 * step / maxStep);
|
||||||
}
|
} else {
|
||||||
else
|
var scale = graph.getView().scale;
|
||||||
{
|
|
||||||
var scale = graph.getView().scale;
|
|
||||||
|
|
||||||
var dx = (change.geometry.x - change.previous.x) * scale;
|
var dx = (change.geometry.x - change.previous.x) * scale;
|
||||||
var dy = (change.geometry.y - change.previous.y) * scale;
|
var dy = (change.geometry.y - change.previous.y) * scale;
|
||||||
|
|
||||||
var sx = (change.geometry.width - change.previous.width) * scale;
|
var sx = (change.geometry.width - change.previous.width) * scale;
|
||||||
var sy = (change.geometry.height - change.previous.height) * scale;
|
var sy = (change.geometry.height - change.previous.height) * scale;
|
||||||
|
|
||||||
if (step == 0)
|
if (step == 0) {
|
||||||
{
|
|
||||||
state.x -= dx;
|
state.x -= dx;
|
||||||
state.y -= dy;
|
state.y -= dy;
|
||||||
state.width -= sx;
|
state.width -= sx;
|
||||||
state.height -= sy;
|
state.height -= sy;
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
state.x += dx / maxStep;
|
state.x += dx / maxStep;
|
||||||
state.y += dy / maxStep;
|
state.y += dy / maxStep;
|
||||||
state.width += sx / maxStep;
|
state.width += sx / maxStep;
|
||||||
state.height += sy / maxStep;
|
state.height += sy / maxStep;
|
||||||
}
|
}
|
||||||
|
|
||||||
graph.cellRenderer.redraw(state);
|
graph.cellRenderer.redraw(state);
|
||||||
|
|
||||||
// Fades all connected edges and children
|
// Fades all connected edges and children
|
||||||
mxEffects.cascadeOpacity(graph, change.cell, 100 * step / maxStep);
|
mxEffects.cascadeOpacity(graph, change.cell, 100 * step / maxStep);
|
||||||
}
|
}
|
||||||
|
@ -100,60 +87,51 @@ var mxEffects =
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (step < maxStep && isRequired)
|
if (step < maxStep && isRequired) {
|
||||||
{
|
|
||||||
step++;
|
step++;
|
||||||
window.setTimeout(animate, delay);
|
window.setTimeout(animate, delay);
|
||||||
}
|
} else if (done != null) {
|
||||||
else if (done != null)
|
|
||||||
{
|
|
||||||
done();
|
done();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
var delay = 30;
|
var delay = 30;
|
||||||
animate();
|
animate();
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function: cascadeOpacity
|
* Function: cascadeOpacity
|
||||||
*
|
*
|
||||||
* Sets the opacity on the given cell and its descendants.
|
* Sets the opacity on the given cell and its descendants.
|
||||||
*
|
*
|
||||||
* Parameters:
|
* Parameters:
|
||||||
*
|
*
|
||||||
* graph - <mxGraph> that contains the cells.
|
* graph - <mxGraph> that contains the cells.
|
||||||
* cell - <mxCell> to set the opacity for.
|
* cell - <mxCell> to set the opacity for.
|
||||||
* opacity - New value for the opacity in %.
|
* opacity - New value for the opacity in %.
|
||||||
*/
|
*/
|
||||||
cascadeOpacity: (graph, cell, opacity)=>
|
cascadeOpacity: (graph, cell, opacity) => {
|
||||||
{
|
|
||||||
// Fades all children
|
// Fades all children
|
||||||
var childCount = graph.model.getChildCount(cell);
|
var childCount = graph.model.getChildCount(cell);
|
||||||
|
|
||||||
for (var i=0; i<childCount; i++)
|
for (var i = 0; i < childCount; i++) {
|
||||||
{
|
|
||||||
var child = graph.model.getChildAt(cell, i);
|
var child = graph.model.getChildAt(cell, i);
|
||||||
var childState = graph.getView().getState(child);
|
var childState = graph.getView().getState(child);
|
||||||
|
|
||||||
if (childState != null)
|
if (childState != null) {
|
||||||
{
|
|
||||||
mxUtils.setOpacity(childState.shape.node, opacity);
|
mxUtils.setOpacity(childState.shape.node, opacity);
|
||||||
mxEffects.cascadeOpacity(graph, child, opacity);
|
mxEffects.cascadeOpacity(graph, child, opacity);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Fades all connected edges
|
// Fades all connected edges
|
||||||
var edges = graph.model.getEdges(cell);
|
var edges = graph.model.getEdges(cell);
|
||||||
|
|
||||||
if (edges != null)
|
if (edges != null) {
|
||||||
{
|
for (var i = 0; i < edges.length; i++) {
|
||||||
for (var i=0; i<edges.length; i++)
|
|
||||||
{
|
|
||||||
var edgeState = graph.getView().getState(edges[i]);
|
var edgeState = graph.getView().getState(edges[i]);
|
||||||
|
|
||||||
if (edgeState != null)
|
if (edgeState != null) {
|
||||||
{
|
|
||||||
mxUtils.setOpacity(edgeState.shape.node, opacity);
|
mxUtils.setOpacity(edgeState.shape.node, opacity);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -162,50 +140,41 @@ var mxEffects =
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function: fadeOut
|
* Function: fadeOut
|
||||||
*
|
*
|
||||||
* Asynchronous fade-out operation.
|
* Asynchronous fade-out operation.
|
||||||
*/
|
*/
|
||||||
fadeOut: (node, from, remove, step, delay, isEnabled)=>
|
fadeOut: (node, from, remove, step, delay, isEnabled) => {
|
||||||
{
|
|
||||||
step = step || 40;
|
step = step || 40;
|
||||||
delay = delay || 30;
|
delay = delay || 30;
|
||||||
|
|
||||||
var opacity = from || 100;
|
var opacity = from || 100;
|
||||||
|
|
||||||
mxUtils.setOpacity(node, opacity);
|
mxUtils.setOpacity(node, opacity);
|
||||||
|
|
||||||
if (isEnabled || isEnabled == null)
|
if (isEnabled || isEnabled == null) {
|
||||||
{
|
var f = () => {
|
||||||
var f = ()=>
|
opacity = Math.max(opacity - step, 0);
|
||||||
{
|
|
||||||
opacity = Math.max(opacity-step, 0);
|
|
||||||
mxUtils.setOpacity(node, opacity);
|
mxUtils.setOpacity(node, opacity);
|
||||||
|
|
||||||
if (opacity > 0)
|
if (opacity > 0) {
|
||||||
{
|
|
||||||
window.setTimeout(f, delay);
|
window.setTimeout(f, delay);
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
node.style.visibility = 'hidden';
|
node.style.visibility = 'hidden';
|
||||||
|
|
||||||
if (remove && node.parentNode)
|
if (remove && node.parentNode) {
|
||||||
{
|
|
||||||
node.parentNode.removeChild(node);
|
node.parentNode.removeChild(node);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
window.setTimeout(f, delay);
|
window.setTimeout(f, delay);
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
node.style.visibility = 'hidden';
|
node.style.visibility = 'hidden';
|
||||||
|
|
||||||
if (remove && node.parentNode)
|
if (remove && node.parentNode) {
|
||||||
{
|
|
||||||
node.parentNode.removeChild(node);
|
node.parentNode.removeChild(node);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export default mxEffects;
|
||||||
|
|
|
@ -2,110 +2,107 @@
|
||||||
* Copyright (c) 2006-2015, JGraph Ltd
|
* Copyright (c) 2006-2015, JGraph Ltd
|
||||||
* Copyright (c) 2006-2015, Gaudenz Alder
|
* Copyright (c) 2006-2015, Gaudenz Alder
|
||||||
*/
|
*/
|
||||||
/**
|
|
||||||
* Class: mxEventObject
|
|
||||||
*
|
|
||||||
* The mxEventObject is a wrapper for all properties of a single event.
|
|
||||||
* Additionally, it also offers functions to consume the event and check if it
|
|
||||||
* was consumed as follows:
|
|
||||||
*
|
|
||||||
* (code)
|
|
||||||
* evt.consume();
|
|
||||||
* INV: evt.isConsumed() == true
|
|
||||||
* (end)
|
|
||||||
*
|
|
||||||
* Constructor: mxEventObject
|
|
||||||
*
|
|
||||||
* Constructs a new event object with the specified name. An optional
|
|
||||||
* sequence of key, value pairs can be appended to define properties.
|
|
||||||
*
|
|
||||||
* Example:
|
|
||||||
*
|
|
||||||
* (code)
|
|
||||||
* new mxEventObject("eventName", key1, val1, .., keyN, valN)
|
|
||||||
* (end)
|
|
||||||
*/
|
|
||||||
function mxEventObject(name)
|
|
||||||
{
|
|
||||||
this.name = name;
|
|
||||||
this.properties = [];
|
|
||||||
|
|
||||||
for (var i = 1; i < arguments.length; i += 2)
|
class mxEventObject {
|
||||||
{
|
/**
|
||||||
if (arguments[i + 1] != null)
|
* Class: mxEventObject
|
||||||
{
|
*
|
||||||
this.properties[arguments[i]] = arguments[i + 1];
|
* The mxEventObject is a wrapper for all properties of a single event.
|
||||||
|
* Additionally, it also offers functions to consume the event and check if it
|
||||||
|
* was consumed as follows:
|
||||||
|
*
|
||||||
|
* (code)
|
||||||
|
* evt.consume();
|
||||||
|
* INV: evt.isConsumed() == true
|
||||||
|
* (end)
|
||||||
|
*
|
||||||
|
* Constructor: mxEventObject
|
||||||
|
*
|
||||||
|
* Constructs a new event object with the specified name. An optional
|
||||||
|
* sequence of key, value pairs can be appended to define properties.
|
||||||
|
*
|
||||||
|
* Example:
|
||||||
|
*
|
||||||
|
* (code)
|
||||||
|
* new mxEventObject("eventName", key1, val1, .., keyN, valN)
|
||||||
|
* (end)
|
||||||
|
*/
|
||||||
|
constructor(name) {
|
||||||
|
this.name = name;
|
||||||
|
this.properties = [];
|
||||||
|
|
||||||
|
for (var i = 1; i < arguments.length; i += 2) {
|
||||||
|
if (arguments[i + 1] != null) {
|
||||||
|
this.properties[arguments[i]] = arguments[i + 1];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Variable: name
|
* Variable: name
|
||||||
*
|
*
|
||||||
* Holds the name.
|
* Holds the name.
|
||||||
*/
|
*/
|
||||||
name = null;
|
name = null;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Variable: properties
|
* Variable: properties
|
||||||
*
|
*
|
||||||
* Holds the properties as an associative array.
|
* Holds the properties as an associative array.
|
||||||
*/
|
*/
|
||||||
properties = null;
|
properties = null;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Variable: consumed
|
* Variable: consumed
|
||||||
*
|
*
|
||||||
* Holds the consumed state. Default is false.
|
* Holds the consumed state. Default is false.
|
||||||
*/
|
*/
|
||||||
consumed = false;
|
consumed = false;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function: getName
|
* Function: getName
|
||||||
*
|
*
|
||||||
* Returns <name>.
|
* Returns <name>.
|
||||||
*/
|
*/
|
||||||
getName = ()=>
|
getName = () => {
|
||||||
{
|
return this.name;
|
||||||
return this.name;
|
};
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function: getProperties
|
* Function: getProperties
|
||||||
*
|
*
|
||||||
* Returns <properties>.
|
* Returns <properties>.
|
||||||
*/
|
*/
|
||||||
getProperties = ()=>
|
getProperties = () => {
|
||||||
{
|
return this.properties;
|
||||||
return this.properties;
|
};
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function: getProperty
|
* Function: getProperty
|
||||||
*
|
*
|
||||||
* Returns the property for the given key.
|
* Returns the property for the given key.
|
||||||
*/
|
*/
|
||||||
getProperty = (key)=>
|
getProperty = (key) => {
|
||||||
{
|
return this.properties[key];
|
||||||
return this.properties[key];
|
};
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function: isConsumed
|
* Function: isConsumed
|
||||||
*
|
*
|
||||||
* Returns true if the event has been consumed.
|
* Returns true if the event has been consumed.
|
||||||
*/
|
*/
|
||||||
isConsumed = ()=>
|
isConsumed = () => {
|
||||||
{
|
return this.consumed;
|
||||||
return this.consumed;
|
};
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function: consume
|
* Function: consume
|
||||||
*
|
*
|
||||||
* Consumes the event.
|
* Consumes the event.
|
||||||
*/
|
*/
|
||||||
consume = ()=>
|
consume = () => {
|
||||||
{
|
this.consumed = true;
|
||||||
this.consumed = true;
|
};
|
||||||
};
|
}
|
||||||
|
|
||||||
|
export default mxEventObject;
|
||||||
|
|
|
@ -2,188 +2,175 @@
|
||||||
* Copyright (c) 2006-2015, JGraph Ltd
|
* Copyright (c) 2006-2015, JGraph Ltd
|
||||||
* Copyright (c) 2006-2015, Gaudenz Alder
|
* Copyright (c) 2006-2015, Gaudenz Alder
|
||||||
*/
|
*/
|
||||||
/**
|
|
||||||
* Class: mxEventSource
|
|
||||||
*
|
|
||||||
* Base class for objects that dispatch named events. To create a subclass that
|
|
||||||
* inherits from mxEventSource, the following code is used.
|
|
||||||
*
|
|
||||||
* (code)
|
|
||||||
* function MyClass() { };
|
|
||||||
*
|
|
||||||
* MyClass.prototype = new mxEventSource();
|
|
||||||
* constructor = MyClass;
|
|
||||||
* (end)
|
|
||||||
*
|
|
||||||
* Known Subclasses:
|
|
||||||
*
|
|
||||||
* <mxGraphModel>, <mxGraph>, <mxGraphView>, <mxEditor>, <mxCellOverlay>,
|
|
||||||
* <mxToolbar>, <mxWindow>
|
|
||||||
*
|
|
||||||
* Constructor: mxEventSource
|
|
||||||
*
|
|
||||||
* Constructs a new event source.
|
|
||||||
*/
|
|
||||||
function mxEventSource(eventSource)
|
|
||||||
{
|
|
||||||
this.setEventSource(eventSource);
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
import mxEventObject from "./mxEventObject";
|
||||||
* Variable: eventListeners
|
|
||||||
*
|
|
||||||
* Holds the event names and associated listeners in an array. The array
|
|
||||||
* contains the event name followed by the respective listener for each
|
|
||||||
* registered listener.
|
|
||||||
*/
|
|
||||||
eventListeners = null;
|
|
||||||
|
|
||||||
/**
|
class mxEventSource {
|
||||||
* Variable: eventsEnabled
|
/**
|
||||||
*
|
* Variable: eventListeners
|
||||||
* Specifies if events can be fired. Default is true.
|
*
|
||||||
*/
|
* Holds the event names and associated listeners in an array. The array
|
||||||
eventsEnabled = true;
|
* contains the event name followed by the respective listener for each
|
||||||
|
* registered listener.
|
||||||
|
*/
|
||||||
|
eventListeners = null;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Variable: eventSource
|
* Variable: eventsEnabled
|
||||||
*
|
*
|
||||||
* Optional source for events. Default is null.
|
* Specifies if events can be fired. Default is true.
|
||||||
*/
|
*/
|
||||||
eventSource = null;
|
eventsEnabled = true;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function: isEventsEnabled
|
* Variable: eventSource
|
||||||
*
|
*
|
||||||
* Returns <eventsEnabled>.
|
* Optional source for events. Default is null.
|
||||||
*/
|
*/
|
||||||
isEventsEnabled = ()=>
|
eventSource = null;
|
||||||
{
|
|
||||||
return this.eventsEnabled;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function: setEventsEnabled
|
* Class: mxEventSource
|
||||||
*
|
*
|
||||||
* Sets <eventsEnabled>.
|
* Base class for objects that dispatch named events. To create a subclass that
|
||||||
*/
|
* inherits from mxEventSource, the following code is used.
|
||||||
setEventsEnabled = (value)=>
|
*
|
||||||
{
|
* (code)
|
||||||
this.eventsEnabled = value;
|
* function MyClass() { };
|
||||||
};
|
*
|
||||||
|
* MyClass.prototype = new mxEventSource();
|
||||||
|
* constructor = MyClass;
|
||||||
|
* (end)
|
||||||
|
*
|
||||||
|
* Known Subclasses:
|
||||||
|
*
|
||||||
|
* <mxGraphModel>, <mxGraph>, <mxGraphView>, <mxEditor>, <mxCellOverlay>,
|
||||||
|
* <mxToolbar>, <mxWindow>
|
||||||
|
*
|
||||||
|
* Constructor: mxEventSource
|
||||||
|
*
|
||||||
|
* Constructs a new event source.
|
||||||
|
*/
|
||||||
|
constructor(eventSource) {
|
||||||
|
this.setEventSource(eventSource);
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function: getEventSource
|
* Function: isEventsEnabled
|
||||||
*
|
*
|
||||||
* Returns <eventSource>.
|
* Returns <eventsEnabled>.
|
||||||
*/
|
*/
|
||||||
getEventSource = ()=>
|
isEventsEnabled = () => {
|
||||||
{
|
return this.eventsEnabled;
|
||||||
return this.eventSource;
|
};
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function: setEventSource
|
* Function: setEventsEnabled
|
||||||
*
|
*
|
||||||
* Sets <eventSource>.
|
* Sets <eventsEnabled>.
|
||||||
*/
|
*/
|
||||||
setEventSource = (value)=>
|
setEventsEnabled = (value) => {
|
||||||
{
|
this.eventsEnabled = value;
|
||||||
this.eventSource = value;
|
};
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function: addListener
|
* Function: getEventSource
|
||||||
*
|
*
|
||||||
* Binds the specified function to the given event name. If no event name
|
* Returns <eventSource>.
|
||||||
* is given, then the listener is registered for all events.
|
*/
|
||||||
*
|
getEventSource = () => {
|
||||||
* The parameters of the listener are the sender and an <mxEventObject>.
|
return this.eventSource;
|
||||||
*/
|
};
|
||||||
addListener = (name, funct)=>
|
|
||||||
{
|
|
||||||
if (this.eventListeners == null)
|
|
||||||
{
|
|
||||||
this.eventListeners = [];
|
|
||||||
}
|
|
||||||
|
|
||||||
this.eventListeners.push(name);
|
|
||||||
this.eventListeners.push(funct);
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function: removeListener
|
* Function: setEventSource
|
||||||
*
|
*
|
||||||
* Removes all occurrences of the given listener from <eventListeners>.
|
* Sets <eventSource>.
|
||||||
*/
|
*/
|
||||||
removeListener = (funct)=>
|
setEventSource = (value) => {
|
||||||
{
|
this.eventSource = value;
|
||||||
if (this.eventListeners != null)
|
};
|
||||||
{
|
|
||||||
var i = 0;
|
/**
|
||||||
|
* Function: addListener
|
||||||
while (i < this.eventListeners.length)
|
*
|
||||||
{
|
* Binds the specified function to the given event name. If no event name
|
||||||
if (this.eventListeners[i+1] == funct)
|
* is given, then the listener is registered for all events.
|
||||||
{
|
*
|
||||||
this.eventListeners.splice(i, 2);
|
* The parameters of the listener are the sender and an <mxEventObject>.
|
||||||
}
|
*/
|
||||||
else
|
addListener = (name, funct) => {
|
||||||
{
|
if (this.eventListeners == null) {
|
||||||
i += 2;
|
this.eventListeners = [];
|
||||||
|
}
|
||||||
|
|
||||||
|
this.eventListeners.push(name);
|
||||||
|
this.eventListeners.push(funct);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function: removeListener
|
||||||
|
*
|
||||||
|
* Removes all occurrences of the given listener from <eventListeners>.
|
||||||
|
*/
|
||||||
|
removeListener = (funct) => {
|
||||||
|
if (this.eventListeners != null) {
|
||||||
|
var i = 0;
|
||||||
|
|
||||||
|
while (i < this.eventListeners.length) {
|
||||||
|
if (this.eventListeners[i + 1] == funct) {
|
||||||
|
this.eventListeners.splice(i, 2);
|
||||||
|
} else {
|
||||||
|
i += 2;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function: fireEvent
|
* Function: fireEvent
|
||||||
*
|
*
|
||||||
* Dispatches the given event to the listeners which are registered for
|
* Dispatches the given event to the listeners which are registered for
|
||||||
* the event. The sender argument is optional. The current execution scope
|
* the event. The sender argument is optional. The current execution scope
|
||||||
* ("this") is used for the listener invocation (see <mxUtils.bind>).
|
* ("this") is used for the listener invocation (see <mxUtils.bind>).
|
||||||
*
|
*
|
||||||
* Example:
|
* Example:
|
||||||
*
|
*
|
||||||
* (code)
|
* (code)
|
||||||
* fireEvent(new mxEventObject("eventName", key1, val1, .., keyN, valN))
|
* fireEvent(new mxEventObject("eventName", key1, val1, .., keyN, valN))
|
||||||
* (end)
|
* (end)
|
||||||
*
|
*
|
||||||
* Parameters:
|
* Parameters:
|
||||||
*
|
*
|
||||||
* evt - <mxEventObject> that represents the event.
|
* evt - <mxEventObject> that represents the event.
|
||||||
* sender - Optional sender to be passed to the listener. Default value is
|
* sender - Optional sender to be passed to the listener. Default value is
|
||||||
* the return value of <getEventSource>.
|
* the return value of <getEventSource>.
|
||||||
*/
|
*/
|
||||||
fireEvent = (evt, sender)=>
|
fireEvent = (evt, sender) => {
|
||||||
{
|
if (this.eventListeners != null && this.isEventsEnabled()) {
|
||||||
if (this.eventListeners != null && this.isEventsEnabled())
|
if (evt == null) {
|
||||||
{
|
evt = new mxEventObject();
|
||||||
if (evt == null)
|
}
|
||||||
{
|
|
||||||
evt = new mxEventObject();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (sender == null)
|
|
||||||
{
|
|
||||||
sender = this.getEventSource();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (sender == null)
|
if (sender == null) {
|
||||||
{
|
sender = this.getEventSource();
|
||||||
sender = this;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
var args = [sender, evt];
|
if (sender == null) {
|
||||||
|
sender = this;
|
||||||
for (var i = 0; i < this.eventListeners.length; i += 2)
|
}
|
||||||
{
|
|
||||||
var listen = this.eventListeners[i];
|
var args = [sender, evt];
|
||||||
|
|
||||||
if (listen == null || listen == evt.getName())
|
for (var i = 0; i < this.eventListeners.length; i += 2) {
|
||||||
{
|
var listen = this.eventListeners[i];
|
||||||
this.eventListeners[i+1].apply(this, args);
|
|
||||||
|
if (listen == null || listen == evt.getName()) {
|
||||||
|
this.eventListeners[i + 1].apply(this, args);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
};
|
}
|
||||||
|
|
||||||
|
export default mxEventSource;
|
||||||
|
|
|
@ -2,201 +2,190 @@
|
||||||
* Copyright (c) 2006-2015, JGraph Ltd
|
* Copyright (c) 2006-2015, JGraph Ltd
|
||||||
* Copyright (c) 2006-2015, Gaudenz Alder
|
* Copyright (c) 2006-2015, Gaudenz Alder
|
||||||
*/
|
*/
|
||||||
/**
|
|
||||||
* Class: mxForm
|
|
||||||
*
|
|
||||||
* A simple class for creating HTML forms.
|
|
||||||
*
|
|
||||||
* Constructor: mxForm
|
|
||||||
*
|
|
||||||
* Creates a HTML table using the specified classname.
|
|
||||||
*/
|
|
||||||
function mxForm(className)
|
|
||||||
{
|
|
||||||
this.table = document.createElement('table');
|
|
||||||
this.table.className = className;
|
|
||||||
this.body = document.createElement('tbody');
|
|
||||||
|
|
||||||
this.table.appendChild(this.body);
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
class mxForm {
|
||||||
* Variable: table
|
/**
|
||||||
*
|
* Variable: table
|
||||||
* Holds the DOM node that represents the table.
|
*
|
||||||
*/
|
* Holds the DOM node that represents the table.
|
||||||
table = null;
|
*/
|
||||||
|
table = null;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Variable: body
|
* Variable: body
|
||||||
*
|
*
|
||||||
* Holds the DOM node that represents the tbody (table body). New rows
|
* Holds the DOM node that represents the tbody (table body). New rows
|
||||||
* can be added to this object using DOM API.
|
* can be added to this object using DOM API.
|
||||||
*/
|
*/
|
||||||
body = false;
|
body = false;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function: getTable
|
* Class: mxForm
|
||||||
*
|
*
|
||||||
* Returns the table that contains this form.
|
* A simple class for creating HTML forms.
|
||||||
*/
|
*
|
||||||
getTable = ()=>
|
* Constructor: mxForm
|
||||||
{
|
*
|
||||||
return this.table;
|
* Creates a HTML table using the specified classname.
|
||||||
};
|
*/
|
||||||
|
constructor(className) {
|
||||||
|
this.table = document.createElement('table');
|
||||||
|
this.table.className = className;
|
||||||
|
this.body = document.createElement('tbody');
|
||||||
|
|
||||||
/**
|
this.table.appendChild(this.body);
|
||||||
* Function: addButtons
|
};
|
||||||
*
|
|
||||||
* Helper method to add an OK and Cancel button using the respective
|
|
||||||
* functions.
|
|
||||||
*/
|
|
||||||
addButtons = (okFunct, cancelFunct)=>
|
|
||||||
{
|
|
||||||
var tr = document.createElement('tr');
|
|
||||||
var td = document.createElement('td');
|
|
||||||
tr.appendChild(td);
|
|
||||||
td = document.createElement('td');
|
|
||||||
|
|
||||||
// Adds the ok button
|
/**
|
||||||
var button = document.createElement('button');
|
* Function: getTable
|
||||||
mxUtils.write(button, mxResources.get('ok') || 'OK');
|
*
|
||||||
td.appendChild(button);
|
* Returns the table that contains this form.
|
||||||
|
*/
|
||||||
|
getTable = () => {
|
||||||
|
return this.table;
|
||||||
|
};
|
||||||
|
|
||||||
mxEvent.addListener(button, 'click', ()=>
|
/**
|
||||||
{
|
* Function: addButtons
|
||||||
okFunct();
|
*
|
||||||
});
|
* Helper method to add an OK and Cancel button using the respective
|
||||||
|
* functions.
|
||||||
// Adds the cancel button
|
*/
|
||||||
button = document.createElement('button');
|
addButtons = (okFunct, cancelFunct) => {
|
||||||
mxUtils.write(button, mxResources.get('cancel') || 'Cancel');
|
var tr = document.createElement('tr');
|
||||||
td.appendChild(button);
|
var td = document.createElement('td');
|
||||||
|
tr.appendChild(td);
|
||||||
mxEvent.addListener(button, 'click', ()=>
|
td = document.createElement('td');
|
||||||
{
|
|
||||||
cancelFunct();
|
|
||||||
});
|
|
||||||
|
|
||||||
tr.appendChild(td);
|
|
||||||
this.body.appendChild(tr);
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
// Adds the ok button
|
||||||
* Function: addText
|
var button = document.createElement('button');
|
||||||
*
|
mxUtils.write(button, mxResources.get('ok') || 'OK');
|
||||||
* Adds an input for the given name, type and value and returns it.
|
td.appendChild(button);
|
||||||
*/
|
|
||||||
addText = (name, value, type)=>
|
|
||||||
{
|
|
||||||
var input = document.createElement('input');
|
|
||||||
|
|
||||||
input.setAttribute('type', type || 'text');
|
|
||||||
input.value = value;
|
|
||||||
|
|
||||||
return this.addField(name, input);
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
mxEvent.addListener(button, 'click', () => {
|
||||||
* Function: addCheckbox
|
okFunct();
|
||||||
*
|
});
|
||||||
* Adds a checkbox for the given name and value and returns the textfield.
|
|
||||||
*/
|
|
||||||
addCheckbox = (name, value)=>
|
|
||||||
{
|
|
||||||
var input = document.createElement('input');
|
|
||||||
|
|
||||||
input.setAttribute('type', 'checkbox');
|
|
||||||
this.addField(name, input);
|
|
||||||
|
|
||||||
// IE can only change the checked value if the input is inside the DOM
|
// Adds the cancel button
|
||||||
if (value)
|
button = document.createElement('button');
|
||||||
{
|
mxUtils.write(button, mxResources.get('cancel') || 'Cancel');
|
||||||
input.checked = true;
|
td.appendChild(button);
|
||||||
}
|
|
||||||
|
|
||||||
return input;
|
mxEvent.addListener(button, 'click', () => {
|
||||||
};
|
cancelFunct();
|
||||||
|
});
|
||||||
|
|
||||||
/**
|
tr.appendChild(td);
|
||||||
* Function: addTextarea
|
this.body.appendChild(tr);
|
||||||
*
|
};
|
||||||
* Adds a textarea for the given name and value and returns the textarea.
|
|
||||||
*/
|
|
||||||
addTextarea = (name, value, rows)=>
|
|
||||||
{
|
|
||||||
var input = document.createElement('textarea');
|
|
||||||
|
|
||||||
if (mxClient.IS_NS)
|
|
||||||
{
|
|
||||||
rows--;
|
|
||||||
}
|
|
||||||
|
|
||||||
input.setAttribute('rows', rows || 2);
|
|
||||||
input.value = value;
|
|
||||||
|
|
||||||
return this.addField(name, input);
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function: addCombo
|
* Function: addText
|
||||||
*
|
*
|
||||||
* Adds a combo for the given name and returns the combo.
|
* Adds an input for the given name, type and value and returns it.
|
||||||
*/
|
*/
|
||||||
addCombo = (name, isMultiSelect, size)=>
|
addText = (name, value, type) => {
|
||||||
{
|
var input = document.createElement('input');
|
||||||
var select = document.createElement('select');
|
|
||||||
|
|
||||||
if (size != null)
|
|
||||||
{
|
|
||||||
select.setAttribute('size', size);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isMultiSelect)
|
|
||||||
{
|
|
||||||
select.setAttribute('multiple', 'true');
|
|
||||||
}
|
|
||||||
|
|
||||||
return this.addField(name, select);
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
input.setAttribute('type', type || 'text');
|
||||||
* Function: addOption
|
input.value = value;
|
||||||
*
|
|
||||||
* Adds an option for the given label to the specified combo.
|
|
||||||
*/
|
|
||||||
addOption = (combo, label, value, isSelected)=>
|
|
||||||
{
|
|
||||||
var option = document.createElement('option');
|
|
||||||
|
|
||||||
mxUtils.writeln(option, label);
|
|
||||||
option.setAttribute('value', value);
|
|
||||||
|
|
||||||
if (isSelected)
|
|
||||||
{
|
|
||||||
option.setAttribute('selected', isSelected);
|
|
||||||
}
|
|
||||||
|
|
||||||
combo.appendChild(option);
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
return this.addField(name, input);
|
||||||
* Function: addField
|
};
|
||||||
*
|
|
||||||
* Adds a new row with the name and the input field in two columns and
|
/**
|
||||||
* returns the given input.
|
* Function: addCheckbox
|
||||||
*/
|
*
|
||||||
addField = (name, input)=>
|
* Adds a checkbox for the given name and value and returns the textfield.
|
||||||
{
|
*/
|
||||||
var tr = document.createElement('tr');
|
addCheckbox = (name, value) => {
|
||||||
var td = document.createElement('td');
|
var input = document.createElement('input');
|
||||||
mxUtils.write(td, name);
|
|
||||||
tr.appendChild(td);
|
input.setAttribute('type', 'checkbox');
|
||||||
|
this.addField(name, input);
|
||||||
td = document.createElement('td');
|
|
||||||
td.appendChild(input);
|
// IE can only change the checked value if the input is inside the DOM
|
||||||
tr.appendChild(td);
|
if (value) {
|
||||||
this.body.appendChild(tr);
|
input.checked = true;
|
||||||
|
}
|
||||||
return input;
|
|
||||||
};
|
return input;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function: addTextarea
|
||||||
|
*
|
||||||
|
* Adds a textarea for the given name and value and returns the textarea.
|
||||||
|
*/
|
||||||
|
addTextarea = (name, value, rows) => {
|
||||||
|
var input = document.createElement('textarea');
|
||||||
|
|
||||||
|
if (mxClient.IS_NS) {
|
||||||
|
rows--;
|
||||||
|
}
|
||||||
|
|
||||||
|
input.setAttribute('rows', rows || 2);
|
||||||
|
input.value = value;
|
||||||
|
|
||||||
|
return this.addField(name, input);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function: addCombo
|
||||||
|
*
|
||||||
|
* Adds a combo for the given name and returns the combo.
|
||||||
|
*/
|
||||||
|
addCombo = (name, isMultiSelect, size) => {
|
||||||
|
var select = document.createElement('select');
|
||||||
|
|
||||||
|
if (size != null) {
|
||||||
|
select.setAttribute('size', size);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isMultiSelect) {
|
||||||
|
select.setAttribute('multiple', 'true');
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.addField(name, select);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function: addOption
|
||||||
|
*
|
||||||
|
* Adds an option for the given label to the specified combo.
|
||||||
|
*/
|
||||||
|
addOption = (combo, label, value, isSelected) => {
|
||||||
|
var option = document.createElement('option');
|
||||||
|
|
||||||
|
mxUtils.writeln(option, label);
|
||||||
|
option.setAttribute('value', value);
|
||||||
|
|
||||||
|
if (isSelected) {
|
||||||
|
option.setAttribute('selected', isSelected);
|
||||||
|
}
|
||||||
|
|
||||||
|
combo.appendChild(option);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function: addField
|
||||||
|
*
|
||||||
|
* Adds a new row with the name and the input field in two columns and
|
||||||
|
* returns the given input.
|
||||||
|
*/
|
||||||
|
addField = (name, input) => {
|
||||||
|
var tr = document.createElement('tr');
|
||||||
|
var td = document.createElement('td');
|
||||||
|
mxUtils.write(td, name);
|
||||||
|
tr.appendChild(td);
|
||||||
|
|
||||||
|
td = document.createElement('td');
|
||||||
|
td.appendChild(input);
|
||||||
|
tr.appendChild(td);
|
||||||
|
this.body.appendChild(tr);
|
||||||
|
|
||||||
|
return input;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export default mxForm;
|
||||||
|
|
|
@ -11,438 +11,385 @@
|
||||||
*
|
*
|
||||||
* Constructs a new guide object.
|
* Constructs a new guide object.
|
||||||
*/
|
*/
|
||||||
function mxGuide(graph, states)
|
class mxGuide {
|
||||||
{
|
constructor(graph, states) {
|
||||||
this.graph = graph;
|
this.graph = graph;
|
||||||
this.setStates(states);
|
this.setStates(states);
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Variable: graph
|
* Variable: graph
|
||||||
*
|
*
|
||||||
* Reference to the enclosing <mxGraph> instance.
|
* Reference to the enclosing <mxGraph> instance.
|
||||||
*/
|
*/
|
||||||
graph = null;
|
graph = null;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Variable: states
|
* Variable: states
|
||||||
*
|
*
|
||||||
* Contains the <mxCellStates> that are used for alignment.
|
* Contains the <mxCellStates> that are used for alignment.
|
||||||
*/
|
*/
|
||||||
states = null;
|
states = null;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Variable: horizontal
|
* Variable: horizontal
|
||||||
*
|
*
|
||||||
* Specifies if horizontal guides are enabled. Default is true.
|
* Specifies if horizontal guides are enabled. Default is true.
|
||||||
*/
|
*/
|
||||||
horizontal = true;
|
horizontal = true;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Variable: vertical
|
* Variable: vertical
|
||||||
*
|
*
|
||||||
* Specifies if vertical guides are enabled. Default is true.
|
* Specifies if vertical guides are enabled. Default is true.
|
||||||
*/
|
*/
|
||||||
vertical = true;
|
vertical = true;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Variable: guideX
|
* Variable: guideX
|
||||||
*
|
*
|
||||||
* Holds the <mxShape> for the horizontal guide.
|
* Holds the <mxShape> for the horizontal guide.
|
||||||
*/
|
*/
|
||||||
guideX = null;
|
guideX = null;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Variable: guideY
|
* Variable: guideY
|
||||||
*
|
*
|
||||||
* Holds the <mxShape> for the vertical guide.
|
* Holds the <mxShape> for the vertical guide.
|
||||||
*/
|
*/
|
||||||
guideY = null;
|
guideY = null;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Variable: rounded
|
* Variable: rounded
|
||||||
*
|
*
|
||||||
* Specifies if rounded coordinates should be used. Default is false.
|
* Specifies if rounded coordinates should be used. Default is false.
|
||||||
*/
|
*/
|
||||||
rounded = false;
|
rounded = false;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Variable: tolerance
|
* Variable: tolerance
|
||||||
*
|
*
|
||||||
* Default tolerance in px if grid is disabled. Default is 2.
|
* Default tolerance in px if grid is disabled. Default is 2.
|
||||||
*/
|
*/
|
||||||
tolerance = 2;
|
tolerance = 2;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function: setStates
|
* Function: setStates
|
||||||
*
|
*
|
||||||
* Sets the <mxCellStates> that should be used for alignment.
|
* Sets the <mxCellStates> that should be used for alignment.
|
||||||
*/
|
*/
|
||||||
setStates = (states)=>
|
setStates = (states) => {
|
||||||
{
|
this.states = states;
|
||||||
this.states = states;
|
};
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function: isEnabledForEvent
|
* Function: isEnabledForEvent
|
||||||
*
|
*
|
||||||
* Returns true if the guide should be enabled for the given native event. This
|
* Returns true if the guide should be enabled for the given native event. This
|
||||||
* implementation always returns true.
|
* implementation always returns true.
|
||||||
*/
|
*/
|
||||||
isEnabledForEvent = (evt)=>
|
isEnabledForEvent = (evt) => {
|
||||||
{
|
return true;
|
||||||
return true;
|
};
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function: getGuideTolerance
|
* Function: getGuideTolerance
|
||||||
*
|
*
|
||||||
* Returns the tolerance for the guides. Default value is gridSize / 2.
|
* Returns the tolerance for the guides. Default value is gridSize / 2.
|
||||||
*/
|
*/
|
||||||
getGuideTolerance = (gridEnabled)=>
|
getGuideTolerance = (gridEnabled) => {
|
||||||
{
|
return (gridEnabled && this.graph.gridEnabled) ? this.graph.gridSize / 2 : this.tolerance;
|
||||||
return (gridEnabled && this.graph.gridEnabled) ? this.graph.gridSize / 2 : this.tolerance;
|
};
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function: createGuideShape
|
* Function: createGuideShape
|
||||||
*
|
*
|
||||||
* Returns the mxShape to be used for painting the respective guide. This
|
* Returns the mxShape to be used for painting the respective guide. This
|
||||||
* implementation returns a new, dashed and crisp <mxPolyline> using
|
* implementation returns a new, dashed and crisp <mxPolyline> using
|
||||||
* <mxConstants.GUIDE_COLOR> and <mxConstants.GUIDE_STROKEWIDTH> as the format.
|
* <mxConstants.GUIDE_COLOR> and <mxConstants.GUIDE_STROKEWIDTH> as the format.
|
||||||
*
|
*
|
||||||
* Parameters:
|
* Parameters:
|
||||||
*
|
*
|
||||||
* horizontal - Boolean that specifies which guide should be created.
|
* horizontal - Boolean that specifies which guide should be created.
|
||||||
*/
|
*/
|
||||||
createGuideShape = (horizontal)=>
|
createGuideShape = (horizontal) => {
|
||||||
{
|
var guide = new mxPolyline([], mxConstants.GUIDE_COLOR, mxConstants.GUIDE_STROKEWIDTH);
|
||||||
var guide = new mxPolyline([], mxConstants.GUIDE_COLOR, mxConstants.GUIDE_STROKEWIDTH);
|
guide.isDashed = true;
|
||||||
guide.isDashed = true;
|
|
||||||
|
|
||||||
return guide;
|
return guide;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function: isStateIgnored
|
* Function: isStateIgnored
|
||||||
*
|
*
|
||||||
* Returns true if the given state should be ignored.
|
* Returns true if the given state should be ignored.
|
||||||
*/
|
*/
|
||||||
isStateIgnored = (state)=>
|
isStateIgnored = (state) => {
|
||||||
{
|
return false;
|
||||||
return false;
|
};
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function: move
|
* Function: move
|
||||||
*
|
*
|
||||||
* Moves the <bounds> by the given <mxPoint> and returnt the snapped point.
|
* Moves the <bounds> by the given <mxPoint> and returnt the snapped point.
|
||||||
*/
|
*/
|
||||||
move = (bounds, delta, gridEnabled, clone)=>
|
move = (bounds, delta, gridEnabled, clone) => {
|
||||||
{
|
if (this.states != null && (this.horizontal || this.vertical) && bounds != null && delta != null) {
|
||||||
if (this.states != null && (this.horizontal || this.vertical) && bounds != null && delta != null)
|
var scale = this.graph.getView().scale;
|
||||||
{
|
var tt = this.getGuideTolerance(gridEnabled) * scale;
|
||||||
var scale = this.graph.getView().scale;
|
var b = bounds.clone();
|
||||||
var tt = this.getGuideTolerance(gridEnabled) * scale;
|
b.x += delta.x;
|
||||||
var b = bounds.clone();
|
b.y += delta.y;
|
||||||
b.x += delta.x;
|
var overrideX = false;
|
||||||
b.y += delta.y;
|
var stateX = null;
|
||||||
var overrideX = false;
|
var valueX = null;
|
||||||
var stateX = null;
|
var overrideY = false;
|
||||||
var valueX = null;
|
var stateY = null;
|
||||||
var overrideY = false;
|
var valueY = null;
|
||||||
var stateY = null;
|
var ttX = tt;
|
||||||
var valueY = null;
|
var ttY = tt;
|
||||||
var ttX = tt;
|
var left = b.x;
|
||||||
var ttY = tt;
|
var right = b.x + b.width;
|
||||||
var left = b.x;
|
var center = b.getCenterX();
|
||||||
var right = b.x + b.width;
|
var top = b.y;
|
||||||
var center = b.getCenterX();
|
var bottom = b.y + b.height;
|
||||||
var top = b.y;
|
var middle = b.getCenterY();
|
||||||
var bottom = b.y + b.height;
|
|
||||||
var middle = b.getCenterY();
|
|
||||||
|
|
||||||
// Snaps the left, center and right to the given x-coordinate
|
// Snaps the left, center and right to the given x-coordinate
|
||||||
function snapX(x, state, centerAlign)
|
function snapX(x, state, centerAlign) {
|
||||||
{
|
var override = false;
|
||||||
var override = false;
|
|
||||||
|
|
||||||
if (centerAlign && Math.abs(x - center) < ttX)
|
if (centerAlign && Math.abs(x - center) < ttX) {
|
||||||
{
|
delta.x = x - bounds.getCenterX();
|
||||||
delta.x = x - bounds.getCenterX();
|
ttX = Math.abs(x - center);
|
||||||
ttX = Math.abs(x - center);
|
|
||||||
override = true;
|
|
||||||
}
|
|
||||||
else if (!centerAlign)
|
|
||||||
{
|
|
||||||
if (Math.abs(x - left) < ttX)
|
|
||||||
{
|
|
||||||
delta.x = x - bounds.x;
|
|
||||||
ttX = Math.abs(x - left);
|
|
||||||
override = true;
|
override = true;
|
||||||
}
|
} else if (!centerAlign) {
|
||||||
else if (Math.abs(x - right) < ttX)
|
if (Math.abs(x - left) < ttX) {
|
||||||
{
|
delta.x = x - bounds.x;
|
||||||
delta.x = x - bounds.x - bounds.width;
|
ttX = Math.abs(x - left);
|
||||||
ttX = Math.abs(x - right);
|
override = true;
|
||||||
override = true;
|
} else if (Math.abs(x - right) < ttX) {
|
||||||
}
|
delta.x = x - bounds.x - bounds.width;
|
||||||
}
|
ttX = Math.abs(x - right);
|
||||||
|
override = true;
|
||||||
if (override)
|
|
||||||
{
|
|
||||||
stateX = state;
|
|
||||||
valueX = x;
|
|
||||||
|
|
||||||
if (this.guideX == null)
|
|
||||||
{
|
|
||||||
this.guideX = this.createGuideShape(true);
|
|
||||||
|
|
||||||
// Makes sure to use either VML or SVG shapes in order to implement
|
|
||||||
// event-transparency on the background area of the rectangle since
|
|
||||||
// HTML shapes do not let mouseevents through even when transparent
|
|
||||||
this.guideX.dialect = (this.graph.dialect != mxConstants.DIALECT_SVG) ?
|
|
||||||
mxConstants.DIALECT_VML : mxConstants.DIALECT_SVG;
|
|
||||||
this.guideX.pointerEvents = false;
|
|
||||||
this.guideX.init(this.graph.getView().getOverlayPane());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
overrideX = overrideX || override;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Snaps the top, middle or bottom to the given y-coordinate
|
|
||||||
function snapY(y, state, centerAlign)
|
|
||||||
{
|
|
||||||
var override = false;
|
|
||||||
|
|
||||||
if (centerAlign && Math.abs(y - middle) < ttY)
|
|
||||||
{
|
|
||||||
delta.y = y - bounds.getCenterY();
|
|
||||||
ttY = Math.abs(y - middle);
|
|
||||||
override = true;
|
|
||||||
}
|
|
||||||
else if (!centerAlign)
|
|
||||||
{
|
|
||||||
if (Math.abs(y - top) < ttY)
|
|
||||||
{
|
|
||||||
delta.y = y - bounds.y;
|
|
||||||
ttY = Math.abs(y - top);
|
|
||||||
override = true;
|
|
||||||
}
|
|
||||||
else if (Math.abs(y - bottom) < ttY)
|
|
||||||
{
|
|
||||||
delta.y = y - bounds.y - bounds.height;
|
|
||||||
ttY = Math.abs(y - bottom);
|
|
||||||
override = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (override)
|
|
||||||
{
|
|
||||||
stateY = state;
|
|
||||||
valueY = y;
|
|
||||||
|
|
||||||
if (this.guideY == null)
|
|
||||||
{
|
|
||||||
this.guideY = this.createGuideShape(false);
|
|
||||||
|
|
||||||
// Makes sure to use either VML or SVG shapes in order to implement
|
|
||||||
// event-transparency on the background area of the rectangle since
|
|
||||||
// HTML shapes do not let mouseevents through even when transparent
|
|
||||||
this.guideY.dialect = (this.graph.dialect != mxConstants.DIALECT_SVG) ?
|
|
||||||
mxConstants.DIALECT_VML : mxConstants.DIALECT_SVG;
|
|
||||||
this.guideY.pointerEvents = false;
|
|
||||||
this.guideY.init(this.graph.getView().getOverlayPane());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
overrideY = overrideY || override;
|
|
||||||
};
|
|
||||||
|
|
||||||
for (var i = 0; i < this.states.length; i++)
|
|
||||||
{
|
|
||||||
var state = this.states[i];
|
|
||||||
|
|
||||||
if (state != null && !this.isStateIgnored(state))
|
|
||||||
{
|
|
||||||
// Align x
|
|
||||||
if (this.horizontal)
|
|
||||||
{
|
|
||||||
snapX.call(this, state.getCenterX(), state, true);
|
|
||||||
snapX.call(this, state.x, state, false);
|
|
||||||
snapX.call(this, state.x + state.width, state, false);
|
|
||||||
|
|
||||||
// Aligns left and right of shape to center of page
|
|
||||||
if (state.cell == null)
|
|
||||||
{
|
|
||||||
snapX.call(this, state.getCenterX(), state, false);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Align y
|
if (override) {
|
||||||
if (this.vertical)
|
stateX = state;
|
||||||
{
|
valueX = x;
|
||||||
snapY.call(this, state.getCenterY(), state, true);
|
|
||||||
snapY.call(this, state.y, state, false);
|
|
||||||
snapY.call(this, state.y + state.height, state, false);
|
|
||||||
|
|
||||||
// Aligns left and right of shape to center of page
|
if (this.guideX == null) {
|
||||||
if (state.cell == null)
|
this.guideX = this.createGuideShape(true);
|
||||||
{
|
|
||||||
snapY.call(this, state.getCenterY(), state, false);
|
// Makes sure to use either VML or SVG shapes in order to implement
|
||||||
|
// event-transparency on the background area of the rectangle since
|
||||||
|
// HTML shapes do not let mouseevents through even when transparent
|
||||||
|
this.guideX.dialect = (this.graph.dialect != mxConstants.DIALECT_SVG) ?
|
||||||
|
mxConstants.DIALECT_VML : mxConstants.DIALECT_SVG;
|
||||||
|
this.guideX.pointerEvents = false;
|
||||||
|
this.guideX.init(this.graph.getView().getOverlayPane());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
overrideX = overrideX || override;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Snaps the top, middle or bottom to the given y-coordinate
|
||||||
|
function snapY(y, state, centerAlign) {
|
||||||
|
var override = false;
|
||||||
|
|
||||||
|
if (centerAlign && Math.abs(y - middle) < ttY) {
|
||||||
|
delta.y = y - bounds.getCenterY();
|
||||||
|
ttY = Math.abs(y - middle);
|
||||||
|
override = true;
|
||||||
|
} else if (!centerAlign) {
|
||||||
|
if (Math.abs(y - top) < ttY) {
|
||||||
|
delta.y = y - bounds.y;
|
||||||
|
ttY = Math.abs(y - top);
|
||||||
|
override = true;
|
||||||
|
} else if (Math.abs(y - bottom) < ttY) {
|
||||||
|
delta.y = y - bounds.y - bounds.height;
|
||||||
|
ttY = Math.abs(y - bottom);
|
||||||
|
override = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (override) {
|
||||||
|
stateY = state;
|
||||||
|
valueY = y;
|
||||||
|
|
||||||
|
if (this.guideY == null) {
|
||||||
|
this.guideY = this.createGuideShape(false);
|
||||||
|
|
||||||
|
// Makes sure to use either VML or SVG shapes in order to implement
|
||||||
|
// event-transparency on the background area of the rectangle since
|
||||||
|
// HTML shapes do not let mouseevents through even when transparent
|
||||||
|
this.guideY.dialect = (this.graph.dialect != mxConstants.DIALECT_SVG) ?
|
||||||
|
mxConstants.DIALECT_VML : mxConstants.DIALECT_SVG;
|
||||||
|
this.guideY.pointerEvents = false;
|
||||||
|
this.guideY.init(this.graph.getView().getOverlayPane());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
overrideY = overrideY || override;
|
||||||
|
};
|
||||||
|
|
||||||
|
for (var i = 0; i < this.states.length; i++) {
|
||||||
|
var state = this.states[i];
|
||||||
|
|
||||||
|
if (state != null && !this.isStateIgnored(state)) {
|
||||||
|
// Align x
|
||||||
|
if (this.horizontal) {
|
||||||
|
snapX.call(this, state.getCenterX(), state, true);
|
||||||
|
snapX.call(this, state.x, state, false);
|
||||||
|
snapX.call(this, state.x + state.width, state, false);
|
||||||
|
|
||||||
|
// Aligns left and right of shape to center of page
|
||||||
|
if (state.cell == null) {
|
||||||
|
snapX.call(this, state.getCenterX(), state, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Align y
|
||||||
|
if (this.vertical) {
|
||||||
|
snapY.call(this, state.getCenterY(), state, true);
|
||||||
|
snapY.call(this, state.y, state, false);
|
||||||
|
snapY.call(this, state.y + state.height, state, false);
|
||||||
|
|
||||||
|
// Aligns left and right of shape to center of page
|
||||||
|
if (state.cell == null) {
|
||||||
|
snapY.call(this, state.getCenterY(), state, false);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Moves cells to the raster if not aligned
|
||||||
|
this.graph.snapDelta(delta, bounds, !gridEnabled, overrideX, overrideY);
|
||||||
|
delta = this.getDelta(bounds, stateX, delta.x, stateY, delta.y)
|
||||||
|
|
||||||
|
// Redraws the guides
|
||||||
|
var c = this.graph.container;
|
||||||
|
|
||||||
|
if (!overrideX && this.guideX != null) {
|
||||||
|
this.guideX.node.style.visibility = 'hidden';
|
||||||
|
} else if (this.guideX != null) {
|
||||||
|
var minY = null;
|
||||||
|
var maxY = null;
|
||||||
|
|
||||||
|
if (stateX != null && bounds != null) {
|
||||||
|
minY = Math.min(bounds.y + delta.y - this.graph.panDy, stateX.y);
|
||||||
|
maxY = Math.max(bounds.y + bounds.height + delta.y - this.graph.panDy, stateX.y + stateX.height);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (minY != null && maxY != null) {
|
||||||
|
this.guideX.points = [new mxPoint(valueX, minY), new mxPoint(valueX, maxY)];
|
||||||
|
} else {
|
||||||
|
this.guideX.points = [new mxPoint(valueX, -this.graph.panDy),
|
||||||
|
new mxPoint(valueX, c.scrollHeight - 3 - this.graph.panDy)];
|
||||||
|
}
|
||||||
|
|
||||||
|
this.guideX.stroke = this.getGuideColor(stateX, true);
|
||||||
|
this.guideX.node.style.visibility = 'visible';
|
||||||
|
this.guideX.redraw();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!overrideY && this.guideY != null) {
|
||||||
|
this.guideY.node.style.visibility = 'hidden';
|
||||||
|
} else if (this.guideY != null) {
|
||||||
|
var minX = null;
|
||||||
|
var maxX = null;
|
||||||
|
|
||||||
|
if (stateY != null && bounds != null) {
|
||||||
|
minX = Math.min(bounds.x + delta.x - this.graph.panDx, stateY.x);
|
||||||
|
maxX = Math.max(bounds.x + bounds.width + delta.x - this.graph.panDx, stateY.x + stateY.width);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (minX != null && maxX != null) {
|
||||||
|
this.guideY.points = [new mxPoint(minX, valueY), new mxPoint(maxX, valueY)];
|
||||||
|
} else {
|
||||||
|
this.guideY.points = [new mxPoint(-this.graph.panDx, valueY),
|
||||||
|
new mxPoint(c.scrollWidth - 3 - this.graph.panDx, valueY)];
|
||||||
|
}
|
||||||
|
|
||||||
|
this.guideY.stroke = this.getGuideColor(stateY, false);
|
||||||
|
this.guideY.node.style.visibility = 'visible';
|
||||||
|
this.guideY.redraw();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Moves cells to the raster if not aligned
|
return delta;
|
||||||
this.graph.snapDelta(delta, bounds, !gridEnabled, overrideX, overrideY);
|
};
|
||||||
delta = this.getDelta(bounds, stateX, delta.x, stateY, delta.y)
|
|
||||||
|
|
||||||
// Redraws the guides
|
/**
|
||||||
var c = this.graph.container;
|
* Function: getDelta
|
||||||
|
*
|
||||||
|
* Rounds to pixels for virtual states (eg. page guides)
|
||||||
|
*/
|
||||||
|
getDelta = (bounds, stateX, dx, stateY, dy) => {
|
||||||
|
var s = this.graph.view.scale;
|
||||||
|
|
||||||
if (!overrideX && this.guideX != null)
|
if (this.rounded || (stateX != null && stateX.cell == null)) {
|
||||||
{
|
dx = Math.round((bounds.x + dx) / s) * s - bounds.x;
|
||||||
this.guideX.node.style.visibility = 'hidden';
|
|
||||||
}
|
|
||||||
else if (this.guideX != null)
|
|
||||||
{
|
|
||||||
var minY = null;
|
|
||||||
var maxY = null;
|
|
||||||
|
|
||||||
if (stateX != null && bounds != null)
|
|
||||||
{
|
|
||||||
minY = Math.min(bounds.y + delta.y - this.graph.panDy, stateX.y);
|
|
||||||
maxY = Math.max(bounds.y + bounds.height + delta.y - this.graph.panDy, stateX.y + stateX.height);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (minY != null && maxY != null)
|
|
||||||
{
|
|
||||||
this.guideX.points = [new mxPoint(valueX, minY), new mxPoint(valueX, maxY)];
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
this.guideX.points = [new mxPoint(valueX, -this.graph.panDy),
|
|
||||||
new mxPoint(valueX, c.scrollHeight - 3 - this.graph.panDy)];
|
|
||||||
}
|
|
||||||
|
|
||||||
this.guideX.stroke = this.getGuideColor(stateX, true);
|
|
||||||
this.guideX.node.style.visibility = 'visible';
|
|
||||||
this.guideX.redraw();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!overrideY && this.guideY != null)
|
if (this.rounded || (stateY != null && stateY.cell == null)) {
|
||||||
{
|
dy = Math.round((bounds.y + dy) / s) * s - bounds.y;
|
||||||
this.guideY.node.style.visibility = 'hidden';
|
|
||||||
}
|
}
|
||||||
else if (this.guideY != null)
|
|
||||||
{
|
|
||||||
var minX = null;
|
|
||||||
var maxX = null;
|
|
||||||
|
|
||||||
if (stateY != null && bounds != null)
|
return new mxPoint(dx, dy);
|
||||||
{
|
};
|
||||||
minX = Math.min(bounds.x + delta.x - this.graph.panDx, stateY.x);
|
|
||||||
maxX = Math.max(bounds.x + bounds.width + delta.x - this.graph.panDx, stateY.x + stateY.width);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (minX != null && maxX != null)
|
/**
|
||||||
{
|
* Function: getGuideColor
|
||||||
this.guideY.points = [new mxPoint(minX, valueY), new mxPoint(maxX, valueY)];
|
*
|
||||||
}
|
* Returns the color for the given state.
|
||||||
else
|
*/
|
||||||
{
|
getGuideColor = (state, horizontal) => {
|
||||||
this.guideY.points = [new mxPoint(-this.graph.panDx, valueY),
|
return mxConstants.GUIDE_COLOR;
|
||||||
new mxPoint(c.scrollWidth - 3 - this.graph.panDx, valueY)];
|
};
|
||||||
}
|
|
||||||
|
|
||||||
this.guideY.stroke = this.getGuideColor(stateY, false);
|
/**
|
||||||
this.guideY.node.style.visibility = 'visible';
|
* Function: hide
|
||||||
this.guideY.redraw();
|
*
|
||||||
|
* Hides all current guides.
|
||||||
|
*/
|
||||||
|
hide = () => {
|
||||||
|
this.setVisible(false);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function: setVisible
|
||||||
|
*
|
||||||
|
* Shows or hides the current guides.
|
||||||
|
*/
|
||||||
|
setVisible = (visible) => {
|
||||||
|
if (this.guideX != null) {
|
||||||
|
this.guideX.node.style.visibility = (visible) ? 'visible' : 'hidden';
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
return delta;
|
if (this.guideY != null) {
|
||||||
};
|
this.guideY.node.style.visibility = (visible) ? 'visible' : 'hidden';
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function: getDelta
|
* Function: destroy
|
||||||
*
|
*
|
||||||
* Rounds to pixels for virtual states (eg. page guides)
|
* Destroys all resources that this object uses.
|
||||||
*/
|
*/
|
||||||
getDelta = (bounds, stateX, dx, stateY, dy)=>
|
destroy = () => {
|
||||||
{
|
if (this.guideX != null) {
|
||||||
var s = this.graph.view.scale;
|
this.guideX.destroy();
|
||||||
|
this.guideX = null;
|
||||||
|
}
|
||||||
|
|
||||||
if (this.rounded || (stateX != null && stateX.cell == null))
|
if (this.guideY != null) {
|
||||||
{
|
this.guideY.destroy();
|
||||||
dx = Math.round((bounds.x + dx) / s) * s - bounds.x;
|
this.guideY = null;
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
if (this.rounded || (stateY != null && stateY.cell == null))
|
export default mxGuide;
|
||||||
{
|
|
||||||
dy = Math.round((bounds.y + dy) / s) * s - bounds.y;
|
|
||||||
}
|
|
||||||
|
|
||||||
return new mxPoint(dx, dy);
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Function: getGuideColor
|
|
||||||
*
|
|
||||||
* Returns the color for the given state.
|
|
||||||
*/
|
|
||||||
getGuideColor = (state, horizontal)=>
|
|
||||||
{
|
|
||||||
return mxConstants.GUIDE_COLOR;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Function: hide
|
|
||||||
*
|
|
||||||
* Hides all current guides.
|
|
||||||
*/
|
|
||||||
hide = ()=>
|
|
||||||
{
|
|
||||||
this.setVisible(false);
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Function: setVisible
|
|
||||||
*
|
|
||||||
* Shows or hides the current guides.
|
|
||||||
*/
|
|
||||||
setVisible = (visible)=>
|
|
||||||
{
|
|
||||||
if (this.guideX != null)
|
|
||||||
{
|
|
||||||
this.guideX.node.style.visibility = (visible) ? 'visible' : 'hidden';
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this.guideY != null)
|
|
||||||
{
|
|
||||||
this.guideY.node.style.visibility = (visible) ? 'visible' : 'hidden';
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Function: destroy
|
|
||||||
*
|
|
||||||
* Destroys all resources that this object uses.
|
|
||||||
*/
|
|
||||||
destroy = ()=>
|
|
||||||
{
|
|
||||||
if (this.guideX != null)
|
|
||||||
{
|
|
||||||
this.guideX.destroy();
|
|
||||||
this.guideX = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this.guideY != null)
|
|
||||||
{
|
|
||||||
this.guideY.destroy();
|
|
||||||
this.guideY = null;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
|
@ -2,39 +2,43 @@
|
||||||
* Copyright (c) 2006-2015, JGraph Ltd
|
* Copyright (c) 2006-2015, JGraph Ltd
|
||||||
* Copyright (c) 2006-2015, Gaudenz Alder
|
* Copyright (c) 2006-2015, Gaudenz Alder
|
||||||
*/
|
*/
|
||||||
/**
|
|
||||||
* Class: mxImage
|
|
||||||
*
|
|
||||||
* Encapsulates the URL, width and height of an image.
|
|
||||||
*
|
|
||||||
* Constructor: mxImage
|
|
||||||
*
|
|
||||||
* Constructs a new image.
|
|
||||||
*/
|
|
||||||
function mxImage(src, width, height)
|
|
||||||
{
|
|
||||||
this.src = src;
|
|
||||||
this.width = width;
|
|
||||||
this.height = height;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
class mxImage {
|
||||||
* Variable: src
|
/**
|
||||||
*
|
* Variable: src
|
||||||
* String that specifies the URL of the image.
|
*
|
||||||
*/
|
* String that specifies the URL of the image.
|
||||||
src = null;
|
*/
|
||||||
|
src = null;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Variable: width
|
* Variable: width
|
||||||
*
|
*
|
||||||
* Integer that specifies the width of the image.
|
* Integer that specifies the width of the image.
|
||||||
*/
|
*/
|
||||||
width = null;
|
width = null;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Variable: height
|
* Variable: height
|
||||||
*
|
*
|
||||||
* Integer that specifies the height of the image.
|
* Integer that specifies the height of the image.
|
||||||
*/
|
*/
|
||||||
height = null;
|
height = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class: mxImage
|
||||||
|
*
|
||||||
|
* Encapsulates the URL, width and height of an image.
|
||||||
|
*
|
||||||
|
* Constructor: mxImage
|
||||||
|
*
|
||||||
|
* Constructs a new image.
|
||||||
|
*/
|
||||||
|
constructor(src, width, height) {
|
||||||
|
this.src = src;
|
||||||
|
this.width = width;
|
||||||
|
this.height = height;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export default mxImage;
|
||||||
|
|
|
@ -2,102 +2,102 @@
|
||||||
* Copyright (c) 2006-2015, JGraph Ltd
|
* Copyright (c) 2006-2015, JGraph Ltd
|
||||||
* Copyright (c) 2006-2015, Gaudenz Alder
|
* Copyright (c) 2006-2015, Gaudenz Alder
|
||||||
*/
|
*/
|
||||||
/**
|
|
||||||
* Class: mxImageBundle
|
|
||||||
*
|
|
||||||
* Maps from keys to base64 encoded images or file locations. All values must
|
|
||||||
* be URLs or use the format data:image/format followed by a comma and the base64
|
|
||||||
* encoded image data, eg. "data:image/gif,XYZ", where XYZ is the base64 encoded
|
|
||||||
* image data.
|
|
||||||
*
|
|
||||||
* To add a new image bundle to an existing graph, the following code is used:
|
|
||||||
*
|
|
||||||
* (code)
|
|
||||||
* var bundle = new mxImageBundle(alt);
|
|
||||||
* bundle.putImage('myImage', 'data:image/gif,R0lGODlhEAAQAMIGAAAAAICAAICAgP' +
|
|
||||||
* '//AOzp2O3r2////////yH+FUNyZWF0ZWQgd2l0aCBUaGUgR0lNUAAh+QQBCgAHACwAAAAA' +
|
|
||||||
* 'EAAQAAADTXi63AowynnAMDfjPUDlnAAJhmeBFxAEloliKltWmiYCQvfVr6lBPB1ggxN1hi' +
|
|
||||||
* 'laSSASFQpIV5HJBDyHpqK2ejVRm2AAgZCdmCGO9CIBADs=', fallback);
|
|
||||||
* bundle.putImage('mySvgImage', 'data:image/svg+xml,' + encodeURIComponent(
|
|
||||||
* '<svg xmlns="http://www.w3.org/2000/svg" width="100%" height="100%">' +
|
|
||||||
* '<linearGradient id="gradient"><stop offset="10%" stop-color="#F00"/>' +
|
|
||||||
* '<stop offset="90%" stop-color="#fcc"/></linearGradient>' +
|
|
||||||
* '<rect fill="url(#gradient)" width="100%" height="100%"/></svg>'), fallback);
|
|
||||||
* graph.addImageBundle(bundle);
|
|
||||||
* (end);
|
|
||||||
*
|
|
||||||
* Alt is an optional boolean (default is false) that specifies if the value
|
|
||||||
* or the fallback should be returned in <getImage>.
|
|
||||||
*
|
|
||||||
* The image can then be referenced in any cell style using image=myImage.
|
|
||||||
* If you are using mxOutline, you should use the same image bundles in the
|
|
||||||
* graph that renders the outline.
|
|
||||||
*
|
|
||||||
* The keys for images are resolved in <mxGraph.postProcessCellStyle> and
|
|
||||||
* turned into a data URI if the returned value has a short data URI format
|
|
||||||
* as specified above.
|
|
||||||
*
|
|
||||||
* A typical value for the fallback is a MTHML link as defined in RFC 2557.
|
|
||||||
* Note that this format requires a file to be dynamically created on the
|
|
||||||
* server-side, or the page that contains the graph to be modified to contain
|
|
||||||
* the resources, this can be done by adding a comment that contains the
|
|
||||||
* resource in the HEAD section of the page after the title tag.
|
|
||||||
*
|
|
||||||
* This type of fallback mechanism should be used in IE6 and IE7. IE8 does
|
|
||||||
* support data URIs, but the maximum size is limited to 32 KB, which means
|
|
||||||
* all data URIs should be limited to 32 KB.
|
|
||||||
*/
|
|
||||||
function mxImageBundle(alt)
|
|
||||||
{
|
|
||||||
this.images = [];
|
|
||||||
this.alt = (alt != null) ? alt : false;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
class mxImageBundle {
|
||||||
* Variable: images
|
/**
|
||||||
*
|
* Variable: images
|
||||||
* Maps from keys to images.
|
*
|
||||||
*/
|
* Maps from keys to images.
|
||||||
images = null;
|
*/
|
||||||
|
images = null;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Variable: alt
|
* Variable: alt
|
||||||
*
|
*
|
||||||
* Specifies if the fallback representation should be returned.
|
* Specifies if the fallback representation should be returned.
|
||||||
*/
|
*/
|
||||||
alt = null;
|
alt = null;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function: putImage
|
* Class: mxImageBundle
|
||||||
*
|
*
|
||||||
* Adds the specified entry to the map. The entry is an object with a value and
|
* Maps from keys to base64 encoded images or file locations. All values must
|
||||||
* fallback property as specified in the arguments.
|
* be URLs or use the format data:image/format followed by a comma and the base64
|
||||||
*/
|
* encoded image data, eg. "data:image/gif,XYZ", where XYZ is the base64 encoded
|
||||||
putImage = (key, value, fallback)=>
|
* image data.
|
||||||
{
|
*
|
||||||
this.images[key] = {value: value, fallback: fallback};
|
* To add a new image bundle to an existing graph, the following code is used:
|
||||||
};
|
*
|
||||||
|
* (code)
|
||||||
|
* var bundle = new mxImageBundle(alt);
|
||||||
|
* bundle.putImage('myImage', 'data:image/gif,R0lGODlhEAAQAMIGAAAAAICAAICAgP' +
|
||||||
|
* '//AOzp2O3r2////////yH+FUNyZWF0ZWQgd2l0aCBUaGUgR0lNUAAh+QQBCgAHACwAAAAA' +
|
||||||
|
* 'EAAQAAADTXi63AowynnAMDfjPUDlnAAJhmeBFxAEloliKltWmiYCQvfVr6lBPB1ggxN1hi' +
|
||||||
|
* 'laSSASFQpIV5HJBDyHpqK2ejVRm2AAgZCdmCGO9CIBADs=', fallback);
|
||||||
|
* bundle.putImage('mySvgImage', 'data:image/svg+xml,' + encodeURIComponent(
|
||||||
|
* '<svg xmlns="http://www.w3.org/2000/svg" width="100%" height="100%">' +
|
||||||
|
* '<linearGradient id="gradient"><stop offset="10%" stop-color="#F00"/>' +
|
||||||
|
* '<stop offset="90%" stop-color="#fcc"/></linearGradient>' +
|
||||||
|
* '<rect fill="url(#gradient)" width="100%" height="100%"/></svg>'), fallback);
|
||||||
|
* graph.addImageBundle(bundle);
|
||||||
|
* (end);
|
||||||
|
*
|
||||||
|
* Alt is an optional boolean (default is false) that specifies if the value
|
||||||
|
* or the fallback should be returned in <getImage>.
|
||||||
|
*
|
||||||
|
* The image can then be referenced in any cell style using image=myImage.
|
||||||
|
* If you are using mxOutline, you should use the same image bundles in the
|
||||||
|
* graph that renders the outline.
|
||||||
|
*
|
||||||
|
* The keys for images are resolved in <mxGraph.postProcessCellStyle> and
|
||||||
|
* turned into a data URI if the returned value has a short data URI format
|
||||||
|
* as specified above.
|
||||||
|
*
|
||||||
|
* A typical value for the fallback is a MTHML link as defined in RFC 2557.
|
||||||
|
* Note that this format requires a file to be dynamically created on the
|
||||||
|
* server-side, or the page that contains the graph to be modified to contain
|
||||||
|
* the resources, this can be done by adding a comment that contains the
|
||||||
|
* resource in the HEAD section of the page after the title tag.
|
||||||
|
*
|
||||||
|
* This type of fallback mechanism should be used in IE6 and IE7. IE8 does
|
||||||
|
* support data URIs, but the maximum size is limited to 32 KB, which means
|
||||||
|
* all data URIs should be limited to 32 KB.
|
||||||
|
*/
|
||||||
|
constructor(alt) {
|
||||||
|
this.images = [];
|
||||||
|
this.alt = (alt != null) ? alt : false;
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function: getImage
|
* Function: putImage
|
||||||
*
|
*
|
||||||
* Returns the value for the given key. This returns the value
|
* Adds the specified entry to the map. The entry is an object with a value and
|
||||||
* or fallback, depending on <alt>. The fallback is returned if
|
* fallback property as specified in the arguments.
|
||||||
* <alt> is true, the value is returned otherwise.
|
*/
|
||||||
*/
|
putImage = (key, value, fallback) => {
|
||||||
getImage = (key)=>
|
this.images[key] = {value: value, fallback: fallback};
|
||||||
{
|
};
|
||||||
var result = null;
|
|
||||||
|
/**
|
||||||
if (key != null)
|
* Function: getImage
|
||||||
{
|
*
|
||||||
var img = this.images[key];
|
* Returns the value for the given key. This returns the value
|
||||||
|
* or fallback, depending on <alt>. The fallback is returned if
|
||||||
if (img != null)
|
* <alt> is true, the value is returned otherwise.
|
||||||
{
|
*/
|
||||||
result = (this.alt) ? img.fallback : img.value;
|
getImage = (key) => {
|
||||||
|
var result = null;
|
||||||
|
|
||||||
|
if (key != null) {
|
||||||
|
var img = this.images[key];
|
||||||
|
|
||||||
|
if (img != null) {
|
||||||
|
result = (this.alt) ? img.fallback : img.value;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
return result;
|
||||||
return result;
|
};
|
||||||
};
|
}
|
||||||
|
|
||||||
|
export default mxImageBundle;
|
||||||
|
|
|
@ -2,182 +2,166 @@
|
||||||
* Copyright (c) 2006-2015, JGraph Ltd
|
* Copyright (c) 2006-2015, JGraph Ltd
|
||||||
* Copyright (c) 2006-2015, Gaudenz Alder
|
* Copyright (c) 2006-2015, Gaudenz Alder
|
||||||
*/
|
*/
|
||||||
/**
|
|
||||||
* Class: mxImageExport
|
|
||||||
*
|
|
||||||
* Creates a new image export instance to be used with an export canvas. Here
|
|
||||||
* is an example that uses this class to create an image via a backend using
|
|
||||||
* <mxXmlExportCanvas>.
|
|
||||||
*
|
|
||||||
* (code)
|
|
||||||
* var xmlDoc = mxUtils.createXmlDocument();
|
|
||||||
* var root = xmlDoc.createElement('output');
|
|
||||||
* xmlDoc.appendChild(root);
|
|
||||||
*
|
|
||||||
* var xmlCanvas = new mxXmlCanvas2D(root);
|
|
||||||
* var imgExport = new mxImageExport();
|
|
||||||
* imgExport.drawState(graph.getView().getState(graph.model.root), xmlCanvas);
|
|
||||||
*
|
|
||||||
* var bounds = graph.getGraphBounds();
|
|
||||||
* var w = Math.ceil(bounds.x + bounds.width);
|
|
||||||
* var h = Math.ceil(bounds.y + bounds.height);
|
|
||||||
*
|
|
||||||
* var xml = mxUtils.getXml(root);
|
|
||||||
* new mxXmlRequest('export', 'format=png&w=' + w +
|
|
||||||
* '&h=' + h + '&bg=#F9F7ED&xml=' + encodeURIComponent(xml))
|
|
||||||
* .simulate(document, '_blank');
|
|
||||||
* (end)
|
|
||||||
*
|
|
||||||
* Constructor: mxImageExport
|
|
||||||
*
|
|
||||||
* Constructs a new image export.
|
|
||||||
*/
|
|
||||||
function mxImageExport() { };
|
|
||||||
|
|
||||||
/**
|
class mxImageExport {
|
||||||
* Variable: includeOverlays
|
/**
|
||||||
*
|
* Variable: includeOverlays
|
||||||
* Specifies if overlays should be included in the export. Default is false.
|
*
|
||||||
*/
|
* Specifies if overlays should be included in the export. Default is false.
|
||||||
includeOverlays = false;
|
*/
|
||||||
|
includeOverlays = false;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function: drawState
|
* Class: mxImageExport
|
||||||
*
|
*
|
||||||
* Draws the given state and all its descendants to the given canvas.
|
* Creates a new image export instance to be used with an export canvas. Here
|
||||||
*/
|
* is an example that uses this class to create an image via a backend using
|
||||||
drawState = (state, canvas)=>
|
* <mxXmlExportCanvas>.
|
||||||
{
|
*
|
||||||
if (state != null)
|
* (code)
|
||||||
{
|
* var xmlDoc = mxUtils.createXmlDocument();
|
||||||
this.visitStatesRecursive(state, canvas, mxUtils.bind(this, ()=>
|
* var root = xmlDoc.createElement('output');
|
||||||
{
|
* xmlDoc.appendChild(root);
|
||||||
this.drawCellState.apply(this, arguments);
|
*
|
||||||
}));
|
* var xmlCanvas = new mxXmlCanvas2D(root);
|
||||||
|
* var imgExport = new mxImageExport();
|
||||||
// Paints the overlays
|
* imgExport.drawState(graph.getView().getState(graph.model.root), xmlCanvas);
|
||||||
if (this.includeOverlays)
|
*
|
||||||
{
|
* var bounds = graph.getGraphBounds();
|
||||||
this.visitStatesRecursive(state, canvas, mxUtils.bind(this, ()=>
|
* var w = Math.ceil(bounds.x + bounds.width);
|
||||||
{
|
* var h = Math.ceil(bounds.y + bounds.height);
|
||||||
this.drawOverlays.apply(this, arguments);
|
*
|
||||||
|
* var xml = mxUtils.getXml(root);
|
||||||
|
* new mxXmlRequest('export', 'format=png&w=' + w +
|
||||||
|
* '&h=' + h + '&bg=#F9F7ED&xml=' + encodeURIComponent(xml))
|
||||||
|
* .simulate(document, '_blank');
|
||||||
|
* (end)
|
||||||
|
*
|
||||||
|
* Constructor: mxImageExport
|
||||||
|
*
|
||||||
|
* Constructs a new image export.
|
||||||
|
*/
|
||||||
|
constructor() {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function: drawState
|
||||||
|
*
|
||||||
|
* Draws the given state and all its descendants to the given canvas.
|
||||||
|
*/
|
||||||
|
drawState = (state, canvas) => {
|
||||||
|
if (state != null) {
|
||||||
|
this.visitStatesRecursive(state, canvas, mxUtils.bind(this, () => {
|
||||||
|
this.drawCellState.apply(this, arguments);
|
||||||
}));
|
}));
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
// Paints the overlays
|
||||||
* Function: visitStatesRecursive
|
if (this.includeOverlays) {
|
||||||
*
|
this.visitStatesRecursive(state, canvas, mxUtils.bind(this, () => {
|
||||||
* Visits the given state and all its descendants to the given canvas recursively.
|
this.drawOverlays.apply(this, arguments);
|
||||||
*/
|
}));
|
||||||
visitStatesRecursive = (state, canvas, visitor)=>
|
|
||||||
{
|
|
||||||
if (state != null)
|
|
||||||
{
|
|
||||||
visitor(state, canvas);
|
|
||||||
|
|
||||||
var graph = state.view.graph;
|
|
||||||
var childCount = graph.model.getChildCount(state.cell);
|
|
||||||
|
|
||||||
for (var i = 0; i < childCount; i++)
|
|
||||||
{
|
|
||||||
var childState = graph.view.getState(graph.model.getChildAt(state.cell, i));
|
|
||||||
this.visitStatesRecursive(childState, canvas, visitor);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Function: getLinkForCellState
|
|
||||||
*
|
|
||||||
* Returns the link for the given cell state and canvas. This returns null.
|
|
||||||
*/
|
|
||||||
getLinkForCellState = (state, canvas)=>
|
|
||||||
{
|
|
||||||
return null;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Function: drawCellState
|
|
||||||
*
|
|
||||||
* Draws the given state to the given canvas.
|
|
||||||
*/
|
|
||||||
drawCellState = (state, canvas)=>
|
|
||||||
{
|
|
||||||
// Experimental feature
|
|
||||||
var link = this.getLinkForCellState(state, canvas);
|
|
||||||
|
|
||||||
if (link != null)
|
|
||||||
{
|
|
||||||
canvas.setLink(link);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Paints the shape and text
|
|
||||||
this.drawShape(state, canvas);
|
|
||||||
this.drawText(state, canvas);
|
|
||||||
|
|
||||||
if (link != null)
|
|
||||||
{
|
|
||||||
canvas.setLink(null);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Function: drawShape
|
|
||||||
*
|
|
||||||
* Draws the shape of the given state.
|
|
||||||
*/
|
|
||||||
drawShape = (state, canvas)=>
|
|
||||||
{
|
|
||||||
if (state.shape instanceof mxShape && state.shape.checkBounds())
|
|
||||||
{
|
|
||||||
canvas.save();
|
|
||||||
|
|
||||||
state.shape.beforePaint(canvas);
|
|
||||||
state.shape.paint(canvas);
|
|
||||||
state.shape.afterPaint(canvas);
|
|
||||||
|
|
||||||
canvas.restore();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Function: drawText
|
|
||||||
*
|
|
||||||
* Draws the text of the given state.
|
|
||||||
*/
|
|
||||||
drawText = (state, canvas)=>
|
|
||||||
{
|
|
||||||
if (state.text != null && state.text.checkBounds())
|
|
||||||
{
|
|
||||||
canvas.save();
|
|
||||||
|
|
||||||
state.text.beforePaint(canvas);
|
|
||||||
state.text.paint(canvas);
|
|
||||||
state.text.afterPaint(canvas);
|
|
||||||
|
|
||||||
canvas.restore();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Function: drawOverlays
|
|
||||||
*
|
|
||||||
* Draws the overlays for the given state. This is called if <includeOverlays>
|
|
||||||
* is true.
|
|
||||||
*/
|
|
||||||
drawOverlays = (state, canvas)=>
|
|
||||||
{
|
|
||||||
if (state.overlays != null)
|
|
||||||
{
|
|
||||||
state.overlays.visit((id, shape)=>
|
|
||||||
{
|
|
||||||
if (shape instanceof mxShape)
|
|
||||||
{
|
|
||||||
shape.paint(canvas);
|
|
||||||
}
|
}
|
||||||
});
|
}
|
||||||
}
|
};
|
||||||
};
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function: visitStatesRecursive
|
||||||
|
*
|
||||||
|
* Visits the given state and all its descendants to the given canvas recursively.
|
||||||
|
*/
|
||||||
|
visitStatesRecursive = (state, canvas, visitor) => {
|
||||||
|
if (state != null) {
|
||||||
|
visitor(state, canvas);
|
||||||
|
|
||||||
|
var graph = state.view.graph;
|
||||||
|
var childCount = graph.model.getChildCount(state.cell);
|
||||||
|
|
||||||
|
for (var i = 0; i < childCount; i++) {
|
||||||
|
var childState = graph.view.getState(graph.model.getChildAt(state.cell, i));
|
||||||
|
this.visitStatesRecursive(childState, canvas, visitor);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function: getLinkForCellState
|
||||||
|
*
|
||||||
|
* Returns the link for the given cell state and canvas. This returns null.
|
||||||
|
*/
|
||||||
|
getLinkForCellState = (state, canvas) => {
|
||||||
|
return null;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function: drawCellState
|
||||||
|
*
|
||||||
|
* Draws the given state to the given canvas.
|
||||||
|
*/
|
||||||
|
drawCellState = (state, canvas) => {
|
||||||
|
// Experimental feature
|
||||||
|
var link = this.getLinkForCellState(state, canvas);
|
||||||
|
|
||||||
|
if (link != null) {
|
||||||
|
canvas.setLink(link);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Paints the shape and text
|
||||||
|
this.drawShape(state, canvas);
|
||||||
|
this.drawText(state, canvas);
|
||||||
|
|
||||||
|
if (link != null) {
|
||||||
|
canvas.setLink(null);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function: drawShape
|
||||||
|
*
|
||||||
|
* Draws the shape of the given state.
|
||||||
|
*/
|
||||||
|
drawShape = (state, canvas) => {
|
||||||
|
if (state.shape instanceof mxShape && state.shape.checkBounds()) {
|
||||||
|
canvas.save();
|
||||||
|
|
||||||
|
state.shape.beforePaint(canvas);
|
||||||
|
state.shape.paint(canvas);
|
||||||
|
state.shape.afterPaint(canvas);
|
||||||
|
|
||||||
|
canvas.restore();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function: drawText
|
||||||
|
*
|
||||||
|
* Draws the text of the given state.
|
||||||
|
*/
|
||||||
|
drawText = (state, canvas) => {
|
||||||
|
if (state.text != null && state.text.checkBounds()) {
|
||||||
|
canvas.save();
|
||||||
|
|
||||||
|
state.text.beforePaint(canvas);
|
||||||
|
state.text.paint(canvas);
|
||||||
|
state.text.afterPaint(canvas);
|
||||||
|
|
||||||
|
canvas.restore();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function: drawOverlays
|
||||||
|
*
|
||||||
|
* Draws the overlays for the given state. This is called if <includeOverlays>
|
||||||
|
* is true.
|
||||||
|
*/
|
||||||
|
drawOverlays = (state, canvas) => {
|
||||||
|
if (state.overlays != null) {
|
||||||
|
state.overlays.visit((id, shape) => {
|
||||||
|
if (shape instanceof mxShape) {
|
||||||
|
shape.paint(canvas);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export default mxImageExport;
|
||||||
|
|
|
@ -2,22 +2,22 @@
|
||||||
* Copyright (c) 2006-2015, JGraph Ltd
|
* Copyright (c) 2006-2015, JGraph Ltd
|
||||||
* Copyright (c) 2006-2015, Gaudenz Alder
|
* Copyright (c) 2006-2015, Gaudenz Alder
|
||||||
*/
|
*/
|
||||||
var mxLog =
|
|
||||||
{
|
var mxLog = {
|
||||||
/**
|
/**
|
||||||
* Class: mxLog
|
* Class: mxLog
|
||||||
*
|
*
|
||||||
* A singleton class that implements a simple console.
|
* A singleton class that implements a simple console.
|
||||||
*
|
*
|
||||||
* Variable: consoleName
|
* Variable: consoleName
|
||||||
*
|
*
|
||||||
* Specifies the name of the console window. Default is 'Console'.
|
* Specifies the name of the console window. Default is 'Console'.
|
||||||
*/
|
*/
|
||||||
consoleName: 'Console',
|
consoleName: 'Console',
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Variable: TRACE
|
* Variable: TRACE
|
||||||
*
|
*
|
||||||
* Specified if the output for <enter> and <leave> should be visible in the
|
* Specified if the output for <enter> and <leave> should be visible in the
|
||||||
* console. Default is false.
|
* console. Default is false.
|
||||||
*/
|
*/
|
||||||
|
@ -25,7 +25,7 @@ var mxLog =
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Variable: DEBUG
|
* Variable: DEBUG
|
||||||
*
|
*
|
||||||
* Specifies if the output for <debug> should be visible in the console.
|
* Specifies if the output for <debug> should be visible in the console.
|
||||||
* Default is true.
|
* Default is true.
|
||||||
*/
|
*/
|
||||||
|
@ -33,7 +33,7 @@ var mxLog =
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Variable: WARN
|
* Variable: WARN
|
||||||
*
|
*
|
||||||
* Specifies if the output for <warn> should be visible in the console.
|
* Specifies if the output for <warn> should be visible in the console.
|
||||||
* Default is true.
|
* Default is true.
|
||||||
*/
|
*/
|
||||||
|
@ -41,11 +41,11 @@ var mxLog =
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Variable: buffer
|
* Variable: buffer
|
||||||
*
|
*
|
||||||
* Buffer for pre-initialized content.
|
* Buffer for pre-initialized content.
|
||||||
*/
|
*/
|
||||||
buffer: '',
|
buffer: '',
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function: init
|
* Function: init
|
||||||
*
|
*
|
||||||
|
@ -53,10 +53,8 @@ var mxLog =
|
||||||
* point to a non-null value. This is called from within <setVisible> if the
|
* point to a non-null value. This is called from within <setVisible> if the
|
||||||
* log has not yet been initialized.
|
* log has not yet been initialized.
|
||||||
*/
|
*/
|
||||||
init: ()=>
|
init: () => {
|
||||||
{
|
if (mxLog.window == null && document.body != null) {
|
||||||
if (mxLog.window == null && document.body != null)
|
|
||||||
{
|
|
||||||
var title = mxLog.consoleName + ' - mxGraph ' + mxClient.VERSION;
|
var title = mxLog.consoleName + ' - mxGraph ' + mxClient.VERSION;
|
||||||
|
|
||||||
// Creates a table that maintains the layout
|
// Creates a table that maintains the layout
|
||||||
|
@ -68,7 +66,7 @@ var mxLog =
|
||||||
var tr = document.createElement('tr');
|
var tr = document.createElement('tr');
|
||||||
var td = document.createElement('td');
|
var td = document.createElement('td');
|
||||||
td.style.verticalAlign = 'top';
|
td.style.verticalAlign = 'top';
|
||||||
|
|
||||||
// Adds the actual console as a textarea
|
// Adds the actual console as a textarea
|
||||||
mxLog.textarea = document.createElement('textarea');
|
mxLog.textarea = document.createElement('textarea');
|
||||||
mxLog.textarea.setAttribute('wrap', 'off');
|
mxLog.textarea.setAttribute('wrap', 'off');
|
||||||
|
@ -78,15 +76,12 @@ var mxLog =
|
||||||
mxLog.textarea.value = mxLog.buffer;
|
mxLog.textarea.value = mxLog.buffer;
|
||||||
|
|
||||||
// Workaround for wrong width in standards mode
|
// Workaround for wrong width in standards mode
|
||||||
if (mxClient.IS_NS && document.compatMode != 'BackCompat')
|
if (mxClient.IS_NS && document.compatMode != 'BackCompat') {
|
||||||
{
|
|
||||||
mxLog.textarea.style.width = '99%';
|
mxLog.textarea.style.width = '99%';
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
mxLog.textarea.style.width = '100%';
|
mxLog.textarea.style.width = '100%';
|
||||||
}
|
}
|
||||||
|
|
||||||
td.appendChild(mxLog.textarea);
|
td.appendChild(mxLog.textarea);
|
||||||
tr.appendChild(td);
|
tr.appendChild(td);
|
||||||
tbody.appendChild(tr);
|
tbody.appendChild(tr);
|
||||||
|
@ -96,77 +91,59 @@ var mxLog =
|
||||||
mxLog.td = document.createElement('td');
|
mxLog.td = document.createElement('td');
|
||||||
mxLog.td.style.verticalAlign = 'top';
|
mxLog.td.style.verticalAlign = 'top';
|
||||||
mxLog.td.setAttribute('height', '30px');
|
mxLog.td.setAttribute('height', '30px');
|
||||||
|
|
||||||
tr.appendChild(mxLog.td);
|
tr.appendChild(mxLog.td);
|
||||||
tbody.appendChild(tr);
|
tbody.appendChild(tr);
|
||||||
table.appendChild(tbody);
|
table.appendChild(tbody);
|
||||||
|
|
||||||
// Adds various debugging buttons
|
// Adds various debugging buttons
|
||||||
mxLog.addButton('Info', function (evt)
|
mxLog.addButton('Info', function (evt) {
|
||||||
{
|
|
||||||
mxLog.info();
|
mxLog.info();
|
||||||
});
|
});
|
||||||
|
|
||||||
mxLog.addButton('DOM', function (evt)
|
mxLog.addButton('DOM', function (evt) {
|
||||||
{
|
|
||||||
var content = mxUtils.getInnerHtml(document.body);
|
var content = mxUtils.getInnerHtml(document.body);
|
||||||
mxLog.debug(content);
|
mxLog.debug(content);
|
||||||
});
|
});
|
||||||
|
|
||||||
mxLog.addButton('Trace', function (evt)
|
mxLog.addButton('Trace', function (evt) {
|
||||||
{
|
|
||||||
mxLog.TRACE = !mxLog.TRACE;
|
mxLog.TRACE = !mxLog.TRACE;
|
||||||
|
|
||||||
if (mxLog.TRACE)
|
if (mxLog.TRACE) {
|
||||||
{
|
|
||||||
mxLog.debug('Tracing enabled');
|
mxLog.debug('Tracing enabled');
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
mxLog.debug('Tracing disabled');
|
mxLog.debug('Tracing disabled');
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
mxLog.addButton('Copy', function (evt)
|
mxLog.addButton('Copy', function (evt) {
|
||||||
{
|
try {
|
||||||
try
|
|
||||||
{
|
|
||||||
mxUtils.copy(mxLog.textarea.value);
|
mxUtils.copy(mxLog.textarea.value);
|
||||||
}
|
} catch (err) {
|
||||||
catch (err)
|
|
||||||
{
|
|
||||||
mxUtils.alert(err);
|
mxUtils.alert(err);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
mxLog.addButton('Show', function (evt)
|
mxLog.addButton('Show', function (evt) {
|
||||||
{
|
try {
|
||||||
try
|
|
||||||
{
|
|
||||||
mxUtils.popup(mxLog.textarea.value);
|
mxUtils.popup(mxLog.textarea.value);
|
||||||
}
|
} catch (err) {
|
||||||
catch (err)
|
|
||||||
{
|
|
||||||
mxUtils.alert(err);
|
mxUtils.alert(err);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
mxLog.addButton('Clear', function (evt)
|
mxLog.addButton('Clear', function (evt) {
|
||||||
{
|
|
||||||
mxLog.textarea.value = '';
|
mxLog.textarea.value = '';
|
||||||
});
|
});
|
||||||
|
|
||||||
// Cross-browser code to get window size
|
// Cross-browser code to get window size
|
||||||
var h = 0;
|
var h = 0;
|
||||||
var w = 0;
|
var w = 0;
|
||||||
|
|
||||||
if (typeof(window.innerWidth) === 'number')
|
if (typeof (window.innerWidth) === 'number') {
|
||||||
{
|
|
||||||
h = window.innerHeight;
|
h = window.innerHeight;
|
||||||
w = window.innerWidth;
|
w = window.innerWidth;
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
h = (document.documentElement.clientHeight || document.body.clientHeight);
|
h = (document.documentElement.clientHeight || document.body.clientHeight);
|
||||||
w = document.body.clientWidth;
|
w = document.body.clientWidth;
|
||||||
}
|
}
|
||||||
|
@ -177,18 +154,16 @@ var mxLog =
|
||||||
mxLog.window.setResizable(true);
|
mxLog.window.setResizable(true);
|
||||||
mxLog.window.setClosable(true);
|
mxLog.window.setClosable(true);
|
||||||
mxLog.window.destroyOnClose = false;
|
mxLog.window.destroyOnClose = false;
|
||||||
|
|
||||||
// Workaround for ignored textarea height in various setups
|
// Workaround for ignored textarea height in various setups
|
||||||
if ((mxClient.IS_NS && !mxClient.IS_GC &&
|
if ((mxClient.IS_NS && !mxClient.IS_GC &&
|
||||||
!mxClient.IS_SF && document.compatMode != 'BackCompat'))
|
!mxClient.IS_SF && document.compatMode != 'BackCompat')) {
|
||||||
{
|
|
||||||
var elt = mxLog.window.getElement();
|
var elt = mxLog.window.getElement();
|
||||||
|
|
||||||
var resizeHandler = (sender, evt)=>
|
var resizeHandler = (sender, evt) => {
|
||||||
{
|
|
||||||
mxLog.textarea.style.height = Math.max(0, elt.offsetHeight - 70) + 'px';
|
mxLog.textarea.style.height = Math.max(0, elt.offsetHeight - 70) + 'px';
|
||||||
};
|
};
|
||||||
|
|
||||||
mxLog.window.addListener(mxEvent.RESIZE_END, resizeHandler);
|
mxLog.window.addListener(mxEvent.RESIZE_END, resizeHandler);
|
||||||
mxLog.window.addListener(mxEvent.MAXIMIZE, resizeHandler);
|
mxLog.window.addListener(mxEvent.MAXIMIZE, resizeHandler);
|
||||||
mxLog.window.addListener(mxEvent.NORMALIZE, resizeHandler);
|
mxLog.window.addListener(mxEvent.NORMALIZE, resizeHandler);
|
||||||
|
@ -197,83 +172,75 @@ var mxLog =
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function: info
|
* Function: info
|
||||||
*
|
*
|
||||||
* Writes the current navigator information to the console.
|
* Writes the current navigator information to the console.
|
||||||
*/
|
*/
|
||||||
info: ()=>
|
info: () => {
|
||||||
{
|
|
||||||
mxLog.writeln(mxUtils.toString(navigator));
|
mxLog.writeln(mxUtils.toString(navigator));
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function: addButton
|
* Function: addButton
|
||||||
*
|
*
|
||||||
* Adds a button to the console using the given label and function.
|
* Adds a button to the console using the given label and function.
|
||||||
*/
|
*/
|
||||||
addButton: (lab, funct)=>
|
addButton: (lab, funct) => {
|
||||||
{
|
|
||||||
var button = document.createElement('button');
|
var button = document.createElement('button');
|
||||||
mxUtils.write(button, lab);
|
mxUtils.write(button, lab);
|
||||||
mxEvent.addListener(button, 'click', funct);
|
mxEvent.addListener(button, 'click', funct);
|
||||||
mxLog.td.appendChild(button);
|
mxLog.td.appendChild(button);
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function: isVisible
|
* Function: isVisible
|
||||||
*
|
*
|
||||||
* Returns true if the console is visible.
|
* Returns true if the console is visible.
|
||||||
*/
|
*/
|
||||||
isVisible: ()=>
|
isVisible: () => {
|
||||||
{
|
if (mxLog.window != null) {
|
||||||
if (mxLog.window != null)
|
|
||||||
{
|
|
||||||
return mxLog.window.isVisible();
|
return mxLog.window.isVisible();
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function: show
|
* Function: show
|
||||||
*
|
*
|
||||||
* Shows the console.
|
* Shows the console.
|
||||||
*/
|
*/
|
||||||
show: ()=>
|
show: () => {
|
||||||
{
|
|
||||||
mxLog.setVisible(true);
|
mxLog.setVisible(true);
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function: setVisible
|
* Function: setVisible
|
||||||
*
|
*
|
||||||
* Shows or hides the console.
|
* Shows or hides the console.
|
||||||
*/
|
*/
|
||||||
setVisible: (visible)=>
|
setVisible: (visible) => {
|
||||||
{
|
if (mxLog.window == null) {
|
||||||
if (mxLog.window == null)
|
|
||||||
{
|
|
||||||
mxLog.init();
|
mxLog.init();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mxLog.window != null)
|
if (mxLog.window != null) {
|
||||||
{
|
|
||||||
mxLog.window.setVisible(visible);
|
mxLog.window.setVisible(visible);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function: enter
|
* Function: enter
|
||||||
*
|
*
|
||||||
* Writes the specified string to the console
|
* Writes the specified string to the console
|
||||||
* if <TRACE> is true and returns the current
|
* if <TRACE> is true and returns the current
|
||||||
* time in milliseconds.
|
* time in milliseconds.
|
||||||
*
|
*
|
||||||
* Example:
|
* Example:
|
||||||
*
|
*
|
||||||
* (code)
|
* (code)
|
||||||
* mxLog.show();
|
* mxLog.show();
|
||||||
* var t0 = mxLog.enter('Hello');
|
* var t0 = mxLog.enter('Hello');
|
||||||
|
@ -281,133 +248,116 @@ var mxLog =
|
||||||
* mxLog.leave('World!', t0);
|
* mxLog.leave('World!', t0);
|
||||||
* (end)
|
* (end)
|
||||||
*/
|
*/
|
||||||
enter: (string)=>
|
enter: (string) => {
|
||||||
{
|
if (mxLog.TRACE) {
|
||||||
if (mxLog.TRACE)
|
mxLog.writeln('Entering ' + string);
|
||||||
{
|
|
||||||
mxLog.writeln('Entering '+string);
|
|
||||||
|
|
||||||
return new Date().getTime();
|
return new Date().getTime();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function: leave
|
* Function: leave
|
||||||
*
|
*
|
||||||
* Writes the specified string to the console
|
* Writes the specified string to the console
|
||||||
* if <TRACE> is true and computes the difference
|
* if <TRACE> is true and computes the difference
|
||||||
* between the current time and t0 in milliseconds.
|
* between the current time and t0 in milliseconds.
|
||||||
* See <enter> for an example.
|
* See <enter> for an example.
|
||||||
*/
|
*/
|
||||||
leave: (string, t0)=>
|
leave: (string, t0) => {
|
||||||
{
|
if (mxLog.TRACE) {
|
||||||
if (mxLog.TRACE)
|
var dt = (t0 != 0) ? ' (' + (new Date().getTime() - t0) + ' ms)' : '';
|
||||||
{
|
mxLog.writeln('Leaving ' + string + dt);
|
||||||
var dt = (t0 != 0) ? ' ('+(new Date().getTime() - t0)+' ms)' : '';
|
|
||||||
mxLog.writeln('Leaving '+string+dt);
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function: debug
|
* Function: debug
|
||||||
*
|
*
|
||||||
* Adds all arguments to the console if <DEBUG> is enabled.
|
* Adds all arguments to the console if <DEBUG> is enabled.
|
||||||
*
|
*
|
||||||
* Example:
|
* Example:
|
||||||
*
|
*
|
||||||
* (code)
|
* (code)
|
||||||
* mxLog.show();
|
* mxLog.show();
|
||||||
* mxLog.debug('Hello, World!');
|
* mxLog.debug('Hello, World!');
|
||||||
* (end)
|
* (end)
|
||||||
*/
|
*/
|
||||||
debug: ()=>
|
debug: () => {
|
||||||
{
|
if (mxLog.DEBUG) {
|
||||||
if (mxLog.DEBUG)
|
|
||||||
{
|
|
||||||
mxLog.writeln.apply(this, arguments);
|
mxLog.writeln.apply(this, arguments);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function: warn
|
* Function: warn
|
||||||
*
|
*
|
||||||
* Adds all arguments to the console if <WARN> is enabled.
|
* Adds all arguments to the console if <WARN> is enabled.
|
||||||
*
|
*
|
||||||
* Example:
|
* Example:
|
||||||
*
|
*
|
||||||
* (code)
|
* (code)
|
||||||
* mxLog.show();
|
* mxLog.show();
|
||||||
* mxLog.warn('Hello, World!');
|
* mxLog.warn('Hello, World!');
|
||||||
* (end)
|
* (end)
|
||||||
*/
|
*/
|
||||||
warn: ()=>
|
warn: () => {
|
||||||
{
|
if (mxLog.WARN) {
|
||||||
if (mxLog.WARN)
|
|
||||||
{
|
|
||||||
mxLog.writeln.apply(this, arguments);
|
mxLog.writeln.apply(this, arguments);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function: write
|
* Function: write
|
||||||
*
|
*
|
||||||
* Adds the specified strings to the console.
|
* Adds the specified strings to the console.
|
||||||
*/
|
*/
|
||||||
write: ()=>
|
write: () => {
|
||||||
{
|
|
||||||
var string = '';
|
var string = '';
|
||||||
|
|
||||||
for (var i = 0; i < arguments.length; i++)
|
for (var i = 0; i < arguments.length; i++) {
|
||||||
{
|
|
||||||
string += arguments[i];
|
string += arguments[i];
|
||||||
|
|
||||||
if (i < arguments.length - 1)
|
if (i < arguments.length - 1) {
|
||||||
{
|
|
||||||
string += ' ';
|
string += ' ';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mxLog.textarea != null)
|
if (mxLog.textarea != null) {
|
||||||
{
|
|
||||||
mxLog.textarea.value = mxLog.textarea.value + string;
|
mxLog.textarea.value = mxLog.textarea.value + string;
|
||||||
|
|
||||||
// Workaround for no update in Presto 2.5.22 (Opera 10.5)
|
// Workaround for no update in Presto 2.5.22 (Opera 10.5)
|
||||||
if (navigator.userAgent != null &&
|
if (navigator.userAgent != null &&
|
||||||
navigator.userAgent.indexOf('Presto/2.5') >= 0)
|
navigator.userAgent.indexOf('Presto/2.5') >= 0) {
|
||||||
{
|
|
||||||
mxLog.textarea.style.visibility = 'hidden';
|
mxLog.textarea.style.visibility = 'hidden';
|
||||||
mxLog.textarea.style.visibility = 'visible';
|
mxLog.textarea.style.visibility = 'visible';
|
||||||
}
|
}
|
||||||
|
|
||||||
mxLog.textarea.scrollTop = mxLog.textarea.scrollHeight;
|
mxLog.textarea.scrollTop = mxLog.textarea.scrollHeight;
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
mxLog.buffer += string;
|
mxLog.buffer += string;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function: writeln
|
* Function: writeln
|
||||||
*
|
*
|
||||||
* Adds the specified strings to the console, appending a linefeed at the
|
* Adds the specified strings to the console, appending a linefeed at the
|
||||||
* end of each string.
|
* end of each string.
|
||||||
*/
|
*/
|
||||||
writeln: ()=>
|
writeln: () => {
|
||||||
{
|
|
||||||
var string = '';
|
var string = '';
|
||||||
|
|
||||||
for (var i = 0; i < arguments.length; i++)
|
for (var i = 0; i < arguments.length; i++) {
|
||||||
{
|
|
||||||
string += arguments[i];
|
string += arguments[i];
|
||||||
|
|
||||||
if (i < arguments.length - 1)
|
if (i < arguments.length - 1) {
|
||||||
{
|
|
||||||
string += ' ';
|
string += ' ';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
mxLog.write(string + '\n');
|
mxLog.write(string + '\n');
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export default mxLog;
|
||||||
|
|
|
@ -2,248 +2,226 @@
|
||||||
* Copyright (c) 2006-2015, JGraph Ltd
|
* Copyright (c) 2006-2015, JGraph Ltd
|
||||||
* Copyright (c) 2006-2015, Gaudenz Alder
|
* Copyright (c) 2006-2015, Gaudenz Alder
|
||||||
*/
|
*/
|
||||||
/**
|
import mxPoint from "./mxPoint";
|
||||||
*
|
import mxCellStatePreview from "../view/mxCellStatePreview";
|
||||||
* Class: mxMorphing
|
|
||||||
*
|
|
||||||
* Implements animation for morphing cells. Here is an example of
|
|
||||||
* using this class for animating the result of a layout algorithm:
|
|
||||||
*
|
|
||||||
* (code)
|
|
||||||
* graph.getModel().beginUpdate();
|
|
||||||
* try
|
|
||||||
* {
|
|
||||||
* var circleLayout = new mxCircleLayout(graph);
|
|
||||||
* circleLayout.execute(graph.getDefaultParent());
|
|
||||||
* }
|
|
||||||
* finally
|
|
||||||
* {
|
|
||||||
* var morph = new mxMorphing(graph);
|
|
||||||
* morph.addListener(mxEvent.DONE, ()=>
|
|
||||||
* {
|
|
||||||
* graph.getModel().endUpdate();
|
|
||||||
* });
|
|
||||||
*
|
|
||||||
* morph.startAnimation();
|
|
||||||
* }
|
|
||||||
* (end)
|
|
||||||
*
|
|
||||||
* Constructor: mxMorphing
|
|
||||||
*
|
|
||||||
* Constructs an animation.
|
|
||||||
*
|
|
||||||
* Parameters:
|
|
||||||
*
|
|
||||||
* graph - Reference to the enclosing <mxGraph>.
|
|
||||||
* steps - Optional number of steps in the morphing animation. Default is 6.
|
|
||||||
* ease - Optional easing constant for the animation. Default is 1.5.
|
|
||||||
* delay - Optional delay between the animation steps. Passed to <mxAnimation>.
|
|
||||||
*/
|
|
||||||
function mxMorphing(graph, steps, ease, delay)
|
|
||||||
{
|
|
||||||
mxAnimation.call(this, delay);
|
|
||||||
this.graph = graph;
|
|
||||||
this.steps = (steps != null) ? steps : 6;
|
|
||||||
this.ease = (ease != null) ? ease : 1.5;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
class mxMorphing extends mxAnimation {
|
||||||
* Extends mxEventSource.
|
/**
|
||||||
*/
|
* Variable: graph
|
||||||
mxMorphing.prototype = new mxAnimation();
|
*
|
||||||
constructor = mxMorphing;
|
* Specifies the delay between the animation steps. Defaul is 30ms.
|
||||||
|
*/
|
||||||
|
graph = null;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Variable: graph
|
* Variable: steps
|
||||||
*
|
*
|
||||||
* Specifies the delay between the animation steps. Defaul is 30ms.
|
* Specifies the maximum number of steps for the morphing.
|
||||||
*/
|
*/
|
||||||
graph = null;
|
steps = null;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Variable: steps
|
* Variable: step
|
||||||
*
|
*
|
||||||
* Specifies the maximum number of steps for the morphing.
|
* Contains the current step.
|
||||||
*/
|
*/
|
||||||
steps = null;
|
step = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Variable: step
|
* Variable: ease
|
||||||
*
|
*
|
||||||
* Contains the current step.
|
* Ease-off for movement towards the given vector. Larger values are
|
||||||
*/
|
* slower and smoother. Default is 4.
|
||||||
step = 0;
|
*/
|
||||||
|
ease = null;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Variable: ease
|
* Variable: cells
|
||||||
*
|
*
|
||||||
* Ease-off for movement towards the given vector. Larger values are
|
* Optional array of cells to be animated. If this is not specified
|
||||||
* slower and smoother. Default is 4.
|
* then all cells are checked and animated if they have been moved
|
||||||
*/
|
* in the current transaction.
|
||||||
ease = null;
|
*/
|
||||||
|
cells = null;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Variable: cells
|
*
|
||||||
*
|
* Class: mxMorphing
|
||||||
* Optional array of cells to be animated. If this is not specified
|
*
|
||||||
* then all cells are checked and animated if they have been moved
|
* Implements animation for morphing cells. Here is an example of
|
||||||
* in the current transaction.
|
* using this class for animating the result of a layout algorithm:
|
||||||
*/
|
*
|
||||||
cells = null;
|
* (code)
|
||||||
|
* graph.getModel().beginUpdate();
|
||||||
|
* try
|
||||||
|
* {
|
||||||
|
* var circleLayout = new mxCircleLayout(graph);
|
||||||
|
* circleLayout.execute(graph.getDefaultParent());
|
||||||
|
* }
|
||||||
|
* finally
|
||||||
|
* {
|
||||||
|
* var morph = new mxMorphing(graph);
|
||||||
|
* morph.addListener(mxEvent.DONE, ()=>
|
||||||
|
* {
|
||||||
|
* graph.getModel().endUpdate();
|
||||||
|
* });
|
||||||
|
*
|
||||||
|
* morph.startAnimation();
|
||||||
|
* }
|
||||||
|
* (end)
|
||||||
|
*
|
||||||
|
* Constructor: mxMorphing
|
||||||
|
*
|
||||||
|
* Constructs an animation.
|
||||||
|
*
|
||||||
|
* Parameters:
|
||||||
|
*
|
||||||
|
* graph - Reference to the enclosing <mxGraph>.
|
||||||
|
* steps - Optional number of steps in the morphing animation. Default is 6.
|
||||||
|
* ease - Optional easing constant for the animation. Default is 1.5.
|
||||||
|
* delay - Optional delay between the animation steps. Passed to <mxAnimation>.
|
||||||
|
*/
|
||||||
|
constructor(graph, steps, ease, delay) {
|
||||||
|
super(delay);
|
||||||
|
this.graph = graph;
|
||||||
|
this.steps = (steps != null) ? steps : 6;
|
||||||
|
this.ease = (ease != null) ? ease : 1.5;
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function: updateAnimation
|
* Function: updateAnimation
|
||||||
*
|
*
|
||||||
* Animation step.
|
* Animation step.
|
||||||
*/
|
*/
|
||||||
updateAnimation = ()=>
|
updateAnimation = () => {
|
||||||
{
|
updateAnimation.apply(this, arguments);
|
||||||
updateAnimation.apply(this, arguments);
|
var move = new mxCellStatePreview(this.graph);
|
||||||
var move = new mxCellStatePreview(this.graph);
|
|
||||||
|
|
||||||
if (this.cells != null)
|
if (this.cells != null) {
|
||||||
{
|
// Animates the given cells individually without recursion
|
||||||
// Animates the given cells individually without recursion
|
for (var i = 0; i < this.cells.length; i++) {
|
||||||
for (var i = 0; i < this.cells.length; i++)
|
this.animateCell(this.cells[i], move, false);
|
||||||
{
|
}
|
||||||
this.animateCell(this.cells[i], move, false);
|
} else {
|
||||||
|
// Animates all changed cells by using recursion to find
|
||||||
|
// the changed cells but not for the animation itself
|
||||||
|
this.animateCell(this.graph.getModel().getRoot(), move, true);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// Animates all changed cells by using recursion to find
|
|
||||||
// the changed cells but not for the animation itself
|
|
||||||
this.animateCell(this.graph.getModel().getRoot(), move, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
this.show(move);
|
|
||||||
|
|
||||||
if (move.isEmpty() || this.step++ >= this.steps)
|
|
||||||
{
|
|
||||||
this.stopAnimation();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
this.show(move);
|
||||||
* Function: show
|
|
||||||
*
|
|
||||||
* Shows the changes in the given <mxCellStatePreview>.
|
|
||||||
*/
|
|
||||||
show = (move)=>
|
|
||||||
{
|
|
||||||
move.show();
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
if (move.isEmpty() || this.step++ >= this.steps) {
|
||||||
* Function: animateCell
|
this.stopAnimation();
|
||||||
*
|
|
||||||
* Animates the given cell state using <mxCellStatePreview.moveState>.
|
|
||||||
*/
|
|
||||||
animateCell = (cell, move, recurse)=>
|
|
||||||
{
|
|
||||||
var state = this.graph.getView().getState(cell);
|
|
||||||
var delta = null;
|
|
||||||
|
|
||||||
if (state != null)
|
|
||||||
{
|
|
||||||
// Moves the animated state from where it will be after the model
|
|
||||||
// change by subtracting the given delta vector from that location
|
|
||||||
delta = this.getDelta(state);
|
|
||||||
|
|
||||||
if (this.graph.getModel().isVertex(cell) && (delta.x != 0 || delta.y != 0))
|
|
||||||
{
|
|
||||||
var translate = this.graph.view.getTranslate();
|
|
||||||
var scale = this.graph.view.getScale();
|
|
||||||
|
|
||||||
delta.x += translate.x * scale;
|
|
||||||
delta.y += translate.y * scale;
|
|
||||||
|
|
||||||
move.moveState(state, -delta.x / this.ease, -delta.y / this.ease);
|
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
if (recurse && !this.stopRecursion(state, delta))
|
|
||||||
{
|
|
||||||
var childCount = this.graph.getModel().getChildCount(cell);
|
|
||||||
|
|
||||||
for (var i = 0; i < childCount; i++)
|
/**
|
||||||
{
|
* Function: show
|
||||||
this.animateCell(this.graph.getModel().getChildAt(cell, i), move, recurse);
|
*
|
||||||
|
* Shows the changes in the given <mxCellStatePreview>.
|
||||||
|
*/
|
||||||
|
show = (move) => {
|
||||||
|
move.show();
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function: animateCell
|
||||||
|
*
|
||||||
|
* Animates the given cell state using <mxCellStatePreview.moveState>.
|
||||||
|
*/
|
||||||
|
animateCell = (cell, move, recurse) => {
|
||||||
|
var state = this.graph.getView().getState(cell);
|
||||||
|
var delta = null;
|
||||||
|
|
||||||
|
if (state != null) {
|
||||||
|
// Moves the animated state from where it will be after the model
|
||||||
|
// change by subtracting the given delta vector from that location
|
||||||
|
delta = this.getDelta(state);
|
||||||
|
|
||||||
|
if (this.graph.getModel().isVertex(cell) && (delta.x != 0 || delta.y != 0)) {
|
||||||
|
var translate = this.graph.view.getTranslate();
|
||||||
|
var scale = this.graph.view.getScale();
|
||||||
|
|
||||||
|
delta.x += translate.x * scale;
|
||||||
|
delta.y += translate.y * scale;
|
||||||
|
|
||||||
|
move.moveState(state, -delta.x / this.ease, -delta.y / this.ease);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
if (recurse && !this.stopRecursion(state, delta)) {
|
||||||
* Function: stopRecursion
|
var childCount = this.graph.getModel().getChildCount(cell);
|
||||||
*
|
|
||||||
* Returns true if the animation should not recursively find more
|
|
||||||
* deltas for children if the given parent state has been animated.
|
|
||||||
*/
|
|
||||||
stopRecursion = (state, delta)=>
|
|
||||||
{
|
|
||||||
return delta != null && (delta.x != 0 || delta.y != 0);
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
for (var i = 0; i < childCount; i++) {
|
||||||
* Function: getDelta
|
this.animateCell(this.graph.getModel().getChildAt(cell, i), move, recurse);
|
||||||
*
|
}
|
||||||
* Returns the vector between the current rendered state and the future
|
}
|
||||||
* location of the state after the display will be updated.
|
};
|
||||||
*/
|
|
||||||
getDelta = (state)=>
|
|
||||||
{
|
|
||||||
var origin = this.getOriginForCell(state.cell);
|
|
||||||
var translate = this.graph.getView().getTranslate();
|
|
||||||
var scale = this.graph.getView().getScale();
|
|
||||||
var x = state.x / scale - translate.x;
|
|
||||||
var y = state.y / scale - translate.y;
|
|
||||||
|
|
||||||
return new mxPoint((origin.x - x) * scale, (origin.y - y) * scale);
|
/**
|
||||||
};
|
* Function: stopRecursion
|
||||||
|
*
|
||||||
|
* Returns true if the animation should not recursively find more
|
||||||
|
* deltas for children if the given parent state has been animated.
|
||||||
|
*/
|
||||||
|
stopRecursion = (state, delta) => {
|
||||||
|
return delta != null && (delta.x != 0 || delta.y != 0);
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function: getOriginForCell
|
* Function: getDelta
|
||||||
*
|
*
|
||||||
* Returns the top, left corner of the given cell. TODO: Improve performance
|
* Returns the vector between the current rendered state and the future
|
||||||
* by using caching inside this method as the result per cell never changes
|
* location of the state after the display will be updated.
|
||||||
* during the lifecycle of this object.
|
*/
|
||||||
*/
|
getDelta = (state) => {
|
||||||
getOriginForCell = (cell)=>
|
var origin = this.getOriginForCell(state.cell);
|
||||||
{
|
var translate = this.graph.getView().getTranslate();
|
||||||
var result = null;
|
var scale = this.graph.getView().getScale();
|
||||||
|
var x = state.x / scale - translate.x;
|
||||||
if (cell != null)
|
var y = state.y / scale - translate.y;
|
||||||
{
|
|
||||||
var parent = this.graph.getModel().getParent(cell);
|
return new mxPoint((origin.x - x) * scale, (origin.y - y) * scale);
|
||||||
var geo = this.graph.getCellGeometry(cell);
|
};
|
||||||
result = this.getOriginForCell(parent);
|
|
||||||
|
/**
|
||||||
// TODO: Handle offsets
|
* Function: getOriginForCell
|
||||||
if (geo != null)
|
*
|
||||||
{
|
* Returns the top, left corner of the given cell. TODO: Improve performance
|
||||||
if (geo.relative)
|
* by using caching inside this method as the result per cell never changes
|
||||||
{
|
* during the lifecycle of this object.
|
||||||
var pgeo = this.graph.getCellGeometry(parent);
|
*/
|
||||||
|
getOriginForCell = (cell) => {
|
||||||
if (pgeo != null)
|
var result = null;
|
||||||
{
|
|
||||||
result.x += geo.x * pgeo.width;
|
if (cell != null) {
|
||||||
result.y += geo.y * pgeo.height;
|
var parent = this.graph.getModel().getParent(cell);
|
||||||
|
var geo = this.graph.getCellGeometry(cell);
|
||||||
|
result = this.getOriginForCell(parent);
|
||||||
|
|
||||||
|
// TODO: Handle offsets
|
||||||
|
if (geo != null) {
|
||||||
|
if (geo.relative) {
|
||||||
|
var pgeo = this.graph.getCellGeometry(parent);
|
||||||
|
|
||||||
|
if (pgeo != null) {
|
||||||
|
result.x += geo.x * pgeo.width;
|
||||||
|
result.y += geo.y * pgeo.height;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
result.x += geo.x;
|
||||||
|
result.y += geo.y;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
result.x += geo.x;
|
|
||||||
result.y += geo.y;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
if (result == null) {
|
||||||
if (result == null)
|
var t = this.graph.view.getTranslate();
|
||||||
{
|
result = new mxPoint(-t.x, -t.y);
|
||||||
var t = this.graph.view.getTranslate();
|
}
|
||||||
result = new mxPoint(-t.x, -t.y);
|
|
||||||
}
|
return result;
|
||||||
|
};
|
||||||
return result;
|
}
|
||||||
};
|
|
||||||
|
export default mxMorphing;
|
||||||
|
|
|
@ -2,237 +2,226 @@
|
||||||
* Copyright (c) 2006-2015, JGraph Ltd
|
* Copyright (c) 2006-2015, JGraph Ltd
|
||||||
* Copyright (c) 2006-2015, Gaudenz Alder
|
* Copyright (c) 2006-2015, Gaudenz Alder
|
||||||
*/
|
*/
|
||||||
/**
|
|
||||||
* Class: mxMouseEvent
|
|
||||||
*
|
|
||||||
* Base class for all mouse events in mxGraph. A listener for this event should
|
|
||||||
* implement the following methods:
|
|
||||||
*
|
|
||||||
* (code)
|
|
||||||
* graph.addMouseListener(
|
|
||||||
* {
|
|
||||||
* mouseDown: (sender, evt)=>
|
|
||||||
* {
|
|
||||||
* mxLog.debug('mouseDown');
|
|
||||||
* },
|
|
||||||
* mouseMove: (sender, evt)=>
|
|
||||||
* {
|
|
||||||
* mxLog.debug('mouseMove');
|
|
||||||
* },
|
|
||||||
* mouseUp: (sender, evt)=>
|
|
||||||
* {
|
|
||||||
* mxLog.debug('mouseUp');
|
|
||||||
* }
|
|
||||||
* });
|
|
||||||
* (end)
|
|
||||||
*
|
|
||||||
* Constructor: mxMouseEvent
|
|
||||||
*
|
|
||||||
* Constructs a new event object for the given arguments.
|
|
||||||
*
|
|
||||||
* Parameters:
|
|
||||||
*
|
|
||||||
* evt - Native mouse event.
|
|
||||||
* state - Optional <mxCellState> under the mouse.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
function mxMouseEvent(evt, state)
|
|
||||||
{
|
|
||||||
this.evt = evt;
|
|
||||||
this.state = state;
|
|
||||||
this.sourceState = state;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
class mxMouseEvent {
|
||||||
* Variable: consumed
|
/**
|
||||||
*
|
* Variable: consumed
|
||||||
* Holds the consumed state of this event.
|
*
|
||||||
*/
|
* Holds the consumed state of this event.
|
||||||
consumed = false;
|
*/
|
||||||
|
consumed = false;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Variable: evt
|
* Variable: evt
|
||||||
*
|
*
|
||||||
* Holds the inner event object.
|
* Holds the inner event object.
|
||||||
*/
|
*/
|
||||||
evt = null;
|
evt = null;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Variable: graphX
|
* Variable: graphX
|
||||||
*
|
*
|
||||||
* Holds the x-coordinate of the event in the graph. This value is set in
|
* Holds the x-coordinate of the event in the graph. This value is set in
|
||||||
* <mxGraph.fireMouseEvent>.
|
* <mxGraph.fireMouseEvent>.
|
||||||
*/
|
*/
|
||||||
graphX = null;
|
graphX = null;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Variable: graphY
|
* Variable: graphY
|
||||||
*
|
*
|
||||||
* Holds the y-coordinate of the event in the graph. This value is set in
|
* Holds the y-coordinate of the event in the graph. This value is set in
|
||||||
* <mxGraph.fireMouseEvent>.
|
* <mxGraph.fireMouseEvent>.
|
||||||
*/
|
*/
|
||||||
graphY = null;
|
graphY = null;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Variable: state
|
* Variable: state
|
||||||
*
|
*
|
||||||
* Holds the optional <mxCellState> associated with this event.
|
* Holds the optional <mxCellState> associated with this event.
|
||||||
*/
|
*/
|
||||||
state = null;
|
state = null;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Variable: sourceState
|
* Variable: sourceState
|
||||||
*
|
*
|
||||||
* Holds the <mxCellState> that was passed to the constructor. This can be
|
* Holds the <mxCellState> that was passed to the constructor. This can be
|
||||||
* different from <state> depending on the result of <mxGraph.getEventState>.
|
* different from <state> depending on the result of <mxGraph.getEventState>.
|
||||||
*/
|
*/
|
||||||
sourceState = null;
|
sourceState = null;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function: getEvent
|
* Class: mxMouseEvent
|
||||||
*
|
*
|
||||||
* Returns <evt>.
|
* Base class for all mouse events in mxGraph. A listener for this event should
|
||||||
*/
|
* implement the following methods:
|
||||||
getEvent = ()=>
|
*
|
||||||
{
|
* (code)
|
||||||
return this.evt;
|
* graph.addMouseListener(
|
||||||
};
|
* {
|
||||||
|
* mouseDown: (sender, evt)=>
|
||||||
|
* {
|
||||||
|
* mxLog.debug('mouseDown');
|
||||||
|
* },
|
||||||
|
* mouseMove: (sender, evt)=>
|
||||||
|
* {
|
||||||
|
* mxLog.debug('mouseMove');
|
||||||
|
* },
|
||||||
|
* mouseUp: (sender, evt)=>
|
||||||
|
* {
|
||||||
|
* mxLog.debug('mouseUp');
|
||||||
|
* }
|
||||||
|
* });
|
||||||
|
* (end)
|
||||||
|
*
|
||||||
|
* Constructor: mxMouseEvent
|
||||||
|
*
|
||||||
|
* Constructs a new event object for the given arguments.
|
||||||
|
*
|
||||||
|
* Parameters:
|
||||||
|
*
|
||||||
|
* evt - Native mouse event.
|
||||||
|
* state - Optional <mxCellState> under the mouse.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
constructor(evt, state) {
|
||||||
|
this.evt = evt;
|
||||||
|
this.state = state;
|
||||||
|
this.sourceState = state;
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function: getSource
|
* Function: getEvent
|
||||||
*
|
*
|
||||||
* Returns the target DOM element using <mxEvent.getSource> for <evt>.
|
* Returns <evt>.
|
||||||
*/
|
*/
|
||||||
getSource = ()=>
|
getEvent = () => {
|
||||||
{
|
return this.evt;
|
||||||
return mxEvent.getSource(this.evt);
|
};
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function: isSource
|
* Function: getSource
|
||||||
*
|
*
|
||||||
* Returns true if the given <mxShape> is the source of <evt>.
|
* Returns the target DOM element using <mxEvent.getSource> for <evt>.
|
||||||
*/
|
*/
|
||||||
isSource = (shape)=>
|
getSource = () => {
|
||||||
{
|
return mxEvent.getSource(this.evt);
|
||||||
if (shape != null)
|
};
|
||||||
{
|
|
||||||
return mxUtils.isAncestorNode(shape.node, this.getSource());
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
/**
|
||||||
};
|
* Function: isSource
|
||||||
|
*
|
||||||
|
* Returns true if the given <mxShape> is the source of <evt>.
|
||||||
|
*/
|
||||||
|
isSource = (shape) => {
|
||||||
|
if (shape != null) {
|
||||||
|
return mxUtils.isAncestorNode(shape.node, this.getSource());
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
return false;
|
||||||
* Function: getX
|
};
|
||||||
*
|
|
||||||
* Returns <evt.clientX>.
|
|
||||||
*/
|
|
||||||
getX = ()=>
|
|
||||||
{
|
|
||||||
return mxEvent.getClientX(this.getEvent());
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function: getY
|
* Function: getX
|
||||||
*
|
*
|
||||||
* Returns <evt.clientY>.
|
* Returns <evt.clientX>.
|
||||||
*/
|
*/
|
||||||
getY = ()=>
|
getX = () => {
|
||||||
{
|
return mxEvent.getClientX(this.getEvent());
|
||||||
return mxEvent.getClientY(this.getEvent());
|
};
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function: getGraphX
|
* Function: getY
|
||||||
*
|
*
|
||||||
* Returns <graphX>.
|
* Returns <evt.clientY>.
|
||||||
*/
|
*/
|
||||||
getGraphX = ()=>
|
getY = () => {
|
||||||
{
|
return mxEvent.getClientY(this.getEvent());
|
||||||
return this.graphX;
|
};
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function: getGraphY
|
* Function: getGraphX
|
||||||
*
|
*
|
||||||
* Returns <graphY>.
|
* Returns <graphX>.
|
||||||
*/
|
*/
|
||||||
getGraphY = ()=>
|
getGraphX = () => {
|
||||||
{
|
return this.graphX;
|
||||||
return this.graphY;
|
};
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function: getState
|
* Function: getGraphY
|
||||||
*
|
*
|
||||||
* Returns <state>.
|
* Returns <graphY>.
|
||||||
*/
|
*/
|
||||||
getState = ()=>
|
getGraphY = () => {
|
||||||
{
|
return this.graphY;
|
||||||
return this.state;
|
};
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function: getCell
|
* Function: getState
|
||||||
*
|
*
|
||||||
* Returns the <mxCell> in <state> is not null.
|
* Returns <state>.
|
||||||
*/
|
*/
|
||||||
getCell = ()=>
|
getState = () => {
|
||||||
{
|
return this.state;
|
||||||
var state = this.getState();
|
};
|
||||||
|
|
||||||
if (state != null)
|
/**
|
||||||
{
|
* Function: getCell
|
||||||
return state.cell;
|
*
|
||||||
}
|
* Returns the <mxCell> in <state> is not null.
|
||||||
|
*/
|
||||||
|
getCell = () => {
|
||||||
|
var state = this.getState();
|
||||||
|
|
||||||
return null;
|
if (state != null) {
|
||||||
};
|
return state.cell;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
return null;
|
||||||
* Function: isPopupTrigger
|
};
|
||||||
*
|
|
||||||
* Returns true if the event is a popup trigger.
|
|
||||||
*/
|
|
||||||
isPopupTrigger = ()=>
|
|
||||||
{
|
|
||||||
return mxEvent.isPopupTrigger(this.getEvent());
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function: isConsumed
|
* Function: isPopupTrigger
|
||||||
*
|
*
|
||||||
* Returns <consumed>.
|
* Returns true if the event is a popup trigger.
|
||||||
*/
|
*/
|
||||||
isConsumed = ()=>
|
isPopupTrigger = () => {
|
||||||
{
|
return mxEvent.isPopupTrigger(this.getEvent());
|
||||||
return this.consumed;
|
};
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function: consume
|
* Function: isConsumed
|
||||||
*
|
*
|
||||||
* Sets <consumed> to true and invokes preventDefault on the native event
|
* Returns <consumed>.
|
||||||
* if such a method is defined. This is used mainly to avoid the cursor from
|
*/
|
||||||
* being changed to a text cursor in Webkit. You can use the preventDefault
|
isConsumed = () => {
|
||||||
* flag to disable this functionality.
|
return this.consumed;
|
||||||
*
|
};
|
||||||
* Parameters:
|
|
||||||
*
|
|
||||||
* preventDefault - Specifies if the native event should be canceled. Default
|
|
||||||
* is true.
|
|
||||||
*/
|
|
||||||
consume = (preventDefault)=>
|
|
||||||
{
|
|
||||||
preventDefault = (preventDefault != null) ? preventDefault :
|
|
||||||
(this.evt.touches != null || mxEvent.isMouseEvent(this.evt));
|
|
||||||
|
|
||||||
if (preventDefault && this.evt.preventDefault)
|
/**
|
||||||
{
|
* Function: consume
|
||||||
this.evt.preventDefault();
|
*
|
||||||
}
|
* Sets <consumed> to true and invokes preventDefault on the native event
|
||||||
|
* if such a method is defined. This is used mainly to avoid the cursor from
|
||||||
|
* being changed to a text cursor in Webkit. You can use the preventDefault
|
||||||
|
* flag to disable this functionality.
|
||||||
|
*
|
||||||
|
* Parameters:
|
||||||
|
*
|
||||||
|
* preventDefault - Specifies if the native event should be canceled. Default
|
||||||
|
* is true.
|
||||||
|
*/
|
||||||
|
consume = (preventDefault) => {
|
||||||
|
preventDefault = (preventDefault != null) ? preventDefault :
|
||||||
|
(this.evt.touches != null || mxEvent.isMouseEvent(this.evt));
|
||||||
|
|
||||||
// Sets local consumed state
|
if (preventDefault && this.evt.preventDefault) {
|
||||||
this.consumed = true;
|
this.evt.preventDefault();
|
||||||
};
|
}
|
||||||
|
|
||||||
|
// Sets local consumed state
|
||||||
|
this.consumed = true;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export default mxMouseEvent;
|
||||||
|
|
|
@ -2,19 +2,19 @@
|
||||||
* Copyright (c) 2006-2015, JGraph Ltd
|
* Copyright (c) 2006-2015, JGraph Ltd
|
||||||
* Copyright (c) 2006-2015, Gaudenz Alder
|
* Copyright (c) 2006-2015, Gaudenz Alder
|
||||||
*/
|
*/
|
||||||
var mxObjectIdentity =
|
|
||||||
{
|
var mxObjectIdentity = {
|
||||||
/**
|
/**
|
||||||
* Class: mxObjectIdentity
|
* Class: mxObjectIdentity
|
||||||
*
|
*
|
||||||
* Identity for JavaScript objects and functions. This is implemented using
|
* Identity for JavaScript objects and functions. This is implemented using
|
||||||
* a simple incrementing counter which is stored in each object under
|
* a simple incrementing counter which is stored in each object under
|
||||||
* <FIELD_NAME>.
|
* <FIELD_NAME>.
|
||||||
*
|
*
|
||||||
* The identity for an object does not change during its lifecycle.
|
* The identity for an object does not change during its lifecycle.
|
||||||
*
|
*
|
||||||
* Variable: FIELD_NAME
|
* Variable: FIELD_NAME
|
||||||
*
|
*
|
||||||
* Name of the field to be used to store the object ID. Default is
|
* Name of the field to be used to store the object ID. Default is
|
||||||
* <code>mxObjectId</code>.
|
* <code>mxObjectId</code>.
|
||||||
*/
|
*/
|
||||||
|
@ -22,51 +22,44 @@ var mxObjectIdentity =
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Variable: counter
|
* Variable: counter
|
||||||
*
|
*
|
||||||
* Current counter.
|
* Current counter.
|
||||||
*/
|
*/
|
||||||
counter: 0,
|
counter: 0,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function: get
|
* Function: get
|
||||||
*
|
*
|
||||||
* Returns the ID for the given object or function or null if no object
|
* Returns the ID for the given object or function or null if no object
|
||||||
* is specified.
|
* is specified.
|
||||||
*/
|
*/
|
||||||
get: (obj)=>
|
get: (obj) => {
|
||||||
{
|
if (obj != null) {
|
||||||
if (obj != null)
|
if (obj[mxObjectIdentity.FIELD_NAME] == null) {
|
||||||
{
|
if (typeof obj === 'object') {
|
||||||
if (obj[mxObjectIdentity.FIELD_NAME] == null)
|
|
||||||
{
|
|
||||||
if (typeof obj === 'object')
|
|
||||||
{
|
|
||||||
var ctor = mxUtils.getFunctionName(obj.constructor);
|
var ctor = mxUtils.getFunctionName(obj.constructor);
|
||||||
obj[mxObjectIdentity.FIELD_NAME] = ctor + '#' + mxObjectIdentity.counter++;
|
obj[mxObjectIdentity.FIELD_NAME] = ctor + '#' + mxObjectIdentity.counter++;
|
||||||
}
|
} else if (typeof obj === 'function') {
|
||||||
else if (typeof obj === 'function')
|
|
||||||
{
|
|
||||||
obj[mxObjectIdentity.FIELD_NAME] = 'Function#' + mxObjectIdentity.counter++;
|
obj[mxObjectIdentity.FIELD_NAME] = 'Function#' + mxObjectIdentity.counter++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return obj[mxObjectIdentity.FIELD_NAME];
|
return obj[mxObjectIdentity.FIELD_NAME];
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function: clear
|
* Function: clear
|
||||||
*
|
*
|
||||||
* Deletes the ID from the given object or function.
|
* Deletes the ID from the given object or function.
|
||||||
*/
|
*/
|
||||||
clear: (obj)=>
|
clear: (obj) => {
|
||||||
{
|
if (typeof (obj) === 'object' || typeof obj === 'function') {
|
||||||
if (typeof(obj) === 'object' || typeof obj === 'function')
|
|
||||||
{
|
|
||||||
delete obj[mxObjectIdentity.FIELD_NAME];
|
delete obj[mxObjectIdentity.FIELD_NAME];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export default mxObjectIdentity;
|
||||||
|
|
|
@ -2,264 +2,221 @@
|
||||||
* Copyright (c) 2006-2015, JGraph Ltd
|
* Copyright (c) 2006-2015, JGraph Ltd
|
||||||
* Copyright (c) 2006-2015, Gaudenz Alder
|
* Copyright (c) 2006-2015, Gaudenz Alder
|
||||||
*/
|
*/
|
||||||
/**
|
|
||||||
* Class: mxPanningManager
|
|
||||||
*
|
|
||||||
* Implements a handler for panning.
|
|
||||||
*/
|
|
||||||
function mxPanningManager(graph)
|
|
||||||
{
|
|
||||||
this.thread = null;
|
|
||||||
this.active = false;
|
|
||||||
this.tdx = 0;
|
|
||||||
this.tdy = 0;
|
|
||||||
this.t0x = 0;
|
|
||||||
this.t0y = 0;
|
|
||||||
this.dx = 0;
|
|
||||||
this.dy = 0;
|
|
||||||
this.scrollbars = false;
|
|
||||||
this.scrollLeft = 0;
|
|
||||||
this.scrollTop = 0;
|
|
||||||
|
|
||||||
this.mouseListener =
|
|
||||||
{
|
|
||||||
mouseDown: (sender, me)=> { },
|
|
||||||
mouseMove: (sender, me)=> { },
|
|
||||||
mouseUp: mxUtils.bind(this, (sender, me)=>
|
|
||||||
{
|
|
||||||
if (this.active)
|
|
||||||
{
|
|
||||||
this.stop();
|
|
||||||
}
|
|
||||||
})
|
|
||||||
};
|
|
||||||
|
|
||||||
graph.addMouseListener(this.mouseListener);
|
|
||||||
|
|
||||||
this.mouseUpListener = mxUtils.bind(this, ()=>
|
|
||||||
{
|
|
||||||
if (this.active)
|
|
||||||
{
|
|
||||||
this.stop();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// Stops scrolling on every mouseup anywhere in the document
|
|
||||||
mxEvent.addListener(document, 'mouseup', this.mouseUpListener);
|
|
||||||
|
|
||||||
var createThread = mxUtils.bind(this, ()=>
|
|
||||||
{
|
|
||||||
this.scrollbars = mxUtils.hasScrollbars(graph.container);
|
|
||||||
this.scrollLeft = graph.container.scrollLeft;
|
|
||||||
this.scrollTop = graph.container.scrollTop;
|
|
||||||
|
|
||||||
return window.setInterval(mxUtils.bind(this, ()=>
|
|
||||||
{
|
|
||||||
this.tdx -= this.dx;
|
|
||||||
this.tdy -= this.dy;
|
|
||||||
|
|
||||||
if (this.scrollbars)
|
class mxPanningManager {
|
||||||
{
|
/**
|
||||||
var left = -graph.container.scrollLeft - Math.ceil(this.dx);
|
* Variable: damper
|
||||||
var top = -graph.container.scrollTop - Math.ceil(this.dy);
|
*
|
||||||
graph.panGraph(left, top);
|
* Damper value for the panning. Default is 1/6.
|
||||||
graph.panDx = this.scrollLeft - graph.container.scrollLeft;
|
*/
|
||||||
graph.panDy = this.scrollTop - graph.container.scrollTop;
|
damper = 1 / 6;
|
||||||
graph.fireEvent(new mxEventObject(mxEvent.PAN));
|
|
||||||
// TODO: Implement graph.autoExtend
|
/**
|
||||||
|
* Variable: delay
|
||||||
|
*
|
||||||
|
* Delay in milliseconds for the panning. Default is 10.
|
||||||
|
*/
|
||||||
|
delay = 10;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Variable: handleMouseOut
|
||||||
|
*
|
||||||
|
* Specifies if mouse events outside of the component should be handled. Default is true.
|
||||||
|
*/
|
||||||
|
handleMouseOut = true;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Variable: border
|
||||||
|
*
|
||||||
|
* Border to handle automatic panning inside the component. Default is 0 (disabled).
|
||||||
|
*/
|
||||||
|
border = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class: mxPanningManager
|
||||||
|
*
|
||||||
|
* Implements a handler for panning.
|
||||||
|
*/
|
||||||
|
constructor(graph) {
|
||||||
|
this.thread = null;
|
||||||
|
this.active = false;
|
||||||
|
this.tdx = 0;
|
||||||
|
this.tdy = 0;
|
||||||
|
this.t0x = 0;
|
||||||
|
this.t0y = 0;
|
||||||
|
this.dx = 0;
|
||||||
|
this.dy = 0;
|
||||||
|
this.scrollbars = false;
|
||||||
|
this.scrollLeft = 0;
|
||||||
|
this.scrollTop = 0;
|
||||||
|
|
||||||
|
this.mouseListener =
|
||||||
|
{
|
||||||
|
mouseDown: (sender, me) => {
|
||||||
|
},
|
||||||
|
mouseMove: (sender, me) => {
|
||||||
|
},
|
||||||
|
mouseUp: mxUtils.bind(this, (sender, me) => {
|
||||||
|
if (this.active) {
|
||||||
|
this.stop();
|
||||||
|
}
|
||||||
|
})
|
||||||
|
};
|
||||||
|
|
||||||
|
graph.addMouseListener(this.mouseListener);
|
||||||
|
|
||||||
|
this.mouseUpListener = mxUtils.bind(this, () => {
|
||||||
|
if (this.active) {
|
||||||
|
this.stop();
|
||||||
}
|
}
|
||||||
else
|
});
|
||||||
{
|
|
||||||
graph.panGraph(this.getDx(), this.getDy());
|
// Stops scrolling on every mouseup anywhere in the document
|
||||||
}
|
mxEvent.addListener(document, 'mouseup', this.mouseUpListener);
|
||||||
}), this.delay);
|
|
||||||
});
|
var createThread = mxUtils.bind(this, () => {
|
||||||
|
this.scrollbars = mxUtils.hasScrollbars(graph.container);
|
||||||
this.isActive = ()=>
|
|
||||||
{
|
|
||||||
return active;
|
|
||||||
};
|
|
||||||
|
|
||||||
this.getDx = ()=>
|
|
||||||
{
|
|
||||||
return Math.round(this.tdx);
|
|
||||||
};
|
|
||||||
|
|
||||||
this.getDy = ()=>
|
|
||||||
{
|
|
||||||
return Math.round(this.tdy);
|
|
||||||
};
|
|
||||||
|
|
||||||
this.start = ()=>
|
|
||||||
{
|
|
||||||
this.t0x = graph.view.translate.x;
|
|
||||||
this.t0y = graph.view.translate.y;
|
|
||||||
this.active = true;
|
|
||||||
};
|
|
||||||
|
|
||||||
this.panTo = (x, y, w, h)=>
|
|
||||||
{
|
|
||||||
if (!this.active)
|
|
||||||
{
|
|
||||||
this.start();
|
|
||||||
}
|
|
||||||
|
|
||||||
this.scrollLeft = graph.container.scrollLeft;
|
this.scrollLeft = graph.container.scrollLeft;
|
||||||
this.scrollTop = graph.container.scrollTop;
|
this.scrollTop = graph.container.scrollTop;
|
||||||
|
|
||||||
w = (w != null) ? w : 0;
|
return window.setInterval(mxUtils.bind(this, () => {
|
||||||
h = (h != null) ? h : 0;
|
this.tdx -= this.dx;
|
||||||
|
this.tdy -= this.dy;
|
||||||
var c = graph.container;
|
|
||||||
this.dx = x + w - c.scrollLeft - c.clientWidth;
|
if (this.scrollbars) {
|
||||||
|
var left = -graph.container.scrollLeft - Math.ceil(this.dx);
|
||||||
if (this.dx < 0 && Math.abs(this.dx) < this.border)
|
var top = -graph.container.scrollTop - Math.ceil(this.dy);
|
||||||
{
|
graph.panGraph(left, top);
|
||||||
this.dx = this.border + this.dx;
|
graph.panDx = this.scrollLeft - graph.container.scrollLeft;
|
||||||
}
|
graph.panDy = this.scrollTop - graph.container.scrollTop;
|
||||||
else if (this.handleMouseOut)
|
graph.fireEvent(new mxEventObject(mxEvent.PAN));
|
||||||
{
|
// TODO: Implement graph.autoExtend
|
||||||
this.dx = Math.max(this.dx, 0);
|
} else {
|
||||||
}
|
graph.panGraph(this.getDx(), this.getDy());
|
||||||
else
|
}
|
||||||
{
|
}), this.delay);
|
||||||
this.dx = 0;
|
});
|
||||||
}
|
|
||||||
|
this.isActive = () => {
|
||||||
if (this.dx == 0)
|
return active;
|
||||||
{
|
};
|
||||||
this.dx = x - c.scrollLeft;
|
|
||||||
|
this.getDx = () => {
|
||||||
if (this.dx > 0 && this.dx < this.border)
|
return Math.round(this.tdx);
|
||||||
{
|
};
|
||||||
this.dx = this.dx - this.border;
|
|
||||||
|
this.getDy = () => {
|
||||||
|
return Math.round(this.tdy);
|
||||||
|
};
|
||||||
|
|
||||||
|
this.start = () => {
|
||||||
|
this.t0x = graph.view.translate.x;
|
||||||
|
this.t0y = graph.view.translate.y;
|
||||||
|
this.active = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
this.panTo = (x, y, w, h) => {
|
||||||
|
if (!this.active) {
|
||||||
|
this.start();
|
||||||
}
|
}
|
||||||
else if (this.handleMouseOut)
|
|
||||||
{
|
this.scrollLeft = graph.container.scrollLeft;
|
||||||
this.dx = Math.min(0, this.dx);
|
this.scrollTop = graph.container.scrollTop;
|
||||||
}
|
|
||||||
else
|
w = (w != null) ? w : 0;
|
||||||
{
|
h = (h != null) ? h : 0;
|
||||||
|
|
||||||
|
var c = graph.container;
|
||||||
|
this.dx = x + w - c.scrollLeft - c.clientWidth;
|
||||||
|
|
||||||
|
if (this.dx < 0 && Math.abs(this.dx) < this.border) {
|
||||||
|
this.dx = this.border + this.dx;
|
||||||
|
} else if (this.handleMouseOut) {
|
||||||
|
this.dx = Math.max(this.dx, 0);
|
||||||
|
} else {
|
||||||
this.dx = 0;
|
this.dx = 0;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
this.dy = y + h - c.scrollTop - c.clientHeight;
|
|
||||||
|
|
||||||
if (this.dy < 0 && Math.abs(this.dy) < this.border)
|
if (this.dx == 0) {
|
||||||
{
|
this.dx = x - c.scrollLeft;
|
||||||
this.dy = this.border + this.dy;
|
|
||||||
}
|
if (this.dx > 0 && this.dx < this.border) {
|
||||||
else if (this.handleMouseOut)
|
this.dx = this.dx - this.border;
|
||||||
{
|
} else if (this.handleMouseOut) {
|
||||||
this.dy = Math.max(this.dy, 0);
|
this.dx = Math.min(0, this.dx);
|
||||||
}
|
} else {
|
||||||
else
|
this.dx = 0;
|
||||||
{
|
}
|
||||||
this.dy = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this.dy == 0)
|
|
||||||
{
|
|
||||||
this.dy = y - c.scrollTop;
|
|
||||||
|
|
||||||
if (this.dy > 0 && this.dy < this.border)
|
|
||||||
{
|
|
||||||
this.dy = this.dy - this.border;
|
|
||||||
}
|
}
|
||||||
else if (this.handleMouseOut)
|
|
||||||
{
|
this.dy = y + h - c.scrollTop - c.clientHeight;
|
||||||
this.dy = Math.min(0, this.dy);
|
|
||||||
}
|
if (this.dy < 0 && Math.abs(this.dy) < this.border) {
|
||||||
else
|
this.dy = this.border + this.dy;
|
||||||
{
|
} else if (this.handleMouseOut) {
|
||||||
|
this.dy = Math.max(this.dy, 0);
|
||||||
|
} else {
|
||||||
this.dy = 0;
|
this.dy = 0;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
if (this.dy == 0) {
|
||||||
if (this.dx != 0 || this.dy != 0)
|
this.dy = y - c.scrollTop;
|
||||||
{
|
|
||||||
this.dx *= this.damper;
|
if (this.dy > 0 && this.dy < this.border) {
|
||||||
this.dy *= this.damper;
|
this.dy = this.dy - this.border;
|
||||||
|
} else if (this.handleMouseOut) {
|
||||||
if (this.thread == null)
|
this.dy = Math.min(0, this.dy);
|
||||||
{
|
} else {
|
||||||
this.thread = createThread();
|
this.dy = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
else if (this.thread != null)
|
if (this.dx != 0 || this.dy != 0) {
|
||||||
{
|
this.dx *= this.damper;
|
||||||
window.clearInterval(this.thread);
|
this.dy *= this.damper;
|
||||||
this.thread = null;
|
|
||||||
}
|
if (this.thread == null) {
|
||||||
};
|
this.thread = createThread();
|
||||||
|
}
|
||||||
this.stop = ()=>
|
} else if (this.thread != null) {
|
||||||
{
|
|
||||||
if (this.active)
|
|
||||||
{
|
|
||||||
this.active = false;
|
|
||||||
|
|
||||||
if (this.thread != null)
|
|
||||||
{
|
|
||||||
window.clearInterval(this.thread);
|
window.clearInterval(this.thread);
|
||||||
this.thread = null;
|
this.thread = null;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
this.stop = () => {
|
||||||
|
if (this.active) {
|
||||||
|
this.active = false;
|
||||||
|
|
||||||
|
if (this.thread != null) {
|
||||||
|
window.clearInterval(this.thread);
|
||||||
|
this.thread = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.tdx = 0;
|
this.tdx = 0;
|
||||||
this.tdy = 0;
|
this.tdy = 0;
|
||||||
|
|
||||||
if (!this.scrollbars)
|
if (!this.scrollbars) {
|
||||||
{
|
var px = graph.panDx;
|
||||||
var px = graph.panDx;
|
var py = graph.panDy;
|
||||||
var py = graph.panDy;
|
|
||||||
|
if (px != 0 || py != 0) {
|
||||||
if (px != 0 || py != 0)
|
|
||||||
{
|
|
||||||
graph.panGraph(0, 0);
|
graph.panGraph(0, 0);
|
||||||
graph.view.setTranslate(this.t0x + px / graph.view.scale, this.t0y + py / graph.view.scale);
|
graph.view.setTranslate(this.t0x + px / graph.view.scale, this.t0y + py / graph.view.scale);
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
graph.panDx = 0;
|
||||||
|
graph.panDy = 0;
|
||||||
|
graph.fireEvent(new mxEventObject(mxEvent.PAN));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
};
|
||||||
{
|
|
||||||
graph.panDx = 0;
|
this.destroy = () => {
|
||||||
graph.panDy = 0;
|
graph.removeMouseListener(this.mouseListener);
|
||||||
graph.fireEvent(new mxEventObject(mxEvent.PAN));
|
mxEvent.removeListener(document, 'mouseup', this.mouseUpListener);
|
||||||
}
|
};
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
}
|
||||||
this.destroy = ()=>
|
|
||||||
{
|
|
||||||
graph.removeMouseListener(this.mouseListener);
|
|
||||||
mxEvent.removeListener(document, 'mouseup', this.mouseUpListener);
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
export default mxPanningManager;
|
||||||
* Variable: damper
|
|
||||||
*
|
|
||||||
* Damper value for the panning. Default is 1/6.
|
|
||||||
*/
|
|
||||||
damper = 1/6;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Variable: delay
|
|
||||||
*
|
|
||||||
* Delay in milliseconds for the panning. Default is 10.
|
|
||||||
*/
|
|
||||||
delay = 10;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Variable: handleMouseOut
|
|
||||||
*
|
|
||||||
* Specifies if mouse events outside of the component should be handled. Default is true.
|
|
||||||
*/
|
|
||||||
handleMouseOut = true;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Variable: border
|
|
||||||
*
|
|
||||||
* Border to handle automatic panning inside the component. Default is 0 (disabled).
|
|
||||||
*/
|
|
||||||
border = 0;
|
|
||||||
|
|
|
@ -2,53 +2,57 @@
|
||||||
* Copyright (c) 2006-2015, JGraph Ltd
|
* Copyright (c) 2006-2015, JGraph Ltd
|
||||||
* Copyright (c) 2006-2015, Gaudenz Alder
|
* Copyright (c) 2006-2015, Gaudenz Alder
|
||||||
*/
|
*/
|
||||||
/**
|
|
||||||
* Class: mxPoint
|
|
||||||
*
|
|
||||||
* Implements a 2-dimensional vector with double precision coordinates.
|
|
||||||
*
|
|
||||||
* Constructor: mxPoint
|
|
||||||
*
|
|
||||||
* Constructs a new point for the optional x and y coordinates. If no
|
|
||||||
* coordinates are given, then the default values for <x> and <y> are used.
|
|
||||||
*/
|
|
||||||
function mxPoint(x, y)
|
|
||||||
{
|
|
||||||
this.x = (x != null) ? x : 0;
|
|
||||||
this.y = (y != null) ? y : 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
import mxUtils from "../util/mxUtils";
|
||||||
* Variable: x
|
|
||||||
*
|
|
||||||
* Holds the x-coordinate of the point. Default is 0.
|
|
||||||
*/
|
|
||||||
x = null;
|
|
||||||
|
|
||||||
/**
|
class mxPoint {
|
||||||
* Variable: y
|
/**
|
||||||
*
|
* Class: mxPoint
|
||||||
* Holds the y-coordinate of the point. Default is 0.
|
*
|
||||||
*/
|
* Implements a 2-dimensional vector with double precision coordinates.
|
||||||
y = null;
|
*
|
||||||
|
* Constructor: mxPoint
|
||||||
|
*
|
||||||
|
* Constructs a new point for the optional x and y coordinates. If no
|
||||||
|
* coordinates are given, then the default values for <x> and <y> are used.
|
||||||
|
*/
|
||||||
|
constructor(x, y) {
|
||||||
|
this.x = (x != null) ? x : 0;
|
||||||
|
this.y = (y != null) ? y : 0;
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function: equals
|
* Variable: x
|
||||||
*
|
*
|
||||||
* Returns true if the given object equals this point.
|
* Holds the x-coordinate of the point. Default is 0.
|
||||||
*/
|
*/
|
||||||
equals = (obj)=>
|
x = null;
|
||||||
{
|
|
||||||
return obj != null && obj.x == this.x && obj.y == this.y;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function: clone
|
* Variable: y
|
||||||
*
|
*
|
||||||
* Returns a clone of this <mxPoint>.
|
* Holds the y-coordinate of the point. Default is 0.
|
||||||
*/
|
*/
|
||||||
clone = ()=>
|
y = null;
|
||||||
{
|
|
||||||
// Handles subclasses as well
|
/**
|
||||||
return mxUtils.clone(this);
|
* Function: equals
|
||||||
};
|
*
|
||||||
|
* Returns true if the given object equals this point.
|
||||||
|
*/
|
||||||
|
equals = (obj) => {
|
||||||
|
return obj != null && obj.x == this.x && obj.y == this.y;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function: clone
|
||||||
|
*
|
||||||
|
* Returns a clone of this <mxPoint>.
|
||||||
|
*/
|
||||||
|
clone = () => {
|
||||||
|
// Handles subclasses as well
|
||||||
|
return mxUtils.clone(this);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export default mxPoint;
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -13,169 +13,156 @@
|
||||||
* Constructs a new rectangle for the optional parameters. If no parameters
|
* Constructs a new rectangle for the optional parameters. If no parameters
|
||||||
* are given then the respective default values are used.
|
* are given then the respective default values are used.
|
||||||
*/
|
*/
|
||||||
function mxRectangle(x, y, width, height)
|
|
||||||
{
|
|
||||||
mxPoint.call(this, x, y);
|
|
||||||
|
|
||||||
this.width = (width != null) ? width : 0;
|
import mxPoint from "./mxPoint";
|
||||||
this.height = (height != null) ? height : 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
class mxRectangle extends mxPoint {
|
||||||
* Extends mxPoint.
|
constructor(x, y, width, height) {
|
||||||
*/
|
super(x, y);
|
||||||
mxRectangle.prototype = new mxPoint();
|
this.width = (width != null) ? width : 0;
|
||||||
constructor = mxRectangle;
|
this.height = (height != null) ? height : 0;
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Variable: width
|
* Variable: width
|
||||||
*
|
*
|
||||||
* Holds the width of the rectangle. Default is 0.
|
* Holds the width of the rectangle. Default is 0.
|
||||||
*/
|
*/
|
||||||
width = null;
|
width = null;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Variable: height
|
* Variable: height
|
||||||
*
|
*
|
||||||
* Holds the height of the rectangle. Default is 0.
|
* Holds the height of the rectangle. Default is 0.
|
||||||
*/
|
*/
|
||||||
height = null;
|
height = null;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function: setRect
|
* Function: setRect
|
||||||
*
|
*
|
||||||
* Sets this rectangle to the specified values
|
* Sets this rectangle to the specified values
|
||||||
*/
|
*/
|
||||||
setRect = (x, y, w, h)=>
|
setRect = (x, y, w, h) => {
|
||||||
{
|
|
||||||
this.x = x;
|
this.x = x;
|
||||||
this.y = y;
|
this.y = y;
|
||||||
this.width = w;
|
this.width = w;
|
||||||
this.height = h;
|
this.height = h;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function: getCenterX
|
* Function: getCenterX
|
||||||
*
|
*
|
||||||
* Returns the x-coordinate of the center point.
|
* Returns the x-coordinate of the center point.
|
||||||
*/
|
*/
|
||||||
getCenterX = function ()
|
getCenterX = function () {
|
||||||
{
|
return this.x + this.width / 2;
|
||||||
return this.x + this.width/2;
|
};
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function: getCenterY
|
* Function: getCenterY
|
||||||
*
|
*
|
||||||
* Returns the y-coordinate of the center point.
|
* Returns the y-coordinate of the center point.
|
||||||
*/
|
*/
|
||||||
getCenterY = function ()
|
getCenterY = function () {
|
||||||
{
|
return this.y + this.height / 2;
|
||||||
return this.y + this.height/2;
|
};
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function: add
|
* Function: add
|
||||||
*
|
*
|
||||||
* Adds the given rectangle to this rectangle.
|
* Adds the given rectangle to this rectangle.
|
||||||
*/
|
*/
|
||||||
add = (rect)=>
|
add = (rect) => {
|
||||||
{
|
if (rect != null) {
|
||||||
if (rect != null)
|
var minX = Math.min(this.x, rect.x);
|
||||||
{
|
var minY = Math.min(this.y, rect.y);
|
||||||
var minX = Math.min(this.x, rect.x);
|
var maxX = Math.max(this.x + this.width, rect.x + rect.width);
|
||||||
var minY = Math.min(this.y, rect.y);
|
var maxY = Math.max(this.y + this.height, rect.y + rect.height);
|
||||||
var maxX = Math.max(this.x + this.width, rect.x + rect.width);
|
|
||||||
var maxY = Math.max(this.y + this.height, rect.y + rect.height);
|
|
||||||
|
|
||||||
this.x = minX;
|
|
||||||
this.y = minY;
|
|
||||||
this.width = maxX - minX;
|
|
||||||
this.height = maxY - minY;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
this.x = minX;
|
||||||
* Function: intersect
|
this.y = minY;
|
||||||
*
|
this.width = maxX - minX;
|
||||||
* Changes this rectangle to where it overlaps with the given rectangle.
|
this.height = maxY - minY;
|
||||||
*/
|
}
|
||||||
intersect = (rect)=>
|
};
|
||||||
{
|
|
||||||
if (rect != null)
|
|
||||||
{
|
|
||||||
var r1 = this.x + this.width;
|
|
||||||
var r2 = rect.x + rect.width;
|
|
||||||
|
|
||||||
var b1 = this.y + this.height;
|
|
||||||
var b2 = rect.y + rect.height;
|
|
||||||
|
|
||||||
this.x = Math.max(this.x, rect.x);
|
|
||||||
this.y = Math.max(this.y, rect.y);
|
|
||||||
this.width = Math.min(r1, r2) - this.x;
|
|
||||||
this.height = Math.min(b1, b2) - this.y;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function: grow
|
* Function: intersect
|
||||||
*
|
*
|
||||||
* Grows the rectangle by the given amount, that is, this method subtracts
|
* Changes this rectangle to where it overlaps with the given rectangle.
|
||||||
* the given amount from the x- and y-coordinates and adds twice the amount
|
*/
|
||||||
* to the width and height.
|
intersect = (rect) => {
|
||||||
*/
|
if (rect != null) {
|
||||||
grow = (amount)=>
|
var r1 = this.x + this.width;
|
||||||
{
|
var r2 = rect.x + rect.width;
|
||||||
this.x -= amount;
|
|
||||||
this.y -= amount;
|
|
||||||
this.width += 2 * amount;
|
|
||||||
this.height += 2 * amount;
|
|
||||||
|
|
||||||
return this;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
var b1 = this.y + this.height;
|
||||||
* Function: getPoint
|
var b2 = rect.y + rect.height;
|
||||||
*
|
|
||||||
* Returns the top, left corner as a new <mxPoint>.
|
|
||||||
*/
|
|
||||||
getPoint = ()=>
|
|
||||||
{
|
|
||||||
return new mxPoint(this.x, this.y);
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
this.x = Math.max(this.x, rect.x);
|
||||||
* Function: rotate90
|
this.y = Math.max(this.y, rect.y);
|
||||||
*
|
this.width = Math.min(r1, r2) - this.x;
|
||||||
* Rotates this rectangle by 90 degree around its center point.
|
this.height = Math.min(b1, b2) - this.y;
|
||||||
*/
|
}
|
||||||
rotate90 = ()=>
|
};
|
||||||
{
|
|
||||||
var t = (this.width - this.height) / 2;
|
|
||||||
this.x += t;
|
|
||||||
this.y -= t;
|
|
||||||
var tmp = this.width;
|
|
||||||
this.width = this.height;
|
|
||||||
this.height = tmp;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function: equals
|
* Function: grow
|
||||||
*
|
*
|
||||||
* Returns true if the given object equals this rectangle.
|
* Grows the rectangle by the given amount, that is, this method subtracts
|
||||||
*/
|
* the given amount from the x- and y-coordinates and adds twice the amount
|
||||||
equals = (obj)=>
|
* to the width and height.
|
||||||
{
|
*/
|
||||||
return obj != null && obj.x == this.x && obj.y == this.y &&
|
grow = (amount) => {
|
||||||
obj.width == this.width && obj.height == this.height;
|
this.x -= amount;
|
||||||
};
|
this.y -= amount;
|
||||||
|
this.width += 2 * amount;
|
||||||
|
this.height += 2 * amount;
|
||||||
|
|
||||||
/**
|
return this;
|
||||||
* Function: fromRectangle
|
};
|
||||||
*
|
|
||||||
* Returns a new <mxRectangle> which is a copy of the given rectangle.
|
/**
|
||||||
*/
|
* Function: getPoint
|
||||||
mxRectangle.fromRectangle = (rect)=>
|
*
|
||||||
{
|
* Returns the top, left corner as a new <mxPoint>.
|
||||||
return new mxRectangle(rect.x, rect.y, rect.width, rect.height);
|
*/
|
||||||
};
|
getPoint = () => {
|
||||||
|
return new mxPoint(this.x, this.y);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function: rotate90
|
||||||
|
*
|
||||||
|
* Rotates this rectangle by 90 degree around its center point.
|
||||||
|
*/
|
||||||
|
rotate90 = () => {
|
||||||
|
var t = (this.width - this.height) / 2;
|
||||||
|
this.x += t;
|
||||||
|
this.y -= t;
|
||||||
|
var tmp = this.width;
|
||||||
|
this.width = this.height;
|
||||||
|
this.height = tmp;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function: equals
|
||||||
|
*
|
||||||
|
* Returns true if the given object equals this rectangle.
|
||||||
|
*/
|
||||||
|
equals = (obj) => {
|
||||||
|
return obj != null && obj.x == this.x && obj.y == this.y &&
|
||||||
|
obj.width == this.width && obj.height == this.height;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function: fromRectangle
|
||||||
|
*
|
||||||
|
* Returns a new <mxRectangle> which is a copy of the given rectangle.
|
||||||
|
*/
|
||||||
|
static fromRectangle = (rect) => {
|
||||||
|
return new mxRectangle(rect.x, rect.y, rect.width, rect.height);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export default mxRectangle;
|
||||||
|
|
|
@ -448,3 +448,5 @@ var mxResources =
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export default mxResources;
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -2,526 +2,468 @@
|
||||||
* Copyright (c) 2006-2015, JGraph Ltd
|
* Copyright (c) 2006-2015, JGraph Ltd
|
||||||
* Copyright (c) 2006-2015, Gaudenz Alder
|
* Copyright (c) 2006-2015, Gaudenz Alder
|
||||||
*/
|
*/
|
||||||
/**
|
|
||||||
* Class: mxToolbar
|
|
||||||
*
|
|
||||||
* Creates a toolbar inside a given DOM node. The toolbar may contain icons,
|
|
||||||
* buttons and combo boxes.
|
|
||||||
*
|
|
||||||
* Event: mxEvent.SELECT
|
|
||||||
*
|
|
||||||
* Fires when an item was selected in the toolbar. The <code>function</code>
|
|
||||||
* property contains the function that was selected in <selectMode>.
|
|
||||||
*
|
|
||||||
* Constructor: mxToolbar
|
|
||||||
*
|
|
||||||
* Constructs a toolbar in the specified container.
|
|
||||||
*
|
|
||||||
* Parameters:
|
|
||||||
*
|
|
||||||
* container - DOM node that contains the toolbar.
|
|
||||||
*/
|
|
||||||
function mxToolbar(container)
|
|
||||||
{
|
|
||||||
this.container = container;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
import mxUtils from "./mxUtils";
|
||||||
* Extends mxEventSource.
|
import mxPoint from "./mxPoint";
|
||||||
*/
|
import mxPopupMenu from "./mxPopupMenu";
|
||||||
mxToolbar.prototype = new mxEventSource();
|
import mxEventSource from "./mxEventSource";
|
||||||
constructor = mxToolbar;
|
import mxEventObject from "./mxEventObject";
|
||||||
|
|
||||||
/**
|
class mxToolbar extends mxEventSource {
|
||||||
* Variable: container
|
/**
|
||||||
*
|
* Variable: container
|
||||||
* Reference to the DOM nodes that contains the toolbar.
|
*
|
||||||
*/
|
* Reference to the DOM nodes that contains the toolbar.
|
||||||
container = null;
|
*/
|
||||||
|
container = null;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Variable: enabled
|
* Variable: enabled
|
||||||
*
|
*
|
||||||
* Specifies if events are handled. Default is true.
|
* Specifies if events are handled. Default is true.
|
||||||
*/
|
*/
|
||||||
enabled = true;
|
enabled = true;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Variable: noReset
|
* Variable: noReset
|
||||||
*
|
*
|
||||||
* Specifies if <resetMode> requires a forced flag of true for resetting
|
* Specifies if <resetMode> requires a forced flag of true for resetting
|
||||||
* the current mode in the toolbar. Default is false. This is set to true
|
* the current mode in the toolbar. Default is false. This is set to true
|
||||||
* if the toolbar item is double clicked to avoid a reset after a single
|
* if the toolbar item is double clicked to avoid a reset after a single
|
||||||
* use of the item.
|
* use of the item.
|
||||||
*/
|
*/
|
||||||
noReset = false;
|
noReset = false;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Variable: updateDefaultMode
|
* Variable: updateDefaultMode
|
||||||
*
|
*
|
||||||
* Boolean indicating if the default mode should be the last selected
|
* Boolean indicating if the default mode should be the last selected
|
||||||
* switch mode or the first inserted switch mode. Default is true, that
|
* switch mode or the first inserted switch mode. Default is true, that
|
||||||
* is the last selected switch mode is the default mode. The default mode
|
* is the last selected switch mode is the default mode. The default mode
|
||||||
* is the mode to be selected after a reset of the toolbar. If this is
|
* is the mode to be selected after a reset of the toolbar. If this is
|
||||||
* false, then the default mode is the first inserted mode item regardless
|
* false, then the default mode is the first inserted mode item regardless
|
||||||
* of what was last selected. Otherwise, the selected item after a reset is
|
* of what was last selected. Otherwise, the selected item after a reset is
|
||||||
* the previously selected item.
|
* the previously selected item.
|
||||||
*/
|
*/
|
||||||
updateDefaultMode = true;
|
updateDefaultMode = true;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function: addItem
|
* Class: mxToolbar
|
||||||
*
|
*
|
||||||
* Adds the given function as an image with the specified title and icon
|
* Creates a toolbar inside a given DOM node. The toolbar may contain icons,
|
||||||
* and returns the new image node.
|
* buttons and combo boxes.
|
||||||
*
|
*
|
||||||
* Parameters:
|
* Event: mxEvent.SELECT
|
||||||
*
|
*
|
||||||
* title - Optional string that is used as the tooltip.
|
* Fires when an item was selected in the toolbar. The <code>function</code>
|
||||||
* icon - Optional URL of the image to be used. If no URL is given, then a
|
* property contains the function that was selected in <selectMode>.
|
||||||
* button is created.
|
*
|
||||||
* funct - Function to execute on a mouse click.
|
* Constructor: mxToolbar
|
||||||
* pressedIcon - Optional URL of the pressed image. Default is a gray
|
*
|
||||||
* background.
|
* Constructs a toolbar in the specified container.
|
||||||
* style - Optional style classname. Default is mxToolbarItem.
|
*
|
||||||
* factoryMethod - Optional factory method for popup menu, eg.
|
* Parameters:
|
||||||
* (menu, evt, cell)=> { menu.addItem('Hello, World!'); }
|
*
|
||||||
*/
|
* container - DOM node that contains the toolbar.
|
||||||
addItem = (title, icon, funct, pressedIcon, style, factoryMethod)=>
|
*/
|
||||||
{
|
constructor(container) {
|
||||||
var img = document.createElement((icon != null) ? 'img' : 'button');
|
this.container = container;
|
||||||
var initialClassName = style || ((factoryMethod != null) ?
|
};
|
||||||
'mxToolbarMode' : 'mxToolbarItem');
|
|
||||||
img.className = initialClassName;
|
|
||||||
img.setAttribute('src', icon);
|
|
||||||
|
|
||||||
if (title != null)
|
|
||||||
{
|
|
||||||
if (icon != null)
|
|
||||||
{
|
|
||||||
img.setAttribute('title', title);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
mxUtils.write(img, title);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
this.container.appendChild(img);
|
|
||||||
|
|
||||||
// Invokes the function on a click on the toolbar item
|
/**
|
||||||
if (funct != null)
|
* Function: addItem
|
||||||
{
|
*
|
||||||
mxEvent.addListener(img, 'click', funct);
|
* Adds the given function as an image with the specified title and icon
|
||||||
|
* and returns the new image node.
|
||||||
if (mxClient.IS_TOUCH)
|
*
|
||||||
{
|
* Parameters:
|
||||||
mxEvent.addListener(img, 'touchend', funct);
|
*
|
||||||
}
|
* title - Optional string that is used as the tooltip.
|
||||||
}
|
* icon - Optional URL of the image to be used. If no URL is given, then a
|
||||||
|
* button is created.
|
||||||
|
* funct - Function to execute on a mouse click.
|
||||||
|
* pressedIcon - Optional URL of the pressed image. Default is a gray
|
||||||
|
* background.
|
||||||
|
* style - Optional style classname. Default is mxToolbarItem.
|
||||||
|
* factoryMethod - Optional factory method for popup menu, eg.
|
||||||
|
* (menu, evt, cell)=> { menu.addItem('Hello, World!'); }
|
||||||
|
*/
|
||||||
|
addItem = (title, icon, funct, pressedIcon, style, factoryMethod) => {
|
||||||
|
var img = document.createElement((icon != null) ? 'img' : 'button');
|
||||||
|
var initialClassName = style || ((factoryMethod != null) ?
|
||||||
|
'mxToolbarMode' : 'mxToolbarItem');
|
||||||
|
img.className = initialClassName;
|
||||||
|
img.setAttribute('src', icon);
|
||||||
|
|
||||||
var mouseHandler = mxUtils.bind(this, (evt)=>
|
if (title != null) {
|
||||||
{
|
if (icon != null) {
|
||||||
if (pressedIcon != null)
|
img.setAttribute('title', title);
|
||||||
{
|
} else {
|
||||||
img.setAttribute('src', icon);
|
mxUtils.write(img, title);
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
img.style.backgroundColor = '';
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// Highlights the toolbar item with a gray background
|
|
||||||
// while it is being clicked with the mouse
|
|
||||||
mxEvent.addGestureListeners(img, mxUtils.bind(this, (evt)=>
|
|
||||||
{
|
|
||||||
if (pressedIcon != null)
|
|
||||||
{
|
|
||||||
img.setAttribute('src', pressedIcon);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
img.style.backgroundColor = 'gray';
|
|
||||||
}
|
|
||||||
|
|
||||||
// Popup Menu
|
|
||||||
if (factoryMethod != null)
|
|
||||||
{
|
|
||||||
if (this.menu == null)
|
|
||||||
{
|
|
||||||
this.menu = new mxPopupMenu();
|
|
||||||
this.menu.init();
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
var last = this.currentImg;
|
|
||||||
|
|
||||||
if (this.menu.isMenuShowing())
|
|
||||||
{
|
|
||||||
this.menu.hideMenu();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (last != img)
|
|
||||||
{
|
|
||||||
// Redirects factory method to local factory method
|
|
||||||
this.currentImg = img;
|
|
||||||
this.menu.factoryMethod = factoryMethod;
|
|
||||||
|
|
||||||
var point = new mxPoint(
|
|
||||||
img.offsetLeft,
|
|
||||||
img.offsetTop + img.offsetHeight);
|
|
||||||
this.menu.popup(point.x, point.y, null, evt);
|
|
||||||
|
|
||||||
// Sets and overrides to restore classname
|
this.container.appendChild(img);
|
||||||
if (this.menu.isMenuShowing())
|
|
||||||
{
|
// Invokes the function on a click on the toolbar item
|
||||||
img.className = initialClassName + 'Selected';
|
if (funct != null) {
|
||||||
|
mxEvent.addListener(img, 'click', funct);
|
||||||
this.menu.hideMenu = ()=>
|
|
||||||
{
|
if (mxClient.IS_TOUCH) {
|
||||||
hideMenu.apply(this);
|
mxEvent.addListener(img, 'touchend', funct);
|
||||||
img.className = initialClassName;
|
}
|
||||||
this.currentImg = null;
|
}
|
||||||
};
|
|
||||||
|
var mouseHandler = mxUtils.bind(this, (evt) => {
|
||||||
|
if (pressedIcon != null) {
|
||||||
|
img.setAttribute('src', icon);
|
||||||
|
} else {
|
||||||
|
img.style.backgroundColor = '';
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Highlights the toolbar item with a gray background
|
||||||
|
// while it is being clicked with the mouse
|
||||||
|
mxEvent.addGestureListeners(img, mxUtils.bind(this, (evt) => {
|
||||||
|
if (pressedIcon != null) {
|
||||||
|
img.setAttribute('src', pressedIcon);
|
||||||
|
} else {
|
||||||
|
img.style.backgroundColor = 'gray';
|
||||||
|
}
|
||||||
|
|
||||||
|
// Popup Menu
|
||||||
|
if (factoryMethod != null) {
|
||||||
|
if (this.menu == null) {
|
||||||
|
this.menu = new mxPopupMenu();
|
||||||
|
this.menu.init();
|
||||||
|
}
|
||||||
|
|
||||||
|
var last = this.currentImg;
|
||||||
|
|
||||||
|
if (this.menu.isMenuShowing()) {
|
||||||
|
this.menu.hideMenu();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (last != img) {
|
||||||
|
// Redirects factory method to local factory method
|
||||||
|
this.currentImg = img;
|
||||||
|
this.menu.factoryMethod = factoryMethod;
|
||||||
|
|
||||||
|
var point = new mxPoint(
|
||||||
|
img.offsetLeft,
|
||||||
|
img.offsetTop + img.offsetHeight);
|
||||||
|
this.menu.popup(point.x, point.y, null, evt);
|
||||||
|
|
||||||
|
// Sets and overrides to restore classname
|
||||||
|
if (this.menu.isMenuShowing()) {
|
||||||
|
img.className = initialClassName + 'Selected';
|
||||||
|
|
||||||
|
this.menu.hideMenu = () => {
|
||||||
|
hideMenu.apply(this);
|
||||||
|
img.className = initialClassName;
|
||||||
|
this.currentImg = null;
|
||||||
|
};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}), null, mouseHandler);
|
||||||
|
|
||||||
|
mxEvent.addListener(img, 'mouseout', mouseHandler);
|
||||||
|
|
||||||
|
return img;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function: addCombo
|
||||||
|
*
|
||||||
|
* Adds and returns a new SELECT element using the given style. The element
|
||||||
|
* is placed inside a DIV with the mxToolbarComboContainer style classname.
|
||||||
|
*
|
||||||
|
* Parameters:
|
||||||
|
*
|
||||||
|
* style - Optional style classname. Default is mxToolbarCombo.
|
||||||
|
*/
|
||||||
|
addCombo = (style) => {
|
||||||
|
var div = document.createElement('div');
|
||||||
|
div.style.display = 'inline';
|
||||||
|
div.className = 'mxToolbarComboContainer';
|
||||||
|
|
||||||
|
var select = document.createElement('select');
|
||||||
|
select.className = style || 'mxToolbarCombo';
|
||||||
|
div.appendChild(select);
|
||||||
|
|
||||||
|
this.container.appendChild(div);
|
||||||
|
|
||||||
|
return select;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function: addActionCombo
|
||||||
|
*
|
||||||
|
* Adds and returns a new SELECT element using the given title as the
|
||||||
|
* default element. The selection is reset to this element after each
|
||||||
|
* change.
|
||||||
|
*
|
||||||
|
* Parameters:
|
||||||
|
*
|
||||||
|
* title - String that specifies the title of the default element.
|
||||||
|
* style - Optional style classname. Default is mxToolbarCombo.
|
||||||
|
*/
|
||||||
|
addActionCombo = (title, style) => {
|
||||||
|
var select = document.createElement('select');
|
||||||
|
select.className = style || 'mxToolbarCombo';
|
||||||
|
this.addOption(select, title, null);
|
||||||
|
|
||||||
|
mxEvent.addListener(select, 'change', (evt) => {
|
||||||
|
var value = select.options[select.selectedIndex];
|
||||||
|
select.selectedIndex = 0;
|
||||||
|
|
||||||
|
if (value.funct != null) {
|
||||||
|
value.funct(evt);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
this.container.appendChild(select);
|
||||||
|
|
||||||
|
return select;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function: addOption
|
||||||
|
*
|
||||||
|
* Adds and returns a new OPTION element inside the given SELECT element.
|
||||||
|
* If the given value is a function then it is stored in the option's funct
|
||||||
|
* field.
|
||||||
|
*
|
||||||
|
* Parameters:
|
||||||
|
*
|
||||||
|
* combo - SELECT element that will contain the new entry.
|
||||||
|
* title - String that specifies the title of the option.
|
||||||
|
* value - Specifies the value associated with this option.
|
||||||
|
*/
|
||||||
|
addOption = (combo, title, value) => {
|
||||||
|
var option = document.createElement('option');
|
||||||
|
mxUtils.writeln(option, title);
|
||||||
|
|
||||||
|
if (typeof (value) == 'function') {
|
||||||
|
option.funct = value;
|
||||||
|
} else {
|
||||||
|
option.setAttribute('value', value);
|
||||||
}
|
}
|
||||||
}), null, mouseHandler);
|
|
||||||
|
|
||||||
mxEvent.addListener(img, 'mouseout', mouseHandler);
|
combo.appendChild(option);
|
||||||
|
|
||||||
return img;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
return option;
|
||||||
* Function: addCombo
|
};
|
||||||
*
|
|
||||||
* Adds and returns a new SELECT element using the given style. The element
|
|
||||||
* is placed inside a DIV with the mxToolbarComboContainer style classname.
|
|
||||||
*
|
|
||||||
* Parameters:
|
|
||||||
*
|
|
||||||
* style - Optional style classname. Default is mxToolbarCombo.
|
|
||||||
*/
|
|
||||||
addCombo = (style)=>
|
|
||||||
{
|
|
||||||
var div = document.createElement('div');
|
|
||||||
div.style.display = 'inline';
|
|
||||||
div.className = 'mxToolbarComboContainer';
|
|
||||||
|
|
||||||
var select = document.createElement('select');
|
|
||||||
select.className = style || 'mxToolbarCombo';
|
|
||||||
div.appendChild(select);
|
|
||||||
|
|
||||||
this.container.appendChild(div);
|
|
||||||
|
|
||||||
return select;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function: addActionCombo
|
* Function: addSwitchMode
|
||||||
*
|
*
|
||||||
* Adds and returns a new SELECT element using the given title as the
|
* Adds a new selectable item to the toolbar. Only one switch mode item may
|
||||||
* default element. The selection is reset to this element after each
|
* be selected at a time. The currently selected item is the default item
|
||||||
* change.
|
* after a reset of the toolbar.
|
||||||
*
|
*/
|
||||||
* Parameters:
|
addSwitchMode = (title, icon, funct, pressedIcon, style) => {
|
||||||
*
|
var img = document.createElement('img');
|
||||||
* title - String that specifies the title of the default element.
|
img.initialClassName = style || 'mxToolbarMode';
|
||||||
* style - Optional style classname. Default is mxToolbarCombo.
|
img.className = img.initialClassName;
|
||||||
*/
|
img.setAttribute('src', icon);
|
||||||
addActionCombo = (title, style)=>
|
img.altIcon = pressedIcon;
|
||||||
{
|
|
||||||
var select = document.createElement('select');
|
if (title != null) {
|
||||||
select.className = style || 'mxToolbarCombo';
|
img.setAttribute('title', title);
|
||||||
this.addOption(select, title, null);
|
|
||||||
|
|
||||||
mxEvent.addListener(select, 'change', (evt)=>
|
|
||||||
{
|
|
||||||
var value = select.options[select.selectedIndex];
|
|
||||||
select.selectedIndex = 0;
|
|
||||||
|
|
||||||
if (value.funct != null)
|
|
||||||
{
|
|
||||||
value.funct(evt);
|
|
||||||
}
|
}
|
||||||
});
|
|
||||||
|
|
||||||
this.container.appendChild(select);
|
|
||||||
|
|
||||||
return select;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
mxEvent.addListener(img, 'click', mxUtils.bind(this, (evt) => {
|
||||||
* Function: addOption
|
|
||||||
*
|
|
||||||
* Adds and returns a new OPTION element inside the given SELECT element.
|
|
||||||
* If the given value is a function then it is stored in the option's funct
|
|
||||||
* field.
|
|
||||||
*
|
|
||||||
* Parameters:
|
|
||||||
*
|
|
||||||
* combo - SELECT element that will contain the new entry.
|
|
||||||
* title - String that specifies the title of the option.
|
|
||||||
* value - Specifies the value associated with this option.
|
|
||||||
*/
|
|
||||||
addOption = (combo, title, value)=>
|
|
||||||
{
|
|
||||||
var option = document.createElement('option');
|
|
||||||
mxUtils.writeln(option, title);
|
|
||||||
|
|
||||||
if (typeof(value) == 'function')
|
|
||||||
{
|
|
||||||
option.funct = value;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
option.setAttribute('value', value);
|
|
||||||
}
|
|
||||||
|
|
||||||
combo.appendChild(option);
|
|
||||||
|
|
||||||
return option;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Function: addSwitchMode
|
|
||||||
*
|
|
||||||
* Adds a new selectable item to the toolbar. Only one switch mode item may
|
|
||||||
* be selected at a time. The currently selected item is the default item
|
|
||||||
* after a reset of the toolbar.
|
|
||||||
*/
|
|
||||||
addSwitchMode = (title, icon, funct, pressedIcon, style)=>
|
|
||||||
{
|
|
||||||
var img = document.createElement('img');
|
|
||||||
img.initialClassName = style || 'mxToolbarMode';
|
|
||||||
img.className = img.initialClassName;
|
|
||||||
img.setAttribute('src', icon);
|
|
||||||
img.altIcon = pressedIcon;
|
|
||||||
|
|
||||||
if (title != null)
|
|
||||||
{
|
|
||||||
img.setAttribute('title', title);
|
|
||||||
}
|
|
||||||
|
|
||||||
mxEvent.addListener(img, 'click', mxUtils.bind(this, (evt)=>
|
|
||||||
{
|
|
||||||
var tmp = this.selectedMode.altIcon;
|
|
||||||
|
|
||||||
if (tmp != null)
|
|
||||||
{
|
|
||||||
this.selectedMode.altIcon = this.selectedMode.getAttribute('src');
|
|
||||||
this.selectedMode.setAttribute('src', tmp);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
this.selectedMode.className = this.selectedMode.initialClassName;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this.updateDefaultMode)
|
|
||||||
{
|
|
||||||
this.defaultMode = img;
|
|
||||||
}
|
|
||||||
|
|
||||||
this.selectedMode = img;
|
|
||||||
|
|
||||||
var tmp = img.altIcon;
|
|
||||||
|
|
||||||
if (tmp != null)
|
|
||||||
{
|
|
||||||
img.altIcon = img.getAttribute('src');
|
|
||||||
img.setAttribute('src', tmp);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
img.className = img.initialClassName+'Selected';
|
|
||||||
}
|
|
||||||
|
|
||||||
this.fireEvent(new mxEventObject(mxEvent.SELECT));
|
|
||||||
funct();
|
|
||||||
}));
|
|
||||||
|
|
||||||
this.container.appendChild(img);
|
|
||||||
|
|
||||||
if (this.defaultMode == null)
|
|
||||||
{
|
|
||||||
this.defaultMode = img;
|
|
||||||
|
|
||||||
// Function should fire only once so
|
|
||||||
// do not pass it with the select event
|
|
||||||
this.selectMode(img);
|
|
||||||
funct();
|
|
||||||
}
|
|
||||||
|
|
||||||
return img;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Function: addMode
|
|
||||||
*
|
|
||||||
* Adds a new item to the toolbar. The selection is typically reset after
|
|
||||||
* the item has been consumed, for example by adding a new vertex to the
|
|
||||||
* graph. The reset is not carried out if the item is double clicked.
|
|
||||||
*
|
|
||||||
* The function argument uses the following signature: funct(evt, cell) where
|
|
||||||
* evt is the native mouse event and cell is the cell under the mouse.
|
|
||||||
*/
|
|
||||||
addMode = (title, icon, funct, pressedIcon, style, toggle)=>
|
|
||||||
{
|
|
||||||
toggle = (toggle != null) ? toggle : true;
|
|
||||||
var img = document.createElement((icon != null) ? 'img' : 'button');
|
|
||||||
|
|
||||||
img.initialClassName = style || 'mxToolbarMode';
|
|
||||||
img.className = img.initialClassName;
|
|
||||||
img.setAttribute('src', icon);
|
|
||||||
img.altIcon = pressedIcon;
|
|
||||||
|
|
||||||
if (title != null)
|
|
||||||
{
|
|
||||||
img.setAttribute('title', title);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this.enabled && toggle)
|
|
||||||
{
|
|
||||||
mxEvent.addListener(img, 'click', mxUtils.bind(this, (evt)=>
|
|
||||||
{
|
|
||||||
this.selectMode(img, funct);
|
|
||||||
this.noReset = false;
|
|
||||||
}));
|
|
||||||
|
|
||||||
mxEvent.addListener(img, 'dblclick', mxUtils.bind(this, (evt)=>
|
|
||||||
{
|
|
||||||
this.selectMode(img, funct);
|
|
||||||
this.noReset = true;
|
|
||||||
}));
|
|
||||||
|
|
||||||
if (this.defaultMode == null)
|
|
||||||
{
|
|
||||||
this.defaultMode = img;
|
|
||||||
this.defaultFunction = funct;
|
|
||||||
this.selectMode(img, funct);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
this.container.appendChild(img);
|
|
||||||
|
|
||||||
return img;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Function: selectMode
|
|
||||||
*
|
|
||||||
* Resets the state of the previously selected mode and displays the given
|
|
||||||
* DOM node as selected. This function fires a select event with the given
|
|
||||||
* function as a parameter.
|
|
||||||
*/
|
|
||||||
selectMode = (domNode, funct)=>
|
|
||||||
{
|
|
||||||
if (this.selectedMode != domNode)
|
|
||||||
{
|
|
||||||
if (this.selectedMode != null)
|
|
||||||
{
|
|
||||||
var tmp = this.selectedMode.altIcon;
|
var tmp = this.selectedMode.altIcon;
|
||||||
|
|
||||||
if (tmp != null)
|
if (tmp != null) {
|
||||||
{
|
|
||||||
this.selectedMode.altIcon = this.selectedMode.getAttribute('src');
|
this.selectedMode.altIcon = this.selectedMode.getAttribute('src');
|
||||||
this.selectedMode.setAttribute('src', tmp);
|
this.selectedMode.setAttribute('src', tmp);
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
this.selectedMode.className = this.selectedMode.initialClassName;
|
this.selectedMode.className = this.selectedMode.initialClassName;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (this.updateDefaultMode) {
|
||||||
|
this.defaultMode = img;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.selectedMode = img;
|
||||||
|
|
||||||
|
var tmp = img.altIcon;
|
||||||
|
|
||||||
|
if (tmp != null) {
|
||||||
|
img.altIcon = img.getAttribute('src');
|
||||||
|
img.setAttribute('src', tmp);
|
||||||
|
} else {
|
||||||
|
img.className = img.initialClassName + 'Selected';
|
||||||
|
}
|
||||||
|
|
||||||
|
this.fireEvent(new mxEventObject(mxEvent.SELECT));
|
||||||
|
funct();
|
||||||
|
}));
|
||||||
|
|
||||||
|
this.container.appendChild(img);
|
||||||
|
|
||||||
|
if (this.defaultMode == null) {
|
||||||
|
this.defaultMode = img;
|
||||||
|
|
||||||
|
// Function should fire only once so
|
||||||
|
// do not pass it with the select event
|
||||||
|
this.selectMode(img);
|
||||||
|
funct();
|
||||||
}
|
}
|
||||||
|
|
||||||
this.selectedMode = domNode;
|
return img;
|
||||||
var tmp = this.selectedMode.altIcon;
|
};
|
||||||
|
|
||||||
if (tmp != null)
|
/**
|
||||||
{
|
* Function: addMode
|
||||||
this.selectedMode.altIcon = this.selectedMode.getAttribute('src');
|
*
|
||||||
this.selectedMode.setAttribute('src', tmp);
|
* Adds a new item to the toolbar. The selection is typically reset after
|
||||||
|
* the item has been consumed, for example by adding a new vertex to the
|
||||||
|
* graph. The reset is not carried out if the item is double clicked.
|
||||||
|
*
|
||||||
|
* The function argument uses the following signature: funct(evt, cell) where
|
||||||
|
* evt is the native mouse event and cell is the cell under the mouse.
|
||||||
|
*/
|
||||||
|
addMode = (title, icon, funct, pressedIcon, style, toggle) => {
|
||||||
|
toggle = (toggle != null) ? toggle : true;
|
||||||
|
var img = document.createElement((icon != null) ? 'img' : 'button');
|
||||||
|
|
||||||
|
img.initialClassName = style || 'mxToolbarMode';
|
||||||
|
img.className = img.initialClassName;
|
||||||
|
img.setAttribute('src', icon);
|
||||||
|
img.altIcon = pressedIcon;
|
||||||
|
|
||||||
|
if (title != null) {
|
||||||
|
img.setAttribute('title', title);
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
if (this.enabled && toggle) {
|
||||||
this.selectedMode.className = this.selectedMode.initialClassName+'Selected';
|
mxEvent.addListener(img, 'click', mxUtils.bind(this, (evt) => {
|
||||||
|
this.selectMode(img, funct);
|
||||||
|
this.noReset = false;
|
||||||
|
}));
|
||||||
|
|
||||||
|
mxEvent.addListener(img, 'dblclick', mxUtils.bind(this, (evt) => {
|
||||||
|
this.selectMode(img, funct);
|
||||||
|
this.noReset = true;
|
||||||
|
}));
|
||||||
|
|
||||||
|
if (this.defaultMode == null) {
|
||||||
|
this.defaultMode = img;
|
||||||
|
this.defaultFunction = funct;
|
||||||
|
this.selectMode(img, funct);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
this.fireEvent(new mxEventObject(mxEvent.SELECT, "function", funct));
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
this.container.appendChild(img);
|
||||||
* Function: resetMode
|
|
||||||
*
|
|
||||||
* Selects the default mode and resets the state of the previously selected
|
|
||||||
* mode.
|
|
||||||
*/
|
|
||||||
resetMode = (forced)=>
|
|
||||||
{
|
|
||||||
if ((forced || !this.noReset) && this.selectedMode != this.defaultMode)
|
|
||||||
{
|
|
||||||
// The last selected switch mode will be activated
|
|
||||||
// so the function was already executed and is
|
|
||||||
// no longer required here
|
|
||||||
this.selectMode(this.defaultMode, this.defaultFunction);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
return img;
|
||||||
* Function: addSeparator
|
};
|
||||||
*
|
|
||||||
* Adds the specifies image as a separator.
|
|
||||||
*
|
|
||||||
* Parameters:
|
|
||||||
*
|
|
||||||
* icon - URL of the separator icon.
|
|
||||||
*/
|
|
||||||
addSeparator = (icon)=>
|
|
||||||
{
|
|
||||||
return this.addItem(null, icon, null);
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function: addBreak
|
* Function: selectMode
|
||||||
*
|
*
|
||||||
* Adds a break to the container.
|
* Resets the state of the previously selected mode and displays the given
|
||||||
*/
|
* DOM node as selected. This function fires a select event with the given
|
||||||
addBreak = ()=>
|
* function as a parameter.
|
||||||
{
|
*/
|
||||||
mxUtils.br(this.container);
|
selectMode = (domNode, funct) => {
|
||||||
};
|
if (this.selectedMode != domNode) {
|
||||||
|
if (this.selectedMode != null) {
|
||||||
|
var tmp = this.selectedMode.altIcon;
|
||||||
|
|
||||||
/**
|
if (tmp != null) {
|
||||||
* Function: addLine
|
this.selectedMode.altIcon = this.selectedMode.getAttribute('src');
|
||||||
*
|
this.selectedMode.setAttribute('src', tmp);
|
||||||
* Adds a horizontal line to the container.
|
} else {
|
||||||
*/
|
this.selectedMode.className = this.selectedMode.initialClassName;
|
||||||
addLine = ()=>
|
}
|
||||||
{
|
}
|
||||||
var hr = document.createElement('hr');
|
|
||||||
|
|
||||||
hr.style.marginRight = '6px';
|
|
||||||
hr.setAttribute('size', '1');
|
|
||||||
|
|
||||||
this.container.appendChild(hr);
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
this.selectedMode = domNode;
|
||||||
* Function: destroy
|
var tmp = this.selectedMode.altIcon;
|
||||||
*
|
|
||||||
* Removes the toolbar and all its associated resources.
|
if (tmp != null) {
|
||||||
*/
|
this.selectedMode.altIcon = this.selectedMode.getAttribute('src');
|
||||||
destroy = function ()
|
this.selectedMode.setAttribute('src', tmp);
|
||||||
{
|
} else {
|
||||||
mxEvent.release(this.container);
|
this.selectedMode.className = this.selectedMode.initialClassName + 'Selected';
|
||||||
this.container = null;
|
}
|
||||||
this.defaultMode = null;
|
|
||||||
this.defaultFunction = null;
|
this.fireEvent(new mxEventObject(mxEvent.SELECT, "function", funct));
|
||||||
this.selectedMode = null;
|
}
|
||||||
|
};
|
||||||
if (this.menu != null)
|
|
||||||
{
|
/**
|
||||||
this.menu.destroy();
|
* Function: resetMode
|
||||||
}
|
*
|
||||||
};
|
* Selects the default mode and resets the state of the previously selected
|
||||||
|
* mode.
|
||||||
|
*/
|
||||||
|
resetMode = (forced) => {
|
||||||
|
if ((forced || !this.noReset) && this.selectedMode != this.defaultMode) {
|
||||||
|
// The last selected switch mode will be activated
|
||||||
|
// so the function was already executed and is
|
||||||
|
// no longer required here
|
||||||
|
this.selectMode(this.defaultMode, this.defaultFunction);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function: addSeparator
|
||||||
|
*
|
||||||
|
* Adds the specifies image as a separator.
|
||||||
|
*
|
||||||
|
* Parameters:
|
||||||
|
*
|
||||||
|
* icon - URL of the separator icon.
|
||||||
|
*/
|
||||||
|
addSeparator = (icon) => {
|
||||||
|
return this.addItem(null, icon, null);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function: addBreak
|
||||||
|
*
|
||||||
|
* Adds a break to the container.
|
||||||
|
*/
|
||||||
|
addBreak = () => {
|
||||||
|
mxUtils.br(this.container);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function: addLine
|
||||||
|
*
|
||||||
|
* Adds a horizontal line to the container.
|
||||||
|
*/
|
||||||
|
addLine = () => {
|
||||||
|
var hr = document.createElement('hr');
|
||||||
|
|
||||||
|
hr.style.marginRight = '6px';
|
||||||
|
hr.setAttribute('size', '1');
|
||||||
|
|
||||||
|
this.container.appendChild(hr);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function: destroy
|
||||||
|
*
|
||||||
|
* Removes the toolbar and all its associated resources.
|
||||||
|
*/
|
||||||
|
destroy = function () {
|
||||||
|
mxEvent.release(this.container);
|
||||||
|
this.container = null;
|
||||||
|
this.defaultMode = null;
|
||||||
|
this.defaultFunction = null;
|
||||||
|
this.selectedMode = null;
|
||||||
|
|
||||||
|
if (this.menu != null) {
|
||||||
|
this.menu.destroy();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export default mxToolbar;
|
||||||
|
|
|
@ -2,228 +2,214 @@
|
||||||
* Copyright (c) 2006-2015, JGraph Ltd
|
* Copyright (c) 2006-2015, JGraph Ltd
|
||||||
* Copyright (c) 2006-2015, Gaudenz Alder
|
* Copyright (c) 2006-2015, Gaudenz Alder
|
||||||
*/
|
*/
|
||||||
/**
|
|
||||||
* Class: mxUndoManager
|
|
||||||
*
|
|
||||||
* Implements a command history. When changing the graph model, an
|
|
||||||
* <mxUndoableChange> object is created at the start of the transaction (when
|
|
||||||
* model.beginUpdate is called). All atomic changes are then added to this
|
|
||||||
* object until the last model.endUpdate call, at which point the
|
|
||||||
* <mxUndoableEdit> is dispatched in an event, and added to the history inside
|
|
||||||
* <mxUndoManager>. This is done by an event listener in
|
|
||||||
* <mxEditor.installUndoHandler>.
|
|
||||||
*
|
|
||||||
* Each atomic change of the model is represented by an object (eg.
|
|
||||||
* <mxRootChange>, <mxChildChange>, <mxTerminalChange> etc) which contains the
|
|
||||||
* complete undo information. The <mxUndoManager> also listens to the
|
|
||||||
* <mxGraphView> and stores it's changes to the current root as insignificant
|
|
||||||
* undoable changes, so that drilling (step into, step up) is undone.
|
|
||||||
*
|
|
||||||
* This means when you execute an atomic change on the model, then change the
|
|
||||||
* current root on the view and click undo, the change of the root will be
|
|
||||||
* undone together with the change of the model so that the display represents
|
|
||||||
* the state at which the model was changed. However, these changes are not
|
|
||||||
* transmitted for sharing as they do not represent a state change.
|
|
||||||
*
|
|
||||||
* Example:
|
|
||||||
*
|
|
||||||
* When adding an undo manager to a graph, make sure to add it
|
|
||||||
* to the model and the view as well to maintain a consistent
|
|
||||||
* display across multiple undo/redo steps.
|
|
||||||
*
|
|
||||||
* (code)
|
|
||||||
* var undoManager = new mxUndoManager();
|
|
||||||
* var listener = (sender, evt)=>
|
|
||||||
* {
|
|
||||||
* undoManager.undoableEditHappened(evt.getProperty('edit'));
|
|
||||||
* };
|
|
||||||
* graph.getModel().addListener(mxEvent.UNDO, listener);
|
|
||||||
* graph.getView().addListener(mxEvent.UNDO, listener);
|
|
||||||
* (end)
|
|
||||||
*
|
|
||||||
* The code creates a function that informs the undoManager
|
|
||||||
* of an undoable edit and binds it to the undo event of
|
|
||||||
* <mxGraphModel> and <mxGraphView> using
|
|
||||||
* <mxEventSource.addListener>.
|
|
||||||
*
|
|
||||||
* Event: mxEvent.CLEAR
|
|
||||||
*
|
|
||||||
* Fires after <clear> was invoked. This event has no properties.
|
|
||||||
*
|
|
||||||
* Event: mxEvent.UNDO
|
|
||||||
*
|
|
||||||
* Fires afer a significant edit was undone in <undo>. The <code>edit</code>
|
|
||||||
* property contains the <mxUndoableEdit> that was undone.
|
|
||||||
*
|
|
||||||
* Event: mxEvent.REDO
|
|
||||||
*
|
|
||||||
* Fires afer a significant edit was redone in <redo>. The <code>edit</code>
|
|
||||||
* property contains the <mxUndoableEdit> that was redone.
|
|
||||||
*
|
|
||||||
* Event: mxEvent.ADD
|
|
||||||
*
|
|
||||||
* Fires after an undoable edit was added to the history. The <code>edit</code>
|
|
||||||
* property contains the <mxUndoableEdit> that was added.
|
|
||||||
*
|
|
||||||
* Constructor: mxUndoManager
|
|
||||||
*
|
|
||||||
* Constructs a new undo manager with the given history size. If no history
|
|
||||||
* size is given, then a default size of 100 steps is used.
|
|
||||||
*/
|
|
||||||
function mxUndoManager(size)
|
|
||||||
{
|
|
||||||
this.size = (size != null) ? size : 100;
|
|
||||||
this.clear();
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
import mxEventObject from "./mxEventObject";
|
||||||
* Extends mxEventSource.
|
import mxEventSource from "./mxEventSource";
|
||||||
*/
|
|
||||||
mxUndoManager.prototype = new mxEventSource();
|
|
||||||
constructor = mxUndoManager;
|
|
||||||
|
|
||||||
/**
|
class mxUndoManager extends mxEventSource {
|
||||||
* Variable: size
|
/**
|
||||||
*
|
* Variable: size
|
||||||
* Maximum command history size. 0 means unlimited history. Default is
|
*
|
||||||
* 100.
|
* Maximum command history size. 0 means unlimited history. Default is
|
||||||
*/
|
* 100.
|
||||||
size = null;
|
*/
|
||||||
|
size = null;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Variable: history
|
* Variable: history
|
||||||
*
|
*
|
||||||
* Array that contains the steps of the command history.
|
* Array that contains the steps of the command history.
|
||||||
*/
|
*/
|
||||||
history = null;
|
history = null;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Variable: indexOfNextAdd
|
* Variable: indexOfNextAdd
|
||||||
*
|
*
|
||||||
* Index of the element to be added next.
|
* Index of the element to be added next.
|
||||||
*/
|
*/
|
||||||
indexOfNextAdd = 0;
|
indexOfNextAdd = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function: isEmpty
|
* Class: mxUndoManager
|
||||||
*
|
*
|
||||||
* Returns true if the history is empty.
|
* Implements a command history. When changing the graph model, an
|
||||||
*/
|
* <mxUndoableChange> object is created at the start of the transaction (when
|
||||||
isEmpty = ()=>
|
* model.beginUpdate is called). All atomic changes are then added to this
|
||||||
{
|
* object until the last model.endUpdate call, at which point the
|
||||||
return this.history.length == 0;
|
* <mxUndoableEdit> is dispatched in an event, and added to the history inside
|
||||||
};
|
* <mxUndoManager>. This is done by an event listener in
|
||||||
|
* <mxEditor.installUndoHandler>.
|
||||||
|
*
|
||||||
|
* Each atomic change of the model is represented by an object (eg.
|
||||||
|
* <mxRootChange>, <mxChildChange>, <mxTerminalChange> etc) which contains the
|
||||||
|
* complete undo information. The <mxUndoManager> also listens to the
|
||||||
|
* <mxGraphView> and stores it's changes to the current root as insignificant
|
||||||
|
* undoable changes, so that drilling (step into, step up) is undone.
|
||||||
|
*
|
||||||
|
* This means when you execute an atomic change on the model, then change the
|
||||||
|
* current root on the view and click undo, the change of the root will be
|
||||||
|
* undone together with the change of the model so that the display represents
|
||||||
|
* the state at which the model was changed. However, these changes are not
|
||||||
|
* transmitted for sharing as they do not represent a state change.
|
||||||
|
*
|
||||||
|
* Example:
|
||||||
|
*
|
||||||
|
* When adding an undo manager to a graph, make sure to add it
|
||||||
|
* to the model and the view as well to maintain a consistent
|
||||||
|
* display across multiple undo/redo steps.
|
||||||
|
*
|
||||||
|
* (code)
|
||||||
|
* var undoManager = new mxUndoManager();
|
||||||
|
* var listener = (sender, evt)=>
|
||||||
|
* {
|
||||||
|
* undoManager.undoableEditHappened(evt.getProperty('edit'));
|
||||||
|
* };
|
||||||
|
* graph.getModel().addListener(mxEvent.UNDO, listener);
|
||||||
|
* graph.getView().addListener(mxEvent.UNDO, listener);
|
||||||
|
* (end)
|
||||||
|
*
|
||||||
|
* The code creates a function that informs the undoManager
|
||||||
|
* of an undoable edit and binds it to the undo event of
|
||||||
|
* <mxGraphModel> and <mxGraphView> using
|
||||||
|
* <mxEventSource.addListener>.
|
||||||
|
*
|
||||||
|
* Event: mxEvent.CLEAR
|
||||||
|
*
|
||||||
|
* Fires after <clear> was invoked. This event has no properties.
|
||||||
|
*
|
||||||
|
* Event: mxEvent.UNDO
|
||||||
|
*
|
||||||
|
* Fires afer a significant edit was undone in <undo>. The <code>edit</code>
|
||||||
|
* property contains the <mxUndoableEdit> that was undone.
|
||||||
|
*
|
||||||
|
* Event: mxEvent.REDO
|
||||||
|
*
|
||||||
|
* Fires afer a significant edit was redone in <redo>. The <code>edit</code>
|
||||||
|
* property contains the <mxUndoableEdit> that was redone.
|
||||||
|
*
|
||||||
|
* Event: mxEvent.ADD
|
||||||
|
*
|
||||||
|
* Fires after an undoable edit was added to the history. The <code>edit</code>
|
||||||
|
* property contains the <mxUndoableEdit> that was added.
|
||||||
|
*
|
||||||
|
* Constructor: mxUndoManager
|
||||||
|
*
|
||||||
|
* Constructs a new undo manager with the given history size. If no history
|
||||||
|
* size is given, then a default size of 100 steps is used.
|
||||||
|
*/
|
||||||
|
constructor(size) {
|
||||||
|
this.size = (size != null) ? size : 100;
|
||||||
|
this.clear();
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function: clear
|
* Function: isEmpty
|
||||||
*
|
*
|
||||||
* Clears the command history.
|
* Returns true if the history is empty.
|
||||||
*/
|
*/
|
||||||
clear = ()=>
|
isEmpty = () => {
|
||||||
{
|
return this.history.length == 0;
|
||||||
this.history = [];
|
};
|
||||||
this.indexOfNextAdd = 0;
|
|
||||||
this.fireEvent(new mxEventObject(mxEvent.CLEAR));
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function: canUndo
|
* Function: clear
|
||||||
*
|
*
|
||||||
* Returns true if an undo is possible.
|
* Clears the command history.
|
||||||
*/
|
*/
|
||||||
canUndo = ()=>
|
clear = () => {
|
||||||
{
|
this.history = [];
|
||||||
return this.indexOfNextAdd > 0;
|
this.indexOfNextAdd = 0;
|
||||||
};
|
this.fireEvent(new mxEventObject(mxEvent.CLEAR));
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function: undo
|
* Function: canUndo
|
||||||
*
|
*
|
||||||
* Undoes the last change.
|
* Returns true if an undo is possible.
|
||||||
*/
|
*/
|
||||||
undo = ()=>
|
canUndo = () => {
|
||||||
{
|
return this.indexOfNextAdd > 0;
|
||||||
while (this.indexOfNextAdd > 0)
|
};
|
||||||
{
|
|
||||||
var edit = this.history[--this.indexOfNextAdd];
|
|
||||||
edit.undo();
|
|
||||||
|
|
||||||
if (edit.isSignificant())
|
/**
|
||||||
{
|
* Function: undo
|
||||||
this.fireEvent(new mxEventObject(mxEvent.UNDO, 'edit', edit));
|
*
|
||||||
break;
|
* Undoes the last change.
|
||||||
}
|
*/
|
||||||
|
undo = () => {
|
||||||
|
while (this.indexOfNextAdd > 0) {
|
||||||
|
var edit = this.history[--this.indexOfNextAdd];
|
||||||
|
edit.undo();
|
||||||
|
|
||||||
|
if (edit.isSignificant()) {
|
||||||
|
this.fireEvent(new mxEventObject(mxEvent.UNDO, 'edit', edit));
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function: canRedo
|
* Function: canRedo
|
||||||
*
|
*
|
||||||
* Returns true if a redo is possible.
|
* Returns true if a redo is possible.
|
||||||
*/
|
*/
|
||||||
canRedo = ()=>
|
canRedo = () => {
|
||||||
{
|
return this.indexOfNextAdd < this.history.length;
|
||||||
return this.indexOfNextAdd < this.history.length;
|
};
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function: redo
|
* Function: redo
|
||||||
*
|
*
|
||||||
* Redoes the last change.
|
* Redoes the last change.
|
||||||
*/
|
*/
|
||||||
redo = ()=>
|
redo = () => {
|
||||||
{
|
|
||||||
var n = this.history.length;
|
var n = this.history.length;
|
||||||
|
|
||||||
while (this.indexOfNextAdd < n)
|
while (this.indexOfNextAdd < n) {
|
||||||
{
|
var edit = this.history[this.indexOfNextAdd++];
|
||||||
var edit = this.history[this.indexOfNextAdd++];
|
edit.redo();
|
||||||
edit.redo();
|
|
||||||
|
if (edit.isSignificant()) {
|
||||||
if (edit.isSignificant())
|
this.fireEvent(new mxEventObject(mxEvent.REDO, 'edit', edit));
|
||||||
{
|
break;
|
||||||
this.fireEvent(new mxEventObject(mxEvent.REDO, 'edit', edit));
|
}
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function: undoableEditHappened
|
* Function: undoableEditHappened
|
||||||
*
|
*
|
||||||
* Method to be called to add new undoable edits to the <history>.
|
* Method to be called to add new undoable edits to the <history>.
|
||||||
*/
|
*/
|
||||||
undoableEditHappened = (undoableEdit)=>
|
undoableEditHappened = (undoableEdit) => {
|
||||||
{
|
this.trim();
|
||||||
this.trim();
|
|
||||||
|
|
||||||
if (this.size > 0 &&
|
if (this.size > 0 &&
|
||||||
this.size == this.history.length)
|
this.size == this.history.length) {
|
||||||
{
|
this.history.shift();
|
||||||
this.history.shift();
|
|
||||||
}
|
|
||||||
|
|
||||||
this.history.push(undoableEdit);
|
|
||||||
this.indexOfNextAdd = this.history.length;
|
|
||||||
this.fireEvent(new mxEventObject(mxEvent.ADD, 'edit', undoableEdit));
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Function: trim
|
|
||||||
*
|
|
||||||
* Removes all pending steps after <indexOfNextAdd> from the history,
|
|
||||||
* invoking die on each edit. This is called from <undoableEditHappened>.
|
|
||||||
*/
|
|
||||||
trim = ()=>
|
|
||||||
{
|
|
||||||
if (this.history.length > this.indexOfNextAdd)
|
|
||||||
{
|
|
||||||
var edits = this.history.splice(this.indexOfNextAdd,
|
|
||||||
this.history.length - this.indexOfNextAdd);
|
|
||||||
|
|
||||||
for (var i = 0; i < edits.length; i++)
|
|
||||||
{
|
|
||||||
edits[i].die();
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
};
|
this.history.push(undoableEdit);
|
||||||
|
this.indexOfNextAdd = this.history.length;
|
||||||
|
this.fireEvent(new mxEventObject(mxEvent.ADD, 'edit', undoableEdit));
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function: trim
|
||||||
|
*
|
||||||
|
* Removes all pending steps after <indexOfNextAdd> from the history,
|
||||||
|
* invoking die on each edit. This is called from <undoableEditHappened>.
|
||||||
|
*/
|
||||||
|
trim = () => {
|
||||||
|
if (this.history.length > this.indexOfNextAdd) {
|
||||||
|
var edits = this.history.splice(this.indexOfNextAdd,
|
||||||
|
this.history.length - this.indexOfNextAdd);
|
||||||
|
|
||||||
|
for (var i = 0; i < edits.length; i++) {
|
||||||
|
edits[i].die();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export default mxUndoManager;
|
||||||
|
|
|
@ -2,212 +2,206 @@
|
||||||
* Copyright (c) 2006-2015, JGraph Ltd
|
* Copyright (c) 2006-2015, JGraph Ltd
|
||||||
* Copyright (c) 2006-2015, Gaudenz Alder
|
* Copyright (c) 2006-2015, Gaudenz Alder
|
||||||
*/
|
*/
|
||||||
/**
|
|
||||||
* Class: mxUndoableEdit
|
|
||||||
*
|
|
||||||
* Implements a composite undoable edit. Here is an example for a custom change
|
|
||||||
* which gets executed via the model:
|
|
||||||
*
|
|
||||||
* (code)
|
|
||||||
* function CustomChange(model, name)
|
|
||||||
* {
|
|
||||||
* this.model = model;
|
|
||||||
* this.name = name;
|
|
||||||
* this.previous = name;
|
|
||||||
* };
|
|
||||||
*
|
|
||||||
* execute = ()=>
|
|
||||||
* {
|
|
||||||
* var tmp = this.model.name;
|
|
||||||
* this.model.name = this.previous;
|
|
||||||
* this.previous = tmp;
|
|
||||||
* };
|
|
||||||
*
|
|
||||||
* var name = prompt('Enter name');
|
|
||||||
* graph.model.execute(new CustomChange(graph.model, name));
|
|
||||||
* (end)
|
|
||||||
*
|
|
||||||
* Event: mxEvent.EXECUTED
|
|
||||||
*
|
|
||||||
* Fires between START_EDIT and END_EDIT after an atomic change was executed.
|
|
||||||
* The <code>change</code> property contains the change that was executed.
|
|
||||||
*
|
|
||||||
* Event: mxEvent.START_EDIT
|
|
||||||
*
|
|
||||||
* Fires before a set of changes will be executed in <undo> or <redo>.
|
|
||||||
* This event contains no properties.
|
|
||||||
*
|
|
||||||
* Event: mxEvent.END_EDIT
|
|
||||||
*
|
|
||||||
* Fires after a set of changeswas executed in <undo> or <redo>.
|
|
||||||
* This event contains no properties.
|
|
||||||
*
|
|
||||||
* Constructor: mxUndoableEdit
|
|
||||||
*
|
|
||||||
* Constructs a new undoable edit for the given source.
|
|
||||||
*/
|
|
||||||
function mxUndoableEdit(source, significant)
|
|
||||||
{
|
|
||||||
this.source = source;
|
|
||||||
this.changes = [];
|
|
||||||
this.significant = (significant != null) ? significant : true;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
import mxEvent from "./mxEvent";
|
||||||
* Variable: source
|
import mxEventObject from "./mxEventObject";
|
||||||
*
|
|
||||||
* Specifies the source of the edit.
|
|
||||||
*/
|
|
||||||
source = null;
|
|
||||||
|
|
||||||
/**
|
class mxUndoableEdit {
|
||||||
* Variable: changes
|
/**
|
||||||
*
|
* Variable: source
|
||||||
* Array that contains the changes that make up this edit. The changes are
|
*
|
||||||
* expected to either have an undo and redo function, or an execute
|
* Specifies the source of the edit.
|
||||||
* function. Default is an empty array.
|
*/
|
||||||
*/
|
source = null;
|
||||||
changes = null;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Variable: significant
|
* Variable: changes
|
||||||
*
|
*
|
||||||
* Specifies if the undoable change is significant.
|
* Array that contains the changes that make up this edit. The changes are
|
||||||
* Default is true.
|
* expected to either have an undo and redo function, or an execute
|
||||||
*/
|
* function. Default is an empty array.
|
||||||
significant = null;
|
*/
|
||||||
|
changes = null;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Variable: undone
|
* Variable: significant
|
||||||
*
|
*
|
||||||
* Specifies if this edit has been undone. Default is false.
|
* Specifies if the undoable change is significant.
|
||||||
*/
|
* Default is true.
|
||||||
undone = false;
|
*/
|
||||||
|
significant = null;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Variable: redone
|
* Variable: undone
|
||||||
*
|
*
|
||||||
* Specifies if this edit has been redone. Default is false.
|
* Specifies if this edit has been undone. Default is false.
|
||||||
*/
|
*/
|
||||||
redone = false;
|
undone = false;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function: isEmpty
|
* Variable: redone
|
||||||
*
|
*
|
||||||
* Returns true if the this edit contains no changes.
|
* Specifies if this edit has been redone. Default is false.
|
||||||
*/
|
*/
|
||||||
isEmpty = ()=>
|
redone = false;
|
||||||
{
|
|
||||||
return this.changes.length == 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function: isSignificant
|
* Class: mxUndoableEdit
|
||||||
*
|
*
|
||||||
* Returns <significant>.
|
* Implements a composite undoable edit. Here is an example for a custom change
|
||||||
*/
|
* which gets executed via the model:
|
||||||
isSignificant = ()=>
|
*
|
||||||
{
|
* (code)
|
||||||
return this.significant;
|
* function CustomChange(model, name)
|
||||||
};
|
* {
|
||||||
|
* this.model = model;
|
||||||
|
* this.name = name;
|
||||||
|
* this.previous = name;
|
||||||
|
* };
|
||||||
|
*
|
||||||
|
* execute = ()=>
|
||||||
|
* {
|
||||||
|
* var tmp = this.model.name;
|
||||||
|
* this.model.name = this.previous;
|
||||||
|
* this.previous = tmp;
|
||||||
|
* };
|
||||||
|
*
|
||||||
|
* var name = prompt('Enter name');
|
||||||
|
* graph.model.execute(new CustomChange(graph.model, name));
|
||||||
|
* (end)
|
||||||
|
*
|
||||||
|
* Event: mxEvent.EXECUTED
|
||||||
|
*
|
||||||
|
* Fires between START_EDIT and END_EDIT after an atomic change was executed.
|
||||||
|
* The <code>change</code> property contains the change that was executed.
|
||||||
|
*
|
||||||
|
* Event: mxEvent.START_EDIT
|
||||||
|
*
|
||||||
|
* Fires before a set of changes will be executed in <undo> or <redo>.
|
||||||
|
* This event contains no properties.
|
||||||
|
*
|
||||||
|
* Event: mxEvent.END_EDIT
|
||||||
|
*
|
||||||
|
* Fires after a set of changeswas executed in <undo> or <redo>.
|
||||||
|
* This event contains no properties.
|
||||||
|
*
|
||||||
|
* Constructor: mxUndoableEdit
|
||||||
|
*
|
||||||
|
* Constructs a new undoable edit for the given source.
|
||||||
|
*/
|
||||||
|
constructor(source, significant) {
|
||||||
|
this.source = source;
|
||||||
|
this.changes = [];
|
||||||
|
this.significant = (significant != null) ? significant : true;
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function: add
|
* Function: isEmpty
|
||||||
*
|
*
|
||||||
* Adds the specified change to this edit. The change is an object that is
|
* Returns true if the this edit contains no changes.
|
||||||
* expected to either have an undo and redo, or an execute function.
|
*/
|
||||||
*/
|
isEmpty = () => {
|
||||||
add = (change)=>
|
return this.changes.length == 0;
|
||||||
{
|
};
|
||||||
this.changes.push(change);
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function: notify
|
* Function: isSignificant
|
||||||
*
|
*
|
||||||
* Hook to notify any listeners of the changes after an <undo> or <redo>
|
* Returns <significant>.
|
||||||
* has been carried out. This implementation is empty.
|
*/
|
||||||
*/
|
isSignificant = () => {
|
||||||
notify = ()=> { };
|
return this.significant;
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function: die
|
* Function: add
|
||||||
*
|
*
|
||||||
* Hook to free resources after the edit has been removed from the command
|
* Adds the specified change to this edit. The change is an object that is
|
||||||
* history. This implementation is empty.
|
* expected to either have an undo and redo, or an execute function.
|
||||||
*/
|
*/
|
||||||
die = ()=> { };
|
add = (change) => {
|
||||||
|
this.changes.push(change);
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function: undo
|
* Function: notify
|
||||||
*
|
*
|
||||||
* Undoes all changes in this edit.
|
* Hook to notify any listeners of the changes after an <undo> or <redo>
|
||||||
*/
|
* has been carried out. This implementation is empty.
|
||||||
undo = ()=>
|
*/
|
||||||
{
|
notify = () => {
|
||||||
if (!this.undone)
|
};
|
||||||
{
|
|
||||||
this.source.fireEvent(new mxEventObject(mxEvent.START_EDIT));
|
/**
|
||||||
var count = this.changes.length;
|
* Function: die
|
||||||
|
*
|
||||||
for (var i = count - 1; i >= 0; i--)
|
* Hook to free resources after the edit has been removed from the command
|
||||||
{
|
* history. This implementation is empty.
|
||||||
var change = this.changes[i];
|
*/
|
||||||
|
die = () => {
|
||||||
if (change.execute != null)
|
};
|
||||||
{
|
|
||||||
change.execute();
|
/**
|
||||||
|
* Function: undo
|
||||||
|
*
|
||||||
|
* Undoes all changes in this edit.
|
||||||
|
*/
|
||||||
|
undo = () => {
|
||||||
|
if (!this.undone) {
|
||||||
|
this.source.fireEvent(new mxEventObject(mxEvent.START_EDIT));
|
||||||
|
var count = this.changes.length;
|
||||||
|
|
||||||
|
for (var i = count - 1; i >= 0; i--) {
|
||||||
|
var change = this.changes[i];
|
||||||
|
|
||||||
|
if (change.execute != null) {
|
||||||
|
change.execute();
|
||||||
|
} else if (change.undo != null) {
|
||||||
|
change.undo();
|
||||||
|
}
|
||||||
|
|
||||||
|
// New global executed event
|
||||||
|
this.source.fireEvent(new mxEventObject(mxEvent.EXECUTED, 'change', change));
|
||||||
}
|
}
|
||||||
else if (change.undo != null)
|
|
||||||
{
|
this.undone = true;
|
||||||
change.undo();
|
this.redone = false;
|
||||||
}
|
this.source.fireEvent(new mxEventObject(mxEvent.END_EDIT));
|
||||||
|
|
||||||
// New global executed event
|
|
||||||
this.source.fireEvent(new mxEventObject(mxEvent.EXECUTED, 'change', change));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
this.undone = true;
|
|
||||||
this.redone = false;
|
|
||||||
this.source.fireEvent(new mxEventObject(mxEvent.END_EDIT));
|
|
||||||
}
|
|
||||||
|
|
||||||
this.notify();
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
this.notify();
|
||||||
* Function: redo
|
};
|
||||||
*
|
|
||||||
* Redoes all changes in this edit.
|
/**
|
||||||
*/
|
* Function: redo
|
||||||
redo = ()=>
|
*
|
||||||
{
|
* Redoes all changes in this edit.
|
||||||
if (!this.redone)
|
*/
|
||||||
{
|
redo = () => {
|
||||||
this.source.fireEvent(new mxEventObject(mxEvent.START_EDIT));
|
if (!this.redone) {
|
||||||
var count = this.changes.length;
|
this.source.fireEvent(new mxEventObject(mxEvent.START_EDIT));
|
||||||
|
var count = this.changes.length;
|
||||||
for (var i = 0; i < count; i++)
|
|
||||||
{
|
for (var i = 0; i < count; i++) {
|
||||||
var change = this.changes[i];
|
var change = this.changes[i];
|
||||||
|
|
||||||
if (change.execute != null)
|
if (change.execute != null) {
|
||||||
{
|
change.execute();
|
||||||
change.execute();
|
} else if (change.redo != null) {
|
||||||
|
change.redo();
|
||||||
|
}
|
||||||
|
|
||||||
|
// New global executed event
|
||||||
|
this.source.fireEvent(new mxEventObject(mxEvent.EXECUTED, 'change', change));
|
||||||
}
|
}
|
||||||
else if (change.redo != null)
|
|
||||||
{
|
this.undone = false;
|
||||||
change.redo();
|
this.redone = true;
|
||||||
}
|
this.source.fireEvent(new mxEventObject(mxEvent.END_EDIT));
|
||||||
|
|
||||||
// New global executed event
|
|
||||||
this.source.fireEvent(new mxEventObject(mxEvent.EXECUTED, 'change', change));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
this.undone = false;
|
this.notify();
|
||||||
this.redone = true;
|
};
|
||||||
this.source.fireEvent(new mxEventObject(mxEvent.END_EDIT));
|
}
|
||||||
}
|
|
||||||
|
export default mxUndoableEdit;
|
||||||
this.notify();
|
|
||||||
};
|
|
||||||
|
|
|
@ -2,152 +2,141 @@
|
||||||
* Copyright (c) 2006-2015, JGraph Ltd
|
* Copyright (c) 2006-2015, JGraph Ltd
|
||||||
* Copyright (c) 2006-2015, Gaudenz Alder
|
* Copyright (c) 2006-2015, Gaudenz Alder
|
||||||
*/
|
*/
|
||||||
/**
|
|
||||||
*
|
|
||||||
* Class: mxUrlConverter
|
|
||||||
*
|
|
||||||
* Converts relative and absolute URLs to absolute URLs with protocol and domain.
|
|
||||||
*/
|
|
||||||
var mxUrlConverter = ()=>
|
|
||||||
{
|
|
||||||
// Empty constructor
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
class mxUrlConverter {
|
||||||
* Variable: enabled
|
/**
|
||||||
*
|
*
|
||||||
* Specifies if the converter is enabled. Default is true.
|
* Class: mxUrlConverter
|
||||||
*/
|
*
|
||||||
enabled = true;
|
* Converts relative and absolute URLs to absolute URLs with protocol and domain.
|
||||||
|
*/
|
||||||
|
constructor() {
|
||||||
|
// Empty constructor
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Variable: baseUrl
|
* Variable: enabled
|
||||||
*
|
*
|
||||||
* Specifies the base URL to be used as a prefix for relative URLs.
|
* Specifies if the converter is enabled. Default is true.
|
||||||
*/
|
*/
|
||||||
baseUrl = null;
|
enabled = true;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Variable: baseDomain
|
* Variable: baseUrl
|
||||||
*
|
*
|
||||||
* Specifies the base domain to be used as a prefix for absolute URLs.
|
* Specifies the base URL to be used as a prefix for relative URLs.
|
||||||
*/
|
*/
|
||||||
baseDomain = null;
|
baseUrl = null;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function: updateBaseUrl
|
* Variable: baseDomain
|
||||||
*
|
*
|
||||||
* Private helper function to update the base URL.
|
* Specifies the base domain to be used as a prefix for absolute URLs.
|
||||||
*/
|
*/
|
||||||
updateBaseUrl = ()=>
|
baseDomain = null;
|
||||||
{
|
|
||||||
this.baseDomain = location.protocol + '//' + location.host;
|
|
||||||
this.baseUrl = this.baseDomain + location.pathname;
|
|
||||||
var tmp = this.baseUrl.lastIndexOf('/');
|
|
||||||
|
|
||||||
// Strips filename etc
|
|
||||||
if (tmp > 0)
|
|
||||||
{
|
|
||||||
this.baseUrl = this.baseUrl.substring(0, tmp + 1);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function: isEnabled
|
* Function: updateBaseUrl
|
||||||
*
|
*
|
||||||
* Returns <enabled>.
|
* Private helper function to update the base URL.
|
||||||
*/
|
*/
|
||||||
isEnabled = ()=>
|
updateBaseUrl = () => {
|
||||||
{
|
this.baseDomain = location.protocol + '//' + location.host;
|
||||||
return this.enabled;
|
this.baseUrl = this.baseDomain + location.pathname;
|
||||||
};
|
var tmp = this.baseUrl.lastIndexOf('/');
|
||||||
|
|
||||||
/**
|
// Strips filename etc
|
||||||
* Function: setEnabled
|
if (tmp > 0) {
|
||||||
*
|
this.baseUrl = this.baseUrl.substring(0, tmp + 1);
|
||||||
* Sets <enabled>.
|
|
||||||
*/
|
|
||||||
setEnabled = (value)=>
|
|
||||||
{
|
|
||||||
this.enabled = value;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Function: getBaseUrl
|
|
||||||
*
|
|
||||||
* Returns <baseUrl>.
|
|
||||||
*/
|
|
||||||
getBaseUrl = ()=>
|
|
||||||
{
|
|
||||||
return this.baseUrl;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Function: setBaseUrl
|
|
||||||
*
|
|
||||||
* Sets <baseUrl>.
|
|
||||||
*/
|
|
||||||
setBaseUrl = (value)=>
|
|
||||||
{
|
|
||||||
this.baseUrl = value;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Function: getBaseDomain
|
|
||||||
*
|
|
||||||
* Returns <baseDomain>.
|
|
||||||
*/
|
|
||||||
getBaseDomain = ()=>
|
|
||||||
{
|
|
||||||
return this.baseDomain;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Function: setBaseDomain
|
|
||||||
*
|
|
||||||
* Sets <baseDomain>.
|
|
||||||
*/
|
|
||||||
setBaseDomain = (value)=>
|
|
||||||
{
|
|
||||||
this.baseDomain = value;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Function: isRelativeUrl
|
|
||||||
*
|
|
||||||
* Returns true if the given URL is relative.
|
|
||||||
*/
|
|
||||||
isRelativeUrl = (url)=>
|
|
||||||
{
|
|
||||||
return url != null && url.substring(0, 2) != '//' && url.substring(0, 7) != 'http://' &&
|
|
||||||
url.substring(0, 8) != 'https://' && url.substring(0, 10) != 'data:image' &&
|
|
||||||
url.substring(0, 7) != 'file://';
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Function: convert
|
|
||||||
*
|
|
||||||
* Converts the given URL to an absolute URL with protol and domain.
|
|
||||||
* Relative URLs are first converted to absolute URLs.
|
|
||||||
*/
|
|
||||||
convert = (url)=>
|
|
||||||
{
|
|
||||||
if (this.isEnabled() && this.isRelativeUrl(url))
|
|
||||||
{
|
|
||||||
if (this.getBaseUrl() == null)
|
|
||||||
{
|
|
||||||
this.updateBaseUrl();
|
|
||||||
}
|
}
|
||||||
|
};
|
||||||
if (url.charAt(0) == '/')
|
|
||||||
{
|
/**
|
||||||
url = this.getBaseDomain() + url;
|
* Function: isEnabled
|
||||||
|
*
|
||||||
|
* Returns <enabled>.
|
||||||
|
*/
|
||||||
|
isEnabled = () => {
|
||||||
|
return this.enabled;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function: setEnabled
|
||||||
|
*
|
||||||
|
* Sets <enabled>.
|
||||||
|
*/
|
||||||
|
setEnabled = (value) => {
|
||||||
|
this.enabled = value;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function: getBaseUrl
|
||||||
|
*
|
||||||
|
* Returns <baseUrl>.
|
||||||
|
*/
|
||||||
|
getBaseUrl = () => {
|
||||||
|
return this.baseUrl;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function: setBaseUrl
|
||||||
|
*
|
||||||
|
* Sets <baseUrl>.
|
||||||
|
*/
|
||||||
|
setBaseUrl = (value) => {
|
||||||
|
this.baseUrl = value;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function: getBaseDomain
|
||||||
|
*
|
||||||
|
* Returns <baseDomain>.
|
||||||
|
*/
|
||||||
|
getBaseDomain = () => {
|
||||||
|
return this.baseDomain;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function: setBaseDomain
|
||||||
|
*
|
||||||
|
* Sets <baseDomain>.
|
||||||
|
*/
|
||||||
|
setBaseDomain = (value) => {
|
||||||
|
this.baseDomain = value;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function: isRelativeUrl
|
||||||
|
*
|
||||||
|
* Returns true if the given URL is relative.
|
||||||
|
*/
|
||||||
|
isRelativeUrl = (url) => {
|
||||||
|
return url != null && url.substring(0, 2) != '//' && url.substring(0, 7) != 'http://' &&
|
||||||
|
url.substring(0, 8) != 'https://' && url.substring(0, 10) != 'data:image' &&
|
||||||
|
url.substring(0, 7) != 'file://';
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function: convert
|
||||||
|
*
|
||||||
|
* Converts the given URL to an absolute URL with protol and domain.
|
||||||
|
* Relative URLs are first converted to absolute URLs.
|
||||||
|
*/
|
||||||
|
convert = (url) => {
|
||||||
|
if (this.isEnabled() && this.isRelativeUrl(url)) {
|
||||||
|
if (this.getBaseUrl() == null) {
|
||||||
|
this.updateBaseUrl();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (url.charAt(0) == '/') {
|
||||||
|
url = this.getBaseDomain() + url;
|
||||||
|
} else {
|
||||||
|
url = this.getBaseUrl() + url;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
return url;
|
||||||
url = this.getBaseUrl() + url;
|
};
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
export default mxUrlConverter;
|
||||||
return url;
|
|
||||||
};
|
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -2,232 +2,216 @@
|
||||||
* Copyright (c) 2006-2015, JGraph Ltd
|
* Copyright (c) 2006-2015, JGraph Ltd
|
||||||
* Copyright (c) 2006-2015, Gaudenz Alder
|
* Copyright (c) 2006-2015, Gaudenz Alder
|
||||||
*/
|
*/
|
||||||
/**
|
|
||||||
* Class: mxCellOverlay
|
|
||||||
*
|
|
||||||
* Extends <mxEventSource> to implement a graph overlay, represented by an icon
|
|
||||||
* and a tooltip. Overlays can handle and fire <click> events and are added to
|
|
||||||
* the graph using <mxGraph.addCellOverlay>, and removed using
|
|
||||||
* <mxGraph.removeCellOverlay>, or <mxGraph.removeCellOverlays> to remove all overlays.
|
|
||||||
* The <mxGraph.getCellOverlays> function returns the array of overlays for a given
|
|
||||||
* cell in a graph. If multiple overlays exist for the same cell, then
|
|
||||||
* <getBounds> should be overridden in at least one of the overlays.
|
|
||||||
*
|
|
||||||
* Overlays appear on top of all cells in a special layer. If this is not
|
|
||||||
* desirable, then the image must be rendered as part of the shape or label of
|
|
||||||
* the cell instead.
|
|
||||||
*
|
|
||||||
* Example:
|
|
||||||
*
|
|
||||||
* The following adds a new overlays for a given vertex and selects the cell
|
|
||||||
* if the overlay is clicked.
|
|
||||||
*
|
|
||||||
* (code)
|
|
||||||
* var overlay = new mxCellOverlay(img, html);
|
|
||||||
* graph.addCellOverlay(vertex, overlay);
|
|
||||||
* overlay.addListener(mxEvent.CLICK, (sender, evt)=>
|
|
||||||
* {
|
|
||||||
* var cell = evt.getProperty('cell');
|
|
||||||
* graph.setSelectionCell(cell);
|
|
||||||
* });
|
|
||||||
* (end)
|
|
||||||
*
|
|
||||||
* For cell overlays to be printed use <mxPrintPreview.printOverlays>.
|
|
||||||
*
|
|
||||||
* Event: mxEvent.CLICK
|
|
||||||
*
|
|
||||||
* Fires when the user clicks on the overlay. The <code>event</code> property
|
|
||||||
* contains the corresponding mouse event and the <code>cell</code> property
|
|
||||||
* contains the cell. For touch devices this is fired if the element receives
|
|
||||||
* a touchend event.
|
|
||||||
*
|
|
||||||
* Constructor: mxCellOverlay
|
|
||||||
*
|
|
||||||
* Constructs a new overlay using the given image and tooltip.
|
|
||||||
*
|
|
||||||
* Parameters:
|
|
||||||
*
|
|
||||||
* image - <mxImage> that represents the icon to be displayed.
|
|
||||||
* tooltip - Optional string that specifies the tooltip.
|
|
||||||
* align - Optional horizontal alignment for the overlay. Possible
|
|
||||||
* values are <ALIGN_LEFT>, <ALIGN_CENTER> and <ALIGN_RIGHT>
|
|
||||||
* (default).
|
|
||||||
* verticalAlign - Vertical alignment for the overlay. Possible
|
|
||||||
* values are <ALIGN_TOP>, <ALIGN_MIDDLE> and <ALIGN_BOTTOM>
|
|
||||||
* (default).
|
|
||||||
*/
|
|
||||||
function mxCellOverlay(image, tooltip, align, verticalAlign, offset, cursor)
|
|
||||||
{
|
|
||||||
this.image = image;
|
|
||||||
this.tooltip = tooltip;
|
|
||||||
this.align = (align != null) ? align : this.align;
|
|
||||||
this.verticalAlign = (verticalAlign != null) ? verticalAlign : this.verticalAlign;
|
|
||||||
this.offset = (offset != null) ? offset : new mxPoint();
|
|
||||||
this.cursor = (cursor != null) ? cursor : 'help';
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
import mxPoint from "FIXME";
|
||||||
* Extends mxEventSource.
|
import mxRectangle from "../util/mxRectangle";
|
||||||
*/
|
|
||||||
mxCellOverlay.prototype = new mxEventSource();
|
|
||||||
constructor = mxCellOverlay;
|
|
||||||
|
|
||||||
/**
|
class mxCellOverlay extends mxEventSource {
|
||||||
* Variable: image
|
/**
|
||||||
*
|
* Variable: image
|
||||||
* Holds the <mxImage> to be used as the icon.
|
*
|
||||||
*/
|
* Holds the <mxImage> to be used as the icon.
|
||||||
image = null;
|
*/
|
||||||
|
image = null;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Variable: tooltip
|
* Variable: tooltip
|
||||||
*
|
*
|
||||||
* Holds the optional string to be used as the tooltip.
|
* Holds the optional string to be used as the tooltip.
|
||||||
*/
|
*/
|
||||||
tooltip = null;
|
tooltip = null;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Variable: align
|
* Variable: align
|
||||||
*
|
*
|
||||||
* Holds the horizontal alignment for the overlay. Default is
|
* Holds the horizontal alignment for the overlay. Default is
|
||||||
* <mxConstants.ALIGN_RIGHT>. For edges, the overlay always appears in the
|
* <mxConstants.ALIGN_RIGHT>. For edges, the overlay always appears in the
|
||||||
* center of the edge.
|
* center of the edge.
|
||||||
*/
|
*/
|
||||||
align = mxConstants.ALIGN_RIGHT;
|
align = mxConstants.ALIGN_RIGHT;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Variable: verticalAlign
|
* Variable: verticalAlign
|
||||||
*
|
*
|
||||||
* Holds the vertical alignment for the overlay. Default is
|
* Holds the vertical alignment for the overlay. Default is
|
||||||
* <mxConstants.ALIGN_BOTTOM>. For edges, the overlay always appears in the
|
* <mxConstants.ALIGN_BOTTOM>. For edges, the overlay always appears in the
|
||||||
* center of the edge.
|
* center of the edge.
|
||||||
*/
|
*/
|
||||||
verticalAlign = mxConstants.ALIGN_BOTTOM;
|
verticalAlign = mxConstants.ALIGN_BOTTOM;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Variable: offset
|
* Variable: offset
|
||||||
*
|
*
|
||||||
* Holds the offset as an <mxPoint>. The offset will be scaled according to the
|
* Holds the offset as an <mxPoint>. The offset will be scaled according to the
|
||||||
* current scale.
|
* current scale.
|
||||||
*/
|
*/
|
||||||
offset = null;
|
offset = null;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Variable: cursor
|
* Variable: cursor
|
||||||
*
|
*
|
||||||
* Holds the cursor for the overlay. Default is 'help'.
|
* Holds the cursor for the overlay. Default is 'help'.
|
||||||
*/
|
*/
|
||||||
cursor = null;
|
cursor = null;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Variable: defaultOverlap
|
* Variable: defaultOverlap
|
||||||
*
|
*
|
||||||
* Defines the overlapping for the overlay, that is, the proportional distance
|
* Defines the overlapping for the overlay, that is, the proportional distance
|
||||||
* from the origin to the point defined by the alignment. Default is 0.5.
|
* from the origin to the point defined by the alignment. Default is 0.5.
|
||||||
*/
|
*/
|
||||||
defaultOverlap = 0.5;
|
defaultOverlap = 0.5;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function: getBounds
|
* Class: mxCellOverlay
|
||||||
*
|
*
|
||||||
* Returns the bounds of the overlay for the given <mxCellState> as an
|
* Extends <mxEventSource> to implement a graph overlay, represented by an icon
|
||||||
* <mxRectangle>. This should be overridden when using multiple overlays
|
* and a tooltip. Overlays can handle and fire <click> events and are added to
|
||||||
* per cell so that the overlays do not overlap.
|
* the graph using <mxGraph.addCellOverlay>, and removed using
|
||||||
*
|
* <mxGraph.removeCellOverlay>, or <mxGraph.removeCellOverlays> to remove all overlays.
|
||||||
* The following example will place the overlay along an edge (where
|
* The <mxGraph.getCellOverlays> function returns the array of overlays for a given
|
||||||
* x=[-1..1] from the start to the end of the edge and y is the
|
* cell in a graph. If multiple overlays exist for the same cell, then
|
||||||
* orthogonal offset in px).
|
* <getBounds> should be overridden in at least one of the overlays.
|
||||||
*
|
*
|
||||||
* (code)
|
* Overlays appear on top of all cells in a special layer. If this is not
|
||||||
* overlay.getBounds = (state)=>
|
* desirable, then the image must be rendered as part of the shape or label of
|
||||||
* {
|
* the cell instead.
|
||||||
* var bounds = getBounds.apply(this, arguments);
|
*
|
||||||
*
|
* Example:
|
||||||
* if (state.view.graph.getModel().isEdge(state.cell))
|
*
|
||||||
* {
|
* The following adds a new overlays for a given vertex and selects the cell
|
||||||
* var pt = state.view.getPoint(state, {x: 0, y: 0, relative: true});
|
* if the overlay is clicked.
|
||||||
*
|
*
|
||||||
* bounds.x = pt.x - bounds.width / 2;
|
* (code)
|
||||||
* bounds.y = pt.y - bounds.height / 2;
|
* var overlay = new mxCellOverlay(img, html);
|
||||||
* }
|
* graph.addCellOverlay(vertex, overlay);
|
||||||
*
|
* overlay.addListener(mxEvent.CLICK, (sender, evt)=>
|
||||||
* return bounds;
|
* {
|
||||||
* };
|
* var cell = evt.getProperty('cell');
|
||||||
* (end)
|
* graph.setSelectionCell(cell);
|
||||||
*
|
* });
|
||||||
* Parameters:
|
* (end)
|
||||||
*
|
*
|
||||||
* state - <mxCellState> that represents the current state of the
|
* For cell overlays to be printed use <mxPrintPreview.printOverlays>.
|
||||||
* associated cell.
|
*
|
||||||
*/
|
* Event: mxEvent.CLICK
|
||||||
getBounds = (state)=>
|
*
|
||||||
{
|
* Fires when the user clicks on the overlay. The <code>event</code> property
|
||||||
var isEdge = state.view.graph.getModel().isEdge(state.cell);
|
* contains the corresponding mouse event and the <code>cell</code> property
|
||||||
var s = state.view.scale;
|
* contains the cell. For touch devices this is fired if the element receives
|
||||||
var pt = null;
|
* a touchend event.
|
||||||
|
*
|
||||||
|
* Constructor: mxCellOverlay
|
||||||
|
*
|
||||||
|
* Constructs a new overlay using the given image and tooltip.
|
||||||
|
*
|
||||||
|
* Parameters:
|
||||||
|
*
|
||||||
|
* image - <mxImage> that represents the icon to be displayed.
|
||||||
|
* tooltip - Optional string that specifies the tooltip.
|
||||||
|
* align - Optional horizontal alignment for the overlay. Possible
|
||||||
|
* values are <ALIGN_LEFT>, <ALIGN_CENTER> and <ALIGN_RIGHT>
|
||||||
|
* (default).
|
||||||
|
* verticalAlign - Vertical alignment for the overlay. Possible
|
||||||
|
* values are <ALIGN_TOP>, <ALIGN_MIDDLE> and <ALIGN_BOTTOM>
|
||||||
|
* (default).
|
||||||
|
*/
|
||||||
|
constructor(image, tooltip, align, verticalAlign, offset, cursor) {
|
||||||
|
// no super
|
||||||
|
this.image = image;
|
||||||
|
this.tooltip = tooltip;
|
||||||
|
this.align = (align != null) ? align : this.align;
|
||||||
|
this.verticalAlign = (verticalAlign != null) ? verticalAlign : this.verticalAlign;
|
||||||
|
this.offset = (offset != null) ? offset : new mxPoint();
|
||||||
|
this.cursor = (cursor != null) ? cursor : 'help';
|
||||||
|
};
|
||||||
|
|
||||||
var w = this.image.width;
|
/**
|
||||||
var h = this.image.height;
|
* Function: getBounds
|
||||||
|
*
|
||||||
if (isEdge)
|
* Returns the bounds of the overlay for the given <mxCellState> as an
|
||||||
{
|
* <mxRectangle>. This should be overridden when using multiple overlays
|
||||||
var pts = state.absolutePoints;
|
* per cell so that the overlays do not overlap.
|
||||||
|
*
|
||||||
if (pts.length % 2 == 1)
|
* The following example will place the overlay along an edge (where
|
||||||
{
|
* x=[-1..1] from the start to the end of the edge and y is the
|
||||||
pt = pts[Math.floor(pts.length / 2)];
|
* orthogonal offset in px).
|
||||||
|
*
|
||||||
|
* (code)
|
||||||
|
* overlay.getBounds = (state)=>
|
||||||
|
* {
|
||||||
|
* var bounds = getBounds.apply(this, arguments);
|
||||||
|
*
|
||||||
|
* if (state.view.graph.getModel().isEdge(state.cell))
|
||||||
|
* {
|
||||||
|
* var pt = state.view.getPoint(state, {x: 0, y: 0, relative: true});
|
||||||
|
*
|
||||||
|
* bounds.x = pt.x - bounds.width / 2;
|
||||||
|
* bounds.y = pt.y - bounds.height / 2;
|
||||||
|
* }
|
||||||
|
*
|
||||||
|
* return bounds;
|
||||||
|
* };
|
||||||
|
* (end)
|
||||||
|
*
|
||||||
|
* Parameters:
|
||||||
|
*
|
||||||
|
* state - <mxCellState> that represents the current state of the
|
||||||
|
* associated cell.
|
||||||
|
*/
|
||||||
|
getBounds = (state) => {
|
||||||
|
var isEdge = state.view.graph.getModel().isEdge(state.cell);
|
||||||
|
var s = state.view.scale;
|
||||||
|
var pt = null;
|
||||||
|
|
||||||
|
var w = this.image.width;
|
||||||
|
var h = this.image.height;
|
||||||
|
|
||||||
|
if (isEdge) {
|
||||||
|
var pts = state.absolutePoints;
|
||||||
|
|
||||||
|
if (pts.length % 2 === 1) {
|
||||||
|
pt = pts[Math.floor(pts.length / 2)];
|
||||||
|
} else {
|
||||||
|
var idx = pts.length / 2;
|
||||||
|
var p0 = pts[idx - 1];
|
||||||
|
var p1 = pts[idx];
|
||||||
|
pt = new mxPoint(p0.x + (p1.x - p0.x) / 2,
|
||||||
|
p0.y + (p1.y - p0.y) / 2);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
pt = new mxPoint();
|
||||||
|
|
||||||
|
if (this.align === mxConstants.ALIGN_LEFT) {
|
||||||
|
pt.x = state.x;
|
||||||
|
} else if (this.align === mxConstants.ALIGN_CENTER) {
|
||||||
|
pt.x = state.x + state.width / 2;
|
||||||
|
} else {
|
||||||
|
pt.x = state.x + state.width;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.verticalAlign === mxConstants.ALIGN_TOP) {
|
||||||
|
pt.y = state.y;
|
||||||
|
} else if (this.verticalAlign === mxConstants.ALIGN_MIDDLE) {
|
||||||
|
pt.y = state.y + state.height / 2;
|
||||||
|
} else {
|
||||||
|
pt.y = state.y + state.height;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
var idx = pts.length / 2;
|
|
||||||
var p0 = pts[idx-1];
|
|
||||||
var p1 = pts[idx];
|
|
||||||
pt = new mxPoint(p0.x + (p1.x - p0.x) / 2,
|
|
||||||
p0.y + (p1.y - p0.y) / 2);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
pt = new mxPoint();
|
|
||||||
|
|
||||||
if (this.align == mxConstants.ALIGN_LEFT)
|
|
||||||
{
|
|
||||||
pt.x = state.x;
|
|
||||||
}
|
|
||||||
else if (this.align == mxConstants.ALIGN_CENTER)
|
|
||||||
{
|
|
||||||
pt.x = state.x + state.width / 2;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
pt.x = state.x + state.width;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this.verticalAlign == mxConstants.ALIGN_TOP)
|
|
||||||
{
|
|
||||||
pt.y = state.y;
|
|
||||||
}
|
|
||||||
else if (this.verticalAlign == mxConstants.ALIGN_MIDDLE)
|
|
||||||
{
|
|
||||||
pt.y = state.y + state.height / 2;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
pt.y = state.y + state.height;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return new mxRectangle(Math.round(pt.x - (w * this.defaultOverlap - this.offset.x) * s),
|
return new mxRectangle(Math.round(pt.x - (w * this.defaultOverlap - this.offset.x) * s),
|
||||||
Math.round(pt.y - (h * this.defaultOverlap - this.offset.y) * s), w * s, h * s);
|
Math.round(pt.y - (h * this.defaultOverlap - this.offset.y) * s), w * s, h * s);
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function: toString
|
* Function: toString
|
||||||
*
|
*
|
||||||
* Returns the textual representation of the overlay to be used as the
|
* Returns the textual representation of the overlay to be used as the
|
||||||
* tooltip. This implementation returns <tooltip>.
|
* tooltip. This implementation returns <tooltip>.
|
||||||
*/
|
*/
|
||||||
toString = ()=>
|
toString = () => {
|
||||||
{
|
return this.tooltip;
|
||||||
return this.tooltip;
|
};
|
||||||
};
|
}
|
||||||
|
|
||||||
|
export default mxCellOverlay;
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -2,446 +2,411 @@
|
||||||
* Copyright (c) 2006-2015, JGraph Ltd
|
* Copyright (c) 2006-2015, JGraph Ltd
|
||||||
* Copyright (c) 2006-2015, Gaudenz Alder
|
* Copyright (c) 2006-2015, Gaudenz Alder
|
||||||
*/
|
*/
|
||||||
/**
|
|
||||||
* Class: mxCellState
|
|
||||||
*
|
|
||||||
* Represents the current state of a cell in a given <mxGraphView>.
|
|
||||||
*
|
|
||||||
* For edges, the edge label position is stored in <absoluteOffset>.
|
|
||||||
*
|
|
||||||
* The size for oversize labels can be retrieved using the boundingBox property
|
|
||||||
* of the <text> field as shown below.
|
|
||||||
*
|
|
||||||
* (code)
|
|
||||||
* var bbox = (state.text != null) ? state.text.boundingBox : null;
|
|
||||||
* (end)
|
|
||||||
*
|
|
||||||
* Constructor: mxCellState
|
|
||||||
*
|
|
||||||
* Constructs a new object that represents the current state of the given
|
|
||||||
* cell in the specified view.
|
|
||||||
*
|
|
||||||
* Parameters:
|
|
||||||
*
|
|
||||||
* view - <mxGraphView> that contains the state.
|
|
||||||
* cell - <mxCell> that this state represents.
|
|
||||||
* style - Array of key, value pairs that constitute the style.
|
|
||||||
*/
|
|
||||||
function mxCellState(view, cell, style)
|
|
||||||
{
|
|
||||||
this.view = view;
|
|
||||||
this.cell = cell;
|
|
||||||
this.style = (style != null) ? style : {};
|
|
||||||
|
|
||||||
this.origin = new mxPoint();
|
|
||||||
this.absoluteOffset = new mxPoint();
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
import mxPoint from "../util/mxPoint";
|
||||||
* Extends mxRectangle.
|
import mxRectangle from "../util/mxRectangle";
|
||||||
*/
|
|
||||||
mxCellState.prototype = new mxRectangle();
|
|
||||||
constructor = mxCellState;
|
|
||||||
|
|
||||||
/**
|
class mxCellState extends mxRectangle {
|
||||||
* Variable: view
|
/**
|
||||||
*
|
* Variable: view
|
||||||
* Reference to the enclosing <mxGraphView>.
|
*
|
||||||
*/
|
* Reference to the enclosing <mxGraphView>.
|
||||||
view = null;
|
*/
|
||||||
|
view = null;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Variable: cell
|
* Variable: cell
|
||||||
*
|
*
|
||||||
* Reference to the <mxCell> that is represented by this state.
|
* Reference to the <mxCell> that is represented by this state.
|
||||||
*/
|
*/
|
||||||
cell = null;
|
cell = null;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Variable: style
|
* Variable: style
|
||||||
*
|
*
|
||||||
* Contains an array of key, value pairs that represent the style of the
|
* Contains an array of key, value pairs that represent the style of the
|
||||||
* cell.
|
* cell.
|
||||||
*/
|
*/
|
||||||
style = null;
|
style = null;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Variable: invalidStyle
|
* Variable: invalidStyle
|
||||||
*
|
*
|
||||||
* Specifies if the style is invalid. Default is false.
|
* Specifies if the style is invalid. Default is false.
|
||||||
*/
|
*/
|
||||||
invalidStyle = false;
|
invalidStyle = false;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Variable: invalid
|
* Variable: invalid
|
||||||
*
|
*
|
||||||
* Specifies if the state is invalid. Default is true.
|
* Specifies if the state is invalid. Default is true.
|
||||||
*/
|
*/
|
||||||
invalid = true;
|
invalid = true;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Variable: origin
|
* Variable: origin
|
||||||
*
|
*
|
||||||
* <mxPoint> that holds the origin for all child cells. Default is a new
|
* <mxPoint> that holds the origin for all child cells. Default is a new
|
||||||
* empty <mxPoint>.
|
* empty <mxPoint>.
|
||||||
*/
|
*/
|
||||||
origin = null;
|
origin = null;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Variable: absolutePoints
|
* Variable: absolutePoints
|
||||||
*
|
*
|
||||||
* Holds an array of <mxPoints> that represent the absolute points of an
|
* Holds an array of <mxPoints> that represent the absolute points of an
|
||||||
* edge.
|
* edge.
|
||||||
*/
|
*/
|
||||||
absolutePoints = null;
|
absolutePoints = null;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Variable: absoluteOffset
|
* Variable: absoluteOffset
|
||||||
*
|
*
|
||||||
* <mxPoint> that holds the absolute offset. For edges, this is the
|
* <mxPoint> that holds the absolute offset. For edges, this is the
|
||||||
* absolute coordinates of the label position. For vertices, this is the
|
* absolute coordinates of the label position. For vertices, this is the
|
||||||
* offset of the label relative to the top, left corner of the vertex.
|
* offset of the label relative to the top, left corner of the vertex.
|
||||||
*/
|
*/
|
||||||
absoluteOffset = null;
|
absoluteOffset = null;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Variable: visibleSourceState
|
* Variable: visibleSourceState
|
||||||
*
|
*
|
||||||
* Caches the visible source terminal state.
|
* Caches the visible source terminal state.
|
||||||
*/
|
*/
|
||||||
visibleSourceState = null;
|
visibleSourceState = null;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Variable: visibleTargetState
|
* Variable: visibleTargetState
|
||||||
*
|
*
|
||||||
* Caches the visible target terminal state.
|
* Caches the visible target terminal state.
|
||||||
*/
|
*/
|
||||||
visibleTargetState = null;
|
visibleTargetState = null;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Variable: terminalDistance
|
* Variable: terminalDistance
|
||||||
*
|
*
|
||||||
* Caches the distance between the end points for an edge.
|
* Caches the distance between the end points for an edge.
|
||||||
*/
|
*/
|
||||||
terminalDistance = 0;
|
terminalDistance = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Variable: length
|
* Variable: length
|
||||||
*
|
*
|
||||||
* Caches the length of an edge.
|
* Caches the length of an edge.
|
||||||
*/
|
*/
|
||||||
length = 0;
|
length = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Variable: segments
|
* Variable: segments
|
||||||
*
|
*
|
||||||
* Array of numbers that represent the cached length of each segment of the
|
* Array of numbers that represent the cached length of each segment of the
|
||||||
* edge.
|
* edge.
|
||||||
*/
|
*/
|
||||||
segments = null;
|
segments = null;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Variable: shape
|
* Variable: shape
|
||||||
*
|
*
|
||||||
* Holds the <mxShape> that represents the cell graphically.
|
* Holds the <mxShape> that represents the cell graphically.
|
||||||
*/
|
*/
|
||||||
shape = null;
|
shape = null;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Variable: text
|
* Variable: text
|
||||||
*
|
*
|
||||||
* Holds the <mxText> that represents the label of the cell. Thi smay be
|
* Holds the <mxText> that represents the label of the cell. Thi smay be
|
||||||
* null if the cell has no label.
|
* null if the cell has no label.
|
||||||
*/
|
*/
|
||||||
text = null;
|
text = null;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Variable: unscaledWidth
|
* Variable: unscaledWidth
|
||||||
*
|
*
|
||||||
* Holds the unscaled width of the state.
|
* Holds the unscaled width of the state.
|
||||||
*/
|
*/
|
||||||
unscaledWidth = null;
|
unscaledWidth = null;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Variable: unscaledHeight
|
* Variable: unscaledHeight
|
||||||
*
|
*
|
||||||
* Holds the unscaled height of the state.
|
* Holds the unscaled height of the state.
|
||||||
*/
|
*/
|
||||||
unscaledHeight = null;
|
unscaledHeight = null;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function: getPerimeterBounds
|
* Class: mxCellState
|
||||||
*
|
*
|
||||||
* Returns the <mxRectangle> that should be used as the perimeter of the
|
* Represents the current state of a cell in a given <mxGraphView>.
|
||||||
* cell.
|
*
|
||||||
*
|
* For edges, the edge label position is stored in <absoluteOffset>.
|
||||||
* Parameters:
|
*
|
||||||
*
|
* The size for oversize labels can be retrieved using the boundingBox property
|
||||||
* border - Optional border to be added around the perimeter bounds.
|
* of the <text> field as shown below.
|
||||||
* bounds - Optional <mxRectangle> to be used as the initial bounds.
|
*
|
||||||
*/
|
* (code)
|
||||||
getPerimeterBounds = (border, bounds)=>
|
* var bbox = (state.text != null) ? state.text.boundingBox : null;
|
||||||
{
|
* (end)
|
||||||
border = border || 0;
|
*
|
||||||
bounds = (bounds != null) ? bounds : new mxRectangle(this.x, this.y, this.width, this.height);
|
* Constructor: mxCellState
|
||||||
|
*
|
||||||
if (this.shape != null && this.shape.stencil != null && this.shape.stencil.aspect == 'fixed')
|
* Constructs a new object that represents the current state of the given
|
||||||
{
|
* cell in the specified view.
|
||||||
var aspect = this.shape.stencil.computeAspect(this.style, bounds.x, bounds.y, bounds.width, bounds.height);
|
*
|
||||||
|
* Parameters:
|
||||||
bounds.x = aspect.x;
|
*
|
||||||
bounds.y = aspect.y;
|
* view - <mxGraphView> that contains the state.
|
||||||
bounds.width = this.shape.stencil.w0 * aspect.width;
|
* cell - <mxCell> that this state represents.
|
||||||
bounds.height = this.shape.stencil.h0 * aspect.height;
|
* style - Array of key, value pairs that constitute the style.
|
||||||
}
|
*/
|
||||||
|
constructor(view, cell, style) {
|
||||||
if (border != 0)
|
// no super
|
||||||
{
|
this.view = view;
|
||||||
bounds.grow(border);
|
this.cell = cell;
|
||||||
}
|
this.style = (style != null) ? style : {};
|
||||||
|
|
||||||
return bounds;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
this.origin = new mxPoint();
|
||||||
* Function: setAbsoluteTerminalPoint
|
this.absoluteOffset = new mxPoint();
|
||||||
*
|
};
|
||||||
* Sets the first or last point in <absolutePoints> depending on isSource.
|
|
||||||
*
|
/**
|
||||||
* Parameters:
|
* Function: getPerimeterBounds
|
||||||
*
|
*
|
||||||
* point - <mxPoint> that represents the terminal point.
|
* Returns the <mxRectangle> that should be used as the perimeter of the
|
||||||
* isSource - Boolean that specifies if the first or last point should
|
* cell.
|
||||||
* be assigned.
|
*
|
||||||
*/
|
* Parameters:
|
||||||
setAbsoluteTerminalPoint = (point, isSource)=>
|
*
|
||||||
{
|
* border - Optional border to be added around the perimeter bounds.
|
||||||
if (isSource)
|
* bounds - Optional <mxRectangle> to be used as the initial bounds.
|
||||||
{
|
*/
|
||||||
if (this.absolutePoints == null)
|
getPerimeterBounds = (border, bounds) => {
|
||||||
{
|
border = border || 0;
|
||||||
this.absolutePoints = [];
|
bounds = (bounds != null) ? bounds : new mxRectangle(this.x, this.y, this.width, this.height);
|
||||||
|
|
||||||
|
if (this.shape != null && this.shape.stencil != null && this.shape.stencil.aspect === 'fixed') {
|
||||||
|
var aspect = this.shape.stencil.computeAspect(this.style, bounds.x, bounds.y, bounds.width, bounds.height);
|
||||||
|
|
||||||
|
bounds.x = aspect.x;
|
||||||
|
bounds.y = aspect.y;
|
||||||
|
bounds.width = this.shape.stencil.w0 * aspect.width;
|
||||||
|
bounds.height = this.shape.stencil.h0 * aspect.height;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.absolutePoints.length == 0)
|
if (border !== 0) {
|
||||||
{
|
bounds.grow(border);
|
||||||
this.absolutePoints.push(point);
|
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
return bounds;
|
||||||
this.absolutePoints[0] = point;
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function: setAbsoluteTerminalPoint
|
||||||
|
*
|
||||||
|
* Sets the first or last point in <absolutePoints> depending on isSource.
|
||||||
|
*
|
||||||
|
* Parameters:
|
||||||
|
*
|
||||||
|
* point - <mxPoint> that represents the terminal point.
|
||||||
|
* isSource - Boolean that specifies if the first or last point should
|
||||||
|
* be assigned.
|
||||||
|
*/
|
||||||
|
setAbsoluteTerminalPoint = (point, isSource) => {
|
||||||
|
if (isSource) {
|
||||||
|
if (this.absolutePoints == null) {
|
||||||
|
this.absolutePoints = [];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.absolutePoints.length === 0) {
|
||||||
|
this.absolutePoints.push(point);
|
||||||
|
} else {
|
||||||
|
this.absolutePoints[0] = point;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (this.absolutePoints == null) {
|
||||||
|
this.absolutePoints = [];
|
||||||
|
this.absolutePoints.push(null);
|
||||||
|
this.absolutePoints.push(point);
|
||||||
|
} else if (this.absolutePoints.length === 1) {
|
||||||
|
this.absolutePoints.push(point);
|
||||||
|
} else {
|
||||||
|
this.absolutePoints[this.absolutePoints.length - 1] = point;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
else
|
|
||||||
{
|
/**
|
||||||
if (this.absolutePoints == null)
|
* Function: setCursor
|
||||||
{
|
*
|
||||||
this.absolutePoints = [];
|
* Sets the given cursor on the shape and text shape.
|
||||||
this.absolutePoints.push(null);
|
*/
|
||||||
this.absolutePoints.push(point);
|
setCursor = (cursor) => {
|
||||||
|
if (this.shape != null) {
|
||||||
|
this.shape.setCursor(cursor);
|
||||||
}
|
}
|
||||||
else if (this.absolutePoints.length == 1)
|
|
||||||
{
|
if (this.text != null) {
|
||||||
this.absolutePoints.push(point);
|
this.text.setCursor(cursor);
|
||||||
}
|
}
|
||||||
else
|
};
|
||||||
{
|
|
||||||
this.absolutePoints[this.absolutePoints.length - 1] = point;
|
/**
|
||||||
|
* Function: getVisibleTerminal
|
||||||
|
*
|
||||||
|
* Returns the visible source or target terminal cell.
|
||||||
|
*
|
||||||
|
* Parameters:
|
||||||
|
*
|
||||||
|
* source - Boolean that specifies if the source or target cell should be
|
||||||
|
* returned.
|
||||||
|
*/
|
||||||
|
getVisibleTerminal = (source) => {
|
||||||
|
var tmp = this.getVisibleTerminalState(source);
|
||||||
|
|
||||||
|
return (tmp != null) ? tmp.cell : null;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function: getVisibleTerminalState
|
||||||
|
*
|
||||||
|
* Returns the visible source or target terminal state.
|
||||||
|
*
|
||||||
|
* Parameters:
|
||||||
|
*
|
||||||
|
* source - Boolean that specifies if the source or target state should be
|
||||||
|
* returned.
|
||||||
|
*/
|
||||||
|
getVisibleTerminalState = (source) => {
|
||||||
|
return (source) ? this.visibleSourceState : this.visibleTargetState;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function: setVisibleTerminalState
|
||||||
|
*
|
||||||
|
* Sets the visible source or target terminal state.
|
||||||
|
*
|
||||||
|
* Parameters:
|
||||||
|
*
|
||||||
|
* terminalState - <mxCellState> that represents the terminal.
|
||||||
|
* source - Boolean that specifies if the source or target state should be set.
|
||||||
|
*/
|
||||||
|
setVisibleTerminalState = (terminalState, source) => {
|
||||||
|
if (source) {
|
||||||
|
this.visibleSourceState = terminalState;
|
||||||
|
} else {
|
||||||
|
this.visibleTargetState = terminalState;
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function: setCursor
|
* Function: getCellBounds
|
||||||
*
|
*
|
||||||
* Sets the given cursor on the shape and text shape.
|
* Returns the unscaled, untranslated bounds.
|
||||||
*/
|
*/
|
||||||
setCursor = (cursor)=>
|
getCellBounds = () => {
|
||||||
{
|
return this.cellBounds;
|
||||||
if (this.shape != null)
|
};
|
||||||
{
|
|
||||||
this.shape.setCursor(cursor);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this.text != null)
|
|
||||||
{
|
|
||||||
this.text.setCursor(cursor);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function: getVisibleTerminal
|
* Function: getPaintBounds
|
||||||
*
|
*
|
||||||
* Returns the visible source or target terminal cell.
|
* Returns the unscaled, untranslated paint bounds. This is the same as
|
||||||
*
|
* <getCellBounds> but with a 90 degree rotation if the shape's
|
||||||
* Parameters:
|
* isPaintBoundsInverted returns true.
|
||||||
*
|
*/
|
||||||
* source - Boolean that specifies if the source or target cell should be
|
getPaintBounds = () => {
|
||||||
* returned.
|
return this.paintBounds;
|
||||||
*/
|
};
|
||||||
getVisibleTerminal = (source)=>
|
|
||||||
{
|
|
||||||
var tmp = this.getVisibleTerminalState(source);
|
|
||||||
|
|
||||||
return (tmp != null) ? tmp.cell : null;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function: getVisibleTerminalState
|
* Function: updateCachedBounds
|
||||||
*
|
*
|
||||||
* Returns the visible source or target terminal state.
|
* Updates the cellBounds and paintBounds.
|
||||||
*
|
*/
|
||||||
* Parameters:
|
updateCachedBounds = () => {
|
||||||
*
|
var tr = this.view.translate;
|
||||||
* source - Boolean that specifies if the source or target state should be
|
var s = this.view.scale;
|
||||||
* returned.
|
this.cellBounds = new mxRectangle(this.x / s - tr.x, this.y / s - tr.y, this.width / s, this.height / s);
|
||||||
*/
|
this.paintBounds = mxRectangle.fromRectangle(this.cellBounds);
|
||||||
getVisibleTerminalState = (source)=>
|
|
||||||
{
|
|
||||||
return (source) ? this.visibleSourceState : this.visibleTargetState;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
if (this.shape != null && this.shape.isPaintBoundsInverted()) {
|
||||||
* Function: setVisibleTerminalState
|
this.paintBounds.rotate90();
|
||||||
*
|
|
||||||
* Sets the visible source or target terminal state.
|
|
||||||
*
|
|
||||||
* Parameters:
|
|
||||||
*
|
|
||||||
* terminalState - <mxCellState> that represents the terminal.
|
|
||||||
* source - Boolean that specifies if the source or target state should be set.
|
|
||||||
*/
|
|
||||||
setVisibleTerminalState = (terminalState, source)=>
|
|
||||||
{
|
|
||||||
if (source)
|
|
||||||
{
|
|
||||||
this.visibleSourceState = terminalState;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
this.visibleTargetState = terminalState;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Function: getCellBounds
|
|
||||||
*
|
|
||||||
* Returns the unscaled, untranslated bounds.
|
|
||||||
*/
|
|
||||||
getCellBounds = ()=>
|
|
||||||
{
|
|
||||||
return this.cellBounds;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Function: getPaintBounds
|
|
||||||
*
|
|
||||||
* Returns the unscaled, untranslated paint bounds. This is the same as
|
|
||||||
* <getCellBounds> but with a 90 degree rotation if the shape's
|
|
||||||
* isPaintBoundsInverted returns true.
|
|
||||||
*/
|
|
||||||
getPaintBounds = ()=>
|
|
||||||
{
|
|
||||||
return this.paintBounds;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Function: updateCachedBounds
|
|
||||||
*
|
|
||||||
* Updates the cellBounds and paintBounds.
|
|
||||||
*/
|
|
||||||
updateCachedBounds = ()=>
|
|
||||||
{
|
|
||||||
var tr = this.view.translate;
|
|
||||||
var s = this.view.scale;
|
|
||||||
this.cellBounds = new mxRectangle(this.x / s - tr.x, this.y / s - tr.y, this.width / s, this.height / s);
|
|
||||||
this.paintBounds = mxRectangle.fromRectangle(this.cellBounds);
|
|
||||||
|
|
||||||
if (this.shape != null && this.shape.isPaintBoundsInverted())
|
|
||||||
{
|
|
||||||
this.paintBounds.rotate90();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Destructor: setState
|
|
||||||
*
|
|
||||||
* Copies all fields from the given state to this state.
|
|
||||||
*/
|
|
||||||
setState = (state)=>
|
|
||||||
{
|
|
||||||
this.view = state.view;
|
|
||||||
this.cell = state.cell;
|
|
||||||
this.style = state.style;
|
|
||||||
this.absolutePoints = state.absolutePoints;
|
|
||||||
this.origin = state.origin;
|
|
||||||
this.absoluteOffset = state.absoluteOffset;
|
|
||||||
this.boundingBox = state.boundingBox;
|
|
||||||
this.terminalDistance = state.terminalDistance;
|
|
||||||
this.segments = state.segments;
|
|
||||||
this.length = state.length;
|
|
||||||
this.x = state.x;
|
|
||||||
this.y = state.y;
|
|
||||||
this.width = state.width;
|
|
||||||
this.height = state.height;
|
|
||||||
this.unscaledWidth = state.unscaledWidth;
|
|
||||||
this.unscaledHeight = state.unscaledHeight;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Function: clone
|
|
||||||
*
|
|
||||||
* Returns a clone of this <mxPoint>.
|
|
||||||
*/
|
|
||||||
clone = ()=>
|
|
||||||
{
|
|
||||||
var clone = new mxCellState(this.view, this.cell, this.style);
|
|
||||||
|
|
||||||
// Clones the absolute points
|
|
||||||
if (this.absolutePoints != null)
|
|
||||||
{
|
|
||||||
clone.absolutePoints = [];
|
|
||||||
|
|
||||||
for (var i = 0; i < this.absolutePoints.length; i++)
|
|
||||||
{
|
|
||||||
clone.absolutePoints[i] = this.absolutePoints[i].clone();
|
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
if (this.origin != null)
|
/**
|
||||||
{
|
* Destructor: setState
|
||||||
clone.origin = this.origin.clone();
|
*
|
||||||
}
|
* Copies all fields from the given state to this state.
|
||||||
|
*/
|
||||||
|
setState = (state) => {
|
||||||
|
this.view = state.view;
|
||||||
|
this.cell = state.cell;
|
||||||
|
this.style = state.style;
|
||||||
|
this.absolutePoints = state.absolutePoints;
|
||||||
|
this.origin = state.origin;
|
||||||
|
this.absoluteOffset = state.absoluteOffset;
|
||||||
|
this.boundingBox = state.boundingBox;
|
||||||
|
this.terminalDistance = state.terminalDistance;
|
||||||
|
this.segments = state.segments;
|
||||||
|
this.length = state.length;
|
||||||
|
this.x = state.x;
|
||||||
|
this.y = state.y;
|
||||||
|
this.width = state.width;
|
||||||
|
this.height = state.height;
|
||||||
|
this.unscaledWidth = state.unscaledWidth;
|
||||||
|
this.unscaledHeight = state.unscaledHeight;
|
||||||
|
};
|
||||||
|
|
||||||
if (this.absoluteOffset != null)
|
/**
|
||||||
{
|
* Function: clone
|
||||||
clone.absoluteOffset = this.absoluteOffset.clone();
|
*
|
||||||
}
|
* Returns a clone of this <mxPoint>.
|
||||||
|
*/
|
||||||
|
clone = () => {
|
||||||
|
var clone = new mxCellState(this.view, this.cell, this.style);
|
||||||
|
|
||||||
if (this.boundingBox != null)
|
// Clones the absolute points
|
||||||
{
|
if (this.absolutePoints != null) {
|
||||||
clone.boundingBox = this.boundingBox.clone();
|
clone.absolutePoints = [];
|
||||||
}
|
|
||||||
|
|
||||||
clone.terminalDistance = this.terminalDistance;
|
for (var i = 0; i < this.absolutePoints.length; i++) {
|
||||||
clone.segments = this.segments;
|
clone.absolutePoints[i] = this.absolutePoints[i].clone();
|
||||||
clone.length = this.length;
|
}
|
||||||
clone.x = this.x;
|
}
|
||||||
clone.y = this.y;
|
|
||||||
clone.width = this.width;
|
|
||||||
clone.height = this.height;
|
|
||||||
clone.unscaledWidth = this.unscaledWidth;
|
|
||||||
clone.unscaledHeight = this.unscaledHeight;
|
|
||||||
|
|
||||||
return clone;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
if (this.origin != null) {
|
||||||
* Destructor: destroy
|
clone.origin = this.origin.clone();
|
||||||
*
|
}
|
||||||
* Destroys the state and all associated resources.
|
|
||||||
*/
|
if (this.absoluteOffset != null) {
|
||||||
destroy = ()=>
|
clone.absoluteOffset = this.absoluteOffset.clone();
|
||||||
{
|
}
|
||||||
this.view.graph.cellRenderer.destroy(this);
|
|
||||||
};
|
if (this.boundingBox != null) {
|
||||||
|
clone.boundingBox = this.boundingBox.clone();
|
||||||
|
}
|
||||||
|
|
||||||
|
clone.terminalDistance = this.terminalDistance;
|
||||||
|
clone.segments = this.segments;
|
||||||
|
clone.length = this.length;
|
||||||
|
clone.x = this.x;
|
||||||
|
clone.y = this.y;
|
||||||
|
clone.width = this.width;
|
||||||
|
clone.height = this.height;
|
||||||
|
clone.unscaledWidth = this.unscaledWidth;
|
||||||
|
clone.unscaledHeight = this.unscaledHeight;
|
||||||
|
|
||||||
|
return clone;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Destructor: destroy
|
||||||
|
*
|
||||||
|
* Destroys the state and all associated resources.
|
||||||
|
*/
|
||||||
|
destroy = () => {
|
||||||
|
this.view.graph.cellRenderer.destroy(this);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export default mxCellState;
|
||||||
|
|
|
@ -2,202 +2,185 @@
|
||||||
* Copyright (c) 2006-2015, JGraph Ltd
|
* Copyright (c) 2006-2015, JGraph Ltd
|
||||||
* Copyright (c) 2006-2015, Gaudenz Alder
|
* Copyright (c) 2006-2015, Gaudenz Alder
|
||||||
*/
|
*/
|
||||||
/**
|
|
||||||
*
|
|
||||||
* Class: mxCellStatePreview
|
|
||||||
*
|
|
||||||
* Implements a live preview for moving cells.
|
|
||||||
*
|
|
||||||
* Constructor: mxCellStatePreview
|
|
||||||
*
|
|
||||||
* Constructs a move preview for the given graph.
|
|
||||||
*
|
|
||||||
* Parameters:
|
|
||||||
*
|
|
||||||
* graph - Reference to the enclosing <mxGraph>.
|
|
||||||
*/
|
|
||||||
function mxCellStatePreview(graph)
|
|
||||||
{
|
|
||||||
this.deltas = new mxDictionary();
|
|
||||||
this.graph = graph;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
import mxUtils from "../util/mxUtils";
|
||||||
* Variable: graph
|
import mxPoint from "../util/mxPoint";
|
||||||
*
|
import mxDictionary from "../util/mxDictionary";
|
||||||
* Reference to the enclosing <mxGraph>.
|
|
||||||
*/
|
|
||||||
graph = null;
|
|
||||||
|
|
||||||
/**
|
class mxCellStatePreview {
|
||||||
* Variable: deltas
|
/**
|
||||||
*
|
* Variable: graph
|
||||||
* Reference to the enclosing <mxGraph>.
|
*
|
||||||
*/
|
* Reference to the enclosing <mxGraph>.
|
||||||
deltas = null;
|
*/
|
||||||
|
graph = null;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Variable: count
|
* Variable: deltas
|
||||||
*
|
*
|
||||||
* Contains the number of entries in the map.
|
* Reference to the enclosing <mxGraph>.
|
||||||
*/
|
*/
|
||||||
count = 0;
|
deltas = null;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function: isEmpty
|
* Variable: count
|
||||||
*
|
*
|
||||||
* Returns true if this contains no entries.
|
* Contains the number of entries in the map.
|
||||||
*/
|
*/
|
||||||
isEmpty = ()=>
|
count = 0;
|
||||||
{
|
|
||||||
return this.count == 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function: moveState
|
*
|
||||||
*/
|
* Class: mxCellStatePreview
|
||||||
moveState = (state, dx, dy, add, includeEdges)=>
|
*
|
||||||
{
|
* Implements a live preview for moving cells.
|
||||||
add = (add != null) ? add : true;
|
*
|
||||||
includeEdges = (includeEdges != null) ? includeEdges : true;
|
* Constructor: mxCellStatePreview
|
||||||
|
*
|
||||||
var delta = this.deltas.get(state.cell);
|
* Constructs a move preview for the given graph.
|
||||||
|
*
|
||||||
|
* Parameters:
|
||||||
|
*
|
||||||
|
* graph - Reference to the enclosing <mxGraph>.
|
||||||
|
*/
|
||||||
|
constructor(graph) {
|
||||||
|
this.deltas = new mxDictionary();
|
||||||
|
this.graph = graph;
|
||||||
|
};
|
||||||
|
|
||||||
if (delta == null)
|
/**
|
||||||
{
|
* Function: isEmpty
|
||||||
// Note: Deltas stores the point and the state since the key is a string.
|
*
|
||||||
delta = {point: new mxPoint(dx, dy), state: state};
|
* Returns true if this contains no entries.
|
||||||
this.deltas.put(state.cell, delta);
|
*/
|
||||||
this.count++;
|
isEmpty = () => {
|
||||||
}
|
return this.count === 0;
|
||||||
else if (add)
|
};
|
||||||
{
|
|
||||||
delta.point.x += dx;
|
|
||||||
delta.point.y += dy;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
delta.point.x = dx;
|
|
||||||
delta.point.y = dy;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (includeEdges)
|
|
||||||
{
|
|
||||||
this.addEdges(state);
|
|
||||||
}
|
|
||||||
|
|
||||||
return delta.point;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function: show
|
* Function: moveState
|
||||||
*/
|
*/
|
||||||
show = (visitor)=>
|
moveState = (state, dx, dy, add, includeEdges) => {
|
||||||
{
|
add = (add != null) ? add : true;
|
||||||
this.deltas.visit(mxUtils.bind(this, (key, delta)=>
|
includeEdges = (includeEdges != null) ? includeEdges : true;
|
||||||
{
|
|
||||||
this.translateState(delta.state, delta.point.x, delta.point.y);
|
|
||||||
}));
|
|
||||||
|
|
||||||
this.deltas.visit(mxUtils.bind(this, (key, delta)=>
|
|
||||||
{
|
|
||||||
this.revalidateState(delta.state, delta.point.x, delta.point.y, visitor);
|
|
||||||
}));
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
var delta = this.deltas.get(state.cell);
|
||||||
* Function: translateState
|
|
||||||
*/
|
if (delta == null) {
|
||||||
translateState = (state, dx, dy)=>
|
// Note: Deltas stores the point and the state since the key is a string.
|
||||||
{
|
delta = {point: new mxPoint(dx, dy), state: state};
|
||||||
if (state != null)
|
this.deltas.put(state.cell, delta);
|
||||||
{
|
this.count++;
|
||||||
var model = this.graph.getModel();
|
} else if (add) {
|
||||||
|
delta.point.x += dx;
|
||||||
if (model.isVertex(state.cell))
|
delta.point.y += dy;
|
||||||
{
|
} else {
|
||||||
state.view.updateCellState(state);
|
delta.point.x = dx;
|
||||||
var geo = model.getGeometry(state.cell);
|
delta.point.y = dy;
|
||||||
|
}
|
||||||
// Moves selection cells and non-relative vertices in
|
|
||||||
// the first phase so that edge terminal points will
|
if (includeEdges) {
|
||||||
// be updated in the second phase
|
this.addEdges(state);
|
||||||
if ((dx != 0 || dy != 0) && geo != null && (!geo.relative || this.deltas.get(state.cell) != null))
|
}
|
||||||
{
|
|
||||||
|
return delta.point;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function: show
|
||||||
|
*/
|
||||||
|
show = (visitor) => {
|
||||||
|
this.deltas.visit(mxUtils.bind(this, (key, delta) => {
|
||||||
|
this.translateState(delta.state, delta.point.x, delta.point.y);
|
||||||
|
}));
|
||||||
|
|
||||||
|
this.deltas.visit(mxUtils.bind(this, (key, delta) => {
|
||||||
|
this.revalidateState(delta.state, delta.point.x, delta.point.y, visitor);
|
||||||
|
}));
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function: translateState
|
||||||
|
*/
|
||||||
|
translateState = (state, dx, dy) => {
|
||||||
|
if (state != null) {
|
||||||
|
var model = this.graph.getModel();
|
||||||
|
|
||||||
|
if (model.isVertex(state.cell)) {
|
||||||
|
state.view.updateCellState(state);
|
||||||
|
var geo = model.getGeometry(state.cell);
|
||||||
|
|
||||||
|
// Moves selection cells and non-relative vertices in
|
||||||
|
// the first phase so that edge terminal points will
|
||||||
|
// be updated in the second phase
|
||||||
|
if ((dx != 0 || dy != 0) && geo != null && (!geo.relative || this.deltas.get(state.cell) != null)) {
|
||||||
|
state.x += dx;
|
||||||
|
state.y += dy;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var childCount = model.getChildCount(state.cell);
|
||||||
|
|
||||||
|
for (var i = 0; i < childCount; i++) {
|
||||||
|
this.translateState(state.view.getState(model.getChildAt(state.cell, i)), dx, dy);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function: revalidateState
|
||||||
|
*/
|
||||||
|
revalidateState = (state, dx, dy, visitor) => {
|
||||||
|
if (state != null) {
|
||||||
|
var model = this.graph.getModel();
|
||||||
|
|
||||||
|
// Updates the edge terminal points and restores the
|
||||||
|
// (relative) positions of any (relative) children
|
||||||
|
if (model.isEdge(state.cell)) {
|
||||||
|
state.view.updateCellState(state);
|
||||||
|
}
|
||||||
|
|
||||||
|
var geo = this.graph.getCellGeometry(state.cell);
|
||||||
|
var pState = state.view.getState(model.getParent(state.cell));
|
||||||
|
|
||||||
|
// Moves selection vertices which are relative
|
||||||
|
if ((dx != 0 || dy != 0) && geo != null && geo.relative &&
|
||||||
|
model.isVertex(state.cell) && (pState == null ||
|
||||||
|
model.isVertex(pState.cell) || this.deltas.get(state.cell) != null)) {
|
||||||
state.x += dx;
|
state.x += dx;
|
||||||
state.y += dy;
|
state.y += dy;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
this.graph.cellRenderer.redraw(state);
|
||||||
var childCount = model.getChildCount(state.cell);
|
|
||||||
|
// Invokes the visitor on the given state
|
||||||
for (var i = 0; i < childCount; i++)
|
if (visitor != null) {
|
||||||
{
|
visitor(state);
|
||||||
this.translateState(state.view.getState(model.getChildAt(state.cell, i)), dx, dy);
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Function: revalidateState
|
|
||||||
*/
|
|
||||||
revalidateState = (state, dx, dy, visitor)=>
|
|
||||||
{
|
|
||||||
if (state != null)
|
|
||||||
{
|
|
||||||
var model = this.graph.getModel();
|
|
||||||
|
|
||||||
// Updates the edge terminal points and restores the
|
|
||||||
// (relative) positions of any (relative) children
|
|
||||||
if (model.isEdge(state.cell))
|
|
||||||
{
|
|
||||||
state.view.updateCellState(state);
|
|
||||||
}
|
|
||||||
|
|
||||||
var geo = this.graph.getCellGeometry(state.cell);
|
|
||||||
var pState = state.view.getState(model.getParent(state.cell));
|
|
||||||
|
|
||||||
// Moves selection vertices which are relative
|
|
||||||
if ((dx != 0 || dy != 0) && geo != null && geo.relative &&
|
|
||||||
model.isVertex(state.cell) && (pState == null ||
|
|
||||||
model.isVertex(pState.cell) || this.deltas.get(state.cell) != null))
|
|
||||||
{
|
|
||||||
state.x += dx;
|
|
||||||
state.y += dy;
|
|
||||||
}
|
|
||||||
|
|
||||||
this.graph.cellRenderer.redraw(state);
|
|
||||||
|
|
||||||
// Invokes the visitor on the given state
|
|
||||||
if (visitor != null)
|
|
||||||
{
|
|
||||||
visitor(state);
|
|
||||||
}
|
|
||||||
|
|
||||||
var childCount = model.getChildCount(state.cell);
|
var childCount = model.getChildCount(state.cell);
|
||||||
|
|
||||||
for (var i = 0; i < childCount; i++)
|
for (var i = 0; i < childCount; i++) {
|
||||||
{
|
|
||||||
this.revalidateState(this.graph.view.getState(model.getChildAt(state.cell, i)), dx, dy, visitor);
|
this.revalidateState(this.graph.view.getState(model.getChildAt(state.cell, i)), dx, dy, visitor);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Function: addEdges
|
|
||||||
*/
|
|
||||||
addEdges = (state)=>
|
|
||||||
{
|
|
||||||
var model = this.graph.getModel();
|
|
||||||
var edgeCount = model.getEdgeCount(state.cell);
|
|
||||||
|
|
||||||
for (var i = 0; i < edgeCount; i++)
|
|
||||||
{
|
|
||||||
var s = state.view.getState(model.getEdgeAt(state.cell, i));
|
|
||||||
|
|
||||||
if (s != null)
|
|
||||||
{
|
|
||||||
this.moveState(s, 0, 0);
|
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
};
|
|
||||||
|
/**
|
||||||
|
* Function: addEdges
|
||||||
|
*/
|
||||||
|
addEdges = (state) => {
|
||||||
|
var model = this.graph.getModel();
|
||||||
|
var edgeCount = model.getEdgeCount(state.cell);
|
||||||
|
|
||||||
|
for (var i = 0; i < edgeCount; i++) {
|
||||||
|
var s = state.view.getState(model.getEdgeAt(state.cell, i));
|
||||||
|
|
||||||
|
if (s != null) {
|
||||||
|
this.moveState(s, 0, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export default mxCellStatePreview;
|
||||||
|
|
|
@ -2,66 +2,69 @@
|
||||||
* Copyright (c) 2006-2015, JGraph Ltd
|
* Copyright (c) 2006-2015, JGraph Ltd
|
||||||
* Copyright (c) 2006-2015, Gaudenz Alder
|
* Copyright (c) 2006-2015, Gaudenz Alder
|
||||||
*/
|
*/
|
||||||
/**
|
|
||||||
* Class: mxConnectionConstraint
|
|
||||||
*
|
|
||||||
* Defines an object that contains the constraints about how to connect one
|
|
||||||
* side of an edge to its terminal.
|
|
||||||
*
|
|
||||||
* Constructor: mxConnectionConstraint
|
|
||||||
*
|
|
||||||
* Constructs a new connection constraint for the given point and boolean
|
|
||||||
* arguments.
|
|
||||||
*
|
|
||||||
* Parameters:
|
|
||||||
*
|
|
||||||
* point - Optional <mxPoint> that specifies the fixed location of the point
|
|
||||||
* in relative coordinates. Default is null.
|
|
||||||
* perimeter - Optional boolean that specifies if the fixed point should be
|
|
||||||
* projected onto the perimeter of the terminal. Default is true.
|
|
||||||
*/
|
|
||||||
function mxConnectionConstraint(point, perimeter, name, dx, dy)
|
|
||||||
{
|
|
||||||
this.point = point;
|
|
||||||
this.perimeter = (perimeter != null) ? perimeter : true;
|
|
||||||
this.name = name;
|
|
||||||
this.dx = dx? dx : 0;
|
|
||||||
this.dy = dy? dy : 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
class mxConnectionConstraint {
|
||||||
* Variable: point
|
/**
|
||||||
*
|
* Variable: point
|
||||||
* <mxPoint> that specifies the fixed location of the connection point.
|
*
|
||||||
*/
|
* <mxPoint> that specifies the fixed location of the connection point.
|
||||||
point = null;
|
*/
|
||||||
|
point = null;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Variable: perimeter
|
* Variable: perimeter
|
||||||
*
|
*
|
||||||
* Boolean that specifies if the point should be projected onto the perimeter
|
* Boolean that specifies if the point should be projected onto the perimeter
|
||||||
* of the terminal.
|
* of the terminal.
|
||||||
*/
|
*/
|
||||||
perimeter = null;
|
perimeter = null;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Variable: name
|
* Variable: name
|
||||||
*
|
*
|
||||||
* Optional string that specifies the name of the constraint.
|
* Optional string that specifies the name of the constraint.
|
||||||
*/
|
*/
|
||||||
name = null;
|
name = null;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Variable: dx
|
* Variable: dx
|
||||||
*
|
*
|
||||||
* Optional float that specifies the horizontal offset of the constraint.
|
* Optional float that specifies the horizontal offset of the constraint.
|
||||||
*/
|
*/
|
||||||
dx = null;
|
dx = null;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Variable: dy
|
* Variable: dy
|
||||||
*
|
*
|
||||||
* Optional float that specifies the vertical offset of the constraint.
|
* Optional float that specifies the vertical offset of the constraint.
|
||||||
*/
|
*/
|
||||||
dy = null;
|
dy = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class: mxConnectionConstraint
|
||||||
|
*
|
||||||
|
* Defines an object that contains the constraints about how to connect one
|
||||||
|
* side of an edge to its terminal.
|
||||||
|
*
|
||||||
|
* Constructor: mxConnectionConstraint
|
||||||
|
*
|
||||||
|
* Constructs a new connection constraint for the given point and boolean
|
||||||
|
* arguments.
|
||||||
|
*
|
||||||
|
* Parameters:
|
||||||
|
*
|
||||||
|
* point - Optional <mxPoint> that specifies the fixed location of the point
|
||||||
|
* in relative coordinates. Default is null.
|
||||||
|
* perimeter - Optional boolean that specifies if the fixed point should be
|
||||||
|
* projected onto the perimeter of the terminal. Default is true.
|
||||||
|
*/
|
||||||
|
constructor(point, perimeter, name, dx, dy) {
|
||||||
|
this.point = point;
|
||||||
|
this.perimeter = (perimeter != null) ? perimeter : true;
|
||||||
|
this.name = name;
|
||||||
|
this.dx = dx ? dx : 0;
|
||||||
|
this.dy = dy ? dy : 0;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export default mxConnectionConstraint;
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
23961
src/js/view/mxGraph.js
23961
src/js/view/mxGraph.js
File diff suppressed because it is too large
Load Diff
|
@ -2,435 +2,394 @@
|
||||||
* Copyright (c) 2006-2015, JGraph Ltd
|
* Copyright (c) 2006-2015, JGraph Ltd
|
||||||
* Copyright (c) 2006-2015, Gaudenz Alder
|
* Copyright (c) 2006-2015, Gaudenz Alder
|
||||||
*/
|
*/
|
||||||
/**
|
|
||||||
* Class: mxGraphSelectionModel
|
|
||||||
*
|
|
||||||
* Implements the selection model for a graph. Here is a listener that handles
|
|
||||||
* all removed selection cells.
|
|
||||||
*
|
|
||||||
* (code)
|
|
||||||
* graph.getSelectionModel().addListener(mxEvent.CHANGE, (sender, evt)=>
|
|
||||||
* {
|
|
||||||
* var cells = evt.getProperty('added');
|
|
||||||
*
|
|
||||||
* for (var i = 0; i < cells.length; i++)
|
|
||||||
* {
|
|
||||||
* // Handle cells[i]...
|
|
||||||
* }
|
|
||||||
* });
|
|
||||||
* (end)
|
|
||||||
*
|
|
||||||
* Event: mxEvent.UNDO
|
|
||||||
*
|
|
||||||
* Fires after the selection was changed in <changeSelection>. The
|
|
||||||
* <code>edit</code> property contains the <mxUndoableEdit> which contains the
|
|
||||||
* <mxSelectionChange>.
|
|
||||||
*
|
|
||||||
* Event: mxEvent.CHANGE
|
|
||||||
*
|
|
||||||
* Fires after the selection changes by executing an <mxSelectionChange>. The
|
|
||||||
* <code>added</code> and <code>removed</code> properties contain arrays of
|
|
||||||
* cells that have been added to or removed from the selection, respectively.
|
|
||||||
* The names are inverted due to historic reasons. This cannot be changed.
|
|
||||||
*
|
|
||||||
* Constructor: mxGraphSelectionModel
|
|
||||||
*
|
|
||||||
* Constructs a new graph selection model for the given <mxGraph>.
|
|
||||||
*
|
|
||||||
* Parameters:
|
|
||||||
*
|
|
||||||
* graph - Reference to the enclosing <mxGraph>.
|
|
||||||
*/
|
|
||||||
function mxGraphSelectionModel(graph)
|
|
||||||
{
|
|
||||||
this.graph = graph;
|
|
||||||
this.cells = [];
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
import mxUndoableEdit from "../util/mxUndoableEdit";
|
||||||
* Extends mxEventSource.
|
import mxEventSource from "../util/mxEventSource";
|
||||||
*/
|
import mxEventObject from "../util/mxEventObject";
|
||||||
mxGraphSelectionModel.prototype = new mxEventSource();
|
|
||||||
constructor = mxGraphSelectionModel;
|
|
||||||
|
|
||||||
/**
|
class mxGraphSelectionModel extends mxEventSource {
|
||||||
* Variable: doneResource
|
/**
|
||||||
*
|
* Variable: doneResource
|
||||||
* Specifies the resource key for the status message after a long operation.
|
*
|
||||||
* If the resource for this key does not exist then the value is used as
|
* Specifies the resource key for the status message after a long operation.
|
||||||
* the status message. Default is 'done'.
|
* If the resource for this key does not exist then the value is used as
|
||||||
*/
|
* the status message. Default is 'done'.
|
||||||
doneResource = (mxClient.language != 'none') ? 'done' : '';
|
*/
|
||||||
|
doneResource = (mxClient.language != 'none') ? 'done' : '';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Variable: updatingSelectionResource
|
* Variable: updatingSelectionResource
|
||||||
*
|
*
|
||||||
* Specifies the resource key for the status message while the selection is
|
* Specifies the resource key for the status message while the selection is
|
||||||
* being updated. If the resource for this key does not exist then the
|
* being updated. If the resource for this key does not exist then the
|
||||||
* value is used as the status message. Default is 'updatingSelection'.
|
* value is used as the status message. Default is 'updatingSelection'.
|
||||||
*/
|
*/
|
||||||
updatingSelectionResource = (mxClient.language != 'none') ? 'updatingSelection' : '';
|
updatingSelectionResource = (mxClient.language != 'none') ? 'updatingSelection' : '';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Variable: graph
|
* Variable: graph
|
||||||
*
|
*
|
||||||
* Reference to the enclosing <mxGraph>.
|
* Reference to the enclosing <mxGraph>.
|
||||||
*/
|
*/
|
||||||
graph = null;
|
graph = null;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Variable: singleSelection
|
* Variable: singleSelection
|
||||||
*
|
*
|
||||||
* Specifies if only one selected item at a time is allowed.
|
* Specifies if only one selected item at a time is allowed.
|
||||||
* Default is false.
|
* Default is false.
|
||||||
*/
|
*/
|
||||||
singleSelection = false;
|
singleSelection = false;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function: isSingleSelection
|
* Class: mxGraphSelectionModel
|
||||||
*
|
*
|
||||||
* Returns <singleSelection> as a boolean.
|
* Implements the selection model for a graph. Here is a listener that handles
|
||||||
*/
|
* all removed selection cells.
|
||||||
isSingleSelection = ()=>
|
*
|
||||||
{
|
* (code)
|
||||||
return this.singleSelection;
|
* graph.getSelectionModel().addListener(mxEvent.CHANGE, (sender, evt)=>
|
||||||
};
|
* {
|
||||||
|
* var cells = evt.getProperty('added');
|
||||||
|
*
|
||||||
|
* for (var i = 0; i < cells.length; i++)
|
||||||
|
* {
|
||||||
|
* // Handle cells[i]...
|
||||||
|
* }
|
||||||
|
* });
|
||||||
|
* (end)
|
||||||
|
*
|
||||||
|
* Event: mxEvent.UNDO
|
||||||
|
*
|
||||||
|
* Fires after the selection was changed in <changeSelection>. The
|
||||||
|
* <code>edit</code> property contains the <mxUndoableEdit> which contains the
|
||||||
|
* <mxSelectionChange>.
|
||||||
|
*
|
||||||
|
* Event: mxEvent.CHANGE
|
||||||
|
*
|
||||||
|
* Fires after the selection changes by executing an <mxSelectionChange>. The
|
||||||
|
* <code>added</code> and <code>removed</code> properties contain arrays of
|
||||||
|
* cells that have been added to or removed from the selection, respectively.
|
||||||
|
* The names are inverted due to historic reasons. This cannot be changed.
|
||||||
|
*
|
||||||
|
* Constructor: mxGraphSelectionModel
|
||||||
|
*
|
||||||
|
* Constructs a new graph selection model for the given <mxGraph>.
|
||||||
|
*
|
||||||
|
* Parameters:
|
||||||
|
*
|
||||||
|
* graph - Reference to the enclosing <mxGraph>.
|
||||||
|
*/
|
||||||
|
constructor(graph) {
|
||||||
|
this.graph = graph;
|
||||||
|
this.cells = [];
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function: setSingleSelection
|
* Function: isSingleSelection
|
||||||
*
|
*
|
||||||
* Sets the <singleSelection> flag.
|
* Returns <singleSelection> as a boolean.
|
||||||
*
|
*/
|
||||||
* Parameters:
|
isSingleSelection = () => {
|
||||||
*
|
return this.singleSelection;
|
||||||
* singleSelection - Boolean that specifies the new value for
|
};
|
||||||
* <singleSelection>.
|
|
||||||
*/
|
|
||||||
setSingleSelection = (singleSelection)=>
|
|
||||||
{
|
|
||||||
this.singleSelection = singleSelection;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function: isSelected
|
* Function: setSingleSelection
|
||||||
*
|
*
|
||||||
* Returns true if the given <mxCell> is selected.
|
* Sets the <singleSelection> flag.
|
||||||
*/
|
*
|
||||||
isSelected = (cell)=>
|
* Parameters:
|
||||||
{
|
*
|
||||||
if (cell != null)
|
* singleSelection - Boolean that specifies the new value for
|
||||||
{
|
* <singleSelection>.
|
||||||
return mxUtils.indexOf(this.cells, cell) >= 0;
|
*/
|
||||||
}
|
setSingleSelection = (singleSelection) => {
|
||||||
|
this.singleSelection = singleSelection;
|
||||||
return false;
|
};
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function: isEmpty
|
* Function: isSelected
|
||||||
*
|
*
|
||||||
* Returns true if no cells are currently selected.
|
* Returns true if the given <mxCell> is selected.
|
||||||
*/
|
*/
|
||||||
isEmpty = ()=>
|
isSelected = (cell) => {
|
||||||
{
|
if (cell != null) {
|
||||||
return this.cells.length == 0;
|
return mxUtils.indexOf(this.cells, cell) >= 0;
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Function: clear
|
|
||||||
*
|
|
||||||
* Clears the selection and fires a <change> event if the selection was not
|
|
||||||
* empty.
|
|
||||||
*/
|
|
||||||
clear = ()=>
|
|
||||||
{
|
|
||||||
this.changeSelection(null, this.cells);
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Function: setCell
|
|
||||||
*
|
|
||||||
* Selects the specified <mxCell> using <setCells>.
|
|
||||||
*
|
|
||||||
* Parameters:
|
|
||||||
*
|
|
||||||
* cell - <mxCell> to be selected.
|
|
||||||
*/
|
|
||||||
setCell = (cell)=>
|
|
||||||
{
|
|
||||||
if (cell != null)
|
|
||||||
{
|
|
||||||
this.setCells([cell]);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Function: setCells
|
|
||||||
*
|
|
||||||
* Selects the given array of <mxCells> and fires a <change> event.
|
|
||||||
*
|
|
||||||
* Parameters:
|
|
||||||
*
|
|
||||||
* cells - Array of <mxCells> to be selected.
|
|
||||||
*/
|
|
||||||
setCells = (cells)=>
|
|
||||||
{
|
|
||||||
if (cells != null)
|
|
||||||
{
|
|
||||||
if (this.singleSelection)
|
|
||||||
{
|
|
||||||
cells = [this.getFirstSelectableCell(cells)];
|
|
||||||
}
|
|
||||||
|
|
||||||
var tmp = [];
|
|
||||||
|
|
||||||
for (var i = 0; i < cells.length; i++)
|
|
||||||
{
|
|
||||||
if (this.graph.isCellSelectable(cells[i]))
|
|
||||||
{
|
|
||||||
tmp.push(cells[i]);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
this.changeSelection(tmp, this.cells);
|
return false;
|
||||||
}
|
};
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function: getFirstSelectableCell
|
* Function: isEmpty
|
||||||
*
|
*
|
||||||
* Returns the first selectable cell in the given array of cells.
|
* Returns true if no cells are currently selected.
|
||||||
*/
|
*/
|
||||||
getFirstSelectableCell = (cells)=>
|
isEmpty = () => {
|
||||||
{
|
return this.cells.length === 0;
|
||||||
if (cells != null)
|
};
|
||||||
{
|
|
||||||
for (var i = 0; i < cells.length; i++)
|
/**
|
||||||
{
|
* Function: clear
|
||||||
if (this.graph.isCellSelectable(cells[i]))
|
*
|
||||||
{
|
* Clears the selection and fires a <change> event if the selection was not
|
||||||
return cells[i];
|
* empty.
|
||||||
|
*/
|
||||||
|
clear = () => {
|
||||||
|
this.changeSelection(null, this.cells);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function: setCell
|
||||||
|
*
|
||||||
|
* Selects the specified <mxCell> using <setCells>.
|
||||||
|
*
|
||||||
|
* Parameters:
|
||||||
|
*
|
||||||
|
* cell - <mxCell> to be selected.
|
||||||
|
*/
|
||||||
|
setCell = (cell) => {
|
||||||
|
if (cell != null) {
|
||||||
|
this.setCells([cell]);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function: setCells
|
||||||
|
*
|
||||||
|
* Selects the given array of <mxCells> and fires a <change> event.
|
||||||
|
*
|
||||||
|
* Parameters:
|
||||||
|
*
|
||||||
|
* cells - Array of <mxCells> to be selected.
|
||||||
|
*/
|
||||||
|
setCells = (cells) => {
|
||||||
|
if (cells != null) {
|
||||||
|
if (this.singleSelection) {
|
||||||
|
cells = [this.getFirstSelectableCell(cells)];
|
||||||
|
}
|
||||||
|
|
||||||
|
var tmp = [];
|
||||||
|
|
||||||
|
for (var i = 0; i < cells.length; i++) {
|
||||||
|
if (this.graph.isCellSelectable(cells[i])) {
|
||||||
|
tmp.push(cells[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
this.changeSelection(tmp, this.cells);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function: getFirstSelectableCell
|
||||||
|
*
|
||||||
|
* Returns the first selectable cell in the given array of cells.
|
||||||
|
*/
|
||||||
|
getFirstSelectableCell = (cells) => {
|
||||||
|
if (cells != null) {
|
||||||
|
for (var i = 0; i < cells.length; i++) {
|
||||||
|
if (this.graph.isCellSelectable(cells[i])) {
|
||||||
|
return cells[i];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
return null;
|
||||||
* Function: addCell
|
};
|
||||||
*
|
|
||||||
* Adds the given <mxCell> to the selection and fires a <select> event.
|
|
||||||
*
|
|
||||||
* Parameters:
|
|
||||||
*
|
|
||||||
* cell - <mxCell> to add to the selection.
|
|
||||||
*/
|
|
||||||
addCell = (cell)=>
|
|
||||||
{
|
|
||||||
if (cell != null)
|
|
||||||
{
|
|
||||||
this.addCells([cell]);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function: addCells
|
* Function: addCell
|
||||||
*
|
*
|
||||||
* Adds the given array of <mxCells> to the selection and fires a <select>
|
* Adds the given <mxCell> to the selection and fires a <select> event.
|
||||||
* event.
|
*
|
||||||
*
|
* Parameters:
|
||||||
* Parameters:
|
*
|
||||||
*
|
* cell - <mxCell> to add to the selection.
|
||||||
* cells - Array of <mxCells> to add to the selection.
|
*/
|
||||||
*/
|
addCell = (cell) => {
|
||||||
addCells = (cells)=>
|
if (cell != null) {
|
||||||
{
|
this.addCells([cell]);
|
||||||
if (cells != null)
|
|
||||||
{
|
|
||||||
var remove = null;
|
|
||||||
|
|
||||||
if (this.singleSelection)
|
|
||||||
{
|
|
||||||
remove = this.cells;
|
|
||||||
cells = [this.getFirstSelectableCell(cells)];
|
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
|
||||||
var tmp = [];
|
/**
|
||||||
|
* Function: addCells
|
||||||
for (var i = 0; i < cells.length; i++)
|
*
|
||||||
{
|
* Adds the given array of <mxCells> to the selection and fires a <select>
|
||||||
if (!this.isSelected(cells[i]) &&
|
* event.
|
||||||
this.graph.isCellSelectable(cells[i]))
|
*
|
||||||
{
|
* Parameters:
|
||||||
tmp.push(cells[i]);
|
*
|
||||||
}
|
* cells - Array of <mxCells> to add to the selection.
|
||||||
|
*/
|
||||||
|
addCells = (cells) => {
|
||||||
|
if (cells != null) {
|
||||||
|
var remove = null;
|
||||||
|
|
||||||
|
if (this.singleSelection) {
|
||||||
|
remove = this.cells;
|
||||||
|
cells = [this.getFirstSelectableCell(cells)];
|
||||||
|
}
|
||||||
|
|
||||||
|
var tmp = [];
|
||||||
|
|
||||||
|
for (var i = 0; i < cells.length; i++) {
|
||||||
|
if (!this.isSelected(cells[i]) &&
|
||||||
|
this.graph.isCellSelectable(cells[i])) {
|
||||||
|
tmp.push(cells[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
this.changeSelection(tmp, remove);
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
|
||||||
this.changeSelection(tmp, remove);
|
/**
|
||||||
}
|
* Function: removeCell
|
||||||
};
|
*
|
||||||
|
* Removes the specified <mxCell> from the selection and fires a <select>
|
||||||
|
* event for the remaining cells.
|
||||||
|
*
|
||||||
|
* Parameters:
|
||||||
|
*
|
||||||
|
* cell - <mxCell> to remove from the selection.
|
||||||
|
*/
|
||||||
|
removeCell = (cell) => {
|
||||||
|
if (cell != null) {
|
||||||
|
this.removeCells([cell]);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function: removeCell
|
* Function: removeCells
|
||||||
*
|
*/
|
||||||
* Removes the specified <mxCell> from the selection and fires a <select>
|
removeCells = (cells) => {
|
||||||
* event for the remaining cells.
|
if (cells != null) {
|
||||||
*
|
var tmp = [];
|
||||||
* Parameters:
|
|
||||||
*
|
|
||||||
* cell - <mxCell> to remove from the selection.
|
|
||||||
*/
|
|
||||||
removeCell = (cell)=>
|
|
||||||
{
|
|
||||||
if (cell != null)
|
|
||||||
{
|
|
||||||
this.removeCells([cell]);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
for (var i = 0; i < cells.length; i++) {
|
||||||
* Function: removeCells
|
if (this.isSelected(cells[i])) {
|
||||||
*/
|
tmp.push(cells[i]);
|
||||||
removeCells = (cells)=>
|
}
|
||||||
{
|
}
|
||||||
if (cells != null)
|
|
||||||
{
|
this.changeSelection(null, tmp);
|
||||||
var tmp = [];
|
}
|
||||||
|
};
|
||||||
for (var i = 0; i < cells.length; i++)
|
|
||||||
{
|
/**
|
||||||
if (this.isSelected(cells[i]))
|
* Function: changeSelection
|
||||||
{
|
*
|
||||||
tmp.push(cells[i]);
|
* Adds/removes the specified arrays of <mxCell> to/from the selection.
|
||||||
|
*
|
||||||
|
* Parameters:
|
||||||
|
*
|
||||||
|
* added - Array of <mxCell> to add to the selection.
|
||||||
|
* remove - Array of <mxCell> to remove from the selection.
|
||||||
|
*/
|
||||||
|
changeSelection = (added, removed) => {
|
||||||
|
if ((added != null &&
|
||||||
|
added.length > 0 &&
|
||||||
|
added[0] != null) ||
|
||||||
|
(removed != null &&
|
||||||
|
removed.length > 0 &&
|
||||||
|
removed[0] != null)) {
|
||||||
|
var change = new mxSelectionChange(this, added, removed);
|
||||||
|
change.execute();
|
||||||
|
var edit = new mxUndoableEdit(this, false);
|
||||||
|
edit.add(change);
|
||||||
|
this.fireEvent(new mxEventObject(mxEvent.UNDO, 'edit', edit));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function: cellAdded
|
||||||
|
*
|
||||||
|
* Inner callback to add the specified <mxCell> to the selection. No event
|
||||||
|
* is fired in this implementation.
|
||||||
|
*
|
||||||
|
* Paramters:
|
||||||
|
*
|
||||||
|
* cell - <mxCell> to add to the selection.
|
||||||
|
*/
|
||||||
|
cellAdded = (cell) => {
|
||||||
|
if (cell != null &&
|
||||||
|
!this.isSelected(cell)) {
|
||||||
|
this.cells.push(cell);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function: cellRemoved
|
||||||
|
*
|
||||||
|
* Inner callback to remove the specified <mxCell> from the selection. No
|
||||||
|
* event is fired in this implementation.
|
||||||
|
*
|
||||||
|
* Parameters:
|
||||||
|
*
|
||||||
|
* cell - <mxCell> to remove from the selection.
|
||||||
|
*/
|
||||||
|
cellRemoved = (cell) => {
|
||||||
|
if (cell != null) {
|
||||||
|
var index = mxUtils.indexOf(this.cells, cell);
|
||||||
|
|
||||||
|
if (index >= 0) {
|
||||||
|
this.cells.splice(index, 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
};
|
||||||
this.changeSelection(null, tmp);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function: changeSelection
|
* Class: mxSelectionChange
|
||||||
*
|
*
|
||||||
* Adds/removes the specified arrays of <mxCell> to/from the selection.
|
* Action to change the current root in a view.
|
||||||
*
|
*
|
||||||
* Parameters:
|
* Constructor: mxCurrentRootChange
|
||||||
*
|
*
|
||||||
* added - Array of <mxCell> to add to the selection.
|
* Constructs a change of the current root in the given view.
|
||||||
* remove - Array of <mxCell> to remove from the selection.
|
*/
|
||||||
*/
|
mxSelectionChange = (selectionModel, added, removed) => {
|
||||||
changeSelection = (added, removed)=>
|
this.selectionModel = selectionModel;
|
||||||
{
|
this.added = (added != null) ? added.slice() : null;
|
||||||
if ((added != null &&
|
this.removed = (removed != null) ? removed.slice() : null;
|
||||||
added.length > 0 &&
|
};
|
||||||
added[0] != null) ||
|
|
||||||
(removed != null &&
|
|
||||||
removed.length > 0 &&
|
|
||||||
removed[0] != null))
|
|
||||||
{
|
|
||||||
var change = new mxSelectionChange(this, added, removed);
|
|
||||||
change.execute();
|
|
||||||
var edit = new mxUndoableEdit(this, false);
|
|
||||||
edit.add(change);
|
|
||||||
this.fireEvent(new mxEventObject(mxEvent.UNDO, 'edit', edit));
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function: cellAdded
|
* Function: execute
|
||||||
*
|
*
|
||||||
* Inner callback to add the specified <mxCell> to the selection. No event
|
* Changes the current root of the view.
|
||||||
* is fired in this implementation.
|
*/
|
||||||
*
|
execute = () => {
|
||||||
* Paramters:
|
var t0 = mxLog.enter('mxSelectionChange.execute');
|
||||||
*
|
window.status = mxResources.get(
|
||||||
* cell - <mxCell> to add to the selection.
|
this.selectionModel.updatingSelectionResource) ||
|
||||||
*/
|
this.selectionModel.updatingSelectionResource;
|
||||||
cellAdded = (cell)=>
|
|
||||||
{
|
|
||||||
if (cell != null &&
|
|
||||||
!this.isSelected(cell))
|
|
||||||
{
|
|
||||||
this.cells.push(cell);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
if (this.removed != null) {
|
||||||
* Function: cellRemoved
|
for (var i = 0; i < this.removed.length; i++) {
|
||||||
*
|
this.selectionModel.cellRemoved(this.removed[i]);
|
||||||
* Inner callback to remove the specified <mxCell> from the selection. No
|
}
|
||||||
* event is fired in this implementation.
|
|
||||||
*
|
|
||||||
* Parameters:
|
|
||||||
*
|
|
||||||
* cell - <mxCell> to remove from the selection.
|
|
||||||
*/
|
|
||||||
cellRemoved = (cell)=>
|
|
||||||
{
|
|
||||||
if (cell != null)
|
|
||||||
{
|
|
||||||
var index = mxUtils.indexOf(this.cells, cell);
|
|
||||||
|
|
||||||
if (index >= 0)
|
|
||||||
{
|
|
||||||
this.cells.splice(index, 1);
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
if (this.added != null) {
|
||||||
* Class: mxSelectionChange
|
for (var i = 0; i < this.added.length; i++) {
|
||||||
*
|
this.selectionModel.cellAdded(this.added[i]);
|
||||||
* Action to change the current root in a view.
|
}
|
||||||
*
|
|
||||||
* Constructor: mxCurrentRootChange
|
|
||||||
*
|
|
||||||
* Constructs a change of the current root in the given view.
|
|
||||||
*/
|
|
||||||
function mxSelectionChange(selectionModel, added, removed)
|
|
||||||
{
|
|
||||||
this.selectionModel = selectionModel;
|
|
||||||
this.added = (added != null) ? added.slice() : null;
|
|
||||||
this.removed = (removed != null) ? removed.slice() : null;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Function: execute
|
|
||||||
*
|
|
||||||
* Changes the current root of the view.
|
|
||||||
*/
|
|
||||||
execute = ()=>
|
|
||||||
{
|
|
||||||
var t0 = mxLog.enter('mxSelectionChange.execute');
|
|
||||||
window.status = mxResources.get(
|
|
||||||
this.selectionModel.updatingSelectionResource) ||
|
|
||||||
this.selectionModel.updatingSelectionResource;
|
|
||||||
|
|
||||||
if (this.removed != null)
|
|
||||||
{
|
|
||||||
for (var i = 0; i < this.removed.length; i++)
|
|
||||||
{
|
|
||||||
this.selectionModel.cellRemoved(this.removed[i]);
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (this.added != null)
|
var tmp = this.added;
|
||||||
{
|
this.added = this.removed;
|
||||||
for (var i = 0; i < this.added.length; i++)
|
this.removed = tmp;
|
||||||
{
|
|
||||||
this.selectionModel.cellAdded(this.added[i]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var tmp = this.added;
|
|
||||||
this.added = this.removed;
|
|
||||||
this.removed = tmp;
|
|
||||||
|
|
||||||
window.status = mxResources.get(this.selectionModel.doneResource) ||
|
window.status = mxResources.get(this.selectionModel.doneResource) ||
|
||||||
this.selectionModel.doneResource;
|
this.selectionModel.doneResource;
|
||||||
mxLog.leave('mxSelectionChange.execute', t0);
|
mxLog.leave('mxSelectionChange.execute', t0);
|
||||||
|
|
||||||
this.selectionModel.fireEvent(new mxEventObject(mxEvent.CHANGE,
|
this.selectionModel.fireEvent(new mxEventObject(mxEvent.CHANGE,
|
||||||
'added', this.added, 'removed', this.removed));
|
'added', this.added, 'removed', this.removed));
|
||||||
};
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export default mxGraphSelectionModel;
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -2,499 +2,443 @@
|
||||||
* Copyright (c) 2006-2015, JGraph Ltd
|
* Copyright (c) 2006-2015, JGraph Ltd
|
||||||
* Copyright (c) 2006-2015, Gaudenz Alder
|
* Copyright (c) 2006-2015, Gaudenz Alder
|
||||||
*/
|
*/
|
||||||
/**
|
|
||||||
* Class: mxLayoutManager
|
|
||||||
*
|
|
||||||
* Implements a layout manager that runs a given layout after any changes to the graph:
|
|
||||||
*
|
|
||||||
* Example:
|
|
||||||
*
|
|
||||||
* (code)
|
|
||||||
* var layoutMgr = new mxLayoutManager(graph);
|
|
||||||
* layoutMgr.getLayout = (cell, eventName)=>
|
|
||||||
* {
|
|
||||||
* return layout;
|
|
||||||
* };
|
|
||||||
* (end)
|
|
||||||
*
|
|
||||||
* See <getLayout> for a description of the possible eventNames.
|
|
||||||
*
|
|
||||||
* Event: mxEvent.LAYOUT_CELLS
|
|
||||||
*
|
|
||||||
* Fires between begin- and endUpdate after all cells have been layouted in
|
|
||||||
* <layoutCells>. The <code>cells</code> property contains all cells that have
|
|
||||||
* been passed to <layoutCells>.
|
|
||||||
*
|
|
||||||
* Constructor: mxLayoutManager
|
|
||||||
*
|
|
||||||
* Constructs a new automatic layout for the given graph.
|
|
||||||
*
|
|
||||||
* Arguments:
|
|
||||||
*
|
|
||||||
* graph - Reference to the enclosing graph.
|
|
||||||
*/
|
|
||||||
function mxLayoutManager(graph)
|
|
||||||
{
|
|
||||||
// Executes the layout before the changes are dispatched
|
|
||||||
this.undoHandler = mxUtils.bind(this, (sender, evt)=>
|
|
||||||
{
|
|
||||||
if (this.isEnabled())
|
|
||||||
{
|
|
||||||
this.beforeUndo(evt.getProperty('edit'));
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// Notifies the layout of a move operation inside a parent
|
|
||||||
this.moveHandler = mxUtils.bind(this, (sender, evt)=>
|
|
||||||
{
|
|
||||||
if (this.isEnabled())
|
|
||||||
{
|
|
||||||
this.cellsMoved(evt.getProperty('cells'), evt.getProperty('event'));
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// Notifies the layout of a move operation inside a parent
|
|
||||||
this.resizeHandler = mxUtils.bind(this, (sender, evt)=>
|
|
||||||
{
|
|
||||||
if (this.isEnabled())
|
|
||||||
{
|
|
||||||
this.cellsResized(evt.getProperty('cells'), evt.getProperty('bounds'),
|
|
||||||
evt.getProperty('previous'));
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
this.setGraph(graph);
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
import mxEventSource from "../util/mxEventSource";
|
||||||
* Extends mxEventSource.
|
|
||||||
*/
|
|
||||||
mxLayoutManager.prototype = new mxEventSource();
|
|
||||||
constructor = mxLayoutManager;
|
|
||||||
|
|
||||||
/**
|
class mxLayoutManager extends mxEventSource {
|
||||||
* Variable: graph
|
/**
|
||||||
*
|
* Variable: graph
|
||||||
* Reference to the enclosing <mxGraph>.
|
*
|
||||||
*/
|
* Reference to the enclosing <mxGraph>.
|
||||||
graph = null;
|
*/
|
||||||
|
graph = null;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Variable: bubbling
|
* Variable: bubbling
|
||||||
*
|
*
|
||||||
* Specifies if the layout should bubble along
|
* Specifies if the layout should bubble along
|
||||||
* the cell hierarchy. Default is true.
|
* the cell hierarchy. Default is true.
|
||||||
*/
|
*/
|
||||||
bubbling = true;
|
bubbling = true;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Variable: enabled
|
* Variable: enabled
|
||||||
*
|
*
|
||||||
* Specifies if event handling is enabled. Default is true.
|
* Specifies if event handling is enabled. Default is true.
|
||||||
*/
|
*/
|
||||||
enabled = true;
|
enabled = true;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Variable: undoHandler
|
* Variable: undoHandler
|
||||||
*
|
*
|
||||||
* Holds the function that handles the endUpdate event.
|
* Holds the function that handles the endUpdate event.
|
||||||
*/
|
*/
|
||||||
undoHandler = null;
|
undoHandler = null;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Variable: moveHandler
|
* Variable: moveHandler
|
||||||
*
|
*
|
||||||
* Holds the function that handles the move event.
|
* Holds the function that handles the move event.
|
||||||
*/
|
*/
|
||||||
moveHandler = null;
|
moveHandler = null;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Variable: resizeHandler
|
* Variable: resizeHandler
|
||||||
*
|
*
|
||||||
* Holds the function that handles the resize event.
|
* Holds the function that handles the resize event.
|
||||||
*/
|
*/
|
||||||
resizeHandler = null;
|
resizeHandler = null;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function: isEnabled
|
* Class: mxLayoutManager
|
||||||
*
|
*
|
||||||
* Returns true if events are handled. This implementation
|
* Implements a layout manager that runs a given layout after any changes to the graph:
|
||||||
* returns <enabled>.
|
*
|
||||||
*/
|
* Example:
|
||||||
isEnabled = ()=>
|
*
|
||||||
{
|
* (code)
|
||||||
return this.enabled;
|
* var layoutMgr = new mxLayoutManager(graph);
|
||||||
};
|
* layoutMgr.getLayout = (cell, eventName)=>
|
||||||
|
* {
|
||||||
/**
|
* return layout;
|
||||||
* Function: setEnabled
|
* };
|
||||||
*
|
* (end)
|
||||||
* Enables or disables event handling. This implementation
|
*
|
||||||
* updates <enabled>.
|
* See <getLayout> for a description of the possible eventNames.
|
||||||
*
|
*
|
||||||
* Parameters:
|
* Event: mxEvent.LAYOUT_CELLS
|
||||||
*
|
*
|
||||||
* enabled - Boolean that specifies the new enabled state.
|
* Fires between begin- and endUpdate after all cells have been layouted in
|
||||||
*/
|
* <layoutCells>. The <code>cells</code> property contains all cells that have
|
||||||
setEnabled = (enabled)=>
|
* been passed to <layoutCells>.
|
||||||
{
|
*
|
||||||
this.enabled = enabled;
|
* Constructor: mxLayoutManager
|
||||||
};
|
*
|
||||||
|
* Constructs a new automatic layout for the given graph.
|
||||||
/**
|
*
|
||||||
* Function: isBubbling
|
* Arguments:
|
||||||
*
|
*
|
||||||
* Returns true if a layout should bubble, that is, if the parent layout
|
* graph - Reference to the enclosing graph.
|
||||||
* should be executed whenever a cell layout (layout of the children of
|
*/
|
||||||
* a cell) has been executed. This implementation returns <bubbling>.
|
constructor(graph) {
|
||||||
*/
|
// Executes the layout before the changes are dispatched
|
||||||
isBubbling = ()=>
|
this.undoHandler = (sender, evt) => {
|
||||||
{
|
if (this.isEnabled()) {
|
||||||
return this.bubbling;
|
this.beforeUndo(evt.getProperty('edit'));
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Function: setBubbling
|
|
||||||
*
|
|
||||||
* Sets <bubbling>.
|
|
||||||
*/
|
|
||||||
setBubbling = (value)=>
|
|
||||||
{
|
|
||||||
this.bubbling = value;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Function: getGraph
|
|
||||||
*
|
|
||||||
* Returns the graph that this layout operates on.
|
|
||||||
*/
|
|
||||||
getGraph = ()=>
|
|
||||||
{
|
|
||||||
return this.graph;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Function: setGraph
|
|
||||||
*
|
|
||||||
* Sets the graph that the layouts operate on.
|
|
||||||
*/
|
|
||||||
setGraph = (graph)=>
|
|
||||||
{
|
|
||||||
if (this.graph != null)
|
|
||||||
{
|
|
||||||
var model = this.graph.getModel();
|
|
||||||
model.removeListener(this.undoHandler);
|
|
||||||
this.graph.removeListener(this.moveHandler);
|
|
||||||
this.graph.removeListener(this.resizeHandler);
|
|
||||||
}
|
|
||||||
|
|
||||||
this.graph = graph;
|
|
||||||
|
|
||||||
if (this.graph != null)
|
|
||||||
{
|
|
||||||
var model = this.graph.getModel();
|
|
||||||
model.addListener(mxEvent.BEFORE_UNDO, this.undoHandler);
|
|
||||||
this.graph.addListener(mxEvent.MOVE_CELLS, this.moveHandler);
|
|
||||||
this.graph.addListener(mxEvent.RESIZE_CELLS, this.resizeHandler);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Function: hasLayout
|
|
||||||
*
|
|
||||||
* Returns true if the given cell has a layout. This implementation invokes
|
|
||||||
* <getLayout> with <mxEvent.LAYOUT_CELLS> as the eventName. Override this
|
|
||||||
* if creating layouts in <getLayout> is expensive and return true if
|
|
||||||
* <getLayout> will return a layout for the given cell for
|
|
||||||
* <mxEvent.BEGIN_UPDATE> or <mxEvent.END_UPDATE>.
|
|
||||||
*/
|
|
||||||
hasLayout = (cell)=>
|
|
||||||
{
|
|
||||||
return this.getLayout(cell, mxEvent.LAYOUT_CELLS);
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Function: getLayout
|
|
||||||
*
|
|
||||||
* Returns the layout for the given cell and eventName. Possible
|
|
||||||
* event names are <mxEvent.MOVE_CELLS> and <mxEvent.RESIZE_CELLS>
|
|
||||||
* when cells are moved or resized and <mxEvent.BEGIN_UPDATE> or
|
|
||||||
* <mxEvent.END_UPDATE> for the bottom up and top down phases after
|
|
||||||
* changes to the graph model. <mxEvent.LAYOUT_CELLS> is used to
|
|
||||||
* check if a layout exists for the given cell. This is called
|
|
||||||
* from <hasLayout>.
|
|
||||||
*/
|
|
||||||
getLayout = (cell, eventName)=>
|
|
||||||
{
|
|
||||||
return null;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Function: beforeUndo
|
|
||||||
*
|
|
||||||
* Called from <undoHandler>.
|
|
||||||
*
|
|
||||||
* Parameters:
|
|
||||||
*
|
|
||||||
* cell - Array of <mxCells> that have been moved.
|
|
||||||
* evt - Mouse event that represents the mousedown.
|
|
||||||
*/
|
|
||||||
beforeUndo = (undoableEdit)=>
|
|
||||||
{
|
|
||||||
this.executeLayoutForCells(this.getCellsForChanges(undoableEdit.changes));
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Function: cellsMoved
|
|
||||||
*
|
|
||||||
* Called from <moveHandler>.
|
|
||||||
*
|
|
||||||
* Parameters:
|
|
||||||
*
|
|
||||||
* cell - Array of <mxCells> that have been moved.
|
|
||||||
* evt - Mouse event that represents the mousedown.
|
|
||||||
*/
|
|
||||||
cellsMoved = (cells, evt)=>
|
|
||||||
{
|
|
||||||
if (cells != null && evt != null)
|
|
||||||
{
|
|
||||||
var point = mxUtils.convertPoint(this.getGraph().container,
|
|
||||||
mxEvent.getClientX(evt), mxEvent.getClientY(evt));
|
|
||||||
var model = this.getGraph().getModel();
|
|
||||||
|
|
||||||
for (var i = 0; i < cells.length; i++)
|
|
||||||
{
|
|
||||||
var layout = this.getLayout(model.getParent(cells[i]), mxEvent.MOVE_CELLS);
|
|
||||||
|
|
||||||
if (layout != null)
|
|
||||||
{
|
|
||||||
layout.moveCell(cells[i], point.x, point.y);
|
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
// Notifies the layout of a move operation inside a parent
|
||||||
* Function: cellsResized
|
this.moveHandler = (sender, evt) => {
|
||||||
*
|
if (this.isEnabled()) {
|
||||||
* Called from <resizeHandler>.
|
this.cellsMoved(evt.getProperty('cells'), evt.getProperty('event'));
|
||||||
*
|
|
||||||
* Parameters:
|
|
||||||
*
|
|
||||||
* cell - Array of <mxCells> that have been resized.
|
|
||||||
* bounds - <mxRectangle> taht represents the new bounds.
|
|
||||||
*/
|
|
||||||
cellsResized = (cells, bounds, prev)=>
|
|
||||||
{
|
|
||||||
if (cells != null && bounds != null)
|
|
||||||
{
|
|
||||||
var model = this.getGraph().getModel();
|
|
||||||
|
|
||||||
for (var i = 0; i < cells.length; i++)
|
|
||||||
{
|
|
||||||
var layout = this.getLayout(model.getParent(cells[i]), mxEvent.RESIZE_CELLS);
|
|
||||||
|
|
||||||
if (layout != null)
|
|
||||||
{
|
|
||||||
layout.resizeCell(cells[i], bounds[i], prev[i]);
|
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
// Notifies the layout of a move operation inside a parent
|
||||||
* Function: getCellsForChanges
|
this.resizeHandler = (sender, evt) => {
|
||||||
*
|
if (this.isEnabled()) {
|
||||||
* Returns the cells for which a layout should be executed.
|
this.cellsResized(evt.getProperty('cells'), evt.getProperty('bounds'),
|
||||||
*/
|
evt.getProperty('previous'));
|
||||||
getCellsForChanges = (changes)=>
|
}
|
||||||
{
|
};
|
||||||
var result = [];
|
|
||||||
|
|
||||||
for (var i = 0; i < changes.length; i++)
|
|
||||||
{
|
|
||||||
var change = changes[i];
|
|
||||||
|
|
||||||
if (change instanceof mxRootChange)
|
|
||||||
{
|
|
||||||
return [];
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
result = result.concat(this.getCellsForChange(change));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
this.setGraph(graph);
|
||||||
* Function: getCellsForChange
|
};
|
||||||
*
|
|
||||||
* Executes all layouts which have been scheduled during the
|
|
||||||
* changes.
|
|
||||||
*/
|
|
||||||
getCellsForChange = (change)=>
|
|
||||||
{
|
|
||||||
if (change instanceof mxChildChange)
|
|
||||||
{
|
|
||||||
return this.addCellsWithLayout(change.child,
|
|
||||||
this.addCellsWithLayout(change.previous));
|
|
||||||
}
|
|
||||||
else if (change instanceof mxTerminalChange ||
|
|
||||||
change instanceof mxGeometryChange)
|
|
||||||
{
|
|
||||||
return this.addCellsWithLayout(change.cell);
|
|
||||||
}
|
|
||||||
else if (change instanceof mxVisibleChange ||
|
|
||||||
change instanceof mxStyleChange)
|
|
||||||
{
|
|
||||||
return this.addCellsWithLayout(change.cell);
|
|
||||||
}
|
|
||||||
|
|
||||||
return [];
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function: addCellsWithLayout
|
* Function: isEnabled
|
||||||
*
|
*
|
||||||
* Adds all ancestors of the given cell that have a layout.
|
* Returns true if events are handled. This implementation
|
||||||
*/
|
* returns <enabled>.
|
||||||
addCellsWithLayout = (cell, result)=>
|
*/
|
||||||
{
|
isEnabled = () => {
|
||||||
return this.addDescendantsWithLayout(cell,
|
return this.enabled;
|
||||||
this.addAncestorsWithLayout(cell, result));
|
};
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function: addAncestorsWithLayout
|
* Function: setEnabled
|
||||||
*
|
*
|
||||||
* Adds all ancestors of the given cell that have a layout.
|
* Enables or disables event handling. This implementation
|
||||||
*/
|
* updates <enabled>.
|
||||||
addAncestorsWithLayout = (cell, result)=>
|
*
|
||||||
{
|
* Parameters:
|
||||||
result = (result != null) ? result : [];
|
*
|
||||||
|
* enabled - Boolean that specifies the new enabled state.
|
||||||
if (cell != null)
|
*/
|
||||||
{
|
setEnabled = (enabled) => {
|
||||||
var layout = this.hasLayout(cell);
|
this.enabled = enabled;
|
||||||
|
};
|
||||||
if (layout != null)
|
|
||||||
{
|
/**
|
||||||
result.push(cell);
|
* Function: isBubbling
|
||||||
|
*
|
||||||
|
* Returns true if a layout should bubble, that is, if the parent layout
|
||||||
|
* should be executed whenever a cell layout (layout of the children of
|
||||||
|
* a cell) has been executed. This implementation returns <bubbling>.
|
||||||
|
*/
|
||||||
|
isBubbling = () => {
|
||||||
|
return this.bubbling;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function: setBubbling
|
||||||
|
*
|
||||||
|
* Sets <bubbling>.
|
||||||
|
*/
|
||||||
|
setBubbling = (value) => {
|
||||||
|
this.bubbling = value;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function: getGraph
|
||||||
|
*
|
||||||
|
* Returns the graph that this layout operates on.
|
||||||
|
*/
|
||||||
|
getGraph = () => {
|
||||||
|
return this.graph;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function: setGraph
|
||||||
|
*
|
||||||
|
* Sets the graph that the layouts operate on.
|
||||||
|
*/
|
||||||
|
setGraph = (graph) => {
|
||||||
|
if (this.graph != null) {
|
||||||
|
var model = this.graph.getModel();
|
||||||
|
model.removeListener(this.undoHandler);
|
||||||
|
this.graph.removeListener(this.moveHandler);
|
||||||
|
this.graph.removeListener(this.resizeHandler);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.isBubbling())
|
this.graph = graph;
|
||||||
{
|
|
||||||
|
if (this.graph != null) {
|
||||||
|
var model = this.graph.getModel();
|
||||||
|
model.addListener(mxEvent.BEFORE_UNDO, this.undoHandler);
|
||||||
|
this.graph.addListener(mxEvent.MOVE_CELLS, this.moveHandler);
|
||||||
|
this.graph.addListener(mxEvent.RESIZE_CELLS, this.resizeHandler);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function: hasLayout
|
||||||
|
*
|
||||||
|
* Returns true if the given cell has a layout. This implementation invokes
|
||||||
|
* <getLayout> with <mxEvent.LAYOUT_CELLS> as the eventName. Override this
|
||||||
|
* if creating layouts in <getLayout> is expensive and return true if
|
||||||
|
* <getLayout> will return a layout for the given cell for
|
||||||
|
* <mxEvent.BEGIN_UPDATE> or <mxEvent.END_UPDATE>.
|
||||||
|
*/
|
||||||
|
hasLayout = (cell) => {
|
||||||
|
return this.getLayout(cell, mxEvent.LAYOUT_CELLS);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function: getLayout
|
||||||
|
*
|
||||||
|
* Returns the layout for the given cell and eventName. Possible
|
||||||
|
* event names are <mxEvent.MOVE_CELLS> and <mxEvent.RESIZE_CELLS>
|
||||||
|
* when cells are moved or resized and <mxEvent.BEGIN_UPDATE> or
|
||||||
|
* <mxEvent.END_UPDATE> for the bottom up and top down phases after
|
||||||
|
* changes to the graph model. <mxEvent.LAYOUT_CELLS> is used to
|
||||||
|
* check if a layout exists for the given cell. This is called
|
||||||
|
* from <hasLayout>.
|
||||||
|
*/
|
||||||
|
getLayout = (cell, eventName) => {
|
||||||
|
return null;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function: beforeUndo
|
||||||
|
*
|
||||||
|
* Called from <undoHandler>.
|
||||||
|
*
|
||||||
|
* Parameters:
|
||||||
|
*
|
||||||
|
* cell - Array of <mxCells> that have been moved.
|
||||||
|
* evt - Mouse event that represents the mousedown.
|
||||||
|
*/
|
||||||
|
beforeUndo = (undoableEdit) => {
|
||||||
|
this.executeLayoutForCells(this.getCellsForChanges(undoableEdit.changes));
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function: cellsMoved
|
||||||
|
*
|
||||||
|
* Called from <moveHandler>.
|
||||||
|
*
|
||||||
|
* Parameters:
|
||||||
|
*
|
||||||
|
* cell - Array of <mxCells> that have been moved.
|
||||||
|
* evt - Mouse event that represents the mousedown.
|
||||||
|
*/
|
||||||
|
cellsMoved = (cells, evt) => {
|
||||||
|
if (cells != null && evt != null) {
|
||||||
|
var point = mxUtils.convertPoint(this.getGraph().container,
|
||||||
|
mxEvent.getClientX(evt), mxEvent.getClientY(evt));
|
||||||
var model = this.getGraph().getModel();
|
var model = this.getGraph().getModel();
|
||||||
this.addAncestorsWithLayout(
|
|
||||||
model.getParent(cell), result);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
for (var i = 0; i < cells.length; i++) {
|
||||||
* Function: addDescendantsWithLayout
|
var layout = this.getLayout(model.getParent(cells[i]), mxEvent.MOVE_CELLS);
|
||||||
*
|
|
||||||
* Adds all descendants of the given cell that have a layout.
|
|
||||||
*/
|
|
||||||
addDescendantsWithLayout = (cell, result)=>
|
|
||||||
{
|
|
||||||
result = (result != null) ? result : [];
|
|
||||||
|
|
||||||
if (cell != null && this.hasLayout(cell))
|
|
||||||
{
|
|
||||||
var model = this.getGraph().getModel();
|
|
||||||
|
|
||||||
for (var i = 0; i < model.getChildCount(cell); i++)
|
|
||||||
{
|
|
||||||
var child = model.getChildAt(cell, i);
|
|
||||||
|
|
||||||
if (this.hasLayout(child))
|
|
||||||
{
|
|
||||||
result.push(child);
|
|
||||||
this.addDescendantsWithLayout(child, result);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
if (layout != null) {
|
||||||
* Function: executeLayoutForCells
|
layout.moveCell(cells[i], point.x, point.y);
|
||||||
*
|
|
||||||
* Executes all layouts for the given cells in two phases: In the first phase
|
|
||||||
* layouts for child cells are executed before layouts for parent cells with
|
|
||||||
* <mxEvent.BEGIN_UPDATE>, in the second phase layouts for parent cells are
|
|
||||||
* executed before layouts for child cells with <mxEvent.END_UPDATE>.
|
|
||||||
*/
|
|
||||||
executeLayoutForCells = (cells)=>
|
|
||||||
{
|
|
||||||
var sorted = mxUtils.sortCells(cells, false);
|
|
||||||
this.layoutCells(sorted, true);
|
|
||||||
this.layoutCells(sorted.reverse(), false);
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Function: layoutCells
|
|
||||||
*
|
|
||||||
* Executes all layouts which have been scheduled during the changes.
|
|
||||||
*/
|
|
||||||
layoutCells = (cells, bubble)=>
|
|
||||||
{
|
|
||||||
if (cells.length > 0)
|
|
||||||
{
|
|
||||||
// Invokes the layouts while removing duplicates
|
|
||||||
var model = this.getGraph().getModel();
|
|
||||||
|
|
||||||
model.beginUpdate();
|
|
||||||
try
|
|
||||||
{
|
|
||||||
var last = null;
|
|
||||||
|
|
||||||
for (var i = 0; i < cells.length; i++)
|
|
||||||
{
|
|
||||||
if (cells[i] != model.getRoot() && cells[i] != last)
|
|
||||||
{
|
|
||||||
this.executeLayout(cells[i], bubble);
|
|
||||||
last = cells[i];
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
this.fireEvent(new mxEventObject(mxEvent.LAYOUT_CELLS, 'cells', cells));
|
|
||||||
}
|
}
|
||||||
finally
|
};
|
||||||
{
|
|
||||||
model.endUpdate();
|
/**
|
||||||
|
* Function: cellsResized
|
||||||
|
*
|
||||||
|
* Called from <resizeHandler>.
|
||||||
|
*
|
||||||
|
* Parameters:
|
||||||
|
*
|
||||||
|
* cell - Array of <mxCells> that have been resized.
|
||||||
|
* bounds - <mxRectangle> taht represents the new bounds.
|
||||||
|
*/
|
||||||
|
cellsResized = (cells, bounds, prev) => {
|
||||||
|
if (cells != null && bounds != null) {
|
||||||
|
var model = this.getGraph().getModel();
|
||||||
|
|
||||||
|
for (var i = 0; i < cells.length; i++) {
|
||||||
|
var layout = this.getLayout(model.getParent(cells[i]), mxEvent.RESIZE_CELLS);
|
||||||
|
|
||||||
|
if (layout != null) {
|
||||||
|
layout.resizeCell(cells[i], bounds[i], prev[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function: executeLayout
|
* Function: getCellsForChanges
|
||||||
*
|
*
|
||||||
* Executes the given layout on the given parent.
|
* Returns the cells for which a layout should be executed.
|
||||||
*/
|
*/
|
||||||
executeLayout = (cell, bubble)=>
|
getCellsForChanges = (changes) => {
|
||||||
{
|
var result = [];
|
||||||
var layout = this.getLayout(cell, (bubble) ?
|
|
||||||
mxEvent.BEGIN_UPDATE : mxEvent.END_UPDATE);
|
|
||||||
|
|
||||||
if (layout != null)
|
for (var i = 0; i < changes.length; i++) {
|
||||||
{
|
var change = changes[i];
|
||||||
layout.execute(cell);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
if (change instanceof mxRootChange) {
|
||||||
* Function: destroy
|
return [];
|
||||||
*
|
} else {
|
||||||
* Removes all handlers from the <graph> and deletes the reference to it.
|
result = result.concat(this.getCellsForChange(change));
|
||||||
*/
|
}
|
||||||
destroy = ()=>
|
}
|
||||||
{
|
|
||||||
this.setGraph(null);
|
return result;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function: getCellsForChange
|
||||||
|
*
|
||||||
|
* Executes all layouts which have been scheduled during the
|
||||||
|
* changes.
|
||||||
|
*/
|
||||||
|
getCellsForChange = (change) => {
|
||||||
|
if (change instanceof mxChildChange) {
|
||||||
|
return this.addCellsWithLayout(change.child,
|
||||||
|
this.addCellsWithLayout(change.previous));
|
||||||
|
} else if (change instanceof mxTerminalChange ||
|
||||||
|
change instanceof mxGeometryChange) {
|
||||||
|
return this.addCellsWithLayout(change.cell);
|
||||||
|
} else if (change instanceof mxVisibleChange ||
|
||||||
|
change instanceof mxStyleChange) {
|
||||||
|
return this.addCellsWithLayout(change.cell);
|
||||||
|
}
|
||||||
|
|
||||||
|
return [];
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function: addCellsWithLayout
|
||||||
|
*
|
||||||
|
* Adds all ancestors of the given cell that have a layout.
|
||||||
|
*/
|
||||||
|
addCellsWithLayout = (cell, result) => {
|
||||||
|
return this.addDescendantsWithLayout(cell,
|
||||||
|
this.addAncestorsWithLayout(cell, result));
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function: addAncestorsWithLayout
|
||||||
|
*
|
||||||
|
* Adds all ancestors of the given cell that have a layout.
|
||||||
|
*/
|
||||||
|
addAncestorsWithLayout = (cell, result) => {
|
||||||
|
result = (result != null) ? result : [];
|
||||||
|
|
||||||
|
if (cell != null) {
|
||||||
|
var layout = this.hasLayout(cell);
|
||||||
|
|
||||||
|
if (layout != null) {
|
||||||
|
result.push(cell);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.isBubbling()) {
|
||||||
|
var model = this.getGraph().getModel();
|
||||||
|
this.addAncestorsWithLayout(
|
||||||
|
model.getParent(cell), result);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function: addDescendantsWithLayout
|
||||||
|
*
|
||||||
|
* Adds all descendants of the given cell that have a layout.
|
||||||
|
*/
|
||||||
|
addDescendantsWithLayout = (cell, result) => {
|
||||||
|
result = (result != null) ? result : [];
|
||||||
|
|
||||||
|
if (cell != null && this.hasLayout(cell)) {
|
||||||
|
var model = this.getGraph().getModel();
|
||||||
|
|
||||||
|
for (var i = 0; i < model.getChildCount(cell); i++) {
|
||||||
|
var child = model.getChildAt(cell, i);
|
||||||
|
|
||||||
|
if (this.hasLayout(child)) {
|
||||||
|
result.push(child);
|
||||||
|
this.addDescendantsWithLayout(child, result);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function: executeLayoutForCells
|
||||||
|
*
|
||||||
|
* Executes all layouts for the given cells in two phases: In the first phase
|
||||||
|
* layouts for child cells are executed before layouts for parent cells with
|
||||||
|
* <mxEvent.BEGIN_UPDATE>, in the second phase layouts for parent cells are
|
||||||
|
* executed before layouts for child cells with <mxEvent.END_UPDATE>.
|
||||||
|
*/
|
||||||
|
executeLayoutForCells = (cells) => {
|
||||||
|
var sorted = mxUtils.sortCells(cells, false);
|
||||||
|
this.layoutCells(sorted, true);
|
||||||
|
this.layoutCells(sorted.reverse(), false);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function: layoutCells
|
||||||
|
*
|
||||||
|
* Executes all layouts which have been scheduled during the changes.
|
||||||
|
*/
|
||||||
|
layoutCells = (cells, bubble) => {
|
||||||
|
if (cells.length > 0) {
|
||||||
|
// Invokes the layouts while removing duplicates
|
||||||
|
var model = this.getGraph().getModel();
|
||||||
|
|
||||||
|
model.beginUpdate();
|
||||||
|
try {
|
||||||
|
var last = null;
|
||||||
|
|
||||||
|
for (var i = 0; i < cells.length; i++) {
|
||||||
|
if (cells[i] != model.getRoot() && cells[i] != last) {
|
||||||
|
this.executeLayout(cells[i], bubble);
|
||||||
|
last = cells[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
this.fireEvent(new mxEventObject(mxEvent.LAYOUT_CELLS, 'cells', cells));
|
||||||
|
} finally {
|
||||||
|
model.endUpdate();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function: executeLayout
|
||||||
|
*
|
||||||
|
* Executes the given layout on the given parent.
|
||||||
|
*/
|
||||||
|
executeLayout = (cell, bubble) => {
|
||||||
|
var layout = this.getLayout(cell, (bubble) ?
|
||||||
|
mxEvent.BEGIN_UPDATE : mxEvent.END_UPDATE);
|
||||||
|
|
||||||
|
if (layout != null) {
|
||||||
|
layout.execute(cell);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function: destroy
|
||||||
|
*
|
||||||
|
* Removes all handlers from the <graph> and deletes the reference to it.
|
||||||
|
*/
|
||||||
|
destroy = () => {
|
||||||
|
this.setGraph(null);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export default mxLayoutManager;
|
||||||
|
|
|
@ -2,256 +2,244 @@
|
||||||
* Copyright (c) 2006-2015, JGraph Ltd
|
* Copyright (c) 2006-2015, JGraph Ltd
|
||||||
* Copyright (c) 2006-2015, Gaudenz Alder
|
* Copyright (c) 2006-2015, Gaudenz Alder
|
||||||
*/
|
*/
|
||||||
/**
|
|
||||||
* Class: mxMultiplicity
|
|
||||||
*
|
|
||||||
* Defines invalid connections along with the error messages that they produce.
|
|
||||||
* To add or remove rules on a graph, you must add/remove instances of this
|
|
||||||
* class to <mxGraph.multiplicities>.
|
|
||||||
*
|
|
||||||
* Example:
|
|
||||||
*
|
|
||||||
* (code)
|
|
||||||
* graph.multiplicities.push(new mxMultiplicity(
|
|
||||||
* true, 'rectangle', null, null, 0, 2, ['circle'],
|
|
||||||
* 'Only 2 targets allowed',
|
|
||||||
* 'Only circle targets allowed'));
|
|
||||||
* (end)
|
|
||||||
*
|
|
||||||
* Defines a rule where each rectangle must be connected to no more than 2
|
|
||||||
* circles and no other types of targets are allowed.
|
|
||||||
*
|
|
||||||
* Constructor: mxMultiplicity
|
|
||||||
*
|
|
||||||
* Instantiate class mxMultiplicity in order to describe allowed
|
|
||||||
* connections in a graph. Not all constraints can be enforced while
|
|
||||||
* editing, some must be checked at validation time. The <countError> and
|
|
||||||
* <typeError> are treated as resource keys in <mxResources>.
|
|
||||||
*
|
|
||||||
* Parameters:
|
|
||||||
*
|
|
||||||
* source - Boolean indicating if this rule applies to the source or target
|
|
||||||
* terminal.
|
|
||||||
* type - Type of the source or target terminal that this rule applies to.
|
|
||||||
* See <type> for more information.
|
|
||||||
* attr - Optional attribute name to match the source or target terminal.
|
|
||||||
* value - Optional attribute value to match the source or target terminal.
|
|
||||||
* min - Minimum number of edges for this rule. Default is 1.
|
|
||||||
* max - Maximum number of edges for this rule. n means infinite. Default
|
|
||||||
* is n.
|
|
||||||
* validNeighbors - Array of types of the opposite terminal for which this
|
|
||||||
* rule applies.
|
|
||||||
* countError - Error to be displayed for invalid number of edges.
|
|
||||||
* typeError - Error to be displayed for invalid opposite terminals.
|
|
||||||
* validNeighborsAllowed - Optional boolean indicating if the array of
|
|
||||||
* opposite types should be valid or invalid.
|
|
||||||
*/
|
|
||||||
function mxMultiplicity(source, type, attr, value, min, max,
|
|
||||||
validNeighbors, countError, typeError, validNeighborsAllowed)
|
|
||||||
{
|
|
||||||
this.source = source;
|
|
||||||
this.type = type;
|
|
||||||
this.attr = attr;
|
|
||||||
this.value = value;
|
|
||||||
this.min = (min != null) ? min : 0;
|
|
||||||
this.max = (max != null) ? max : 'n';
|
|
||||||
this.validNeighbors = validNeighbors;
|
|
||||||
this.countError = mxResources.get(countError) || countError;
|
|
||||||
this.typeError = mxResources.get(typeError) || typeError;
|
|
||||||
this.validNeighborsAllowed = (validNeighborsAllowed != null) ?
|
|
||||||
validNeighborsAllowed : true;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
class mxMultiplicity {
|
||||||
* Variable: type
|
/**
|
||||||
*
|
* Variable: type
|
||||||
* Defines the type of the source or target terminal. The type is a string
|
*
|
||||||
* passed to <mxUtils.isNode> together with the source or target vertex
|
* Defines the type of the source or target terminal. The type is a string
|
||||||
* value as the first argument.
|
* passed to <mxUtils.isNode> together with the source or target vertex
|
||||||
*/
|
* value as the first argument.
|
||||||
type = null;
|
*/
|
||||||
|
type = null;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Variable: attr
|
* Variable: attr
|
||||||
*
|
*
|
||||||
* Optional string that specifies the attributename to be passed to
|
* Optional string that specifies the attributename to be passed to
|
||||||
* <mxUtils.isNode> to check if the rule applies to a cell.
|
* <mxUtils.isNode> to check if the rule applies to a cell.
|
||||||
*/
|
*/
|
||||||
attr = null;
|
attr = null;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Variable: value
|
* Variable: value
|
||||||
*
|
*
|
||||||
* Optional string that specifies the value of the attribute to be passed
|
* Optional string that specifies the value of the attribute to be passed
|
||||||
* to <mxUtils.isNode> to check if the rule applies to a cell.
|
* to <mxUtils.isNode> to check if the rule applies to a cell.
|
||||||
*/
|
*/
|
||||||
value = null;
|
value = null;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Variable: source
|
* Variable: source
|
||||||
*
|
*
|
||||||
* Boolean that specifies if the rule is applied to the source or target
|
* Boolean that specifies if the rule is applied to the source or target
|
||||||
* terminal of an edge.
|
* terminal of an edge.
|
||||||
*/
|
*/
|
||||||
source = null;
|
source = null;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Variable: min
|
* Variable: min
|
||||||
*
|
*
|
||||||
* Defines the minimum number of connections for which this rule applies.
|
* Defines the minimum number of connections for which this rule applies.
|
||||||
* Default is 0.
|
* Default is 0.
|
||||||
*/
|
*/
|
||||||
min = null;
|
min = null;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Variable: max
|
* Variable: max
|
||||||
*
|
*
|
||||||
* Defines the maximum number of connections for which this rule applies.
|
* Defines the maximum number of connections for which this rule applies.
|
||||||
* A value of 'n' means unlimited times. Default is 'n'.
|
* A value of 'n' means unlimited times. Default is 'n'.
|
||||||
*/
|
*/
|
||||||
max = null;
|
max = null;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Variable: validNeighbors
|
* Variable: validNeighbors
|
||||||
*
|
*
|
||||||
* Holds an array of strings that specify the type of neighbor for which
|
* Holds an array of strings that specify the type of neighbor for which
|
||||||
* this rule applies. The strings are used in <mxCell.is> on the opposite
|
* this rule applies. The strings are used in <mxCell.is> on the opposite
|
||||||
* terminal to check if the rule applies to the connection.
|
* terminal to check if the rule applies to the connection.
|
||||||
*/
|
*/
|
||||||
validNeighbors = null;
|
validNeighbors = null;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Variable: validNeighborsAllowed
|
* Variable: validNeighborsAllowed
|
||||||
*
|
*
|
||||||
* Boolean indicating if the list of validNeighbors are those that are allowed
|
* Boolean indicating if the list of validNeighbors are those that are allowed
|
||||||
* for this rule or those that are not allowed for this rule.
|
* for this rule or those that are not allowed for this rule.
|
||||||
*/
|
*/
|
||||||
validNeighborsAllowed = true;
|
validNeighborsAllowed = true;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Variable: countError
|
* Variable: countError
|
||||||
*
|
*
|
||||||
* Holds the localized error message to be displayed if the number of
|
* Holds the localized error message to be displayed if the number of
|
||||||
* connections for which the rule applies is smaller than <min> or greater
|
* connections for which the rule applies is smaller than <min> or greater
|
||||||
* than <max>.
|
* than <max>.
|
||||||
*/
|
*/
|
||||||
countError = null;
|
countError = null;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Variable: typeError
|
* Variable: typeError
|
||||||
*
|
*
|
||||||
* Holds the localized error message to be displayed if the type of the
|
* Holds the localized error message to be displayed if the type of the
|
||||||
* neighbor for a connection does not match the rule.
|
* neighbor for a connection does not match the rule.
|
||||||
*/
|
*/
|
||||||
typeError = null;
|
typeError = null;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function: check
|
* Class: mxMultiplicity
|
||||||
*
|
*
|
||||||
* Checks the multiplicity for the given arguments and returns the error
|
* Defines invalid connections along with the error messages that they produce.
|
||||||
* for the given connection or null if the multiplicity does not apply.
|
* To add or remove rules on a graph, you must add/remove instances of this
|
||||||
*
|
* class to <mxGraph.multiplicities>.
|
||||||
* Parameters:
|
*
|
||||||
*
|
* Example:
|
||||||
* graph - Reference to the enclosing <mxGraph> instance.
|
*
|
||||||
* edge - <mxCell> that represents the edge to validate.
|
* (code)
|
||||||
* source - <mxCell> that represents the source terminal.
|
* graph.multiplicities.push(new mxMultiplicity(
|
||||||
* target - <mxCell> that represents the target terminal.
|
* true, 'rectangle', null, null, 0, 2, ['circle'],
|
||||||
* sourceOut - Number of outgoing edges from the source terminal.
|
* 'Only 2 targets allowed',
|
||||||
* targetIn - Number of incoming edges for the target terminal.
|
* 'Only circle targets allowed'));
|
||||||
*/
|
* (end)
|
||||||
check = (graph, edge, source, target, sourceOut, targetIn)=>
|
*
|
||||||
{
|
* Defines a rule where each rectangle must be connected to no more than 2
|
||||||
var error = '';
|
* circles and no other types of targets are allowed.
|
||||||
|
*
|
||||||
|
* Constructor: mxMultiplicity
|
||||||
|
*
|
||||||
|
* Instantiate class mxMultiplicity in order to describe allowed
|
||||||
|
* connections in a graph. Not all constraints can be enforced while
|
||||||
|
* editing, some must be checked at validation time. The <countError> and
|
||||||
|
* <typeError> are treated as resource keys in <mxResources>.
|
||||||
|
*
|
||||||
|
* Parameters:
|
||||||
|
*
|
||||||
|
* source - Boolean indicating if this rule applies to the source or target
|
||||||
|
* terminal.
|
||||||
|
* type - Type of the source or target terminal that this rule applies to.
|
||||||
|
* See <type> for more information.
|
||||||
|
* attr - Optional attribute name to match the source or target terminal.
|
||||||
|
* value - Optional attribute value to match the source or target terminal.
|
||||||
|
* min - Minimum number of edges for this rule. Default is 1.
|
||||||
|
* max - Maximum number of edges for this rule. n means infinite. Default
|
||||||
|
* is n.
|
||||||
|
* validNeighbors - Array of types of the opposite terminal for which this
|
||||||
|
* rule applies.
|
||||||
|
* countError - Error to be displayed for invalid number of edges.
|
||||||
|
* typeError - Error to be displayed for invalid opposite terminals.
|
||||||
|
* validNeighborsAllowed - Optional boolean indicating if the array of
|
||||||
|
* opposite types should be valid or invalid.
|
||||||
|
*/
|
||||||
|
constructor(source, type, attr, value, min, max,
|
||||||
|
validNeighbors, countError, typeError, validNeighborsAllowed) {
|
||||||
|
this.source = source;
|
||||||
|
this.type = type;
|
||||||
|
this.attr = attr;
|
||||||
|
this.value = value;
|
||||||
|
this.min = (min != null) ? min : 0;
|
||||||
|
this.max = (max != null) ? max : 'n';
|
||||||
|
this.validNeighbors = validNeighbors;
|
||||||
|
this.countError = mxResources.get(countError) || countError;
|
||||||
|
this.typeError = mxResources.get(typeError) || typeError;
|
||||||
|
this.validNeighborsAllowed = (validNeighborsAllowed != null) ?
|
||||||
|
validNeighborsAllowed : true;
|
||||||
|
};
|
||||||
|
|
||||||
if ((this.source && this.checkTerminal(graph, source, edge)) ||
|
/**
|
||||||
(!this.source && this.checkTerminal(graph, target, edge)))
|
* Function: check
|
||||||
{
|
*
|
||||||
if (this.countError != null &&
|
* Checks the multiplicity for the given arguments and returns the error
|
||||||
((this.source && (this.max == 0 || (sourceOut >= this.max))) ||
|
* for the given connection or null if the multiplicity does not apply.
|
||||||
(!this.source && (this.max == 0 || (targetIn >= this.max)))))
|
*
|
||||||
{
|
* Parameters:
|
||||||
error += this.countError + '\n';
|
*
|
||||||
}
|
* graph - Reference to the enclosing <mxGraph> instance.
|
||||||
|
* edge - <mxCell> that represents the edge to validate.
|
||||||
|
* source - <mxCell> that represents the source terminal.
|
||||||
|
* target - <mxCell> that represents the target terminal.
|
||||||
|
* sourceOut - Number of outgoing edges from the source terminal.
|
||||||
|
* targetIn - Number of incoming edges for the target terminal.
|
||||||
|
*/
|
||||||
|
check = (graph, edge, source, target, sourceOut, targetIn) => {
|
||||||
|
var error = '';
|
||||||
|
|
||||||
if (this.validNeighbors != null && this.typeError != null && this.validNeighbors.length > 0)
|
if ((this.source && this.checkTerminal(graph, source, edge)) ||
|
||||||
{
|
(!this.source && this.checkTerminal(graph, target, edge))) {
|
||||||
var isValid = this.checkNeighbors(graph, edge, source, target);
|
if (this.countError != null &&
|
||||||
|
((this.source && (this.max == 0 || (sourceOut >= this.max))) ||
|
||||||
|
(!this.source && (this.max == 0 || (targetIn >= this.max))))) {
|
||||||
|
error += this.countError + '\n';
|
||||||
|
}
|
||||||
|
|
||||||
if (!isValid)
|
if (this.validNeighbors != null && this.typeError != null && this.validNeighbors.length > 0) {
|
||||||
{
|
var isValid = this.checkNeighbors(graph, edge, source, target);
|
||||||
error += this.typeError + '\n';
|
|
||||||
|
if (!isValid) {
|
||||||
|
error += this.typeError + '\n';
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
return (error.length > 0) ? error : null;
|
return (error.length > 0) ? error : null;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function: checkNeighbors
|
* Function: checkNeighbors
|
||||||
*
|
*
|
||||||
* Checks if there are any valid neighbours in <validNeighbors>. This is only
|
* Checks if there are any valid neighbours in <validNeighbors>. This is only
|
||||||
* called if <validNeighbors> is a non-empty array.
|
* called if <validNeighbors> is a non-empty array.
|
||||||
*/
|
*/
|
||||||
checkNeighbors = (graph, edge, source, target)=>
|
checkNeighbors = (graph, edge, source, target) => {
|
||||||
{
|
var sourceValue = graph.model.getValue(source);
|
||||||
var sourceValue = graph.model.getValue(source);
|
var targetValue = graph.model.getValue(target);
|
||||||
var targetValue = graph.model.getValue(target);
|
var isValid = !this.validNeighborsAllowed;
|
||||||
var isValid = !this.validNeighborsAllowed;
|
var valid = this.validNeighbors;
|
||||||
var valid = this.validNeighbors;
|
|
||||||
|
|
||||||
for (var j = 0; j < valid.length; j++)
|
for (var j = 0; j < valid.length; j++) {
|
||||||
{
|
if (this.source &&
|
||||||
if (this.source &&
|
this.checkType(graph, targetValue, valid[j])) {
|
||||||
this.checkType(graph, targetValue, valid[j]))
|
isValid = this.validNeighborsAllowed;
|
||||||
{
|
break;
|
||||||
isValid = this.validNeighborsAllowed;
|
} else if (!this.source &&
|
||||||
break;
|
this.checkType(graph, sourceValue, valid[j])) {
|
||||||
|
isValid = this.validNeighborsAllowed;
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if (!this.source &&
|
|
||||||
this.checkType(graph, sourceValue, valid[j]))
|
return isValid;
|
||||||
{
|
};
|
||||||
isValid = this.validNeighborsAllowed;
|
|
||||||
break;
|
/**
|
||||||
|
* Function: checkTerminal
|
||||||
|
*
|
||||||
|
* Checks the given terminal cell and returns true if this rule applies. The
|
||||||
|
* given cell is the source or target of the given edge, depending on
|
||||||
|
* <source>. This implementation uses <checkType> on the terminal's value.
|
||||||
|
*/
|
||||||
|
checkTerminal = (graph, terminal, edge) => {
|
||||||
|
var value = graph.model.getValue(terminal);
|
||||||
|
|
||||||
|
return this.checkType(graph, value, this.type, this.attr, this.value);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function: checkType
|
||||||
|
*
|
||||||
|
* Checks the type of the given value.
|
||||||
|
*/
|
||||||
|
checkType = (graph, value, type, attr, attrValue) => {
|
||||||
|
if (value != null) {
|
||||||
|
if (!isNaN(value.nodeType)) // Checks if value is a DOM node
|
||||||
|
{
|
||||||
|
return mxUtils.isNode(value, type, attr, attrValue);
|
||||||
|
} else {
|
||||||
|
return value == type;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
return false;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
return isValid;
|
export default mxMultiplicity;
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Function: checkTerminal
|
|
||||||
*
|
|
||||||
* Checks the given terminal cell and returns true if this rule applies. The
|
|
||||||
* given cell is the source or target of the given edge, depending on
|
|
||||||
* <source>. This implementation uses <checkType> on the terminal's value.
|
|
||||||
*/
|
|
||||||
checkTerminal = (graph, terminal, edge)=>
|
|
||||||
{
|
|
||||||
var value = graph.model.getValue(terminal);
|
|
||||||
|
|
||||||
return this.checkType(graph, value, this.type, this.attr, this.value);
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Function: checkType
|
|
||||||
*
|
|
||||||
* Checks the type of the given value.
|
|
||||||
*/
|
|
||||||
checkType = (graph, value, type, attr, attrValue)=>
|
|
||||||
{
|
|
||||||
if (value != null)
|
|
||||||
{
|
|
||||||
if (!isNaN(value.nodeType)) // Checks if value is a DOM node
|
|
||||||
{
|
|
||||||
return mxUtils.isNode(value, type, attr, attrValue);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return value == type;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
};
|
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -2,14 +2,16 @@
|
||||||
* Copyright (c) 2006-2015, JGraph Ltd
|
* Copyright (c) 2006-2015, JGraph Ltd
|
||||||
* Copyright (c) 2006-2015, Gaudenz Alder
|
* Copyright (c) 2006-2015, Gaudenz Alder
|
||||||
*/
|
*/
|
||||||
var mxStyleRegistry =
|
|
||||||
{
|
import mxConstants from "../util/mxConstants";
|
||||||
|
|
||||||
|
var mxStyleRegistry = {
|
||||||
/**
|
/**
|
||||||
* Class: mxStyleRegistry
|
* Class: mxStyleRegistry
|
||||||
*
|
*
|
||||||
* Singleton class that acts as a global converter from string to object values
|
* Singleton class that acts as a global converter from string to object values
|
||||||
* in a style. This is currently only used to perimeters and edge styles.
|
* in a style. This is currently only used to perimeters and edge styles.
|
||||||
*
|
*
|
||||||
* Variable: values
|
* Variable: values
|
||||||
*
|
*
|
||||||
* Maps from strings to objects.
|
* Maps from strings to objects.
|
||||||
|
@ -21,8 +23,7 @@ var mxStyleRegistry =
|
||||||
*
|
*
|
||||||
* Puts the given object into the registry under the given name.
|
* Puts the given object into the registry under the given name.
|
||||||
*/
|
*/
|
||||||
putValue: (name, obj)=>
|
putValue: (name, obj) => {
|
||||||
{
|
|
||||||
mxStyleRegistry.values[name] = obj;
|
mxStyleRegistry.values[name] = obj;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -31,29 +32,23 @@ var mxStyleRegistry =
|
||||||
*
|
*
|
||||||
* Returns the value associated with the given name.
|
* Returns the value associated with the given name.
|
||||||
*/
|
*/
|
||||||
getValue: (name)=>
|
getValue: (name) => {
|
||||||
{
|
|
||||||
return mxStyleRegistry.values[name];
|
return mxStyleRegistry.values[name];
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function: getName
|
* Function: getName
|
||||||
*
|
*
|
||||||
* Returns the name for the given value.
|
* Returns the name for the given value.
|
||||||
*/
|
*/
|
||||||
getName: (value)=>
|
getName: (value) => {
|
||||||
{
|
for (var key in mxStyleRegistry.values) {
|
||||||
for (var key in mxStyleRegistry.values)
|
if (mxStyleRegistry.values[key] === value) {
|
||||||
{
|
|
||||||
if (mxStyleRegistry.values[key] == value)
|
|
||||||
{
|
|
||||||
return key;
|
return key;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
mxStyleRegistry.putValue(mxConstants.EDGESTYLE_ELBOW, mxEdgeStyle.ElbowConnector);
|
mxStyleRegistry.putValue(mxConstants.EDGESTYLE_ELBOW, mxEdgeStyle.ElbowConnector);
|
||||||
|
@ -69,3 +64,5 @@ mxStyleRegistry.putValue(mxConstants.PERIMETER_RECTANGLE, mxPerimeter.RectangleP
|
||||||
mxStyleRegistry.putValue(mxConstants.PERIMETER_RHOMBUS, mxPerimeter.RhombusPerimeter);
|
mxStyleRegistry.putValue(mxConstants.PERIMETER_RHOMBUS, mxPerimeter.RhombusPerimeter);
|
||||||
mxStyleRegistry.putValue(mxConstants.PERIMETER_TRIANGLE, mxPerimeter.TrianglePerimeter);
|
mxStyleRegistry.putValue(mxConstants.PERIMETER_TRIANGLE, mxPerimeter.TrianglePerimeter);
|
||||||
mxStyleRegistry.putValue(mxConstants.PERIMETER_HEXAGON, mxPerimeter.HexagonPerimeter);
|
mxStyleRegistry.putValue(mxConstants.PERIMETER_HEXAGON, mxPerimeter.HexagonPerimeter);
|
||||||
|
|
||||||
|
export default mxStyleRegistry;
|
||||||
|
|
|
@ -7,127 +7,121 @@
|
||||||
*
|
*
|
||||||
* Creates a temporary set of cell states.
|
* Creates a temporary set of cell states.
|
||||||
*/
|
*/
|
||||||
function mxTemporaryCellStates(view, scale, cells, isCellVisibleFn, getLinkForCellState)
|
|
||||||
{
|
|
||||||
scale = (scale != null) ? scale : 1;
|
|
||||||
this.view = view;
|
|
||||||
|
|
||||||
// Stores the previous state
|
|
||||||
this.oldValidateCellState = view.validateCellState;
|
|
||||||
this.oldBounds = view.getGraphBounds();
|
|
||||||
this.oldStates = view.getStates();
|
|
||||||
this.oldScale = view.getScale();
|
|
||||||
this.oldDoRedrawShape = view.graph.cellRenderer.doRedrawShape;
|
|
||||||
|
|
||||||
var self = this;
|
import mxRectangle from "../util/mxRectangle";
|
||||||
|
import mxDictionary from "../util/mxDictionary";
|
||||||
|
|
||||||
// Overrides doRedrawShape and paint shape to add links on shapes
|
class mxTemporaryCellStates {
|
||||||
if (getLinkForCellState != null)
|
/**
|
||||||
{
|
* Variable: view
|
||||||
view.graph.cellRenderer.doRedrawShape = (state)=>
|
*
|
||||||
{
|
* Holds the width of the rectangle. Default is 0.
|
||||||
var oldPaint = state.shape.paint;
|
*/
|
||||||
|
view = null;
|
||||||
state.shape.paint = (c)=>
|
|
||||||
{
|
/**
|
||||||
var link = getLinkForCellState(state);
|
* Variable: oldStates
|
||||||
|
*
|
||||||
if (link != null)
|
* Holds the height of the rectangle. Default is 0.
|
||||||
{
|
*/
|
||||||
c.setLink(link);
|
oldStates = null;
|
||||||
}
|
|
||||||
|
/**
|
||||||
oldPaint.apply(this, arguments);
|
* Variable: oldBounds
|
||||||
|
*
|
||||||
if (link != null)
|
* Holds the height of the rectangle. Default is 0.
|
||||||
{
|
*/
|
||||||
c.setLink(null);
|
oldBounds = null;
|
||||||
}
|
|
||||||
|
/**
|
||||||
|
* Variable: oldScale
|
||||||
|
*
|
||||||
|
* Holds the height of the rectangle. Default is 0.
|
||||||
|
*/
|
||||||
|
oldScale = null;
|
||||||
|
|
||||||
|
constructor(view, scale, cells, isCellVisibleFn, getLinkForCellState) {
|
||||||
|
scale = (scale != null) ? scale : 1;
|
||||||
|
this.view = view;
|
||||||
|
|
||||||
|
// Stores the previous state
|
||||||
|
this.oldValidateCellState = view.validateCellState;
|
||||||
|
this.oldBounds = view.getGraphBounds();
|
||||||
|
this.oldStates = view.getStates();
|
||||||
|
this.oldScale = view.getScale();
|
||||||
|
this.oldDoRedrawShape = view.graph.cellRenderer.doRedrawShape;
|
||||||
|
|
||||||
|
var self = this;
|
||||||
|
|
||||||
|
// Overrides doRedrawShape and paint shape to add links on shapes
|
||||||
|
if (getLinkForCellState != null) {
|
||||||
|
view.graph.cellRenderer.doRedrawShape = (state) => {
|
||||||
|
var oldPaint = state.shape.paint;
|
||||||
|
|
||||||
|
state.shape.paint = (c) => {
|
||||||
|
var link = getLinkForCellState(state);
|
||||||
|
|
||||||
|
if (link != null) {
|
||||||
|
c.setLink(link);
|
||||||
|
}
|
||||||
|
|
||||||
|
oldPaint.apply(this, arguments);
|
||||||
|
|
||||||
|
if (link != null) {
|
||||||
|
c.setLink(null);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
self.oldDoRedrawShape.apply(view.graph.cellRenderer, arguments);
|
||||||
|
state.shape.paint = oldPaint;
|
||||||
};
|
};
|
||||||
|
}
|
||||||
self.oldDoRedrawShape.apply(view.graph.cellRenderer, arguments);
|
|
||||||
state.shape.paint = oldPaint;
|
// Overrides validateCellState to ignore invisible cells
|
||||||
|
view.validateCellState = (cell, resurse) => {
|
||||||
|
if (cell == null || isCellVisibleFn == null || isCellVisibleFn(cell)) {
|
||||||
|
return self.oldValidateCellState.apply(view, arguments);
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
};
|
};
|
||||||
}
|
|
||||||
|
|
||||||
// Overrides validateCellState to ignore invisible cells
|
// Creates space for new states
|
||||||
view.validateCellState = (cell, resurse)=>
|
view.setStates(new mxDictionary());
|
||||||
{
|
view.setScale(scale);
|
||||||
if (cell == null || isCellVisibleFn == null || isCellVisibleFn(cell))
|
|
||||||
{
|
if (cells != null) {
|
||||||
return self.oldValidateCellState.apply(view, arguments);
|
view.resetValidationState();
|
||||||
|
var bbox = null;
|
||||||
|
|
||||||
|
// Validates the vertices and edges without adding them to
|
||||||
|
// the model so that the original cells are not modified
|
||||||
|
for (var i = 0; i < cells.length; i++) {
|
||||||
|
var bounds = view.getBoundingBox(view.validateCellState(view.validateCell(cells[i])));
|
||||||
|
|
||||||
|
if (bbox == null) {
|
||||||
|
bbox = bounds;
|
||||||
|
} else {
|
||||||
|
bbox.add(bounds);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
view.setGraphBounds(bbox || new mxRectangle());
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// Creates space for new states
|
|
||||||
view.setStates(new mxDictionary());
|
|
||||||
view.setScale(scale);
|
|
||||||
|
|
||||||
if (cells != null)
|
|
||||||
{
|
|
||||||
view.resetValidationState();
|
|
||||||
var bbox = null;
|
|
||||||
|
|
||||||
// Validates the vertices and edges without adding them to
|
/**
|
||||||
// the model so that the original cells are not modified
|
* Function: destroy
|
||||||
for (var i = 0; i < cells.length; i++)
|
*
|
||||||
{
|
* Returns the top, left corner as a new <mxPoint>.
|
||||||
var bounds = view.getBoundingBox(view.validateCellState(view.validateCell(cells[i])));
|
*/
|
||||||
|
destroy = () => {
|
||||||
if (bbox == null)
|
this.view.setScale(this.oldScale);
|
||||||
{
|
this.view.setStates(this.oldStates);
|
||||||
bbox = bounds;
|
this.view.setGraphBounds(this.oldBounds);
|
||||||
}
|
this.view.validateCellState = this.oldValidateCellState;
|
||||||
else
|
this.view.graph.cellRenderer.doRedrawShape = this.oldDoRedrawShape;
|
||||||
{
|
};
|
||||||
bbox.add(bounds);
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
view.setGraphBounds(bbox || new mxRectangle());
|
export default mxTemporaryCellStates;
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Variable: view
|
|
||||||
*
|
|
||||||
* Holds the width of the rectangle. Default is 0.
|
|
||||||
*/
|
|
||||||
view = null;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Variable: oldStates
|
|
||||||
*
|
|
||||||
* Holds the height of the rectangle. Default is 0.
|
|
||||||
*/
|
|
||||||
oldStates = null;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Variable: oldBounds
|
|
||||||
*
|
|
||||||
* Holds the height of the rectangle. Default is 0.
|
|
||||||
*/
|
|
||||||
oldBounds = null;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Variable: oldScale
|
|
||||||
*
|
|
||||||
* Holds the height of the rectangle. Default is 0.
|
|
||||||
*/
|
|
||||||
oldScale = null;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Function: destroy
|
|
||||||
*
|
|
||||||
* Returns the top, left corner as a new <mxPoint>.
|
|
||||||
*/
|
|
||||||
destroy = ()=>
|
|
||||||
{
|
|
||||||
this.view.setScale(this.oldScale);
|
|
||||||
this.view.setStates(this.oldStates);
|
|
||||||
this.view.setGraphBounds(this.oldBounds);
|
|
||||||
this.view.validateCellState = this.oldValidateCellState;
|
|
||||||
this.view.graph.cellRenderer.doRedrawShape = this.oldDoRedrawShape;
|
|
||||||
};
|
|
||||||
|
|
Loading…
Reference in New Issue