updates to js syntax
parent
fc98630dad
commit
8ed2f25c20
|
@ -3,7 +3,7 @@
|
|||
* Copyright (c) 2006-2018, Gaudenz Alder
|
||||
*/
|
||||
|
||||
import mxRectangle from "FIXME";
|
||||
import mxRectangle from "../util/mxRectangle";
|
||||
import mxDictionary from "FIXME";
|
||||
|
||||
class mxGraphLayout {
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
* Copyright (c) 2006-2015, Gaudenz Alder
|
||||
*/
|
||||
|
||||
import mxRectangle from "FIXME";
|
||||
import mxRectangle from "../util/mxRectangle";
|
||||
|
||||
class mxPartitionLayout extends mxGraphLayout {
|
||||
/**
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
*/
|
||||
|
||||
import mxPoint from "FIXME";
|
||||
import mxRectangle from "FIXME";
|
||||
import mxRectangle from "../util/mxRectangle";
|
||||
|
||||
class mxGeometry extends mxRectangle {
|
||||
/**
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
* Copyright (c) 2006-2015, Gaudenz Alder
|
||||
*/
|
||||
|
||||
import mxRectangle from "FIXME";
|
||||
import mxRectangle from "../util/mxRectangle";
|
||||
|
||||
class mxDoubleEllipse extends mxShape {
|
||||
/**
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
* Copyright (c) 2006-2015, Gaudenz Alder
|
||||
*/
|
||||
|
||||
import mxRectangle from "FIXME";
|
||||
import mxRectangle from "../util/mxRectangle";
|
||||
import mxConnectionConstraint from "FIXME";
|
||||
|
||||
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, Gaudenz Alder
|
||||
*/
|
||||
/**
|
||||
*
|
||||
* Class: mxAnimation
|
||||
*
|
||||
* 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;
|
||||
};
|
||||
import mxUtils from "./mxUtils";
|
||||
import mxEventSource from "./mxEventSource";
|
||||
import mxEventObject from "./mxEventObject";
|
||||
|
||||
/**
|
||||
* Extends mxEventSource.
|
||||
*/
|
||||
mxAnimation.prototype = new mxEventSource();
|
||||
constructor = mxAnimation;
|
||||
class mxAnimation extends mxEventSource {
|
||||
/**
|
||||
* Variable: delay
|
||||
*
|
||||
* Specifies the delay between the animation steps. Defaul is 30ms.
|
||||
*/
|
||||
delay = null;
|
||||
|
||||
/**
|
||||
* Variable: delay
|
||||
*
|
||||
* Specifies the delay between the animation steps. Defaul is 30ms.
|
||||
*/
|
||||
delay = null;
|
||||
/**
|
||||
* Variable: thread
|
||||
*
|
||||
* Reference to the thread while the animation is running.
|
||||
*/
|
||||
thread = null;
|
||||
|
||||
/**
|
||||
* Variable: thread
|
||||
*
|
||||
* Reference to the thread while the animation is running.
|
||||
*/
|
||||
thread = null;
|
||||
/**
|
||||
*
|
||||
* Class: mxAnimation
|
||||
*
|
||||
* Implements a basic animation in JavaScript.
|
||||
*
|
||||
* Constructor: mxAnimation
|
||||
*
|
||||
* Constructs an animation.
|
||||
*
|
||||
* Parameters:
|
||||
*
|
||||
* graph - Reference to the enclosing <mxGraph>.
|
||||
*/
|
||||
constructor(delay) {
|
||||
this.delay = (delay != null) ? delay : 20;
|
||||
};
|
||||
|
||||
/**
|
||||
* Function: isRunning
|
||||
*
|
||||
* Returns true if the animation is running.
|
||||
*/
|
||||
isRunning = ()=>
|
||||
{
|
||||
return this.thread != null;
|
||||
};
|
||||
/**
|
||||
* Function: isRunning
|
||||
*
|
||||
* Returns true if the animation is running.
|
||||
*/
|
||||
isRunning = () => {
|
||||
return this.thread != null;
|
||||
};
|
||||
|
||||
/**
|
||||
* Function: startAnimation
|
||||
*
|
||||
* Starts the animation by repeatedly invoking updateAnimation.
|
||||
*/
|
||||
startAnimation = ()=>
|
||||
{
|
||||
if (this.thread == null)
|
||||
{
|
||||
this.thread = window.setInterval(mxUtils.bind(this, this.updateAnimation), this.delay);
|
||||
}
|
||||
};
|
||||
/**
|
||||
* Function: startAnimation
|
||||
*
|
||||
* Starts the animation by repeatedly invoking updateAnimation.
|
||||
*/
|
||||
startAnimation = () => {
|
||||
if (this.thread == null) {
|
||||
this.thread = window.setInterval(mxUtils.bind(this, this.updateAnimation), this.delay);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Function: updateAnimation
|
||||
*
|
||||
* Hook for subclassers to implement the animation. Invoke stopAnimation
|
||||
* when finished, startAnimation to resume. This is called whenever the
|
||||
* timer fires and fires an mxEvent.EXECUTE event with no properties.
|
||||
*/
|
||||
updateAnimation = ()=>
|
||||
{
|
||||
this.fireEvent(new mxEventObject(mxEvent.EXECUTE));
|
||||
};
|
||||
/**
|
||||
* Function: updateAnimation
|
||||
*
|
||||
* Hook for subclassers to implement the animation. Invoke stopAnimation
|
||||
* when finished, startAnimation to resume. This is called whenever the
|
||||
* timer fires and fires an mxEvent.EXECUTE event with no properties.
|
||||
*/
|
||||
updateAnimation = () => {
|
||||
this.fireEvent(new mxEventObject(mxEvent.EXECUTE));
|
||||
};
|
||||
|
||||
/**
|
||||
* Function: stopAnimation
|
||||
*
|
||||
* Stops the animation by deleting the timer and fires an <mxEvent.DONE>.
|
||||
*/
|
||||
stopAnimation = ()=>
|
||||
{
|
||||
if (this.thread != null)
|
||||
{
|
||||
window.clearInterval(this.thread);
|
||||
this.thread = null;
|
||||
this.fireEvent(new mxEventObject(mxEvent.DONE));
|
||||
}
|
||||
};
|
||||
/**
|
||||
* Function: stopAnimation
|
||||
*
|
||||
* Stops the animation by deleting the timer and fires an <mxEvent.DONE>.
|
||||
*/
|
||||
stopAnimation = () => {
|
||||
if (this.thread != null) {
|
||||
window.clearInterval(this.thread);
|
||||
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, Gaudenz Alder
|
||||
*/
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
function mxAutoSaveManager(graph)
|
||||
{
|
||||
// Notifies the manager of a change
|
||||
this.changeHandler = mxUtils.bind(this, (sender, evt)=>
|
||||
{
|
||||
if (this.isEnabled())
|
||||
{
|
||||
this.graphModelChanged(evt.getProperty('edit').changes);
|
||||
import mxEventSource from "./mxEventSource";
|
||||
import mxUtils from "./mxUtils";
|
||||
|
||||
class mxAutoSaveManager extends mxEventSource {
|
||||
/**
|
||||
* Variable: graph
|
||||
*
|
||||
* Reference to the enclosing <mxGraph>.
|
||||
*/
|
||||
graph = null;
|
||||
|
||||
/**
|
||||
* Variable: autoSaveDelay
|
||||
*
|
||||
* Minimum amount of seconds between two consecutive autosaves. Eg. a
|
||||
* value of 1 (s) means the graph is not stored more than once per second.
|
||||
* Default is 10.
|
||||
*/
|
||||
autoSaveDelay = 10;
|
||||
|
||||
/**
|
||||
* Variable: autoSaveThrottle
|
||||
*
|
||||
* Minimum amount of seconds between two consecutive autosaves triggered by
|
||||
* more than <autoSaveThreshhold> changes within a timespan of less than
|
||||
* <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
|
||||
* <autoSaveThreshold> changes within that timespan. Default is 2.
|
||||
*/
|
||||
autoSaveThrottle = 2;
|
||||
|
||||
/**
|
||||
* 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;
|
||||
|
||||
/**
|
||||
* Extends mxEventSource.
|
||||
*/
|
||||
mxAutoSaveManager.prototype = new mxEventSource();
|
||||
constructor = mxAutoSaveManager;
|
||||
if (this.graph != null) {
|
||||
this.graph.getModel().addListener(mxEvent.CHANGE, this.changeHandler);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Variable: graph
|
||||
*
|
||||
* Reference to the enclosing <mxGraph>.
|
||||
*/
|
||||
graph = null;
|
||||
/**
|
||||
* Function: save
|
||||
*
|
||||
* Empty hook that is called if the graph should be saved.
|
||||
*/
|
||||
save = () => {
|
||||
// empty
|
||||
};
|
||||
|
||||
/**
|
||||
* Variable: autoSaveDelay
|
||||
*
|
||||
* Minimum amount of seconds between two consecutive autosaves. Eg. a
|
||||
* value of 1 (s) means the graph is not stored more than once per second.
|
||||
* Default is 10.
|
||||
*/
|
||||
autoSaveDelay = 10;
|
||||
/**
|
||||
* Function: graphModelChanged
|
||||
*
|
||||
* Invoked when the graph model has changed.
|
||||
*/
|
||||
graphModelChanged = (changes) => {
|
||||
var now = new Date().getTime();
|
||||
var dt = (now - this.lastSnapshot) / 1000;
|
||||
|
||||
/**
|
||||
* Variable: autoSaveThrottle
|
||||
*
|
||||
* Minimum amount of seconds between two consecutive autosaves triggered by
|
||||
* more than <autoSaveThreshhold> changes within a timespan of less than
|
||||
* <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
|
||||
* <autoSaveThreshold> changes within that timespan. Default is 2.
|
||||
*/
|
||||
autoSaveThrottle = 2;
|
||||
if (dt > this.autoSaveDelay ||
|
||||
(this.ignoredChanges >= this.autoSaveThreshold &&
|
||||
dt > this.autoSaveThrottle)) {
|
||||
this.save();
|
||||
this.reset();
|
||||
} else {
|
||||
// Increments the number of ignored changes
|
||||
this.ignoredChanges++;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* 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;
|
||||
/**
|
||||
* Function: reset
|
||||
*
|
||||
* Resets all counters.
|
||||
*/
|
||||
reset = () => {
|
||||
this.lastSnapshot = new Date().getTime();
|
||||
this.ignoredChanges = 0;
|
||||
};
|
||||
|
||||
/**
|
||||
* Variable: ignoredChanges
|
||||
*
|
||||
* Counter for ignored changes in autosave.
|
||||
*/
|
||||
ignoredChanges = 0;
|
||||
/**
|
||||
* Function: destroy
|
||||
*
|
||||
* Removes all handlers from the <graph> and deletes the reference to it.
|
||||
*/
|
||||
destroy = () => {
|
||||
this.setGraph(null);
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* 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);
|
||||
};
|
||||
export default mxAutoSaveManager;
|
||||
|
|
|
@ -2,8 +2,7 @@
|
|||
* Copyright (c) 2006-2015, JGraph Ltd
|
||||
* Copyright (c) 2006-2015, Gaudenz Alder
|
||||
*/
|
||||
var mxClipboard =
|
||||
{
|
||||
var mxClipboard = {
|
||||
/**
|
||||
* Class: mxClipboard
|
||||
*
|
||||
|
@ -217,5 +216,6 @@ var mxClipboard =
|
|||
|
||||
return cells;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
export default mxClipboard;
|
||||
|
|
|
@ -2,8 +2,8 @@
|
|||
* Copyright (c) 2006-2015, JGraph Ltd
|
||||
* Copyright (c) 2006-2015, Gaudenz Alder
|
||||
*/
|
||||
var mxConstants =
|
||||
{
|
||||
|
||||
var mxConstants = {
|
||||
/**
|
||||
* Class: mxConstants
|
||||
*
|
||||
|
@ -2336,3 +2336,5 @@
|
|||
*/
|
||||
PERIMETER_TRIANGLE: 'trianglePerimeter'
|
||||
};
|
||||
|
||||
export default mxConstants;
|
||||
|
|
|
@ -12,119 +12,113 @@
|
|||
*
|
||||
* Constructs a new dictionary which allows object to be used as keys.
|
||||
*/
|
||||
function mxDictionary()
|
||||
{
|
||||
this.clear();
|
||||
};
|
||||
|
||||
/**
|
||||
* Function: map
|
||||
*
|
||||
* Stores the (key, value) pairs in this dictionary.
|
||||
*/
|
||||
map = null;
|
||||
class mxDictionary {
|
||||
constructor() {
|
||||
this.clear();
|
||||
};
|
||||
|
||||
/**
|
||||
* Function: clear
|
||||
*
|
||||
* Clears the dictionary.
|
||||
*/
|
||||
clear = ()=>
|
||||
{
|
||||
this.map = {};
|
||||
};
|
||||
/**
|
||||
* Function: map
|
||||
*
|
||||
* Stores the (key, value) pairs in this dictionary.
|
||||
*/
|
||||
map = null;
|
||||
|
||||
/**
|
||||
* Function: get
|
||||
*
|
||||
* Returns the value for the given key.
|
||||
*/
|
||||
get = (key)=>
|
||||
{
|
||||
var id = mxObjectIdentity.get(key);
|
||||
/**
|
||||
* Function: clear
|
||||
*
|
||||
* Clears the dictionary.
|
||||
*/
|
||||
clear = () => {
|
||||
this.map = {};
|
||||
};
|
||||
|
||||
return this.map[id];
|
||||
};
|
||||
/**
|
||||
* Function: get
|
||||
*
|
||||
* Returns the value for the given key.
|
||||
*/
|
||||
get = (key) => {
|
||||
var id = mxObjectIdentity.get(key);
|
||||
|
||||
/**
|
||||
* 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 this.map[id];
|
||||
};
|
||||
|
||||
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;
|
||||
|
||||
/**
|
||||
* 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;
|
||||
};
|
||||
|
||||
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];
|
||||
|
||||
/**
|
||||
* Function: getKeys
|
||||
*
|
||||
* Returns all keys as an array.
|
||||
*/
|
||||
getKeys = ()=>
|
||||
{
|
||||
var result = [];
|
||||
return previous;
|
||||
};
|
||||
|
||||
for (var key in this.map)
|
||||
{
|
||||
result.push(key);
|
||||
}
|
||||
/**
|
||||
* Function: getKeys
|
||||
*
|
||||
* Returns all keys as an array.
|
||||
*/
|
||||
getKeys = () => {
|
||||
var result = [];
|
||||
|
||||
return result;
|
||||
};
|
||||
for (var key in this.map) {
|
||||
result.push(key);
|
||||
}
|
||||
|
||||
/**
|
||||
* Function: getValues
|
||||
*
|
||||
* Returns all values as an array.
|
||||
*/
|
||||
getValues = ()=>
|
||||
{
|
||||
var result = [];
|
||||
return result;
|
||||
};
|
||||
|
||||
for (var key in this.map)
|
||||
{
|
||||
result.push(this.map[key]);
|
||||
}
|
||||
/**
|
||||
* Function: getValues
|
||||
*
|
||||
* Returns all values as an array.
|
||||
*/
|
||||
getValues = () => {
|
||||
var result = [];
|
||||
|
||||
return result;
|
||||
};
|
||||
for (var key in this.map) {
|
||||
result.push(this.map[key]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Function: visit
|
||||
*
|
||||
* Visits all entries in the dictionary using the given function with the
|
||||
* following signature: (key, value)=> where key is a string and
|
||||
* value is an object.
|
||||
*
|
||||
* Parameters:
|
||||
*
|
||||
* visitor - A function that takes the key and value as arguments.
|
||||
*/
|
||||
visit = (visitor)=>
|
||||
{
|
||||
for (var key in this.map)
|
||||
{
|
||||
visitor(key, 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
|
||||
* value is an object.
|
||||
*
|
||||
* Parameters:
|
||||
*
|
||||
* visitor - A function that takes the key and value as arguments.
|
||||
*/
|
||||
visit = (visitor) => {
|
||||
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
|
||||
* window.
|
||||
*/
|
||||
function mxDivResizer(div, container)
|
||||
{
|
||||
if (div.nodeName.toLowerCase() == 'div')
|
||||
{
|
||||
if (container == null)
|
||||
{
|
||||
container = window;
|
||||
class mxDivResizer {
|
||||
constructor(div, container) {
|
||||
if (div.nodeName.toLowerCase() == 'div') {
|
||||
if (container == null) {
|
||||
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;
|
||||
var style = mxUtils.getCurrentStyle(div);
|
||||
|
||||
if (style != null)
|
||||
{
|
||||
this.resizeWidth = style.width == 'auto';
|
||||
this.resizeHeight = style.height == 'auto';
|
||||
if (this.resizeHeight &&
|
||||
!isNaN(t) &&
|
||||
!isNaN(b) &&
|
||||
t >= 0 &&
|
||||
b >= 0 &&
|
||||
h - t - b > 0) {
|
||||
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
|
||||
*
|
||||
* Boolean specifying if the width should be updated.
|
||||
*/
|
||||
resizeWidth = true;
|
||||
/**
|
||||
* Function: getDocumentWidth
|
||||
*
|
||||
* Hook for subclassers to return the width of the document (without
|
||||
* scrollbars).
|
||||
*/
|
||||
getDocumentWidth = () => {
|
||||
return document.body.clientWidth;
|
||||
};
|
||||
|
||||
/**
|
||||
* Function: resizeHeight
|
||||
*
|
||||
* Boolean specifying if the height should be updated.
|
||||
*/
|
||||
resizeHeight = true;
|
||||
/**
|
||||
* Function: getDocumentHeight
|
||||
*
|
||||
* Hook for subclassers to return the height of the document (without
|
||||
* scrollbars).
|
||||
*/
|
||||
getDocumentHeight = () => {
|
||||
return document.body.clientHeight;
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* 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;
|
||||
};
|
||||
export default mxDivResizer;
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -2,97 +2,84 @@
|
|||
* Copyright (c) 2006-2015, JGraph Ltd
|
||||
* Copyright (c) 2006-2015, Gaudenz Alder
|
||||
*/
|
||||
var mxEffects =
|
||||
{
|
||||
|
||||
var mxEffects = {
|
||||
/**
|
||||
* Class: mxEffects
|
||||
*
|
||||
*
|
||||
* Provides animation effects.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Function: animateChanges
|
||||
*
|
||||
*
|
||||
* Asynchronous animated move operation. See also: <mxMorphing>.
|
||||
*
|
||||
*
|
||||
* Example:
|
||||
*
|
||||
*
|
||||
* (code)
|
||||
* graph.model.addListener(mxEvent.CHANGE, (sender, evt)=>
|
||||
* {
|
||||
* var changes = evt.getProperty('edit').changes;
|
||||
*
|
||||
*
|
||||
* if (changes.length < 10)
|
||||
* {
|
||||
* mxEffects.animateChanges(graph, changes);
|
||||
* }
|
||||
* });
|
||||
* (end)
|
||||
*
|
||||
*
|
||||
* Parameters:
|
||||
*
|
||||
*
|
||||
* graph - <mxGraph> that received the changes.
|
||||
* changes - Array of changes to be animated.
|
||||
* done - Optional function argument that is invoked after the
|
||||
* last step of the animation.
|
||||
*/
|
||||
animateChanges: (graph, changes, done)=>
|
||||
{
|
||||
animateChanges: (graph, changes, done) => {
|
||||
var maxStep = 10;
|
||||
var step = 0;
|
||||
|
||||
var animate = ()=>
|
||||
{
|
||||
var animate = () => {
|
||||
var isRequired = false;
|
||||
|
||||
for (var i = 0; i < changes.length; i++)
|
||||
{
|
||||
|
||||
for (var i = 0; i < changes.length; i++) {
|
||||
var change = changes[i];
|
||||
|
||||
|
||||
if (change instanceof mxGeometryChange ||
|
||||
change instanceof mxTerminalChange ||
|
||||
change instanceof mxValueChange ||
|
||||
change instanceof mxChildChange ||
|
||||
change instanceof mxStyleChange)
|
||||
{
|
||||
change instanceof mxTerminalChange ||
|
||||
change instanceof mxValueChange ||
|
||||
change instanceof mxChildChange ||
|
||||
change instanceof mxStyleChange) {
|
||||
var state = graph.getView().getState(change.cell || change.child, false);
|
||||
|
||||
if (state != null)
|
||||
{
|
||||
|
||||
if (state != null) {
|
||||
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);
|
||||
}
|
||||
else
|
||||
{
|
||||
var scale = graph.getView().scale;
|
||||
} else {
|
||||
var scale = graph.getView().scale;
|
||||
|
||||
var dx = (change.geometry.x - change.previous.x) * scale;
|
||||
var dy = (change.geometry.y - change.previous.y) * scale;
|
||||
|
||||
|
||||
var sx = (change.geometry.width - change.previous.width) * scale;
|
||||
var sy = (change.geometry.height - change.previous.height) * scale;
|
||||
|
||||
if (step == 0)
|
||||
{
|
||||
|
||||
if (step == 0) {
|
||||
state.x -= dx;
|
||||
state.y -= dy;
|
||||
state.width -= sx;
|
||||
state.height -= sy;
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
state.x += dx / maxStep;
|
||||
state.y += dy / maxStep;
|
||||
state.width += sx / maxStep;
|
||||
state.height += sy / maxStep;
|
||||
}
|
||||
|
||||
|
||||
graph.cellRenderer.redraw(state);
|
||||
|
||||
|
||||
// Fades all connected edges and children
|
||||
mxEffects.cascadeOpacity(graph, change.cell, 100 * step / maxStep);
|
||||
}
|
||||
|
@ -100,60 +87,51 @@ var mxEffects =
|
|||
}
|
||||
}
|
||||
|
||||
if (step < maxStep && isRequired)
|
||||
{
|
||||
if (step < maxStep && isRequired) {
|
||||
step++;
|
||||
window.setTimeout(animate, delay);
|
||||
}
|
||||
else if (done != null)
|
||||
{
|
||||
} else if (done != null) {
|
||||
done();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
var delay = 30;
|
||||
animate();
|
||||
},
|
||||
|
||||
|
||||
/**
|
||||
* Function: cascadeOpacity
|
||||
*
|
||||
*
|
||||
* Sets the opacity on the given cell and its descendants.
|
||||
*
|
||||
*
|
||||
* Parameters:
|
||||
*
|
||||
*
|
||||
* graph - <mxGraph> that contains the cells.
|
||||
* cell - <mxCell> to set the opacity for.
|
||||
* opacity - New value for the opacity in %.
|
||||
*/
|
||||
cascadeOpacity: (graph, cell, opacity)=>
|
||||
{
|
||||
cascadeOpacity: (graph, cell, opacity) => {
|
||||
// Fades all children
|
||||
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 childState = graph.getView().getState(child);
|
||||
|
||||
if (childState != null)
|
||||
{
|
||||
|
||||
if (childState != null) {
|
||||
mxUtils.setOpacity(childState.shape.node, opacity);
|
||||
mxEffects.cascadeOpacity(graph, child, opacity);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Fades all connected edges
|
||||
var edges = graph.model.getEdges(cell);
|
||||
|
||||
if (edges != null)
|
||||
{
|
||||
for (var i=0; i<edges.length; i++)
|
||||
{
|
||||
|
||||
if (edges != null) {
|
||||
for (var i = 0; i < edges.length; i++) {
|
||||
var edgeState = graph.getView().getState(edges[i]);
|
||||
|
||||
if (edgeState != null)
|
||||
{
|
||||
|
||||
if (edgeState != null) {
|
||||
mxUtils.setOpacity(edgeState.shape.node, opacity);
|
||||
}
|
||||
}
|
||||
|
@ -162,50 +140,41 @@ var mxEffects =
|
|||
|
||||
/**
|
||||
* Function: fadeOut
|
||||
*
|
||||
*
|
||||
* Asynchronous fade-out operation.
|
||||
*/
|
||||
fadeOut: (node, from, remove, step, delay, isEnabled)=>
|
||||
{
|
||||
fadeOut: (node, from, remove, step, delay, isEnabled) => {
|
||||
step = step || 40;
|
||||
delay = delay || 30;
|
||||
|
||||
|
||||
var opacity = from || 100;
|
||||
|
||||
|
||||
mxUtils.setOpacity(node, opacity);
|
||||
|
||||
if (isEnabled || isEnabled == null)
|
||||
{
|
||||
var f = ()=>
|
||||
{
|
||||
opacity = Math.max(opacity-step, 0);
|
||||
|
||||
if (isEnabled || isEnabled == null) {
|
||||
var f = () => {
|
||||
opacity = Math.max(opacity - step, 0);
|
||||
mxUtils.setOpacity(node, opacity);
|
||||
|
||||
if (opacity > 0)
|
||||
{
|
||||
|
||||
if (opacity > 0) {
|
||||
window.setTimeout(f, delay);
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
node.style.visibility = 'hidden';
|
||||
|
||||
if (remove && node.parentNode)
|
||||
{
|
||||
|
||||
if (remove && node.parentNode) {
|
||||
node.parentNode.removeChild(node);
|
||||
}
|
||||
}
|
||||
};
|
||||
window.setTimeout(f, delay);
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
node.style.visibility = 'hidden';
|
||||
|
||||
if (remove && node.parentNode)
|
||||
{
|
||||
|
||||
if (remove && node.parentNode) {
|
||||
node.parentNode.removeChild(node);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
export default mxEffects;
|
||||
|
|
|
@ -2,110 +2,107 @@
|
|||
* Copyright (c) 2006-2015, JGraph Ltd
|
||||
* 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)
|
||||
{
|
||||
if (arguments[i + 1] != null)
|
||||
{
|
||||
this.properties[arguments[i]] = arguments[i + 1];
|
||||
class mxEventObject {
|
||||
/**
|
||||
* 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)
|
||||
*/
|
||||
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
|
||||
*
|
||||
* Holds the name.
|
||||
*/
|
||||
name = null;
|
||||
/**
|
||||
* Variable: name
|
||||
*
|
||||
* Holds the name.
|
||||
*/
|
||||
name = null;
|
||||
|
||||
/**
|
||||
* Variable: properties
|
||||
*
|
||||
* Holds the properties as an associative array.
|
||||
*/
|
||||
properties = null;
|
||||
/**
|
||||
* Variable: properties
|
||||
*
|
||||
* Holds the properties as an associative array.
|
||||
*/
|
||||
properties = null;
|
||||
|
||||
/**
|
||||
* Variable: consumed
|
||||
*
|
||||
* Holds the consumed state. Default is false.
|
||||
*/
|
||||
consumed = false;
|
||||
/**
|
||||
* Variable: consumed
|
||||
*
|
||||
* Holds the consumed state. Default is false.
|
||||
*/
|
||||
consumed = false;
|
||||
|
||||
/**
|
||||
* Function: getName
|
||||
*
|
||||
* Returns <name>.
|
||||
*/
|
||||
getName = ()=>
|
||||
{
|
||||
return this.name;
|
||||
};
|
||||
/**
|
||||
* Function: getName
|
||||
*
|
||||
* Returns <name>.
|
||||
*/
|
||||
getName = () => {
|
||||
return this.name;
|
||||
};
|
||||
|
||||
/**
|
||||
* Function: getProperties
|
||||
*
|
||||
* Returns <properties>.
|
||||
*/
|
||||
getProperties = ()=>
|
||||
{
|
||||
return this.properties;
|
||||
};
|
||||
/**
|
||||
* Function: getProperties
|
||||
*
|
||||
* Returns <properties>.
|
||||
*/
|
||||
getProperties = () => {
|
||||
return this.properties;
|
||||
};
|
||||
|
||||
/**
|
||||
* Function: getProperty
|
||||
*
|
||||
* Returns the property for the given key.
|
||||
*/
|
||||
getProperty = (key)=>
|
||||
{
|
||||
return this.properties[key];
|
||||
};
|
||||
/**
|
||||
* Function: getProperty
|
||||
*
|
||||
* Returns the property for the given key.
|
||||
*/
|
||||
getProperty = (key) => {
|
||||
return this.properties[key];
|
||||
};
|
||||
|
||||
/**
|
||||
* Function: isConsumed
|
||||
*
|
||||
* Returns true if the event has been consumed.
|
||||
*/
|
||||
isConsumed = ()=>
|
||||
{
|
||||
return this.consumed;
|
||||
};
|
||||
/**
|
||||
* Function: isConsumed
|
||||
*
|
||||
* Returns true if the event has been consumed.
|
||||
*/
|
||||
isConsumed = () => {
|
||||
return this.consumed;
|
||||
};
|
||||
|
||||
/**
|
||||
* Function: consume
|
||||
*
|
||||
* Consumes the event.
|
||||
*/
|
||||
consume = ()=>
|
||||
{
|
||||
this.consumed = true;
|
||||
};
|
||||
/**
|
||||
* Function: consume
|
||||
*
|
||||
* Consumes the event.
|
||||
*/
|
||||
consume = () => {
|
||||
this.consumed = true;
|
||||
};
|
||||
}
|
||||
|
||||
export default mxEventObject;
|
||||
|
|
|
@ -2,188 +2,175 @@
|
|||
* Copyright (c) 2006-2015, JGraph Ltd
|
||||
* 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);
|
||||
};
|
||||
|
||||
/**
|
||||
* 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;
|
||||
import mxEventObject from "./mxEventObject";
|
||||
|
||||
/**
|
||||
* Variable: eventsEnabled
|
||||
*
|
||||
* Specifies if events can be fired. Default is true.
|
||||
*/
|
||||
eventsEnabled = true;
|
||||
class mxEventSource {
|
||||
/**
|
||||
* 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;
|
||||
|
||||
/**
|
||||
* Variable: eventSource
|
||||
*
|
||||
* Optional source for events. Default is null.
|
||||
*/
|
||||
eventSource = null;
|
||||
/**
|
||||
* Variable: eventsEnabled
|
||||
*
|
||||
* Specifies if events can be fired. Default is true.
|
||||
*/
|
||||
eventsEnabled = true;
|
||||
|
||||
/**
|
||||
* Function: isEventsEnabled
|
||||
*
|
||||
* Returns <eventsEnabled>.
|
||||
*/
|
||||
isEventsEnabled = ()=>
|
||||
{
|
||||
return this.eventsEnabled;
|
||||
};
|
||||
/**
|
||||
* Variable: eventSource
|
||||
*
|
||||
* Optional source for events. Default is null.
|
||||
*/
|
||||
eventSource = null;
|
||||
|
||||
/**
|
||||
* Function: setEventsEnabled
|
||||
*
|
||||
* Sets <eventsEnabled>.
|
||||
*/
|
||||
setEventsEnabled = (value)=>
|
||||
{
|
||||
this.eventsEnabled = value;
|
||||
};
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
constructor(eventSource) {
|
||||
this.setEventSource(eventSource);
|
||||
};
|
||||
|
||||
/**
|
||||
* Function: getEventSource
|
||||
*
|
||||
* Returns <eventSource>.
|
||||
*/
|
||||
getEventSource = ()=>
|
||||
{
|
||||
return this.eventSource;
|
||||
};
|
||||
/**
|
||||
* Function: isEventsEnabled
|
||||
*
|
||||
* Returns <eventsEnabled>.
|
||||
*/
|
||||
isEventsEnabled = () => {
|
||||
return this.eventsEnabled;
|
||||
};
|
||||
|
||||
/**
|
||||
* Function: setEventSource
|
||||
*
|
||||
* Sets <eventSource>.
|
||||
*/
|
||||
setEventSource = (value)=>
|
||||
{
|
||||
this.eventSource = value;
|
||||
};
|
||||
/**
|
||||
* Function: setEventsEnabled
|
||||
*
|
||||
* Sets <eventsEnabled>.
|
||||
*/
|
||||
setEventsEnabled = (value) => {
|
||||
this.eventsEnabled = value;
|
||||
};
|
||||
|
||||
/**
|
||||
* Function: addListener
|
||||
*
|
||||
* Binds the specified function to the given event name. If no event name
|
||||
* is given, then the listener is registered for all events.
|
||||
*
|
||||
* The parameters of the listener are the sender and an <mxEventObject>.
|
||||
*/
|
||||
addListener = (name, funct)=>
|
||||
{
|
||||
if (this.eventListeners == null)
|
||||
{
|
||||
this.eventListeners = [];
|
||||
}
|
||||
|
||||
this.eventListeners.push(name);
|
||||
this.eventListeners.push(funct);
|
||||
};
|
||||
/**
|
||||
* Function: getEventSource
|
||||
*
|
||||
* Returns <eventSource>.
|
||||
*/
|
||||
getEventSource = () => {
|
||||
return this.eventSource;
|
||||
};
|
||||
|
||||
/**
|
||||
* 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: setEventSource
|
||||
*
|
||||
* Sets <eventSource>.
|
||||
*/
|
||||
setEventSource = (value) => {
|
||||
this.eventSource = value;
|
||||
};
|
||||
|
||||
/**
|
||||
* Function: addListener
|
||||
*
|
||||
* Binds the specified function to the given event name. If no event name
|
||||
* is given, then the listener is registered for all events.
|
||||
*
|
||||
* The parameters of the listener are the sender and an <mxEventObject>.
|
||||
*/
|
||||
addListener = (name, funct) => {
|
||||
if (this.eventListeners == null) {
|
||||
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
|
||||
*
|
||||
* Dispatches the given event to the listeners which are registered for
|
||||
* the event. The sender argument is optional. The current execution scope
|
||||
* ("this") is used for the listener invocation (see <mxUtils.bind>).
|
||||
*
|
||||
* Example:
|
||||
*
|
||||
* (code)
|
||||
* fireEvent(new mxEventObject("eventName", key1, val1, .., keyN, valN))
|
||||
* (end)
|
||||
*
|
||||
* Parameters:
|
||||
*
|
||||
* evt - <mxEventObject> that represents the event.
|
||||
* sender - Optional sender to be passed to the listener. Default value is
|
||||
* the return value of <getEventSource>.
|
||||
*/
|
||||
fireEvent = (evt, sender)=>
|
||||
{
|
||||
if (this.eventListeners != null && this.isEventsEnabled())
|
||||
{
|
||||
if (evt == null)
|
||||
{
|
||||
evt = new mxEventObject();
|
||||
}
|
||||
|
||||
if (sender == null)
|
||||
{
|
||||
sender = this.getEventSource();
|
||||
}
|
||||
/**
|
||||
* Function: fireEvent
|
||||
*
|
||||
* Dispatches the given event to the listeners which are registered for
|
||||
* the event. The sender argument is optional. The current execution scope
|
||||
* ("this") is used for the listener invocation (see <mxUtils.bind>).
|
||||
*
|
||||
* Example:
|
||||
*
|
||||
* (code)
|
||||
* fireEvent(new mxEventObject("eventName", key1, val1, .., keyN, valN))
|
||||
* (end)
|
||||
*
|
||||
* Parameters:
|
||||
*
|
||||
* evt - <mxEventObject> that represents the event.
|
||||
* sender - Optional sender to be passed to the listener. Default value is
|
||||
* the return value of <getEventSource>.
|
||||
*/
|
||||
fireEvent = (evt, sender) => {
|
||||
if (this.eventListeners != null && this.isEventsEnabled()) {
|
||||
if (evt == null) {
|
||||
evt = new mxEventObject();
|
||||
}
|
||||
|
||||
if (sender == null)
|
||||
{
|
||||
sender = this;
|
||||
}
|
||||
if (sender == null) {
|
||||
sender = this.getEventSource();
|
||||
}
|
||||
|
||||
var args = [sender, evt];
|
||||
|
||||
for (var i = 0; i < this.eventListeners.length; i += 2)
|
||||
{
|
||||
var listen = this.eventListeners[i];
|
||||
|
||||
if (listen == null || listen == evt.getName())
|
||||
{
|
||||
this.eventListeners[i+1].apply(this, args);
|
||||
if (sender == null) {
|
||||
sender = this;
|
||||
}
|
||||
|
||||
var args = [sender, evt];
|
||||
|
||||
for (var i = 0; i < this.eventListeners.length; i += 2) {
|
||||
var listen = this.eventListeners[i];
|
||||
|
||||
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, 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);
|
||||
};
|
||||
|
||||
/**
|
||||
* Variable: table
|
||||
*
|
||||
* Holds the DOM node that represents the table.
|
||||
*/
|
||||
table = null;
|
||||
class mxForm {
|
||||
/**
|
||||
* Variable: table
|
||||
*
|
||||
* Holds the DOM node that represents the table.
|
||||
*/
|
||||
table = null;
|
||||
|
||||
/**
|
||||
* Variable: body
|
||||
*
|
||||
* Holds the DOM node that represents the tbody (table body). New rows
|
||||
* can be added to this object using DOM API.
|
||||
*/
|
||||
body = false;
|
||||
/**
|
||||
* Variable: body
|
||||
*
|
||||
* Holds the DOM node that represents the tbody (table body). New rows
|
||||
* can be added to this object using DOM API.
|
||||
*/
|
||||
body = false;
|
||||
|
||||
/**
|
||||
* Function: getTable
|
||||
*
|
||||
* Returns the table that contains this form.
|
||||
*/
|
||||
getTable = ()=>
|
||||
{
|
||||
return this.table;
|
||||
};
|
||||
/**
|
||||
* Class: mxForm
|
||||
*
|
||||
* A simple class for creating HTML forms.
|
||||
*
|
||||
* Constructor: mxForm
|
||||
*
|
||||
* Creates a HTML table using the specified classname.
|
||||
*/
|
||||
constructor(className) {
|
||||
this.table = document.createElement('table');
|
||||
this.table.className = className;
|
||||
this.body = document.createElement('tbody');
|
||||
|
||||
/**
|
||||
* 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');
|
||||
this.table.appendChild(this.body);
|
||||
};
|
||||
|
||||
// Adds the ok button
|
||||
var button = document.createElement('button');
|
||||
mxUtils.write(button, mxResources.get('ok') || 'OK');
|
||||
td.appendChild(button);
|
||||
/**
|
||||
* Function: getTable
|
||||
*
|
||||
* Returns the table that contains this form.
|
||||
*/
|
||||
getTable = () => {
|
||||
return this.table;
|
||||
};
|
||||
|
||||
mxEvent.addListener(button, 'click', ()=>
|
||||
{
|
||||
okFunct();
|
||||
});
|
||||
|
||||
// Adds the cancel button
|
||||
button = document.createElement('button');
|
||||
mxUtils.write(button, mxResources.get('cancel') || 'Cancel');
|
||||
td.appendChild(button);
|
||||
|
||||
mxEvent.addListener(button, 'click', ()=>
|
||||
{
|
||||
cancelFunct();
|
||||
});
|
||||
|
||||
tr.appendChild(td);
|
||||
this.body.appendChild(tr);
|
||||
};
|
||||
/**
|
||||
* 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');
|
||||
|
||||
/**
|
||||
* Function: addText
|
||||
*
|
||||
* Adds an input for the given name, type and value and returns it.
|
||||
*/
|
||||
addText = (name, value, type)=>
|
||||
{
|
||||
var input = document.createElement('input');
|
||||
|
||||
input.setAttribute('type', type || 'text');
|
||||
input.value = value;
|
||||
|
||||
return this.addField(name, input);
|
||||
};
|
||||
// Adds the ok button
|
||||
var button = document.createElement('button');
|
||||
mxUtils.write(button, mxResources.get('ok') || 'OK');
|
||||
td.appendChild(button);
|
||||
|
||||
/**
|
||||
* Function: addCheckbox
|
||||
*
|
||||
* 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);
|
||||
mxEvent.addListener(button, 'click', () => {
|
||||
okFunct();
|
||||
});
|
||||
|
||||
// IE can only change the checked value if the input is inside the DOM
|
||||
if (value)
|
||||
{
|
||||
input.checked = true;
|
||||
}
|
||||
// Adds the cancel button
|
||||
button = document.createElement('button');
|
||||
mxUtils.write(button, mxResources.get('cancel') || 'Cancel');
|
||||
td.appendChild(button);
|
||||
|
||||
return input;
|
||||
};
|
||||
mxEvent.addListener(button, 'click', () => {
|
||||
cancelFunct();
|
||||
});
|
||||
|
||||
/**
|
||||
* 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);
|
||||
};
|
||||
tr.appendChild(td);
|
||||
this.body.appendChild(tr);
|
||||
};
|
||||
|
||||
/**
|
||||
* 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: addText
|
||||
*
|
||||
* Adds an input for the given name, type and value and returns it.
|
||||
*/
|
||||
addText = (name, value, type) => {
|
||||
var input = document.createElement('input');
|
||||
|
||||
/**
|
||||
* 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);
|
||||
};
|
||||
input.setAttribute('type', type || 'text');
|
||||
input.value = value;
|
||||
|
||||
/**
|
||||
* 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;
|
||||
};
|
||||
return this.addField(name, input);
|
||||
};
|
||||
|
||||
/**
|
||||
* Function: addCheckbox
|
||||
*
|
||||
* 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
|
||||
if (value) {
|
||||
input.checked = true;
|
||||
}
|
||||
|
||||
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.
|
||||
*/
|
||||
function mxGuide(graph, states)
|
||||
{
|
||||
this.graph = graph;
|
||||
this.setStates(states);
|
||||
};
|
||||
class mxGuide {
|
||||
constructor(graph, states) {
|
||||
this.graph = graph;
|
||||
this.setStates(states);
|
||||
};
|
||||
|
||||
/**
|
||||
* Variable: graph
|
||||
*
|
||||
* Reference to the enclosing <mxGraph> instance.
|
||||
*/
|
||||
graph = null;
|
||||
/**
|
||||
* Variable: graph
|
||||
*
|
||||
* Reference to the enclosing <mxGraph> instance.
|
||||
*/
|
||||
graph = null;
|
||||
|
||||
/**
|
||||
* Variable: states
|
||||
*
|
||||
* Contains the <mxCellStates> that are used for alignment.
|
||||
*/
|
||||
states = null;
|
||||
/**
|
||||
* Variable: states
|
||||
*
|
||||
* Contains the <mxCellStates> that are used for alignment.
|
||||
*/
|
||||
states = null;
|
||||
|
||||
/**
|
||||
* Variable: horizontal
|
||||
*
|
||||
* Specifies if horizontal guides are enabled. Default is true.
|
||||
*/
|
||||
horizontal = true;
|
||||
/**
|
||||
* Variable: horizontal
|
||||
*
|
||||
* Specifies if horizontal guides are enabled. Default is true.
|
||||
*/
|
||||
horizontal = true;
|
||||
|
||||
/**
|
||||
* Variable: vertical
|
||||
*
|
||||
* Specifies if vertical guides are enabled. Default is true.
|
||||
*/
|
||||
vertical = true;
|
||||
/**
|
||||
* Variable: vertical
|
||||
*
|
||||
* Specifies if vertical guides are enabled. Default is true.
|
||||
*/
|
||||
vertical = true;
|
||||
|
||||
/**
|
||||
* Variable: guideX
|
||||
*
|
||||
* Holds the <mxShape> for the horizontal guide.
|
||||
*/
|
||||
guideX = null;
|
||||
/**
|
||||
* Variable: guideX
|
||||
*
|
||||
* Holds the <mxShape> for the horizontal guide.
|
||||
*/
|
||||
guideX = null;
|
||||
|
||||
/**
|
||||
* Variable: guideY
|
||||
*
|
||||
* Holds the <mxShape> for the vertical guide.
|
||||
*/
|
||||
guideY = null;
|
||||
/**
|
||||
* Variable: guideY
|
||||
*
|
||||
* Holds the <mxShape> for the vertical guide.
|
||||
*/
|
||||
guideY = null;
|
||||
|
||||
/**
|
||||
* Variable: rounded
|
||||
*
|
||||
* Specifies if rounded coordinates should be used. Default is false.
|
||||
*/
|
||||
rounded = false;
|
||||
/**
|
||||
* Variable: rounded
|
||||
*
|
||||
* Specifies if rounded coordinates should be used. Default is false.
|
||||
*/
|
||||
rounded = false;
|
||||
|
||||
/**
|
||||
* Variable: tolerance
|
||||
*
|
||||
* Default tolerance in px if grid is disabled. Default is 2.
|
||||
*/
|
||||
tolerance = 2;
|
||||
/**
|
||||
* Variable: tolerance
|
||||
*
|
||||
* Default tolerance in px if grid is disabled. Default is 2.
|
||||
*/
|
||||
tolerance = 2;
|
||||
|
||||
/**
|
||||
* Function: setStates
|
||||
*
|
||||
* Sets the <mxCellStates> that should be used for alignment.
|
||||
*/
|
||||
setStates = (states)=>
|
||||
{
|
||||
this.states = states;
|
||||
};
|
||||
/**
|
||||
* Function: setStates
|
||||
*
|
||||
* Sets the <mxCellStates> that should be used for alignment.
|
||||
*/
|
||||
setStates = (states) => {
|
||||
this.states = states;
|
||||
};
|
||||
|
||||
/**
|
||||
* Function: isEnabledForEvent
|
||||
*
|
||||
* Returns true if the guide should be enabled for the given native event. This
|
||||
* implementation always returns true.
|
||||
*/
|
||||
isEnabledForEvent = (evt)=>
|
||||
{
|
||||
return true;
|
||||
};
|
||||
/**
|
||||
* Function: isEnabledForEvent
|
||||
*
|
||||
* Returns true if the guide should be enabled for the given native event. This
|
||||
* implementation always returns true.
|
||||
*/
|
||||
isEnabledForEvent = (evt) => {
|
||||
return true;
|
||||
};
|
||||
|
||||
/**
|
||||
* Function: getGuideTolerance
|
||||
*
|
||||
* Returns the tolerance for the guides. Default value is gridSize / 2.
|
||||
*/
|
||||
getGuideTolerance = (gridEnabled)=>
|
||||
{
|
||||
return (gridEnabled && this.graph.gridEnabled) ? this.graph.gridSize / 2 : this.tolerance;
|
||||
};
|
||||
/**
|
||||
* Function: getGuideTolerance
|
||||
*
|
||||
* Returns the tolerance for the guides. Default value is gridSize / 2.
|
||||
*/
|
||||
getGuideTolerance = (gridEnabled) => {
|
||||
return (gridEnabled && this.graph.gridEnabled) ? this.graph.gridSize / 2 : this.tolerance;
|
||||
};
|
||||
|
||||
/**
|
||||
* Function: createGuideShape
|
||||
*
|
||||
* Returns the mxShape to be used for painting the respective guide. This
|
||||
* implementation returns a new, dashed and crisp <mxPolyline> using
|
||||
* <mxConstants.GUIDE_COLOR> and <mxConstants.GUIDE_STROKEWIDTH> as the format.
|
||||
*
|
||||
* Parameters:
|
||||
*
|
||||
* horizontal - Boolean that specifies which guide should be created.
|
||||
*/
|
||||
createGuideShape = (horizontal)=>
|
||||
{
|
||||
var guide = new mxPolyline([], mxConstants.GUIDE_COLOR, mxConstants.GUIDE_STROKEWIDTH);
|
||||
guide.isDashed = true;
|
||||
/**
|
||||
* Function: createGuideShape
|
||||
*
|
||||
* Returns the mxShape to be used for painting the respective guide. This
|
||||
* implementation returns a new, dashed and crisp <mxPolyline> using
|
||||
* <mxConstants.GUIDE_COLOR> and <mxConstants.GUIDE_STROKEWIDTH> as the format.
|
||||
*
|
||||
* Parameters:
|
||||
*
|
||||
* horizontal - Boolean that specifies which guide should be created.
|
||||
*/
|
||||
createGuideShape = (horizontal) => {
|
||||
var guide = new mxPolyline([], mxConstants.GUIDE_COLOR, mxConstants.GUIDE_STROKEWIDTH);
|
||||
guide.isDashed = true;
|
||||
|
||||
return guide;
|
||||
};
|
||||
return guide;
|
||||
};
|
||||
|
||||
/**
|
||||
* Function: isStateIgnored
|
||||
*
|
||||
* Returns true if the given state should be ignored.
|
||||
*/
|
||||
isStateIgnored = (state)=>
|
||||
{
|
||||
return false;
|
||||
};
|
||||
/**
|
||||
* Function: isStateIgnored
|
||||
*
|
||||
* Returns true if the given state should be ignored.
|
||||
*/
|
||||
isStateIgnored = (state) => {
|
||||
return false;
|
||||
};
|
||||
|
||||
/**
|
||||
* Function: move
|
||||
*
|
||||
* Moves the <bounds> by the given <mxPoint> and returnt the snapped point.
|
||||
*/
|
||||
move = (bounds, delta, gridEnabled, clone)=>
|
||||
{
|
||||
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 b = bounds.clone();
|
||||
b.x += delta.x;
|
||||
b.y += delta.y;
|
||||
var overrideX = false;
|
||||
var stateX = null;
|
||||
var valueX = null;
|
||||
var overrideY = false;
|
||||
var stateY = null;
|
||||
var valueY = null;
|
||||
var ttX = tt;
|
||||
var ttY = tt;
|
||||
var left = b.x;
|
||||
var right = b.x + b.width;
|
||||
var center = b.getCenterX();
|
||||
var top = b.y;
|
||||
var bottom = b.y + b.height;
|
||||
var middle = b.getCenterY();
|
||||
/**
|
||||
* Function: move
|
||||
*
|
||||
* Moves the <bounds> by the given <mxPoint> and returnt the snapped point.
|
||||
*/
|
||||
move = (bounds, delta, gridEnabled, clone) => {
|
||||
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 b = bounds.clone();
|
||||
b.x += delta.x;
|
||||
b.y += delta.y;
|
||||
var overrideX = false;
|
||||
var stateX = null;
|
||||
var valueX = null;
|
||||
var overrideY = false;
|
||||
var stateY = null;
|
||||
var valueY = null;
|
||||
var ttX = tt;
|
||||
var ttY = tt;
|
||||
var left = b.x;
|
||||
var right = b.x + b.width;
|
||||
var center = b.getCenterX();
|
||||
var top = b.y;
|
||||
var bottom = b.y + b.height;
|
||||
var middle = b.getCenterY();
|
||||
|
||||
// Snaps the left, center and right to the given x-coordinate
|
||||
function snapX(x, state, centerAlign)
|
||||
{
|
||||
var override = false;
|
||||
// Snaps the left, center and right to the given x-coordinate
|
||||
function snapX(x, state, centerAlign) {
|
||||
var override = false;
|
||||
|
||||
if (centerAlign && Math.abs(x - center) < ttX)
|
||||
{
|
||||
delta.x = x - bounds.getCenterX();
|
||||
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);
|
||||
if (centerAlign && Math.abs(x - center) < ttX) {
|
||||
delta.x = x - bounds.getCenterX();
|
||||
ttX = Math.abs(x - center);
|
||||
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);
|
||||
} else if (!centerAlign) {
|
||||
if (Math.abs(x - left) < ttX) {
|
||||
delta.x = x - bounds.x;
|
||||
ttX = Math.abs(x - left);
|
||||
override = true;
|
||||
} else if (Math.abs(x - right) < ttX) {
|
||||
delta.x = x - bounds.x - bounds.width;
|
||||
ttX = Math.abs(x - right);
|
||||
override = true;
|
||||
}
|
||||
}
|
||||
|
||||
// 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);
|
||||
if (override) {
|
||||
stateX = state;
|
||||
valueX = x;
|
||||
|
||||
// Aligns left and right of shape to center of page
|
||||
if (state.cell == null)
|
||||
{
|
||||
snapY.call(this, state.getCenterY(), state, false);
|
||||
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 (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
|
||||
this.graph.snapDelta(delta, bounds, !gridEnabled, overrideX, overrideY);
|
||||
delta = this.getDelta(bounds, stateX, delta.x, stateY, delta.y)
|
||||
return delta;
|
||||
};
|
||||
|
||||
// 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)
|
||||
{
|
||||
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 (this.rounded || (stateX != null && stateX.cell == null)) {
|
||||
dx = Math.round((bounds.x + dx) / s) * s - bounds.x;
|
||||
}
|
||||
|
||||
if (!overrideY && this.guideY != null)
|
||||
{
|
||||
this.guideY.node.style.visibility = 'hidden';
|
||||
if (this.rounded || (stateY != null && stateY.cell == null)) {
|
||||
dy = Math.round((bounds.y + dy) / s) * s - bounds.y;
|
||||
}
|
||||
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);
|
||||
}
|
||||
return new mxPoint(dx, dy);
|
||||
};
|
||||
|
||||
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)];
|
||||
}
|
||||
/**
|
||||
* Function: getGuideColor
|
||||
*
|
||||
* Returns the color for the given state.
|
||||
*/
|
||||
getGuideColor = (state, horizontal) => {
|
||||
return mxConstants.GUIDE_COLOR;
|
||||
};
|
||||
|
||||
this.guideY.stroke = this.getGuideColor(stateY, false);
|
||||
this.guideY.node.style.visibility = 'visible';
|
||||
this.guideY.redraw();
|
||||
/**
|
||||
* 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';
|
||||
}
|
||||
}
|
||||
|
||||
return delta;
|
||||
};
|
||||
if (this.guideY != null) {
|
||||
this.guideY.node.style.visibility = (visible) ? 'visible' : 'hidden';
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Function: getDelta
|
||||
*
|
||||
* Rounds to pixels for virtual states (eg. page guides)
|
||||
*/
|
||||
getDelta = (bounds, stateX, dx, stateY, dy)=>
|
||||
{
|
||||
var s = this.graph.view.scale;
|
||||
/**
|
||||
* Function: destroy
|
||||
*
|
||||
* Destroys all resources that this object uses.
|
||||
*/
|
||||
destroy = () => {
|
||||
if (this.guideX != null) {
|
||||
this.guideX.destroy();
|
||||
this.guideX = null;
|
||||
}
|
||||
|
||||
if (this.rounded || (stateX != null && stateX.cell == null))
|
||||
{
|
||||
dx = Math.round((bounds.x + dx) / s) * s - bounds.x;
|
||||
}
|
||||
if (this.guideY != null) {
|
||||
this.guideY.destroy();
|
||||
this.guideY = null;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
if (this.rounded || (stateY != null && stateY.cell == null))
|
||||
{
|
||||
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;
|
||||
}
|
||||
};
|
||||
export default mxGuide;
|
||||
|
|
|
@ -2,39 +2,43 @@
|
|||
* Copyright (c) 2006-2015, JGraph Ltd
|
||||
* 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;
|
||||
};
|
||||
|
||||
/**
|
||||
* Variable: src
|
||||
*
|
||||
* String that specifies the URL of the image.
|
||||
*/
|
||||
src = null;
|
||||
class mxImage {
|
||||
/**
|
||||
* Variable: src
|
||||
*
|
||||
* String that specifies the URL of the image.
|
||||
*/
|
||||
src = null;
|
||||
|
||||
/**
|
||||
* Variable: width
|
||||
*
|
||||
* Integer that specifies the width of the image.
|
||||
*/
|
||||
width = null;
|
||||
/**
|
||||
* Variable: width
|
||||
*
|
||||
* Integer that specifies the width of the image.
|
||||
*/
|
||||
width = null;
|
||||
|
||||
/**
|
||||
* Variable: height
|
||||
*
|
||||
* Integer that specifies the height of the image.
|
||||
*/
|
||||
height = null;
|
||||
/**
|
||||
* Variable: height
|
||||
*
|
||||
* Integer that specifies the height of the image.
|
||||
*/
|
||||
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, 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;
|
||||
};
|
||||
|
||||
/**
|
||||
* Variable: images
|
||||
*
|
||||
* Maps from keys to images.
|
||||
*/
|
||||
images = null;
|
||||
class mxImageBundle {
|
||||
/**
|
||||
* Variable: images
|
||||
*
|
||||
* Maps from keys to images.
|
||||
*/
|
||||
images = null;
|
||||
|
||||
/**
|
||||
* Variable: alt
|
||||
*
|
||||
* Specifies if the fallback representation should be returned.
|
||||
*/
|
||||
alt = null;
|
||||
/**
|
||||
* Variable: alt
|
||||
*
|
||||
* Specifies if the fallback representation should be returned.
|
||||
*/
|
||||
alt = null;
|
||||
|
||||
/**
|
||||
* Function: putImage
|
||||
*
|
||||
* Adds the specified entry to the map. The entry is an object with a value and
|
||||
* fallback property as specified in the arguments.
|
||||
*/
|
||||
putImage = (key, value, fallback)=>
|
||||
{
|
||||
this.images[key] = {value: value, fallback: fallback};
|
||||
};
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
constructor(alt) {
|
||||
this.images = [];
|
||||
this.alt = (alt != null) ? alt : false;
|
||||
};
|
||||
|
||||
/**
|
||||
* Function: getImage
|
||||
*
|
||||
* Returns the value for the given key. This returns the value
|
||||
* or fallback, depending on <alt>. The fallback is returned if
|
||||
* <alt> is true, the value is returned otherwise.
|
||||
*/
|
||||
getImage = (key)=>
|
||||
{
|
||||
var result = null;
|
||||
|
||||
if (key != null)
|
||||
{
|
||||
var img = this.images[key];
|
||||
|
||||
if (img != null)
|
||||
{
|
||||
result = (this.alt) ? img.fallback : img.value;
|
||||
/**
|
||||
* Function: putImage
|
||||
*
|
||||
* Adds the specified entry to the map. The entry is an object with a value and
|
||||
* fallback property as specified in the arguments.
|
||||
*/
|
||||
putImage = (key, value, fallback) => {
|
||||
this.images[key] = {value: value, fallback: fallback};
|
||||
};
|
||||
|
||||
/**
|
||||
* Function: getImage
|
||||
*
|
||||
* Returns the value for the given key. This returns the value
|
||||
* or fallback, depending on <alt>. The fallback is returned if
|
||||
* <alt> is true, the value is returned otherwise.
|
||||
*/
|
||||
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, 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() { };
|
||||
|
||||
/**
|
||||
* Variable: includeOverlays
|
||||
*
|
||||
* Specifies if overlays should be included in the export. Default is false.
|
||||
*/
|
||||
includeOverlays = false;
|
||||
class mxImageExport {
|
||||
/**
|
||||
* Variable: includeOverlays
|
||||
*
|
||||
* Specifies if overlays should be included in the export. Default is false.
|
||||
*/
|
||||
includeOverlays = false;
|
||||
|
||||
/**
|
||||
* 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
|
||||
if (this.includeOverlays)
|
||||
{
|
||||
this.visitStatesRecursive(state, canvas, mxUtils.bind(this, ()=>
|
||||
{
|
||||
this.drawOverlays.apply(this, arguments);
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
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);
|
||||
}));
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* 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);
|
||||
// Paints the overlays
|
||||
if (this.includeOverlays) {
|
||||
this.visitStatesRecursive(state, canvas, mxUtils.bind(this, () => {
|
||||
this.drawOverlays.apply(this, arguments);
|
||||
}));
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* 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, Gaudenz Alder
|
||||
*/
|
||||
var mxLog =
|
||||
{
|
||||
|
||||
var mxLog = {
|
||||
/**
|
||||
* Class: mxLog
|
||||
*
|
||||
*
|
||||
* A singleton class that implements a simple console.
|
||||
*
|
||||
*
|
||||
* Variable: consoleName
|
||||
*
|
||||
*
|
||||
* Specifies the name of the console window. Default is 'Console'.
|
||||
*/
|
||||
consoleName: 'Console',
|
||||
|
||||
|
||||
/**
|
||||
* Variable: TRACE
|
||||
*
|
||||
*
|
||||
* Specified if the output for <enter> and <leave> should be visible in the
|
||||
* console. Default is false.
|
||||
*/
|
||||
|
@ -25,7 +25,7 @@ var mxLog =
|
|||
|
||||
/**
|
||||
* Variable: DEBUG
|
||||
*
|
||||
*
|
||||
* Specifies if the output for <debug> should be visible in the console.
|
||||
* Default is true.
|
||||
*/
|
||||
|
@ -33,7 +33,7 @@ var mxLog =
|
|||
|
||||
/**
|
||||
* Variable: WARN
|
||||
*
|
||||
*
|
||||
* Specifies if the output for <warn> should be visible in the console.
|
||||
* Default is true.
|
||||
*/
|
||||
|
@ -41,11 +41,11 @@ var mxLog =
|
|||
|
||||
/**
|
||||
* Variable: buffer
|
||||
*
|
||||
*
|
||||
* Buffer for pre-initialized content.
|
||||
*/
|
||||
buffer: '',
|
||||
|
||||
|
||||
/**
|
||||
* Function: init
|
||||
*
|
||||
|
@ -53,10 +53,8 @@ var mxLog =
|
|||
* point to a non-null value. This is called from within <setVisible> if the
|
||||
* log has not yet been initialized.
|
||||
*/
|
||||
init: ()=>
|
||||
{
|
||||
if (mxLog.window == null && document.body != null)
|
||||
{
|
||||
init: () => {
|
||||
if (mxLog.window == null && document.body != null) {
|
||||
var title = mxLog.consoleName + ' - mxGraph ' + mxClient.VERSION;
|
||||
|
||||
// Creates a table that maintains the layout
|
||||
|
@ -68,7 +66,7 @@ var mxLog =
|
|||
var tr = document.createElement('tr');
|
||||
var td = document.createElement('td');
|
||||
td.style.verticalAlign = 'top';
|
||||
|
||||
|
||||
// Adds the actual console as a textarea
|
||||
mxLog.textarea = document.createElement('textarea');
|
||||
mxLog.textarea.setAttribute('wrap', 'off');
|
||||
|
@ -78,15 +76,12 @@ var mxLog =
|
|||
mxLog.textarea.value = mxLog.buffer;
|
||||
|
||||
// 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%';
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
mxLog.textarea.style.width = '100%';
|
||||
}
|
||||
|
||||
|
||||
td.appendChild(mxLog.textarea);
|
||||
tr.appendChild(td);
|
||||
tbody.appendChild(tr);
|
||||
|
@ -96,77 +91,59 @@ var mxLog =
|
|||
mxLog.td = document.createElement('td');
|
||||
mxLog.td.style.verticalAlign = 'top';
|
||||
mxLog.td.setAttribute('height', '30px');
|
||||
|
||||
|
||||
tr.appendChild(mxLog.td);
|
||||
tbody.appendChild(tr);
|
||||
table.appendChild(tbody);
|
||||
|
||||
// Adds various debugging buttons
|
||||
mxLog.addButton('Info', function (evt)
|
||||
{
|
||||
mxLog.addButton('Info', function (evt) {
|
||||
mxLog.info();
|
||||
});
|
||||
|
||||
mxLog.addButton('DOM', function (evt)
|
||||
{
|
||||
|
||||
mxLog.addButton('DOM', function (evt) {
|
||||
var content = mxUtils.getInnerHtml(document.body);
|
||||
mxLog.debug(content);
|
||||
});
|
||||
|
||||
mxLog.addButton('Trace', function (evt)
|
||||
{
|
||||
|
||||
mxLog.addButton('Trace', function (evt) {
|
||||
mxLog.TRACE = !mxLog.TRACE;
|
||||
|
||||
if (mxLog.TRACE)
|
||||
{
|
||||
|
||||
if (mxLog.TRACE) {
|
||||
mxLog.debug('Tracing enabled');
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
mxLog.debug('Tracing disabled');
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
mxLog.addButton('Copy', function (evt)
|
||||
{
|
||||
try
|
||||
{
|
||||
mxLog.addButton('Copy', function (evt) {
|
||||
try {
|
||||
mxUtils.copy(mxLog.textarea.value);
|
||||
}
|
||||
catch (err)
|
||||
{
|
||||
} catch (err) {
|
||||
mxUtils.alert(err);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
mxLog.addButton('Show', function (evt)
|
||||
{
|
||||
try
|
||||
{
|
||||
mxLog.addButton('Show', function (evt) {
|
||||
try {
|
||||
mxUtils.popup(mxLog.textarea.value);
|
||||
}
|
||||
catch (err)
|
||||
{
|
||||
} catch (err) {
|
||||
mxUtils.alert(err);
|
||||
}
|
||||
});
|
||||
|
||||
mxLog.addButton('Clear', function (evt)
|
||||
{
|
||||
});
|
||||
|
||||
mxLog.addButton('Clear', function (evt) {
|
||||
mxLog.textarea.value = '';
|
||||
});
|
||||
|
||||
// Cross-browser code to get window size
|
||||
var h = 0;
|
||||
var w = 0;
|
||||
|
||||
if (typeof(window.innerWidth) === 'number')
|
||||
{
|
||||
|
||||
if (typeof (window.innerWidth) === 'number') {
|
||||
h = window.innerHeight;
|
||||
w = window.innerWidth;
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
h = (document.documentElement.clientHeight || document.body.clientHeight);
|
||||
w = document.body.clientWidth;
|
||||
}
|
||||
|
@ -177,18 +154,16 @@ var mxLog =
|
|||
mxLog.window.setResizable(true);
|
||||
mxLog.window.setClosable(true);
|
||||
mxLog.window.destroyOnClose = false;
|
||||
|
||||
|
||||
// Workaround for ignored textarea height in various setups
|
||||
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 resizeHandler = (sender, evt)=>
|
||||
{
|
||||
|
||||
var resizeHandler = (sender, evt) => {
|
||||
mxLog.textarea.style.height = Math.max(0, elt.offsetHeight - 70) + 'px';
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
mxLog.window.addListener(mxEvent.RESIZE_END, resizeHandler);
|
||||
mxLog.window.addListener(mxEvent.MAXIMIZE, resizeHandler);
|
||||
mxLog.window.addListener(mxEvent.NORMALIZE, resizeHandler);
|
||||
|
@ -197,83 +172,75 @@ var mxLog =
|
|||
}
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
/**
|
||||
* Function: info
|
||||
*
|
||||
*
|
||||
* Writes the current navigator information to the console.
|
||||
*/
|
||||
info: ()=>
|
||||
{
|
||||
info: () => {
|
||||
mxLog.writeln(mxUtils.toString(navigator));
|
||||
},
|
||||
|
||||
|
||||
/**
|
||||
* Function: addButton
|
||||
*
|
||||
*
|
||||
* Adds a button to the console using the given label and function.
|
||||
*/
|
||||
addButton: (lab, funct)=>
|
||||
{
|
||||
addButton: (lab, funct) => {
|
||||
var button = document.createElement('button');
|
||||
mxUtils.write(button, lab);
|
||||
mxEvent.addListener(button, 'click', funct);
|
||||
mxLog.td.appendChild(button);
|
||||
},
|
||||
|
||||
|
||||
/**
|
||||
* Function: isVisible
|
||||
*
|
||||
*
|
||||
* Returns true if the console is visible.
|
||||
*/
|
||||
isVisible: ()=>
|
||||
{
|
||||
if (mxLog.window != null)
|
||||
{
|
||||
isVisible: () => {
|
||||
if (mxLog.window != null) {
|
||||
return mxLog.window.isVisible();
|
||||
}
|
||||
|
||||
|
||||
return false;
|
||||
},
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Function: show
|
||||
*
|
||||
*
|
||||
* Shows the console.
|
||||
*/
|
||||
show: ()=>
|
||||
{
|
||||
show: () => {
|
||||
mxLog.setVisible(true);
|
||||
},
|
||||
|
||||
/**
|
||||
* Function: setVisible
|
||||
*
|
||||
*
|
||||
* Shows or hides the console.
|
||||
*/
|
||||
setVisible: (visible)=>
|
||||
{
|
||||
if (mxLog.window == null)
|
||||
{
|
||||
setVisible: (visible) => {
|
||||
if (mxLog.window == null) {
|
||||
mxLog.init();
|
||||
}
|
||||
|
||||
if (mxLog.window != null)
|
||||
{
|
||||
if (mxLog.window != null) {
|
||||
mxLog.window.setVisible(visible);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Function: enter
|
||||
*
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* Example:
|
||||
*
|
||||
*
|
||||
* (code)
|
||||
* mxLog.show();
|
||||
* var t0 = mxLog.enter('Hello');
|
||||
|
@ -281,133 +248,116 @@ var mxLog =
|
|||
* mxLog.leave('World!', t0);
|
||||
* (end)
|
||||
*/
|
||||
enter: (string)=>
|
||||
{
|
||||
if (mxLog.TRACE)
|
||||
{
|
||||
mxLog.writeln('Entering '+string);
|
||||
|
||||
enter: (string) => {
|
||||
if (mxLog.TRACE) {
|
||||
mxLog.writeln('Entering ' + string);
|
||||
|
||||
return new Date().getTime();
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Function: leave
|
||||
*
|
||||
*
|
||||
* Writes the specified string to the console
|
||||
* if <TRACE> is true and computes the difference
|
||||
* between the current time and t0 in milliseconds.
|
||||
* See <enter> for an example.
|
||||
*/
|
||||
leave: (string, t0)=>
|
||||
{
|
||||
if (mxLog.TRACE)
|
||||
{
|
||||
var dt = (t0 != 0) ? ' ('+(new Date().getTime() - t0)+' ms)' : '';
|
||||
mxLog.writeln('Leaving '+string+dt);
|
||||
leave: (string, t0) => {
|
||||
if (mxLog.TRACE) {
|
||||
var dt = (t0 != 0) ? ' (' + (new Date().getTime() - t0) + ' ms)' : '';
|
||||
mxLog.writeln('Leaving ' + string + dt);
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
/**
|
||||
* Function: debug
|
||||
*
|
||||
*
|
||||
* Adds all arguments to the console if <DEBUG> is enabled.
|
||||
*
|
||||
* Example:
|
||||
*
|
||||
*
|
||||
* (code)
|
||||
* mxLog.show();
|
||||
* mxLog.debug('Hello, World!');
|
||||
* (end)
|
||||
*/
|
||||
debug: ()=>
|
||||
{
|
||||
if (mxLog.DEBUG)
|
||||
{
|
||||
debug: () => {
|
||||
if (mxLog.DEBUG) {
|
||||
mxLog.writeln.apply(this, arguments);
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
/**
|
||||
* Function: warn
|
||||
*
|
||||
*
|
||||
* Adds all arguments to the console if <WARN> is enabled.
|
||||
*
|
||||
* Example:
|
||||
*
|
||||
*
|
||||
* (code)
|
||||
* mxLog.show();
|
||||
* mxLog.warn('Hello, World!');
|
||||
* (end)
|
||||
*/
|
||||
warn: ()=>
|
||||
{
|
||||
if (mxLog.WARN)
|
||||
{
|
||||
warn: () => {
|
||||
if (mxLog.WARN) {
|
||||
mxLog.writeln.apply(this, arguments);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Function: write
|
||||
*
|
||||
*
|
||||
* Adds the specified strings to the console.
|
||||
*/
|
||||
write: ()=>
|
||||
{
|
||||
write: () => {
|
||||
var string = '';
|
||||
|
||||
for (var i = 0; i < arguments.length; i++)
|
||||
{
|
||||
|
||||
for (var i = 0; i < arguments.length; i++) {
|
||||
string += arguments[i];
|
||||
|
||||
if (i < arguments.length - 1)
|
||||
{
|
||||
|
||||
if (i < arguments.length - 1) {
|
||||
string += ' ';
|
||||
}
|
||||
}
|
||||
|
||||
if (mxLog.textarea != null)
|
||||
{
|
||||
|
||||
if (mxLog.textarea != null) {
|
||||
mxLog.textarea.value = mxLog.textarea.value + string;
|
||||
|
||||
// Workaround for no update in Presto 2.5.22 (Opera 10.5)
|
||||
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 = 'visible';
|
||||
}
|
||||
|
||||
|
||||
mxLog.textarea.scrollTop = mxLog.textarea.scrollHeight;
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
mxLog.buffer += string;
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
/**
|
||||
* Function: writeln
|
||||
*
|
||||
*
|
||||
* Adds the specified strings to the console, appending a linefeed at the
|
||||
* end of each string.
|
||||
*/
|
||||
writeln: ()=>
|
||||
{
|
||||
writeln: () => {
|
||||
var string = '';
|
||||
|
||||
for (var i = 0; i < arguments.length; i++)
|
||||
{
|
||||
|
||||
for (var i = 0; i < arguments.length; i++) {
|
||||
string += arguments[i];
|
||||
|
||||
if (i < arguments.length - 1)
|
||||
{
|
||||
|
||||
if (i < arguments.length - 1) {
|
||||
string += ' ';
|
||||
}
|
||||
}
|
||||
|
||||
mxLog.write(string + '\n');
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
export default mxLog;
|
||||
|
|
|
@ -2,248 +2,226 @@
|
|||
* Copyright (c) 2006-2015, JGraph Ltd
|
||||
* Copyright (c) 2006-2015, Gaudenz Alder
|
||||
*/
|
||||
/**
|
||||
*
|
||||
* 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;
|
||||
};
|
||||
import mxPoint from "./mxPoint";
|
||||
import mxCellStatePreview from "../view/mxCellStatePreview";
|
||||
|
||||
/**
|
||||
* Extends mxEventSource.
|
||||
*/
|
||||
mxMorphing.prototype = new mxAnimation();
|
||||
constructor = mxMorphing;
|
||||
class mxMorphing extends mxAnimation {
|
||||
/**
|
||||
* Variable: graph
|
||||
*
|
||||
* Specifies the delay between the animation steps. Defaul is 30ms.
|
||||
*/
|
||||
graph = null;
|
||||
|
||||
/**
|
||||
* Variable: graph
|
||||
*
|
||||
* Specifies the delay between the animation steps. Defaul is 30ms.
|
||||
*/
|
||||
graph = null;
|
||||
/**
|
||||
* Variable: steps
|
||||
*
|
||||
* Specifies the maximum number of steps for the morphing.
|
||||
*/
|
||||
steps = null;
|
||||
|
||||
/**
|
||||
* Variable: steps
|
||||
*
|
||||
* Specifies the maximum number of steps for the morphing.
|
||||
*/
|
||||
steps = null;
|
||||
/**
|
||||
* Variable: step
|
||||
*
|
||||
* Contains the current step.
|
||||
*/
|
||||
step = 0;
|
||||
|
||||
/**
|
||||
* Variable: step
|
||||
*
|
||||
* Contains the current step.
|
||||
*/
|
||||
step = 0;
|
||||
/**
|
||||
* Variable: ease
|
||||
*
|
||||
* Ease-off for movement towards the given vector. Larger values are
|
||||
* slower and smoother. Default is 4.
|
||||
*/
|
||||
ease = null;
|
||||
|
||||
/**
|
||||
* Variable: ease
|
||||
*
|
||||
* Ease-off for movement towards the given vector. Larger values are
|
||||
* slower and smoother. Default is 4.
|
||||
*/
|
||||
ease = null;
|
||||
/**
|
||||
* Variable: cells
|
||||
*
|
||||
* Optional array of cells to be animated. If this is not specified
|
||||
* then all cells are checked and animated if they have been moved
|
||||
* in the current transaction.
|
||||
*/
|
||||
cells = null;
|
||||
|
||||
/**
|
||||
* Variable: cells
|
||||
*
|
||||
* Optional array of cells to be animated. If this is not specified
|
||||
* then all cells are checked and animated if they have been moved
|
||||
* in the current transaction.
|
||||
*/
|
||||
cells = null;
|
||||
/**
|
||||
*
|
||||
* 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>.
|
||||
*/
|
||||
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
|
||||
*
|
||||
* Animation step.
|
||||
*/
|
||||
updateAnimation = ()=>
|
||||
{
|
||||
updateAnimation.apply(this, arguments);
|
||||
var move = new mxCellStatePreview(this.graph);
|
||||
/**
|
||||
* Function: updateAnimation
|
||||
*
|
||||
* Animation step.
|
||||
*/
|
||||
updateAnimation = () => {
|
||||
updateAnimation.apply(this, arguments);
|
||||
var move = new mxCellStatePreview(this.graph);
|
||||
|
||||
if (this.cells != null)
|
||||
{
|
||||
// Animates the given cells individually without recursion
|
||||
for (var i = 0; i < this.cells.length; i++)
|
||||
{
|
||||
this.animateCell(this.cells[i], move, false);
|
||||
if (this.cells != null) {
|
||||
// Animates the given cells individually without recursion
|
||||
for (var i = 0; i < this.cells.length; i++) {
|
||||
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();
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Function: show
|
||||
*
|
||||
* Shows the changes in the given <mxCellStatePreview>.
|
||||
*/
|
||||
show = (move)=>
|
||||
{
|
||||
move.show();
|
||||
};
|
||||
this.show(move);
|
||||
|
||||
/**
|
||||
* 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 (move.isEmpty() || this.step++ >= this.steps) {
|
||||
this.stopAnimation();
|
||||
}
|
||||
}
|
||||
|
||||
if (recurse && !this.stopRecursion(state, delta))
|
||||
{
|
||||
var childCount = this.graph.getModel().getChildCount(cell);
|
||||
};
|
||||
|
||||
for (var i = 0; i < childCount; i++)
|
||||
{
|
||||
this.animateCell(this.graph.getModel().getChildAt(cell, i), move, recurse);
|
||||
/**
|
||||
* Function: show
|
||||
*
|
||||
* 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* 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);
|
||||
};
|
||||
if (recurse && !this.stopRecursion(state, delta)) {
|
||||
var childCount = this.graph.getModel().getChildCount(cell);
|
||||
|
||||
/**
|
||||
* Function: getDelta
|
||||
*
|
||||
* 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;
|
||||
for (var i = 0; i < childCount; i++) {
|
||||
this.animateCell(this.graph.getModel().getChildAt(cell, i), move, recurse);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
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
|
||||
*
|
||||
* Returns the top, left corner of the given cell. TODO: Improve performance
|
||||
* by using caching inside this method as the result per cell never changes
|
||||
* during the lifecycle of this object.
|
||||
*/
|
||||
getOriginForCell = (cell)=>
|
||||
{
|
||||
var result = null;
|
||||
|
||||
if (cell != null)
|
||||
{
|
||||
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;
|
||||
/**
|
||||
* Function: getDelta
|
||||
*
|
||||
* 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: getOriginForCell
|
||||
*
|
||||
* Returns the top, left corner of the given cell. TODO: Improve performance
|
||||
* by using caching inside this method as the result per cell never changes
|
||||
* during the lifecycle of this object.
|
||||
*/
|
||||
getOriginForCell = (cell) => {
|
||||
var result = null;
|
||||
|
||||
if (cell != null) {
|
||||
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)
|
||||
{
|
||||
var t = this.graph.view.getTranslate();
|
||||
result = new mxPoint(-t.x, -t.y);
|
||||
}
|
||||
|
||||
return result;
|
||||
};
|
||||
|
||||
if (result == null) {
|
||||
var t = this.graph.view.getTranslate();
|
||||
result = new mxPoint(-t.x, -t.y);
|
||||
}
|
||||
|
||||
return result;
|
||||
};
|
||||
}
|
||||
|
||||
export default mxMorphing;
|
||||
|
|
|
@ -2,237 +2,226 @@
|
|||
* Copyright (c) 2006-2015, JGraph Ltd
|
||||
* 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;
|
||||
};
|
||||
|
||||
/**
|
||||
* Variable: consumed
|
||||
*
|
||||
* Holds the consumed state of this event.
|
||||
*/
|
||||
consumed = false;
|
||||
class mxMouseEvent {
|
||||
/**
|
||||
* Variable: consumed
|
||||
*
|
||||
* Holds the consumed state of this event.
|
||||
*/
|
||||
consumed = false;
|
||||
|
||||
/**
|
||||
* Variable: evt
|
||||
*
|
||||
* Holds the inner event object.
|
||||
*/
|
||||
evt = null;
|
||||
/**
|
||||
* Variable: evt
|
||||
*
|
||||
* Holds the inner event object.
|
||||
*/
|
||||
evt = null;
|
||||
|
||||
/**
|
||||
* Variable: graphX
|
||||
*
|
||||
* Holds the x-coordinate of the event in the graph. This value is set in
|
||||
* <mxGraph.fireMouseEvent>.
|
||||
*/
|
||||
graphX = null;
|
||||
/**
|
||||
* Variable: graphX
|
||||
*
|
||||
* Holds the x-coordinate of the event in the graph. This value is set in
|
||||
* <mxGraph.fireMouseEvent>.
|
||||
*/
|
||||
graphX = null;
|
||||
|
||||
/**
|
||||
* Variable: graphY
|
||||
*
|
||||
* Holds the y-coordinate of the event in the graph. This value is set in
|
||||
* <mxGraph.fireMouseEvent>.
|
||||
*/
|
||||
graphY = null;
|
||||
/**
|
||||
* Variable: graphY
|
||||
*
|
||||
* Holds the y-coordinate of the event in the graph. This value is set in
|
||||
* <mxGraph.fireMouseEvent>.
|
||||
*/
|
||||
graphY = null;
|
||||
|
||||
/**
|
||||
* Variable: state
|
||||
*
|
||||
* Holds the optional <mxCellState> associated with this event.
|
||||
*/
|
||||
state = null;
|
||||
/**
|
||||
* Variable: state
|
||||
*
|
||||
* Holds the optional <mxCellState> associated with this event.
|
||||
*/
|
||||
state = null;
|
||||
|
||||
/**
|
||||
* Variable: sourceState
|
||||
*
|
||||
* Holds the <mxCellState> that was passed to the constructor. This can be
|
||||
* different from <state> depending on the result of <mxGraph.getEventState>.
|
||||
*/
|
||||
sourceState = null;
|
||||
/**
|
||||
* Variable: sourceState
|
||||
*
|
||||
* Holds the <mxCellState> that was passed to the constructor. This can be
|
||||
* different from <state> depending on the result of <mxGraph.getEventState>.
|
||||
*/
|
||||
sourceState = null;
|
||||
|
||||
/**
|
||||
* Function: getEvent
|
||||
*
|
||||
* Returns <evt>.
|
||||
*/
|
||||
getEvent = ()=>
|
||||
{
|
||||
return this.evt;
|
||||
};
|
||||
/**
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
constructor(evt, state) {
|
||||
this.evt = evt;
|
||||
this.state = state;
|
||||
this.sourceState = state;
|
||||
};
|
||||
|
||||
/**
|
||||
* Function: getSource
|
||||
*
|
||||
* Returns the target DOM element using <mxEvent.getSource> for <evt>.
|
||||
*/
|
||||
getSource = ()=>
|
||||
{
|
||||
return mxEvent.getSource(this.evt);
|
||||
};
|
||||
/**
|
||||
* Function: getEvent
|
||||
*
|
||||
* Returns <evt>.
|
||||
*/
|
||||
getEvent = () => {
|
||||
return this.evt;
|
||||
};
|
||||
|
||||
/**
|
||||
* 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());
|
||||
}
|
||||
/**
|
||||
* Function: getSource
|
||||
*
|
||||
* Returns the target DOM element using <mxEvent.getSource> for <evt>.
|
||||
*/
|
||||
getSource = () => {
|
||||
return mxEvent.getSource(this.evt);
|
||||
};
|
||||
|
||||
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());
|
||||
}
|
||||
|
||||
/**
|
||||
* Function: getX
|
||||
*
|
||||
* Returns <evt.clientX>.
|
||||
*/
|
||||
getX = ()=>
|
||||
{
|
||||
return mxEvent.getClientX(this.getEvent());
|
||||
};
|
||||
return false;
|
||||
};
|
||||
|
||||
/**
|
||||
* Function: getY
|
||||
*
|
||||
* Returns <evt.clientY>.
|
||||
*/
|
||||
getY = ()=>
|
||||
{
|
||||
return mxEvent.getClientY(this.getEvent());
|
||||
};
|
||||
/**
|
||||
* Function: getX
|
||||
*
|
||||
* Returns <evt.clientX>.
|
||||
*/
|
||||
getX = () => {
|
||||
return mxEvent.getClientX(this.getEvent());
|
||||
};
|
||||
|
||||
/**
|
||||
* Function: getGraphX
|
||||
*
|
||||
* Returns <graphX>.
|
||||
*/
|
||||
getGraphX = ()=>
|
||||
{
|
||||
return this.graphX;
|
||||
};
|
||||
/**
|
||||
* Function: getY
|
||||
*
|
||||
* Returns <evt.clientY>.
|
||||
*/
|
||||
getY = () => {
|
||||
return mxEvent.getClientY(this.getEvent());
|
||||
};
|
||||
|
||||
/**
|
||||
* Function: getGraphY
|
||||
*
|
||||
* Returns <graphY>.
|
||||
*/
|
||||
getGraphY = ()=>
|
||||
{
|
||||
return this.graphY;
|
||||
};
|
||||
/**
|
||||
* Function: getGraphX
|
||||
*
|
||||
* Returns <graphX>.
|
||||
*/
|
||||
getGraphX = () => {
|
||||
return this.graphX;
|
||||
};
|
||||
|
||||
/**
|
||||
* Function: getState
|
||||
*
|
||||
* Returns <state>.
|
||||
*/
|
||||
getState = ()=>
|
||||
{
|
||||
return this.state;
|
||||
};
|
||||
/**
|
||||
* Function: getGraphY
|
||||
*
|
||||
* Returns <graphY>.
|
||||
*/
|
||||
getGraphY = () => {
|
||||
return this.graphY;
|
||||
};
|
||||
|
||||
/**
|
||||
* Function: getCell
|
||||
*
|
||||
* Returns the <mxCell> in <state> is not null.
|
||||
*/
|
||||
getCell = ()=>
|
||||
{
|
||||
var state = this.getState();
|
||||
/**
|
||||
* Function: getState
|
||||
*
|
||||
* Returns <state>.
|
||||
*/
|
||||
getState = () => {
|
||||
return this.state;
|
||||
};
|
||||
|
||||
if (state != null)
|
||||
{
|
||||
return state.cell;
|
||||
}
|
||||
/**
|
||||
* Function: getCell
|
||||
*
|
||||
* Returns the <mxCell> in <state> is not null.
|
||||
*/
|
||||
getCell = () => {
|
||||
var state = this.getState();
|
||||
|
||||
return null;
|
||||
};
|
||||
if (state != null) {
|
||||
return state.cell;
|
||||
}
|
||||
|
||||
/**
|
||||
* Function: isPopupTrigger
|
||||
*
|
||||
* Returns true if the event is a popup trigger.
|
||||
*/
|
||||
isPopupTrigger = ()=>
|
||||
{
|
||||
return mxEvent.isPopupTrigger(this.getEvent());
|
||||
};
|
||||
return null;
|
||||
};
|
||||
|
||||
/**
|
||||
* Function: isConsumed
|
||||
*
|
||||
* Returns <consumed>.
|
||||
*/
|
||||
isConsumed = ()=>
|
||||
{
|
||||
return this.consumed;
|
||||
};
|
||||
/**
|
||||
* Function: isPopupTrigger
|
||||
*
|
||||
* Returns true if the event is a popup trigger.
|
||||
*/
|
||||
isPopupTrigger = () => {
|
||||
return mxEvent.isPopupTrigger(this.getEvent());
|
||||
};
|
||||
|
||||
/**
|
||||
* Function: consume
|
||||
*
|
||||
* 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));
|
||||
/**
|
||||
* Function: isConsumed
|
||||
*
|
||||
* Returns <consumed>.
|
||||
*/
|
||||
isConsumed = () => {
|
||||
return this.consumed;
|
||||
};
|
||||
|
||||
if (preventDefault && this.evt.preventDefault)
|
||||
{
|
||||
this.evt.preventDefault();
|
||||
}
|
||||
/**
|
||||
* Function: consume
|
||||
*
|
||||
* 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
|
||||
this.consumed = true;
|
||||
};
|
||||
if (preventDefault && this.evt.preventDefault) {
|
||||
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, Gaudenz Alder
|
||||
*/
|
||||
var mxObjectIdentity =
|
||||
{
|
||||
|
||||
var mxObjectIdentity = {
|
||||
/**
|
||||
* Class: mxObjectIdentity
|
||||
*
|
||||
*
|
||||
* Identity for JavaScript objects and functions. This is implemented using
|
||||
* a simple incrementing counter which is stored in each object under
|
||||
* <FIELD_NAME>.
|
||||
*
|
||||
*
|
||||
* The identity for an object does not change during its lifecycle.
|
||||
*
|
||||
*
|
||||
* Variable: FIELD_NAME
|
||||
*
|
||||
*
|
||||
* Name of the field to be used to store the object ID. Default is
|
||||
* <code>mxObjectId</code>.
|
||||
*/
|
||||
|
@ -22,51 +22,44 @@ var mxObjectIdentity =
|
|||
|
||||
/**
|
||||
* Variable: counter
|
||||
*
|
||||
*
|
||||
* Current counter.
|
||||
*/
|
||||
counter: 0,
|
||||
|
||||
/**
|
||||
* Function: get
|
||||
*
|
||||
*
|
||||
* Returns the ID for the given object or function or null if no object
|
||||
* is specified.
|
||||
*/
|
||||
get: (obj)=>
|
||||
{
|
||||
if (obj != null)
|
||||
{
|
||||
if (obj[mxObjectIdentity.FIELD_NAME] == null)
|
||||
{
|
||||
if (typeof obj === 'object')
|
||||
{
|
||||
get: (obj) => {
|
||||
if (obj != null) {
|
||||
if (obj[mxObjectIdentity.FIELD_NAME] == null) {
|
||||
if (typeof obj === 'object') {
|
||||
var ctor = mxUtils.getFunctionName(obj.constructor);
|
||||
obj[mxObjectIdentity.FIELD_NAME] = ctor + '#' + mxObjectIdentity.counter++;
|
||||
}
|
||||
else if (typeof obj === 'function')
|
||||
{
|
||||
} else if (typeof obj === 'function') {
|
||||
obj[mxObjectIdentity.FIELD_NAME] = 'Function#' + mxObjectIdentity.counter++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return obj[mxObjectIdentity.FIELD_NAME];
|
||||
}
|
||||
|
||||
|
||||
return null;
|
||||
},
|
||||
|
||||
/**
|
||||
* Function: clear
|
||||
*
|
||||
*
|
||||
* Deletes the ID from the given object or function.
|
||||
*/
|
||||
clear: (obj)=>
|
||||
{
|
||||
if (typeof(obj) === 'object' || typeof obj === 'function')
|
||||
{
|
||||
clear: (obj) => {
|
||||
if (typeof (obj) === 'object' || typeof obj === 'function') {
|
||||
delete obj[mxObjectIdentity.FIELD_NAME];
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
export default mxObjectIdentity;
|
||||
|
|
|
@ -2,264 +2,221 @@
|
|||
* Copyright (c) 2006-2015, JGraph Ltd
|
||||
* 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)
|
||||
{
|
||||
var left = -graph.container.scrollLeft - Math.ceil(this.dx);
|
||||
var top = -graph.container.scrollTop - Math.ceil(this.dy);
|
||||
graph.panGraph(left, top);
|
||||
graph.panDx = this.scrollLeft - graph.container.scrollLeft;
|
||||
graph.panDy = this.scrollTop - graph.container.scrollTop;
|
||||
graph.fireEvent(new mxEventObject(mxEvent.PAN));
|
||||
// TODO: Implement graph.autoExtend
|
||||
class 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;
|
||||
|
||||
/**
|
||||
* 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());
|
||||
}
|
||||
}), this.delay);
|
||||
});
|
||||
|
||||
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();
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
// 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;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
if (this.dx == 0)
|
||||
{
|
||||
this.dx = x - c.scrollLeft;
|
||||
|
||||
if (this.dx > 0 && this.dx < this.border)
|
||||
{
|
||||
this.dx = this.dx - this.border;
|
||||
|
||||
return window.setInterval(mxUtils.bind(this, () => {
|
||||
this.tdx -= this.dx;
|
||||
this.tdy -= this.dy;
|
||||
|
||||
if (this.scrollbars) {
|
||||
var left = -graph.container.scrollLeft - Math.ceil(this.dx);
|
||||
var top = -graph.container.scrollTop - Math.ceil(this.dy);
|
||||
graph.panGraph(left, top);
|
||||
graph.panDx = this.scrollLeft - graph.container.scrollLeft;
|
||||
graph.panDy = this.scrollTop - graph.container.scrollTop;
|
||||
graph.fireEvent(new mxEventObject(mxEvent.PAN));
|
||||
// TODO: Implement graph.autoExtend
|
||||
} else {
|
||||
graph.panGraph(this.getDx(), this.getDy());
|
||||
}
|
||||
}), this.delay);
|
||||
});
|
||||
|
||||
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();
|
||||
}
|
||||
else if (this.handleMouseOut)
|
||||
{
|
||||
this.dx = Math.min(0, this.dx);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
this.scrollLeft = graph.container.scrollLeft;
|
||||
this.scrollTop = graph.container.scrollTop;
|
||||
|
||||
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.dy = y + h - c.scrollTop - c.clientHeight;
|
||||
|
||||
if (this.dy < 0 && Math.abs(this.dy) < this.border)
|
||||
{
|
||||
this.dy = this.border + this.dy;
|
||||
}
|
||||
else if (this.handleMouseOut)
|
||||
{
|
||||
this.dy = Math.max(this.dy, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
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;
|
||||
if (this.dx == 0) {
|
||||
this.dx = x - c.scrollLeft;
|
||||
|
||||
if (this.dx > 0 && this.dx < this.border) {
|
||||
this.dx = this.dx - this.border;
|
||||
} else if (this.handleMouseOut) {
|
||||
this.dx = Math.min(0, this.dx);
|
||||
} else {
|
||||
this.dx = 0;
|
||||
}
|
||||
}
|
||||
else if (this.handleMouseOut)
|
||||
{
|
||||
this.dy = Math.min(0, this.dy);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
this.dy = y + h - c.scrollTop - c.clientHeight;
|
||||
|
||||
if (this.dy < 0 && Math.abs(this.dy) < this.border) {
|
||||
this.dy = this.border + this.dy;
|
||||
} else if (this.handleMouseOut) {
|
||||
this.dy = Math.max(this.dy, 0);
|
||||
} else {
|
||||
this.dy = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (this.dx != 0 || this.dy != 0)
|
||||
{
|
||||
this.dx *= this.damper;
|
||||
this.dy *= this.damper;
|
||||
|
||||
if (this.thread == null)
|
||||
{
|
||||
this.thread = createThread();
|
||||
|
||||
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 = Math.min(0, this.dy);
|
||||
} else {
|
||||
this.dy = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (this.thread != null)
|
||||
{
|
||||
window.clearInterval(this.thread);
|
||||
this.thread = null;
|
||||
}
|
||||
};
|
||||
|
||||
this.stop = ()=>
|
||||
{
|
||||
if (this.active)
|
||||
{
|
||||
this.active = false;
|
||||
|
||||
if (this.thread != null)
|
||||
{
|
||||
|
||||
if (this.dx != 0 || this.dy != 0) {
|
||||
this.dx *= this.damper;
|
||||
this.dy *= this.damper;
|
||||
|
||||
if (this.thread == null) {
|
||||
this.thread = createThread();
|
||||
}
|
||||
} else if (this.thread != null) {
|
||||
window.clearInterval(this.thread);
|
||||
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.tdy = 0;
|
||||
|
||||
if (!this.scrollbars)
|
||||
{
|
||||
var px = graph.panDx;
|
||||
var py = graph.panDy;
|
||||
|
||||
if (px != 0 || py != 0)
|
||||
{
|
||||
|
||||
this.tdx = 0;
|
||||
this.tdy = 0;
|
||||
|
||||
if (!this.scrollbars) {
|
||||
var px = graph.panDx;
|
||||
var py = graph.panDy;
|
||||
|
||||
if (px != 0 || py != 0) {
|
||||
graph.panGraph(0, 0);
|
||||
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;
|
||||
graph.panDy = 0;
|
||||
graph.fireEvent(new mxEventObject(mxEvent.PAN));
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
this.destroy = () => {
|
||||
graph.removeMouseListener(this.mouseListener);
|
||||
mxEvent.removeListener(document, 'mouseup', this.mouseUpListener);
|
||||
};
|
||||
};
|
||||
|
||||
this.destroy = ()=>
|
||||
{
|
||||
graph.removeMouseListener(this.mouseListener);
|
||||
mxEvent.removeListener(document, 'mouseup', this.mouseUpListener);
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* 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;
|
||||
export default mxPanningManager;
|
||||
|
|
|
@ -2,53 +2,57 @@
|
|||
* Copyright (c) 2006-2015, JGraph Ltd
|
||||
* 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;
|
||||
};
|
||||
|
||||
/**
|
||||
* Variable: x
|
||||
*
|
||||
* Holds the x-coordinate of the point. Default is 0.
|
||||
*/
|
||||
x = null;
|
||||
import mxUtils from "../util/mxUtils";
|
||||
|
||||
/**
|
||||
* Variable: y
|
||||
*
|
||||
* Holds the y-coordinate of the point. Default is 0.
|
||||
*/
|
||||
y = null;
|
||||
class mxPoint {
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
constructor(x, y) {
|
||||
this.x = (x != null) ? x : 0;
|
||||
this.y = (y != null) ? y : 0;
|
||||
};
|
||||
|
||||
/**
|
||||
* Function: equals
|
||||
*
|
||||
* Returns true if the given object equals this point.
|
||||
*/
|
||||
equals = (obj)=>
|
||||
{
|
||||
return obj != null && obj.x == this.x && obj.y == this.y;
|
||||
};
|
||||
/**
|
||||
* Variable: x
|
||||
*
|
||||
* Holds the x-coordinate of the point. Default is 0.
|
||||
*/
|
||||
x = null;
|
||||
|
||||
/**
|
||||
* Function: clone
|
||||
*
|
||||
* Returns a clone of this <mxPoint>.
|
||||
*/
|
||||
clone = ()=>
|
||||
{
|
||||
// Handles subclasses as well
|
||||
return mxUtils.clone(this);
|
||||
};
|
||||
/**
|
||||
* Variable: y
|
||||
*
|
||||
* Holds the y-coordinate of the point. Default is 0.
|
||||
*/
|
||||
y = null;
|
||||
|
||||
/**
|
||||
* 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
|
||||
* 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;
|
||||
this.height = (height != null) ? height : 0;
|
||||
};
|
||||
import mxPoint from "./mxPoint";
|
||||
|
||||
/**
|
||||
* Extends mxPoint.
|
||||
*/
|
||||
mxRectangle.prototype = new mxPoint();
|
||||
constructor = mxRectangle;
|
||||
class mxRectangle extends mxPoint {
|
||||
constructor(x, y, width, height) {
|
||||
super(x, y);
|
||||
this.width = (width != null) ? width : 0;
|
||||
this.height = (height != null) ? height : 0;
|
||||
};
|
||||
|
||||
/**
|
||||
* Variable: width
|
||||
*
|
||||
* Holds the width of the rectangle. Default is 0.
|
||||
*/
|
||||
width = null;
|
||||
/**
|
||||
* Variable: width
|
||||
*
|
||||
* Holds the width of the rectangle. Default is 0.
|
||||
*/
|
||||
width = null;
|
||||
|
||||
/**
|
||||
* Variable: height
|
||||
*
|
||||
* Holds the height of the rectangle. Default is 0.
|
||||
*/
|
||||
height = null;
|
||||
/**
|
||||
* Variable: height
|
||||
*
|
||||
* Holds the height of the rectangle. Default is 0.
|
||||
*/
|
||||
height = null;
|
||||
|
||||
/**
|
||||
* Function: setRect
|
||||
*
|
||||
* Sets this rectangle to the specified values
|
||||
*/
|
||||
setRect = (x, y, w, h)=>
|
||||
{
|
||||
/**
|
||||
* Function: setRect
|
||||
*
|
||||
* Sets this rectangle to the specified values
|
||||
*/
|
||||
setRect = (x, y, w, h) => {
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
this.width = w;
|
||||
this.height = h;
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
* Function: getCenterX
|
||||
*
|
||||
* Returns the x-coordinate of the center point.
|
||||
*/
|
||||
getCenterX = function ()
|
||||
{
|
||||
return this.x + this.width/2;
|
||||
};
|
||||
/**
|
||||
* Function: getCenterX
|
||||
*
|
||||
* Returns the x-coordinate of the center point.
|
||||
*/
|
||||
getCenterX = function () {
|
||||
return this.x + this.width / 2;
|
||||
};
|
||||
|
||||
/**
|
||||
* Function: getCenterY
|
||||
*
|
||||
* Returns the y-coordinate of the center point.
|
||||
*/
|
||||
getCenterY = function ()
|
||||
{
|
||||
return this.y + this.height/2;
|
||||
};
|
||||
/**
|
||||
* Function: getCenterY
|
||||
*
|
||||
* Returns the y-coordinate of the center point.
|
||||
*/
|
||||
getCenterY = function () {
|
||||
return this.y + this.height / 2;
|
||||
};
|
||||
|
||||
/**
|
||||
* Function: add
|
||||
*
|
||||
* Adds the given rectangle to this rectangle.
|
||||
*/
|
||||
add = (rect)=>
|
||||
{
|
||||
if (rect != null)
|
||||
{
|
||||
var minX = Math.min(this.x, rect.x);
|
||||
var minY = Math.min(this.y, rect.y);
|
||||
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;
|
||||
}
|
||||
};
|
||||
/**
|
||||
* Function: add
|
||||
*
|
||||
* Adds the given rectangle to this rectangle.
|
||||
*/
|
||||
add = (rect) => {
|
||||
if (rect != null) {
|
||||
var minX = Math.min(this.x, rect.x);
|
||||
var minY = Math.min(this.y, rect.y);
|
||||
var maxX = Math.max(this.x + this.width, rect.x + rect.width);
|
||||
var maxY = Math.max(this.y + this.height, rect.y + rect.height);
|
||||
|
||||
/**
|
||||
* Function: intersect
|
||||
*
|
||||
* Changes this rectangle to where it overlaps with the given rectangle.
|
||||
*/
|
||||
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;
|
||||
}
|
||||
};
|
||||
this.x = minX;
|
||||
this.y = minY;
|
||||
this.width = maxX - minX;
|
||||
this.height = maxY - minY;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Function: grow
|
||||
*
|
||||
* 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
|
||||
* to the width and height.
|
||||
*/
|
||||
grow = (amount)=>
|
||||
{
|
||||
this.x -= amount;
|
||||
this.y -= amount;
|
||||
this.width += 2 * amount;
|
||||
this.height += 2 * amount;
|
||||
|
||||
return this;
|
||||
};
|
||||
/**
|
||||
* Function: intersect
|
||||
*
|
||||
* Changes this rectangle to where it overlaps with the given rectangle.
|
||||
*/
|
||||
intersect = (rect) => {
|
||||
if (rect != null) {
|
||||
var r1 = this.x + this.width;
|
||||
var r2 = rect.x + rect.width;
|
||||
|
||||
/**
|
||||
* Function: getPoint
|
||||
*
|
||||
* Returns the top, left corner as a new <mxPoint>.
|
||||
*/
|
||||
getPoint = ()=>
|
||||
{
|
||||
return new mxPoint(this.x, this.y);
|
||||
};
|
||||
var b1 = this.y + this.height;
|
||||
var b2 = rect.y + rect.height;
|
||||
|
||||
/**
|
||||
* 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;
|
||||
};
|
||||
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: 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: grow
|
||||
*
|
||||
* 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
|
||||
* to the width and height.
|
||||
*/
|
||||
grow = (amount) => {
|
||||
this.x -= amount;
|
||||
this.y -= amount;
|
||||
this.width += 2 * amount;
|
||||
this.height += 2 * amount;
|
||||
|
||||
/**
|
||||
* Function: fromRectangle
|
||||
*
|
||||
* Returns a new <mxRectangle> which is a copy of the given rectangle.
|
||||
*/
|
||||
mxRectangle.fromRectangle = (rect)=>
|
||||
{
|
||||
return new mxRectangle(rect.x, rect.y, rect.width, rect.height);
|
||||
};
|
||||
return this;
|
||||
};
|
||||
|
||||
/**
|
||||
* Function: getPoint
|
||||
*
|
||||
* Returns the top, left corner as a new <mxPoint>.
|
||||
*/
|
||||
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, 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;
|
||||
};
|
||||
|
||||
/**
|
||||
* Extends mxEventSource.
|
||||
*/
|
||||
mxToolbar.prototype = new mxEventSource();
|
||||
constructor = mxToolbar;
|
||||
import mxUtils from "./mxUtils";
|
||||
import mxPoint from "./mxPoint";
|
||||
import mxPopupMenu from "./mxPopupMenu";
|
||||
import mxEventSource from "./mxEventSource";
|
||||
import mxEventObject from "./mxEventObject";
|
||||
|
||||
/**
|
||||
* Variable: container
|
||||
*
|
||||
* Reference to the DOM nodes that contains the toolbar.
|
||||
*/
|
||||
container = null;
|
||||
class mxToolbar extends mxEventSource {
|
||||
/**
|
||||
* Variable: container
|
||||
*
|
||||
* Reference to the DOM nodes that contains the toolbar.
|
||||
*/
|
||||
container = null;
|
||||
|
||||
/**
|
||||
* Variable: enabled
|
||||
*
|
||||
* Specifies if events are handled. Default is true.
|
||||
*/
|
||||
enabled = true;
|
||||
/**
|
||||
* Variable: enabled
|
||||
*
|
||||
* Specifies if events are handled. Default is true.
|
||||
*/
|
||||
enabled = true;
|
||||
|
||||
/**
|
||||
* Variable: noReset
|
||||
*
|
||||
* 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
|
||||
* if the toolbar item is double clicked to avoid a reset after a single
|
||||
* use of the item.
|
||||
*/
|
||||
noReset = false;
|
||||
/**
|
||||
* Variable: noReset
|
||||
*
|
||||
* 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
|
||||
* if the toolbar item is double clicked to avoid a reset after a single
|
||||
* use of the item.
|
||||
*/
|
||||
noReset = false;
|
||||
|
||||
/**
|
||||
* Variable: updateDefaultMode
|
||||
*
|
||||
* Boolean indicating if the default mode should be the last selected
|
||||
* 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 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
|
||||
* of what was last selected. Otherwise, the selected item after a reset is
|
||||
* the previously selected item.
|
||||
*/
|
||||
updateDefaultMode = true;
|
||||
/**
|
||||
* Variable: updateDefaultMode
|
||||
*
|
||||
* Boolean indicating if the default mode should be the last selected
|
||||
* 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 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
|
||||
* of what was last selected. Otherwise, the selected item after a reset is
|
||||
* the previously selected item.
|
||||
*/
|
||||
updateDefaultMode = true;
|
||||
|
||||
/**
|
||||
* Function: addItem
|
||||
*
|
||||
* Adds the given function as an image with the specified title and icon
|
||||
* and returns the new image node.
|
||||
*
|
||||
* Parameters:
|
||||
*
|
||||
* 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);
|
||||
|
||||
if (title != null)
|
||||
{
|
||||
if (icon != null)
|
||||
{
|
||||
img.setAttribute('title', title);
|
||||
}
|
||||
else
|
||||
{
|
||||
mxUtils.write(img, title);
|
||||
}
|
||||
}
|
||||
|
||||
this.container.appendChild(img);
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
constructor(container) {
|
||||
this.container = container;
|
||||
};
|
||||
|
||||
// Invokes the function on a click on the toolbar item
|
||||
if (funct != null)
|
||||
{
|
||||
mxEvent.addListener(img, 'click', funct);
|
||||
|
||||
if (mxClient.IS_TOUCH)
|
||||
{
|
||||
mxEvent.addListener(img, 'touchend', funct);
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Function: addItem
|
||||
*
|
||||
* Adds the given function as an image with the specified title and icon
|
||||
* and returns the new image node.
|
||||
*
|
||||
* Parameters:
|
||||
*
|
||||
* 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 (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();
|
||||
if (title != null) {
|
||||
if (icon != null) {
|
||||
img.setAttribute('title', title);
|
||||
} else {
|
||||
mxUtils.write(img, title);
|
||||
}
|
||||
|
||||
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;
|
||||
};
|
||||
this.container.appendChild(img);
|
||||
|
||||
// Invokes the function on a click on the toolbar item
|
||||
if (funct != null) {
|
||||
mxEvent.addListener(img, 'click', funct);
|
||||
|
||||
if (mxClient.IS_TOUCH) {
|
||||
mxEvent.addListener(img, 'touchend', funct);
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
return img;
|
||||
};
|
||||
combo.appendChild(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;
|
||||
};
|
||||
return option;
|
||||
};
|
||||
|
||||
/**
|
||||
* 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);
|
||||
/**
|
||||
* 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);
|
||||
}
|
||||
});
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
mxEvent.addListener(img, 'click', mxUtils.bind(this, (evt) => {
|
||||
var tmp = this.selectedMode.altIcon;
|
||||
|
||||
if (tmp != null)
|
||||
{
|
||||
|
||||
if (tmp != null) {
|
||||
this.selectedMode.altIcon = this.selectedMode.getAttribute('src');
|
||||
this.selectedMode.setAttribute('src', tmp);
|
||||
}
|
||||
else
|
||||
{
|
||||
} 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();
|
||||
}
|
||||
|
||||
this.selectedMode = domNode;
|
||||
var tmp = this.selectedMode.altIcon;
|
||||
|
||||
if (tmp != null)
|
||||
{
|
||||
this.selectedMode.altIcon = this.selectedMode.getAttribute('src');
|
||||
this.selectedMode.setAttribute('src', tmp);
|
||||
|
||||
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);
|
||||
}
|
||||
else
|
||||
{
|
||||
this.selectedMode.className = this.selectedMode.initialClassName+'Selected';
|
||||
|
||||
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.fireEvent(new mxEventObject(mxEvent.SELECT, "function", funct));
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* 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);
|
||||
}
|
||||
};
|
||||
this.container.appendChild(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);
|
||||
};
|
||||
return img;
|
||||
};
|
||||
|
||||
/**
|
||||
* Function: addBreak
|
||||
*
|
||||
* Adds a break to the container.
|
||||
*/
|
||||
addBreak = ()=>
|
||||
{
|
||||
mxUtils.br(this.container);
|
||||
};
|
||||
/**
|
||||
* 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;
|
||||
|
||||
/**
|
||||
* 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);
|
||||
};
|
||||
if (tmp != null) {
|
||||
this.selectedMode.altIcon = this.selectedMode.getAttribute('src');
|
||||
this.selectedMode.setAttribute('src', tmp);
|
||||
} else {
|
||||
this.selectedMode.className = this.selectedMode.initialClassName;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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();
|
||||
}
|
||||
};
|
||||
this.selectedMode = domNode;
|
||||
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 + 'Selected';
|
||||
}
|
||||
|
||||
this.fireEvent(new mxEventObject(mxEvent.SELECT, "function", funct));
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* 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, 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();
|
||||
};
|
||||
|
||||
/**
|
||||
* Extends mxEventSource.
|
||||
*/
|
||||
mxUndoManager.prototype = new mxEventSource();
|
||||
constructor = mxUndoManager;
|
||||
import mxEventObject from "./mxEventObject";
|
||||
import mxEventSource from "./mxEventSource";
|
||||
|
||||
/**
|
||||
* Variable: size
|
||||
*
|
||||
* Maximum command history size. 0 means unlimited history. Default is
|
||||
* 100.
|
||||
*/
|
||||
size = null;
|
||||
class mxUndoManager extends mxEventSource {
|
||||
/**
|
||||
* Variable: size
|
||||
*
|
||||
* Maximum command history size. 0 means unlimited history. Default is
|
||||
* 100.
|
||||
*/
|
||||
size = null;
|
||||
|
||||
/**
|
||||
* Variable: history
|
||||
*
|
||||
* Array that contains the steps of the command history.
|
||||
*/
|
||||
history = null;
|
||||
/**
|
||||
* Variable: history
|
||||
*
|
||||
* Array that contains the steps of the command history.
|
||||
*/
|
||||
history = null;
|
||||
|
||||
/**
|
||||
* Variable: indexOfNextAdd
|
||||
*
|
||||
* Index of the element to be added next.
|
||||
*/
|
||||
indexOfNextAdd = 0;
|
||||
/**
|
||||
* Variable: indexOfNextAdd
|
||||
*
|
||||
* Index of the element to be added next.
|
||||
*/
|
||||
indexOfNextAdd = 0;
|
||||
|
||||
/**
|
||||
* Function: isEmpty
|
||||
*
|
||||
* Returns true if the history is empty.
|
||||
*/
|
||||
isEmpty = ()=>
|
||||
{
|
||||
return this.history.length == 0;
|
||||
};
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
constructor(size) {
|
||||
this.size = (size != null) ? size : 100;
|
||||
this.clear();
|
||||
};
|
||||
|
||||
/**
|
||||
* Function: clear
|
||||
*
|
||||
* Clears the command history.
|
||||
*/
|
||||
clear = ()=>
|
||||
{
|
||||
this.history = [];
|
||||
this.indexOfNextAdd = 0;
|
||||
this.fireEvent(new mxEventObject(mxEvent.CLEAR));
|
||||
};
|
||||
/**
|
||||
* Function: isEmpty
|
||||
*
|
||||
* Returns true if the history is empty.
|
||||
*/
|
||||
isEmpty = () => {
|
||||
return this.history.length == 0;
|
||||
};
|
||||
|
||||
/**
|
||||
* Function: canUndo
|
||||
*
|
||||
* Returns true if an undo is possible.
|
||||
*/
|
||||
canUndo = ()=>
|
||||
{
|
||||
return this.indexOfNextAdd > 0;
|
||||
};
|
||||
/**
|
||||
* Function: clear
|
||||
*
|
||||
* Clears the command history.
|
||||
*/
|
||||
clear = () => {
|
||||
this.history = [];
|
||||
this.indexOfNextAdd = 0;
|
||||
this.fireEvent(new mxEventObject(mxEvent.CLEAR));
|
||||
};
|
||||
|
||||
/**
|
||||
* Function: undo
|
||||
*
|
||||
* Undoes the last change.
|
||||
*/
|
||||
undo = ()=>
|
||||
{
|
||||
while (this.indexOfNextAdd > 0)
|
||||
{
|
||||
var edit = this.history[--this.indexOfNextAdd];
|
||||
edit.undo();
|
||||
/**
|
||||
* Function: canUndo
|
||||
*
|
||||
* Returns true if an undo is possible.
|
||||
*/
|
||||
canUndo = () => {
|
||||
return this.indexOfNextAdd > 0;
|
||||
};
|
||||
|
||||
if (edit.isSignificant())
|
||||
{
|
||||
this.fireEvent(new mxEventObject(mxEvent.UNDO, 'edit', edit));
|
||||
break;
|
||||
}
|
||||
/**
|
||||
* Function: undo
|
||||
*
|
||||
* 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
|
||||
*
|
||||
* Returns true if a redo is possible.
|
||||
*/
|
||||
canRedo = ()=>
|
||||
{
|
||||
return this.indexOfNextAdd < this.history.length;
|
||||
};
|
||||
/**
|
||||
* Function: canRedo
|
||||
*
|
||||
* Returns true if a redo is possible.
|
||||
*/
|
||||
canRedo = () => {
|
||||
return this.indexOfNextAdd < this.history.length;
|
||||
};
|
||||
|
||||
/**
|
||||
* Function: redo
|
||||
*
|
||||
* Redoes the last change.
|
||||
*/
|
||||
redo = ()=>
|
||||
{
|
||||
/**
|
||||
* Function: redo
|
||||
*
|
||||
* Redoes the last change.
|
||||
*/
|
||||
redo = () => {
|
||||
var n = this.history.length;
|
||||
|
||||
while (this.indexOfNextAdd < n)
|
||||
{
|
||||
var edit = this.history[this.indexOfNextAdd++];
|
||||
edit.redo();
|
||||
|
||||
if (edit.isSignificant())
|
||||
{
|
||||
this.fireEvent(new mxEventObject(mxEvent.REDO, 'edit', edit));
|
||||
break;
|
||||
}
|
||||
|
||||
while (this.indexOfNextAdd < n) {
|
||||
var edit = this.history[this.indexOfNextAdd++];
|
||||
edit.redo();
|
||||
|
||||
if (edit.isSignificant()) {
|
||||
this.fireEvent(new mxEventObject(mxEvent.REDO, 'edit', edit));
|
||||
break;
|
||||
}
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
* Function: undoableEditHappened
|
||||
*
|
||||
* Method to be called to add new undoable edits to the <history>.
|
||||
*/
|
||||
undoableEditHappened = (undoableEdit)=>
|
||||
{
|
||||
this.trim();
|
||||
/**
|
||||
* Function: undoableEditHappened
|
||||
*
|
||||
* Method to be called to add new undoable edits to the <history>.
|
||||
*/
|
||||
undoableEditHappened = (undoableEdit) => {
|
||||
this.trim();
|
||||
|
||||
if (this.size > 0 &&
|
||||
this.size == this.history.length)
|
||||
{
|
||||
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();
|
||||
if (this.size > 0 &&
|
||||
this.size == this.history.length) {
|
||||
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();
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
export default mxUndoManager;
|
||||
|
|
|
@ -2,212 +2,206 @@
|
|||
* Copyright (c) 2006-2015, JGraph Ltd
|
||||
* 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;
|
||||
};
|
||||
|
||||
/**
|
||||
* Variable: source
|
||||
*
|
||||
* Specifies the source of the edit.
|
||||
*/
|
||||
source = null;
|
||||
import mxEvent from "./mxEvent";
|
||||
import mxEventObject from "./mxEventObject";
|
||||
|
||||
/**
|
||||
* Variable: changes
|
||||
*
|
||||
* 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
|
||||
* function. Default is an empty array.
|
||||
*/
|
||||
changes = null;
|
||||
class mxUndoableEdit {
|
||||
/**
|
||||
* Variable: source
|
||||
*
|
||||
* Specifies the source of the edit.
|
||||
*/
|
||||
source = null;
|
||||
|
||||
/**
|
||||
* Variable: significant
|
||||
*
|
||||
* Specifies if the undoable change is significant.
|
||||
* Default is true.
|
||||
*/
|
||||
significant = null;
|
||||
/**
|
||||
* Variable: changes
|
||||
*
|
||||
* 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
|
||||
* function. Default is an empty array.
|
||||
*/
|
||||
changes = null;
|
||||
|
||||
/**
|
||||
* Variable: undone
|
||||
*
|
||||
* Specifies if this edit has been undone. Default is false.
|
||||
*/
|
||||
undone = false;
|
||||
/**
|
||||
* Variable: significant
|
||||
*
|
||||
* Specifies if the undoable change is significant.
|
||||
* Default is true.
|
||||
*/
|
||||
significant = null;
|
||||
|
||||
/**
|
||||
* Variable: redone
|
||||
*
|
||||
* Specifies if this edit has been redone. Default is false.
|
||||
*/
|
||||
redone = false;
|
||||
/**
|
||||
* Variable: undone
|
||||
*
|
||||
* Specifies if this edit has been undone. Default is false.
|
||||
*/
|
||||
undone = false;
|
||||
|
||||
/**
|
||||
* Function: isEmpty
|
||||
*
|
||||
* Returns true if the this edit contains no changes.
|
||||
*/
|
||||
isEmpty = ()=>
|
||||
{
|
||||
return this.changes.length == 0;
|
||||
};
|
||||
/**
|
||||
* Variable: redone
|
||||
*
|
||||
* Specifies if this edit has been redone. Default is false.
|
||||
*/
|
||||
redone = false;
|
||||
|
||||
/**
|
||||
* Function: isSignificant
|
||||
*
|
||||
* Returns <significant>.
|
||||
*/
|
||||
isSignificant = ()=>
|
||||
{
|
||||
return this.significant;
|
||||
};
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
constructor(source, significant) {
|
||||
this.source = source;
|
||||
this.changes = [];
|
||||
this.significant = (significant != null) ? significant : true;
|
||||
};
|
||||
|
||||
/**
|
||||
* Function: add
|
||||
*
|
||||
* Adds the specified change to this edit. The change is an object that is
|
||||
* expected to either have an undo and redo, or an execute function.
|
||||
*/
|
||||
add = (change)=>
|
||||
{
|
||||
this.changes.push(change);
|
||||
};
|
||||
/**
|
||||
* Function: isEmpty
|
||||
*
|
||||
* Returns true if the this edit contains no changes.
|
||||
*/
|
||||
isEmpty = () => {
|
||||
return this.changes.length == 0;
|
||||
};
|
||||
|
||||
/**
|
||||
* Function: notify
|
||||
*
|
||||
* Hook to notify any listeners of the changes after an <undo> or <redo>
|
||||
* has been carried out. This implementation is empty.
|
||||
*/
|
||||
notify = ()=> { };
|
||||
/**
|
||||
* Function: isSignificant
|
||||
*
|
||||
* Returns <significant>.
|
||||
*/
|
||||
isSignificant = () => {
|
||||
return this.significant;
|
||||
};
|
||||
|
||||
/**
|
||||
* Function: die
|
||||
*
|
||||
* Hook to free resources after the edit has been removed from the command
|
||||
* history. This implementation is empty.
|
||||
*/
|
||||
die = ()=> { };
|
||||
/**
|
||||
* Function: add
|
||||
*
|
||||
* Adds the specified change to this edit. The change is an object that is
|
||||
* expected to either have an undo and redo, or an execute function.
|
||||
*/
|
||||
add = (change) => {
|
||||
this.changes.push(change);
|
||||
};
|
||||
|
||||
/**
|
||||
* 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();
|
||||
/**
|
||||
* Function: notify
|
||||
*
|
||||
* Hook to notify any listeners of the changes after an <undo> or <redo>
|
||||
* has been carried out. This implementation is empty.
|
||||
*/
|
||||
notify = () => {
|
||||
};
|
||||
|
||||
/**
|
||||
* Function: die
|
||||
*
|
||||
* Hook to free resources after the edit has been removed from the command
|
||||
* history. This implementation is empty.
|
||||
*/
|
||||
die = () => {
|
||||
};
|
||||
|
||||
/**
|
||||
* 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)
|
||||
{
|
||||
change.undo();
|
||||
}
|
||||
|
||||
// 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.undone = true;
|
||||
this.redone = false;
|
||||
this.source.fireEvent(new mxEventObject(mxEvent.END_EDIT));
|
||||
}
|
||||
|
||||
this.notify();
|
||||
};
|
||||
|
||||
/**
|
||||
* Function: redo
|
||||
*
|
||||
* Redoes all changes in this edit.
|
||||
*/
|
||||
redo = ()=>
|
||||
{
|
||||
if (!this.redone)
|
||||
{
|
||||
this.source.fireEvent(new mxEventObject(mxEvent.START_EDIT));
|
||||
var count = this.changes.length;
|
||||
|
||||
for (var i = 0; i < count; i++)
|
||||
{
|
||||
var change = this.changes[i];
|
||||
|
||||
if (change.execute != null)
|
||||
{
|
||||
change.execute();
|
||||
this.notify();
|
||||
};
|
||||
|
||||
/**
|
||||
* Function: redo
|
||||
*
|
||||
* Redoes all changes in this edit.
|
||||
*/
|
||||
redo = () => {
|
||||
if (!this.redone) {
|
||||
this.source.fireEvent(new mxEventObject(mxEvent.START_EDIT));
|
||||
var count = this.changes.length;
|
||||
|
||||
for (var i = 0; i < count; i++) {
|
||||
var change = this.changes[i];
|
||||
|
||||
if (change.execute != null) {
|
||||
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)
|
||||
{
|
||||
change.redo();
|
||||
}
|
||||
|
||||
// New global executed event
|
||||
this.source.fireEvent(new mxEventObject(mxEvent.EXECUTED, 'change', change));
|
||||
|
||||
this.undone = false;
|
||||
this.redone = true;
|
||||
this.source.fireEvent(new mxEventObject(mxEvent.END_EDIT));
|
||||
}
|
||||
|
||||
this.undone = false;
|
||||
this.redone = true;
|
||||
this.source.fireEvent(new mxEventObject(mxEvent.END_EDIT));
|
||||
}
|
||||
|
||||
this.notify();
|
||||
};
|
||||
|
||||
this.notify();
|
||||
};
|
||||
}
|
||||
|
||||
export default mxUndoableEdit;
|
||||
|
|
|
@ -2,152 +2,141 @@
|
|||
* Copyright (c) 2006-2015, JGraph Ltd
|
||||
* Copyright (c) 2006-2015, Gaudenz Alder
|
||||
*/
|
||||
/**
|
||||
*
|
||||
* Class: mxUrlConverter
|
||||
*
|
||||
* Converts relative and absolute URLs to absolute URLs with protocol and domain.
|
||||
*/
|
||||
var mxUrlConverter = ()=>
|
||||
{
|
||||
// Empty constructor
|
||||
};
|
||||
|
||||
/**
|
||||
* Variable: enabled
|
||||
*
|
||||
* Specifies if the converter is enabled. Default is true.
|
||||
*/
|
||||
enabled = true;
|
||||
class mxUrlConverter {
|
||||
/**
|
||||
*
|
||||
* Class: mxUrlConverter
|
||||
*
|
||||
* Converts relative and absolute URLs to absolute URLs with protocol and domain.
|
||||
*/
|
||||
constructor() {
|
||||
// Empty constructor
|
||||
};
|
||||
|
||||
/**
|
||||
* Variable: baseUrl
|
||||
*
|
||||
* Specifies the base URL to be used as a prefix for relative URLs.
|
||||
*/
|
||||
baseUrl = null;
|
||||
/**
|
||||
* Variable: enabled
|
||||
*
|
||||
* Specifies if the converter is enabled. Default is true.
|
||||
*/
|
||||
enabled = true;
|
||||
|
||||
/**
|
||||
* Variable: baseDomain
|
||||
*
|
||||
* Specifies the base domain to be used as a prefix for absolute URLs.
|
||||
*/
|
||||
baseDomain = null;
|
||||
/**
|
||||
* Variable: baseUrl
|
||||
*
|
||||
* Specifies the base URL to be used as a prefix for relative URLs.
|
||||
*/
|
||||
baseUrl = null;
|
||||
|
||||
/**
|
||||
* Function: updateBaseUrl
|
||||
*
|
||||
* Private helper function to update the base URL.
|
||||
*/
|
||||
updateBaseUrl = ()=>
|
||||
{
|
||||
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);
|
||||
}
|
||||
};
|
||||
/**
|
||||
* Variable: baseDomain
|
||||
*
|
||||
* Specifies the base domain to be used as a prefix for absolute URLs.
|
||||
*/
|
||||
baseDomain = null;
|
||||
|
||||
/**
|
||||
* Function: isEnabled
|
||||
*
|
||||
* Returns <enabled>.
|
||||
*/
|
||||
isEnabled = ()=>
|
||||
{
|
||||
return this.enabled;
|
||||
};
|
||||
/**
|
||||
* Function: updateBaseUrl
|
||||
*
|
||||
* Private helper function to update the base URL.
|
||||
*/
|
||||
updateBaseUrl = () => {
|
||||
this.baseDomain = location.protocol + '//' + location.host;
|
||||
this.baseUrl = this.baseDomain + location.pathname;
|
||||
var tmp = this.baseUrl.lastIndexOf('/');
|
||||
|
||||
/**
|
||||
* 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();
|
||||
// Strips filename etc
|
||||
if (tmp > 0) {
|
||||
this.baseUrl = this.baseUrl.substring(0, tmp + 1);
|
||||
}
|
||||
|
||||
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
|
||||
{
|
||||
url = this.getBaseUrl() + url;
|
||||
}
|
||||
}
|
||||
|
||||
return url;
|
||||
};
|
||||
|
||||
return url;
|
||||
};
|
||||
}
|
||||
|
||||
export default mxUrlConverter;
|
||||
|
|
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, 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';
|
||||
};
|
||||
|
||||
/**
|
||||
* Extends mxEventSource.
|
||||
*/
|
||||
mxCellOverlay.prototype = new mxEventSource();
|
||||
constructor = mxCellOverlay;
|
||||
import mxPoint from "FIXME";
|
||||
import mxRectangle from "../util/mxRectangle";
|
||||
|
||||
/**
|
||||
* Variable: image
|
||||
*
|
||||
* Holds the <mxImage> to be used as the icon.
|
||||
*/
|
||||
image = null;
|
||||
class mxCellOverlay extends mxEventSource {
|
||||
/**
|
||||
* Variable: image
|
||||
*
|
||||
* Holds the <mxImage> to be used as the icon.
|
||||
*/
|
||||
image = null;
|
||||
|
||||
/**
|
||||
* Variable: tooltip
|
||||
*
|
||||
* Holds the optional string to be used as the tooltip.
|
||||
*/
|
||||
tooltip = null;
|
||||
/**
|
||||
* Variable: tooltip
|
||||
*
|
||||
* Holds the optional string to be used as the tooltip.
|
||||
*/
|
||||
tooltip = null;
|
||||
|
||||
/**
|
||||
* Variable: align
|
||||
*
|
||||
* Holds the horizontal alignment for the overlay. Default is
|
||||
* <mxConstants.ALIGN_RIGHT>. For edges, the overlay always appears in the
|
||||
* center of the edge.
|
||||
*/
|
||||
align = mxConstants.ALIGN_RIGHT;
|
||||
/**
|
||||
* Variable: align
|
||||
*
|
||||
* Holds the horizontal alignment for the overlay. Default is
|
||||
* <mxConstants.ALIGN_RIGHT>. For edges, the overlay always appears in the
|
||||
* center of the edge.
|
||||
*/
|
||||
align = mxConstants.ALIGN_RIGHT;
|
||||
|
||||
/**
|
||||
* Variable: verticalAlign
|
||||
*
|
||||
* Holds the vertical alignment for the overlay. Default is
|
||||
* <mxConstants.ALIGN_BOTTOM>. For edges, the overlay always appears in the
|
||||
* center of the edge.
|
||||
*/
|
||||
verticalAlign = mxConstants.ALIGN_BOTTOM;
|
||||
/**
|
||||
* Variable: verticalAlign
|
||||
*
|
||||
* Holds the vertical alignment for the overlay. Default is
|
||||
* <mxConstants.ALIGN_BOTTOM>. For edges, the overlay always appears in the
|
||||
* center of the edge.
|
||||
*/
|
||||
verticalAlign = mxConstants.ALIGN_BOTTOM;
|
||||
|
||||
/**
|
||||
* Variable: offset
|
||||
*
|
||||
* Holds the offset as an <mxPoint>. The offset will be scaled according to the
|
||||
* current scale.
|
||||
*/
|
||||
offset = null;
|
||||
/**
|
||||
* Variable: offset
|
||||
*
|
||||
* Holds the offset as an <mxPoint>. The offset will be scaled according to the
|
||||
* current scale.
|
||||
*/
|
||||
offset = null;
|
||||
|
||||
/**
|
||||
* Variable: cursor
|
||||
*
|
||||
* Holds the cursor for the overlay. Default is 'help'.
|
||||
*/
|
||||
cursor = null;
|
||||
/**
|
||||
* Variable: cursor
|
||||
*
|
||||
* Holds the cursor for the overlay. Default is 'help'.
|
||||
*/
|
||||
cursor = null;
|
||||
|
||||
/**
|
||||
* Variable: defaultOverlap
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
defaultOverlap = 0.5;
|
||||
/**
|
||||
* Variable: defaultOverlap
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
defaultOverlap = 0.5;
|
||||
|
||||
/**
|
||||
* Function: getBounds
|
||||
*
|
||||
* Returns the bounds of the overlay for the given <mxCellState> as an
|
||||
* <mxRectangle>. This should be overridden when using multiple overlays
|
||||
* per cell so that the overlays do not overlap.
|
||||
*
|
||||
* 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
|
||||
* 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;
|
||||
/**
|
||||
* 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).
|
||||
*/
|
||||
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;
|
||||
|
||||
if (isEdge)
|
||||
{
|
||||
var pts = state.absolutePoints;
|
||||
|
||||
if (pts.length % 2 == 1)
|
||||
{
|
||||
pt = pts[Math.floor(pts.length / 2)];
|
||||
/**
|
||||
* Function: getBounds
|
||||
*
|
||||
* Returns the bounds of the overlay for the given <mxCellState> as an
|
||||
* <mxRectangle>. This should be overridden when using multiple overlays
|
||||
* per cell so that the overlays do not overlap.
|
||||
*
|
||||
* 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
|
||||
* 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),
|
||||
Math.round(pt.y - (h * this.defaultOverlap - this.offset.y) * s), w * s, h * 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);
|
||||
};
|
||||
|
||||
/**
|
||||
* Function: toString
|
||||
*
|
||||
* Returns the textual representation of the overlay to be used as the
|
||||
* tooltip. This implementation returns <tooltip>.
|
||||
*/
|
||||
toString = ()=>
|
||||
{
|
||||
return this.tooltip;
|
||||
};
|
||||
/**
|
||||
* Function: toString
|
||||
*
|
||||
* Returns the textual representation of the overlay to be used as the
|
||||
* tooltip. This implementation returns <tooltip>.
|
||||
*/
|
||||
toString = () => {
|
||||
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, 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();
|
||||
};
|
||||
|
||||
/**
|
||||
* Extends mxRectangle.
|
||||
*/
|
||||
mxCellState.prototype = new mxRectangle();
|
||||
constructor = mxCellState;
|
||||
import mxPoint from "../util/mxPoint";
|
||||
import mxRectangle from "../util/mxRectangle";
|
||||
|
||||
/**
|
||||
* Variable: view
|
||||
*
|
||||
* Reference to the enclosing <mxGraphView>.
|
||||
*/
|
||||
view = null;
|
||||
class mxCellState extends mxRectangle {
|
||||
/**
|
||||
* Variable: view
|
||||
*
|
||||
* Reference to the enclosing <mxGraphView>.
|
||||
*/
|
||||
view = null;
|
||||
|
||||
/**
|
||||
* Variable: cell
|
||||
*
|
||||
* Reference to the <mxCell> that is represented by this state.
|
||||
*/
|
||||
cell = null;
|
||||
/**
|
||||
* Variable: cell
|
||||
*
|
||||
* Reference to the <mxCell> that is represented by this state.
|
||||
*/
|
||||
cell = null;
|
||||
|
||||
/**
|
||||
* Variable: style
|
||||
*
|
||||
* Contains an array of key, value pairs that represent the style of the
|
||||
* cell.
|
||||
*/
|
||||
style = null;
|
||||
/**
|
||||
* Variable: style
|
||||
*
|
||||
* Contains an array of key, value pairs that represent the style of the
|
||||
* cell.
|
||||
*/
|
||||
style = null;
|
||||
|
||||
/**
|
||||
* Variable: invalidStyle
|
||||
*
|
||||
* Specifies if the style is invalid. Default is false.
|
||||
*/
|
||||
invalidStyle = false;
|
||||
/**
|
||||
* Variable: invalidStyle
|
||||
*
|
||||
* Specifies if the style is invalid. Default is false.
|
||||
*/
|
||||
invalidStyle = false;
|
||||
|
||||
/**
|
||||
* Variable: invalid
|
||||
*
|
||||
* Specifies if the state is invalid. Default is true.
|
||||
*/
|
||||
invalid = true;
|
||||
/**
|
||||
* Variable: invalid
|
||||
*
|
||||
* Specifies if the state is invalid. Default is true.
|
||||
*/
|
||||
invalid = true;
|
||||
|
||||
/**
|
||||
* Variable: origin
|
||||
*
|
||||
* <mxPoint> that holds the origin for all child cells. Default is a new
|
||||
* empty <mxPoint>.
|
||||
*/
|
||||
origin = null;
|
||||
/**
|
||||
* Variable: origin
|
||||
*
|
||||
* <mxPoint> that holds the origin for all child cells. Default is a new
|
||||
* empty <mxPoint>.
|
||||
*/
|
||||
origin = null;
|
||||
|
||||
/**
|
||||
* Variable: absolutePoints
|
||||
*
|
||||
* Holds an array of <mxPoints> that represent the absolute points of an
|
||||
* edge.
|
||||
*/
|
||||
absolutePoints = null;
|
||||
/**
|
||||
* Variable: absolutePoints
|
||||
*
|
||||
* Holds an array of <mxPoints> that represent the absolute points of an
|
||||
* edge.
|
||||
*/
|
||||
absolutePoints = null;
|
||||
|
||||
/**
|
||||
* Variable: absoluteOffset
|
||||
*
|
||||
* <mxPoint> that holds the absolute offset. For edges, 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.
|
||||
*/
|
||||
absoluteOffset = null;
|
||||
/**
|
||||
* Variable: absoluteOffset
|
||||
*
|
||||
* <mxPoint> that holds the absolute offset. For edges, 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.
|
||||
*/
|
||||
absoluteOffset = null;
|
||||
|
||||
/**
|
||||
* Variable: visibleSourceState
|
||||
*
|
||||
* Caches the visible source terminal state.
|
||||
*/
|
||||
visibleSourceState = null;
|
||||
/**
|
||||
* Variable: visibleSourceState
|
||||
*
|
||||
* Caches the visible source terminal state.
|
||||
*/
|
||||
visibleSourceState = null;
|
||||
|
||||
/**
|
||||
* Variable: visibleTargetState
|
||||
*
|
||||
* Caches the visible target terminal state.
|
||||
*/
|
||||
visibleTargetState = null;
|
||||
/**
|
||||
* Variable: visibleTargetState
|
||||
*
|
||||
* Caches the visible target terminal state.
|
||||
*/
|
||||
visibleTargetState = null;
|
||||
|
||||
/**
|
||||
* Variable: terminalDistance
|
||||
*
|
||||
* Caches the distance between the end points for an edge.
|
||||
*/
|
||||
terminalDistance = 0;
|
||||
/**
|
||||
* Variable: terminalDistance
|
||||
*
|
||||
* Caches the distance between the end points for an edge.
|
||||
*/
|
||||
terminalDistance = 0;
|
||||
|
||||
/**
|
||||
* Variable: length
|
||||
*
|
||||
* Caches the length of an edge.
|
||||
*/
|
||||
length = 0;
|
||||
/**
|
||||
* Variable: length
|
||||
*
|
||||
* Caches the length of an edge.
|
||||
*/
|
||||
length = 0;
|
||||
|
||||
/**
|
||||
* Variable: segments
|
||||
*
|
||||
* Array of numbers that represent the cached length of each segment of the
|
||||
* edge.
|
||||
*/
|
||||
segments = null;
|
||||
/**
|
||||
* Variable: segments
|
||||
*
|
||||
* Array of numbers that represent the cached length of each segment of the
|
||||
* edge.
|
||||
*/
|
||||
segments = null;
|
||||
|
||||
/**
|
||||
* Variable: shape
|
||||
*
|
||||
* Holds the <mxShape> that represents the cell graphically.
|
||||
*/
|
||||
shape = null;
|
||||
/**
|
||||
* Variable: shape
|
||||
*
|
||||
* Holds the <mxShape> that represents the cell graphically.
|
||||
*/
|
||||
shape = null;
|
||||
|
||||
/**
|
||||
* Variable: text
|
||||
*
|
||||
* Holds the <mxText> that represents the label of the cell. Thi smay be
|
||||
* null if the cell has no label.
|
||||
*/
|
||||
text = null;
|
||||
/**
|
||||
* Variable: text
|
||||
*
|
||||
* Holds the <mxText> that represents the label of the cell. Thi smay be
|
||||
* null if the cell has no label.
|
||||
*/
|
||||
text = null;
|
||||
|
||||
/**
|
||||
* Variable: unscaledWidth
|
||||
*
|
||||
* Holds the unscaled width of the state.
|
||||
*/
|
||||
unscaledWidth = null;
|
||||
/**
|
||||
* Variable: unscaledWidth
|
||||
*
|
||||
* Holds the unscaled width of the state.
|
||||
*/
|
||||
unscaledWidth = null;
|
||||
|
||||
/**
|
||||
* Variable: unscaledHeight
|
||||
*
|
||||
* Holds the unscaled height of the state.
|
||||
*/
|
||||
unscaledHeight = null;
|
||||
/**
|
||||
* Variable: unscaledHeight
|
||||
*
|
||||
* Holds the unscaled height of the state.
|
||||
*/
|
||||
unscaledHeight = null;
|
||||
|
||||
/**
|
||||
* Function: getPerimeterBounds
|
||||
*
|
||||
* Returns the <mxRectangle> that should be used as the perimeter of the
|
||||
* cell.
|
||||
*
|
||||
* Parameters:
|
||||
*
|
||||
* border - Optional border to be added around the perimeter bounds.
|
||||
* bounds - Optional <mxRectangle> to be used as the initial bounds.
|
||||
*/
|
||||
getPerimeterBounds = (border, bounds)=>
|
||||
{
|
||||
border = border || 0;
|
||||
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 (border != 0)
|
||||
{
|
||||
bounds.grow(border);
|
||||
}
|
||||
|
||||
return bounds;
|
||||
};
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
constructor(view, cell, style) {
|
||||
// no super
|
||||
this.view = view;
|
||||
this.cell = cell;
|
||||
this.style = (style != null) ? style : {};
|
||||
|
||||
/**
|
||||
* 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 = [];
|
||||
this.origin = new mxPoint();
|
||||
this.absoluteOffset = new mxPoint();
|
||||
};
|
||||
|
||||
/**
|
||||
* Function: getPerimeterBounds
|
||||
*
|
||||
* Returns the <mxRectangle> that should be used as the perimeter of the
|
||||
* cell.
|
||||
*
|
||||
* Parameters:
|
||||
*
|
||||
* border - Optional border to be added around the perimeter bounds.
|
||||
* bounds - Optional <mxRectangle> to be used as the initial bounds.
|
||||
*/
|
||||
getPerimeterBounds = (border, bounds) => {
|
||||
border = border || 0;
|
||||
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)
|
||||
{
|
||||
this.absolutePoints.push(point);
|
||||
|
||||
if (border !== 0) {
|
||||
bounds.grow(border);
|
||||
}
|
||||
else
|
||||
{
|
||||
this.absolutePoints[0] = point;
|
||||
|
||||
return bounds;
|
||||
};
|
||||
|
||||
/**
|
||||
* 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)
|
||||
{
|
||||
this.absolutePoints = [];
|
||||
this.absolutePoints.push(null);
|
||||
this.absolutePoints.push(point);
|
||||
};
|
||||
|
||||
/**
|
||||
* Function: setCursor
|
||||
*
|
||||
* Sets the given cursor on the shape and text shape.
|
||||
*/
|
||||
setCursor = (cursor) => {
|
||||
if (this.shape != null) {
|
||||
this.shape.setCursor(cursor);
|
||||
}
|
||||
else if (this.absolutePoints.length == 1)
|
||||
{
|
||||
this.absolutePoints.push(point);
|
||||
|
||||
if (this.text != null) {
|
||||
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
|
||||
*
|
||||
* Sets the given cursor on the shape and text shape.
|
||||
*/
|
||||
setCursor = (cursor)=>
|
||||
{
|
||||
if (this.shape != null)
|
||||
{
|
||||
this.shape.setCursor(cursor);
|
||||
}
|
||||
|
||||
if (this.text != null)
|
||||
{
|
||||
this.text.setCursor(cursor);
|
||||
}
|
||||
};
|
||||
/**
|
||||
* Function: getCellBounds
|
||||
*
|
||||
* Returns the unscaled, untranslated bounds.
|
||||
*/
|
||||
getCellBounds = () => {
|
||||
return this.cellBounds;
|
||||
};
|
||||
|
||||
/**
|
||||
* 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: 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: 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: 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);
|
||||
|
||||
/**
|
||||
* 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: 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.shape != null && this.shape.isPaintBoundsInverted()) {
|
||||
this.paintBounds.rotate90();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
if (this.origin != null)
|
||||
{
|
||||
clone.origin = this.origin.clone();
|
||||
}
|
||||
/**
|
||||
* 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;
|
||||
};
|
||||
|
||||
if (this.absoluteOffset != null)
|
||||
{
|
||||
clone.absoluteOffset = this.absoluteOffset.clone();
|
||||
}
|
||||
/**
|
||||
* Function: clone
|
||||
*
|
||||
* Returns a clone of this <mxPoint>.
|
||||
*/
|
||||
clone = () => {
|
||||
var clone = new mxCellState(this.view, this.cell, this.style);
|
||||
|
||||
if (this.boundingBox != null)
|
||||
{
|
||||
clone.boundingBox = this.boundingBox.clone();
|
||||
}
|
||||
// Clones the absolute points
|
||||
if (this.absolutePoints != null) {
|
||||
clone.absolutePoints = [];
|
||||
|
||||
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;
|
||||
};
|
||||
for (var i = 0; i < this.absolutePoints.length; i++) {
|
||||
clone.absolutePoints[i] = this.absolutePoints[i].clone();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Destructor: destroy
|
||||
*
|
||||
* Destroys the state and all associated resources.
|
||||
*/
|
||||
destroy = ()=>
|
||||
{
|
||||
this.view.graph.cellRenderer.destroy(this);
|
||||
};
|
||||
if (this.origin != null) {
|
||||
clone.origin = this.origin.clone();
|
||||
}
|
||||
|
||||
if (this.absoluteOffset != null) {
|
||||
clone.absoluteOffset = this.absoluteOffset.clone();
|
||||
}
|
||||
|
||||
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, 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;
|
||||
};
|
||||
|
||||
/**
|
||||
* Variable: graph
|
||||
*
|
||||
* Reference to the enclosing <mxGraph>.
|
||||
*/
|
||||
graph = null;
|
||||
import mxUtils from "../util/mxUtils";
|
||||
import mxPoint from "../util/mxPoint";
|
||||
import mxDictionary from "../util/mxDictionary";
|
||||
|
||||
/**
|
||||
* Variable: deltas
|
||||
*
|
||||
* Reference to the enclosing <mxGraph>.
|
||||
*/
|
||||
deltas = null;
|
||||
class mxCellStatePreview {
|
||||
/**
|
||||
* Variable: graph
|
||||
*
|
||||
* Reference to the enclosing <mxGraph>.
|
||||
*/
|
||||
graph = null;
|
||||
|
||||
/**
|
||||
* Variable: count
|
||||
*
|
||||
* Contains the number of entries in the map.
|
||||
*/
|
||||
count = 0;
|
||||
/**
|
||||
* Variable: deltas
|
||||
*
|
||||
* Reference to the enclosing <mxGraph>.
|
||||
*/
|
||||
deltas = null;
|
||||
|
||||
/**
|
||||
* Function: isEmpty
|
||||
*
|
||||
* Returns true if this contains no entries.
|
||||
*/
|
||||
isEmpty = ()=>
|
||||
{
|
||||
return this.count == 0;
|
||||
};
|
||||
/**
|
||||
* Variable: count
|
||||
*
|
||||
* Contains the number of entries in the map.
|
||||
*/
|
||||
count = 0;
|
||||
|
||||
/**
|
||||
* Function: moveState
|
||||
*/
|
||||
moveState = (state, dx, dy, add, includeEdges)=>
|
||||
{
|
||||
add = (add != null) ? add : true;
|
||||
includeEdges = (includeEdges != null) ? includeEdges : true;
|
||||
|
||||
var delta = this.deltas.get(state.cell);
|
||||
/**
|
||||
*
|
||||
* 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>.
|
||||
*/
|
||||
constructor(graph) {
|
||||
this.deltas = new mxDictionary();
|
||||
this.graph = graph;
|
||||
};
|
||||
|
||||
if (delta == null)
|
||||
{
|
||||
// Note: Deltas stores the point and the state since the key is a string.
|
||||
delta = {point: new mxPoint(dx, dy), state: state};
|
||||
this.deltas.put(state.cell, delta);
|
||||
this.count++;
|
||||
}
|
||||
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: isEmpty
|
||||
*
|
||||
* Returns true if this contains no entries.
|
||||
*/
|
||||
isEmpty = () => {
|
||||
return this.count === 0;
|
||||
};
|
||||
|
||||
/**
|
||||
* 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: moveState
|
||||
*/
|
||||
moveState = (state, dx, dy, add, includeEdges) => {
|
||||
add = (add != null) ? add : true;
|
||||
includeEdges = (includeEdges != null) ? includeEdges : true;
|
||||
|
||||
/**
|
||||
* 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))
|
||||
{
|
||||
var delta = this.deltas.get(state.cell);
|
||||
|
||||
if (delta == null) {
|
||||
// Note: Deltas stores the point and the state since the key is a string.
|
||||
delta = {point: new mxPoint(dx, dy), state: state};
|
||||
this.deltas.put(state.cell, delta);
|
||||
this.count++;
|
||||
} 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
|
||||
*/
|
||||
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.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);
|
||||
|
||||
this.graph.cellRenderer.redraw(state);
|
||||
|
||||
// Invokes the visitor on the given state
|
||||
if (visitor != null) {
|
||||
visitor(state);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* 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);
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* 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, 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;
|
||||
};
|
||||
|
||||
/**
|
||||
* Variable: point
|
||||
*
|
||||
* <mxPoint> that specifies the fixed location of the connection point.
|
||||
*/
|
||||
point = null;
|
||||
class mxConnectionConstraint {
|
||||
/**
|
||||
* Variable: point
|
||||
*
|
||||
* <mxPoint> that specifies the fixed location of the connection point.
|
||||
*/
|
||||
point = null;
|
||||
|
||||
/**
|
||||
* Variable: perimeter
|
||||
*
|
||||
* Boolean that specifies if the point should be projected onto the perimeter
|
||||
* of the terminal.
|
||||
*/
|
||||
perimeter = null;
|
||||
/**
|
||||
* Variable: perimeter
|
||||
*
|
||||
* Boolean that specifies if the point should be projected onto the perimeter
|
||||
* of the terminal.
|
||||
*/
|
||||
perimeter = null;
|
||||
|
||||
/**
|
||||
* Variable: name
|
||||
*
|
||||
* Optional string that specifies the name of the constraint.
|
||||
*/
|
||||
name = null;
|
||||
/**
|
||||
* Variable: name
|
||||
*
|
||||
* Optional string that specifies the name of the constraint.
|
||||
*/
|
||||
name = null;
|
||||
|
||||
/**
|
||||
* Variable: dx
|
||||
*
|
||||
* Optional float that specifies the horizontal offset of the constraint.
|
||||
*/
|
||||
dx = null;
|
||||
/**
|
||||
* Variable: dx
|
||||
*
|
||||
* Optional float that specifies the horizontal offset of the constraint.
|
||||
*/
|
||||
dx = null;
|
||||
|
||||
/**
|
||||
* Variable: dy
|
||||
*
|
||||
* Optional float that specifies the vertical offset of the constraint.
|
||||
*/
|
||||
dy = null;
|
||||
/**
|
||||
* Variable: dy
|
||||
*
|
||||
* Optional float that specifies the vertical offset of the constraint.
|
||||
*/
|
||||
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, 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 = [];
|
||||
};
|
||||
|
||||
/**
|
||||
* Extends mxEventSource.
|
||||
*/
|
||||
mxGraphSelectionModel.prototype = new mxEventSource();
|
||||
constructor = mxGraphSelectionModel;
|
||||
import mxUndoableEdit from "../util/mxUndoableEdit";
|
||||
import mxEventSource from "../util/mxEventSource";
|
||||
import mxEventObject from "../util/mxEventObject";
|
||||
|
||||
/**
|
||||
* 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
|
||||
* the status message. Default is 'done'.
|
||||
*/
|
||||
doneResource = (mxClient.language != 'none') ? 'done' : '';
|
||||
class mxGraphSelectionModel extends mxEventSource {
|
||||
/**
|
||||
* 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
|
||||
* the status message. Default is 'done'.
|
||||
*/
|
||||
doneResource = (mxClient.language != 'none') ? 'done' : '';
|
||||
|
||||
/**
|
||||
* Variable: updatingSelectionResource
|
||||
*
|
||||
* 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
|
||||
* value is used as the status message. Default is 'updatingSelection'.
|
||||
*/
|
||||
updatingSelectionResource = (mxClient.language != 'none') ? 'updatingSelection' : '';
|
||||
/**
|
||||
* Variable: updatingSelectionResource
|
||||
*
|
||||
* 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
|
||||
* value is used as the status message. Default is 'updatingSelection'.
|
||||
*/
|
||||
updatingSelectionResource = (mxClient.language != 'none') ? 'updatingSelection' : '';
|
||||
|
||||
/**
|
||||
* Variable: graph
|
||||
*
|
||||
* Reference to the enclosing <mxGraph>.
|
||||
*/
|
||||
graph = null;
|
||||
/**
|
||||
* Variable: graph
|
||||
*
|
||||
* Reference to the enclosing <mxGraph>.
|
||||
*/
|
||||
graph = null;
|
||||
|
||||
/**
|
||||
* Variable: singleSelection
|
||||
*
|
||||
* Specifies if only one selected item at a time is allowed.
|
||||
* Default is false.
|
||||
*/
|
||||
singleSelection = false;
|
||||
/**
|
||||
* Variable: singleSelection
|
||||
*
|
||||
* Specifies if only one selected item at a time is allowed.
|
||||
* Default is false.
|
||||
*/
|
||||
singleSelection = false;
|
||||
|
||||
/**
|
||||
* Function: isSingleSelection
|
||||
*
|
||||
* Returns <singleSelection> as a boolean.
|
||||
*/
|
||||
isSingleSelection = ()=>
|
||||
{
|
||||
return this.singleSelection;
|
||||
};
|
||||
/**
|
||||
* 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>.
|
||||
*/
|
||||
constructor(graph) {
|
||||
this.graph = graph;
|
||||
this.cells = [];
|
||||
};
|
||||
|
||||
/**
|
||||
* Function: setSingleSelection
|
||||
*
|
||||
* Sets the <singleSelection> flag.
|
||||
*
|
||||
* Parameters:
|
||||
*
|
||||
* singleSelection - Boolean that specifies the new value for
|
||||
* <singleSelection>.
|
||||
*/
|
||||
setSingleSelection = (singleSelection)=>
|
||||
{
|
||||
this.singleSelection = singleSelection;
|
||||
};
|
||||
/**
|
||||
* Function: isSingleSelection
|
||||
*
|
||||
* Returns <singleSelection> as a boolean.
|
||||
*/
|
||||
isSingleSelection = () => {
|
||||
return this.singleSelection;
|
||||
};
|
||||
|
||||
/**
|
||||
* Function: isSelected
|
||||
*
|
||||
* Returns true if the given <mxCell> is selected.
|
||||
*/
|
||||
isSelected = (cell)=>
|
||||
{
|
||||
if (cell != null)
|
||||
{
|
||||
return mxUtils.indexOf(this.cells, cell) >= 0;
|
||||
}
|
||||
|
||||
return false;
|
||||
};
|
||||
/**
|
||||
* Function: setSingleSelection
|
||||
*
|
||||
* Sets the <singleSelection> flag.
|
||||
*
|
||||
* Parameters:
|
||||
*
|
||||
* singleSelection - Boolean that specifies the new value for
|
||||
* <singleSelection>.
|
||||
*/
|
||||
setSingleSelection = (singleSelection) => {
|
||||
this.singleSelection = singleSelection;
|
||||
};
|
||||
|
||||
/**
|
||||
* Function: isEmpty
|
||||
*
|
||||
* Returns true if no cells are currently selected.
|
||||
*/
|
||||
isEmpty = ()=>
|
||||
{
|
||||
return this.cells.length == 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]);
|
||||
}
|
||||
/**
|
||||
* Function: isSelected
|
||||
*
|
||||
* Returns true if the given <mxCell> is selected.
|
||||
*/
|
||||
isSelected = (cell) => {
|
||||
if (cell != null) {
|
||||
return mxUtils.indexOf(this.cells, cell) >= 0;
|
||||
}
|
||||
|
||||
this.changeSelection(tmp, this.cells);
|
||||
}
|
||||
};
|
||||
return false;
|
||||
};
|
||||
|
||||
/**
|
||||
* 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];
|
||||
/**
|
||||
* Function: isEmpty
|
||||
*
|
||||
* Returns true if no cells are currently selected.
|
||||
*/
|
||||
isEmpty = () => {
|
||||
return this.cells.length === 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);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* 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;
|
||||
};
|
||||
|
||||
/**
|
||||
* 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]);
|
||||
}
|
||||
};
|
||||
return null;
|
||||
};
|
||||
|
||||
/**
|
||||
* Function: addCells
|
||||
*
|
||||
* Adds the given array of <mxCells> to the selection and fires a <select>
|
||||
* event.
|
||||
*
|
||||
* Parameters:
|
||||
*
|
||||
* 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)];
|
||||
/**
|
||||
* 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]);
|
||||
}
|
||||
};
|
||||
|
||||
var tmp = [];
|
||||
|
||||
for (var i = 0; i < cells.length; i++)
|
||||
{
|
||||
if (!this.isSelected(cells[i]) &&
|
||||
this.graph.isCellSelectable(cells[i]))
|
||||
{
|
||||
tmp.push(cells[i]);
|
||||
}
|
||||
/**
|
||||
* Function: addCells
|
||||
*
|
||||
* Adds the given array of <mxCells> to the selection and fires a <select>
|
||||
* event.
|
||||
*
|
||||
* Parameters:
|
||||
*
|
||||
* 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
|
||||
*
|
||||
* 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: removeCells
|
||||
*/
|
||||
removeCells = (cells) => {
|
||||
if (cells != null) {
|
||||
var tmp = [];
|
||||
|
||||
/**
|
||||
* Function: removeCells
|
||||
*/
|
||||
removeCells = (cells)=>
|
||||
{
|
||||
if (cells != null)
|
||||
{
|
||||
var tmp = [];
|
||||
|
||||
for (var i = 0; i < cells.length; i++)
|
||||
{
|
||||
if (this.isSelected(cells[i]))
|
||||
{
|
||||
tmp.push(cells[i]);
|
||||
for (var i = 0; i < cells.length; i++) {
|
||||
if (this.isSelected(cells[i])) {
|
||||
tmp.push(cells[i]);
|
||||
}
|
||||
}
|
||||
|
||||
this.changeSelection(null, tmp);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Function: changeSelection
|
||||
*
|
||||
* 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
|
||||
*
|
||||
* 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));
|
||||
}
|
||||
};
|
||||
/**
|
||||
* Class: mxSelectionChange
|
||||
*
|
||||
* Action to change the current root in a view.
|
||||
*
|
||||
* Constructor: mxCurrentRootChange
|
||||
*
|
||||
* Constructs a change of the current root in the given view.
|
||||
*/
|
||||
mxSelectionChange = (selectionModel, added, removed) => {
|
||||
this.selectionModel = selectionModel;
|
||||
this.added = (added != null) ? added.slice() : null;
|
||||
this.removed = (removed != null) ? removed.slice() : null;
|
||||
};
|
||||
|
||||
/**
|
||||
* 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: 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;
|
||||
|
||||
/**
|
||||
* 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);
|
||||
if (this.removed != null) {
|
||||
for (var i = 0; i < this.removed.length; i++) {
|
||||
this.selectionModel.cellRemoved(this.removed[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Class: mxSelectionChange
|
||||
*
|
||||
* 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) {
|
||||
for (var i = 0; i < this.added.length; i++) {
|
||||
this.selectionModel.cellAdded(this.added[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (this.added != null)
|
||||
{
|
||||
for (var i = 0; i < this.added.length; i++)
|
||||
{
|
||||
this.selectionModel.cellAdded(this.added[i]);
|
||||
}
|
||||
}
|
||||
|
||||
var tmp = this.added;
|
||||
this.added = this.removed;
|
||||
this.removed = tmp;
|
||||
var tmp = this.added;
|
||||
this.added = this.removed;
|
||||
this.removed = tmp;
|
||||
|
||||
window.status = mxResources.get(this.selectionModel.doneResource) ||
|
||||
this.selectionModel.doneResource;
|
||||
mxLog.leave('mxSelectionChange.execute', t0);
|
||||
|
||||
this.selectionModel.fireEvent(new mxEventObject(mxEvent.CHANGE,
|
||||
'added', this.added, 'removed', this.removed));
|
||||
};
|
||||
window.status = mxResources.get(this.selectionModel.doneResource) ||
|
||||
this.selectionModel.doneResource;
|
||||
mxLog.leave('mxSelectionChange.execute', t0);
|
||||
|
||||
this.selectionModel.fireEvent(new mxEventObject(mxEvent.CHANGE,
|
||||
'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, 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);
|
||||
};
|
||||
|
||||
/**
|
||||
* Extends mxEventSource.
|
||||
*/
|
||||
mxLayoutManager.prototype = new mxEventSource();
|
||||
constructor = mxLayoutManager;
|
||||
import mxEventSource from "../util/mxEventSource";
|
||||
|
||||
/**
|
||||
* Variable: graph
|
||||
*
|
||||
* Reference to the enclosing <mxGraph>.
|
||||
*/
|
||||
graph = null;
|
||||
class mxLayoutManager extends mxEventSource {
|
||||
/**
|
||||
* Variable: graph
|
||||
*
|
||||
* Reference to the enclosing <mxGraph>.
|
||||
*/
|
||||
graph = null;
|
||||
|
||||
/**
|
||||
* Variable: bubbling
|
||||
*
|
||||
* Specifies if the layout should bubble along
|
||||
* the cell hierarchy. Default is true.
|
||||
*/
|
||||
bubbling = true;
|
||||
/**
|
||||
* Variable: bubbling
|
||||
*
|
||||
* Specifies if the layout should bubble along
|
||||
* the cell hierarchy. Default is true.
|
||||
*/
|
||||
bubbling = true;
|
||||
|
||||
/**
|
||||
* Variable: enabled
|
||||
*
|
||||
* Specifies if event handling is enabled. Default is true.
|
||||
*/
|
||||
enabled = true;
|
||||
/**
|
||||
* Variable: enabled
|
||||
*
|
||||
* Specifies if event handling is enabled. Default is true.
|
||||
*/
|
||||
enabled = true;
|
||||
|
||||
/**
|
||||
* Variable: undoHandler
|
||||
*
|
||||
* Holds the function that handles the endUpdate event.
|
||||
*/
|
||||
undoHandler = null;
|
||||
/**
|
||||
* Variable: undoHandler
|
||||
*
|
||||
* Holds the function that handles the endUpdate event.
|
||||
*/
|
||||
undoHandler = null;
|
||||
|
||||
/**
|
||||
* Variable: moveHandler
|
||||
*
|
||||
* Holds the function that handles the move event.
|
||||
*/
|
||||
moveHandler = null;
|
||||
/**
|
||||
* Variable: moveHandler
|
||||
*
|
||||
* Holds the function that handles the move event.
|
||||
*/
|
||||
moveHandler = null;
|
||||
|
||||
/**
|
||||
* Variable: resizeHandler
|
||||
*
|
||||
* Holds the function that handles the resize event.
|
||||
*/
|
||||
resizeHandler = null;
|
||||
/**
|
||||
* Variable: resizeHandler
|
||||
*
|
||||
* Holds the function that handles the resize event.
|
||||
*/
|
||||
resizeHandler = 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 = (enabled)=>
|
||||
{
|
||||
this.enabled = enabled;
|
||||
};
|
||||
|
||||
/**
|
||||
* 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);
|
||||
}
|
||||
|
||||
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);
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
constructor(graph) {
|
||||
// Executes the layout before the changes are dispatched
|
||||
this.undoHandler = (sender, evt) => {
|
||||
if (this.isEnabled()) {
|
||||
this.beforeUndo(evt.getProperty('edit'));
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
* 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]);
|
||||
// Notifies the layout of a move operation inside a parent
|
||||
this.moveHandler = (sender, evt) => {
|
||||
if (this.isEnabled()) {
|
||||
this.cellsMoved(evt.getProperty('cells'), evt.getProperty('event'));
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
* Function: getCellsForChanges
|
||||
*
|
||||
* Returns the cells for which a layout should be executed.
|
||||
*/
|
||||
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;
|
||||
};
|
||||
// Notifies the layout of a move operation inside a parent
|
||||
this.resizeHandler = (sender, evt) => {
|
||||
if (this.isEnabled()) {
|
||||
this.cellsResized(evt.getProperty('cells'), evt.getProperty('bounds'),
|
||||
evt.getProperty('previous'));
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* 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 [];
|
||||
};
|
||||
this.setGraph(graph);
|
||||
};
|
||||
|
||||
/**
|
||||
* 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: isEnabled
|
||||
*
|
||||
* Returns true if events are handled. This implementation
|
||||
* returns <enabled>.
|
||||
*/
|
||||
isEnabled = () => {
|
||||
return this.enabled;
|
||||
};
|
||||
|
||||
/**
|
||||
* 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);
|
||||
/**
|
||||
* Function: setEnabled
|
||||
*
|
||||
* Enables or disables event handling. This implementation
|
||||
* updates <enabled>.
|
||||
*
|
||||
* Parameters:
|
||||
*
|
||||
* enabled - Boolean that specifies the new enabled state.
|
||||
*/
|
||||
setEnabled = (enabled) => {
|
||||
this.enabled = enabled;
|
||||
};
|
||||
|
||||
/**
|
||||
* 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();
|
||||
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;
|
||||
};
|
||||
for (var i = 0; i < cells.length; i++) {
|
||||
var layout = this.getLayout(model.getParent(cells[i]), mxEvent.MOVE_CELLS);
|
||||
|
||||
/**
|
||||
* 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];
|
||||
if (layout != null) {
|
||||
layout.moveCell(cells[i], point.x, point.y);
|
||||
}
|
||||
}
|
||||
|
||||
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
|
||||
*
|
||||
* Executes the given layout on the given parent.
|
||||
*/
|
||||
executeLayout = (cell, bubble)=>
|
||||
{
|
||||
var layout = this.getLayout(cell, (bubble) ?
|
||||
mxEvent.BEGIN_UPDATE : mxEvent.END_UPDATE);
|
||||
/**
|
||||
* Function: getCellsForChanges
|
||||
*
|
||||
* Returns the cells for which a layout should be executed.
|
||||
*/
|
||||
getCellsForChanges = (changes) => {
|
||||
var result = [];
|
||||
|
||||
if (layout != null)
|
||||
{
|
||||
layout.execute(cell);
|
||||
}
|
||||
};
|
||||
for (var i = 0; i < changes.length; i++) {
|
||||
var change = changes[i];
|
||||
|
||||
/**
|
||||
* Function: destroy
|
||||
*
|
||||
* Removes all handlers from the <graph> and deletes the reference to it.
|
||||
*/
|
||||
destroy = ()=>
|
||||
{
|
||||
this.setGraph(null);
|
||||
};
|
||||
if (change instanceof mxRootChange) {
|
||||
return [];
|
||||
} else {
|
||||
result = result.concat(this.getCellsForChange(change));
|
||||
}
|
||||
}
|
||||
|
||||
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, 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;
|
||||
};
|
||||
|
||||
/**
|
||||
* 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
|
||||
* value as the first argument.
|
||||
*/
|
||||
type = null;
|
||||
class mxMultiplicity {
|
||||
/**
|
||||
* 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
|
||||
* value as the first argument.
|
||||
*/
|
||||
type = null;
|
||||
|
||||
/**
|
||||
* Variable: attr
|
||||
*
|
||||
* Optional string that specifies the attributename to be passed to
|
||||
* <mxUtils.isNode> to check if the rule applies to a cell.
|
||||
*/
|
||||
attr = null;
|
||||
/**
|
||||
* Variable: attr
|
||||
*
|
||||
* Optional string that specifies the attributename to be passed to
|
||||
* <mxUtils.isNode> to check if the rule applies to a cell.
|
||||
*/
|
||||
attr = null;
|
||||
|
||||
/**
|
||||
* Variable: value
|
||||
*
|
||||
* Optional string that specifies the value of the attribute to be passed
|
||||
* to <mxUtils.isNode> to check if the rule applies to a cell.
|
||||
*/
|
||||
value = null;
|
||||
/**
|
||||
* Variable: value
|
||||
*
|
||||
* Optional string that specifies the value of the attribute to be passed
|
||||
* to <mxUtils.isNode> to check if the rule applies to a cell.
|
||||
*/
|
||||
value = null;
|
||||
|
||||
/**
|
||||
* Variable: source
|
||||
*
|
||||
* Boolean that specifies if the rule is applied to the source or target
|
||||
* terminal of an edge.
|
||||
*/
|
||||
source = null;
|
||||
/**
|
||||
* Variable: source
|
||||
*
|
||||
* Boolean that specifies if the rule is applied to the source or target
|
||||
* terminal of an edge.
|
||||
*/
|
||||
source = null;
|
||||
|
||||
/**
|
||||
* Variable: min
|
||||
*
|
||||
* Defines the minimum number of connections for which this rule applies.
|
||||
* Default is 0.
|
||||
*/
|
||||
min = null;
|
||||
/**
|
||||
* Variable: min
|
||||
*
|
||||
* Defines the minimum number of connections for which this rule applies.
|
||||
* Default is 0.
|
||||
*/
|
||||
min = null;
|
||||
|
||||
/**
|
||||
* Variable: max
|
||||
*
|
||||
* Defines the maximum number of connections for which this rule applies.
|
||||
* A value of 'n' means unlimited times. Default is 'n'.
|
||||
*/
|
||||
max = null;
|
||||
/**
|
||||
* Variable: max
|
||||
*
|
||||
* Defines the maximum number of connections for which this rule applies.
|
||||
* A value of 'n' means unlimited times. Default is 'n'.
|
||||
*/
|
||||
max = null;
|
||||
|
||||
/**
|
||||
* Variable: validNeighbors
|
||||
*
|
||||
* 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
|
||||
* terminal to check if the rule applies to the connection.
|
||||
*/
|
||||
validNeighbors = null;
|
||||
/**
|
||||
* Variable: validNeighbors
|
||||
*
|
||||
* 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
|
||||
* terminal to check if the rule applies to the connection.
|
||||
*/
|
||||
validNeighbors = null;
|
||||
|
||||
/**
|
||||
* Variable: validNeighborsAllowed
|
||||
*
|
||||
* Boolean indicating if the list of validNeighbors are those that are allowed
|
||||
* for this rule or those that are not allowed for this rule.
|
||||
*/
|
||||
validNeighborsAllowed = true;
|
||||
/**
|
||||
* Variable: validNeighborsAllowed
|
||||
*
|
||||
* Boolean indicating if the list of validNeighbors are those that are allowed
|
||||
* for this rule or those that are not allowed for this rule.
|
||||
*/
|
||||
validNeighborsAllowed = true;
|
||||
|
||||
/**
|
||||
* Variable: countError
|
||||
*
|
||||
* Holds the localized error message to be displayed if the number of
|
||||
* connections for which the rule applies is smaller than <min> or greater
|
||||
* than <max>.
|
||||
*/
|
||||
countError = null;
|
||||
/**
|
||||
* Variable: countError
|
||||
*
|
||||
* Holds the localized error message to be displayed if the number of
|
||||
* connections for which the rule applies is smaller than <min> or greater
|
||||
* than <max>.
|
||||
*/
|
||||
countError = null;
|
||||
|
||||
/**
|
||||
* Variable: typeError
|
||||
*
|
||||
* Holds the localized error message to be displayed if the type of the
|
||||
* neighbor for a connection does not match the rule.
|
||||
*/
|
||||
typeError = null;
|
||||
/**
|
||||
* Variable: typeError
|
||||
*
|
||||
* Holds the localized error message to be displayed if the type of the
|
||||
* neighbor for a connection does not match the rule.
|
||||
*/
|
||||
typeError = null;
|
||||
|
||||
/**
|
||||
* Function: check
|
||||
*
|
||||
* Checks the multiplicity for the given arguments and returns the error
|
||||
* for the given connection or null if the multiplicity does not apply.
|
||||
*
|
||||
* Parameters:
|
||||
*
|
||||
* 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 = '';
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
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)))
|
||||
{
|
||||
if (this.countError != null &&
|
||||
((this.source && (this.max == 0 || (sourceOut >= this.max))) ||
|
||||
(!this.source && (this.max == 0 || (targetIn >= this.max)))))
|
||||
{
|
||||
error += this.countError + '\n';
|
||||
}
|
||||
/**
|
||||
* Function: check
|
||||
*
|
||||
* Checks the multiplicity for the given arguments and returns the error
|
||||
* for the given connection or null if the multiplicity does not apply.
|
||||
*
|
||||
* Parameters:
|
||||
*
|
||||
* 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)
|
||||
{
|
||||
var isValid = this.checkNeighbors(graph, edge, source, target);
|
||||
if ((this.source && this.checkTerminal(graph, source, edge)) ||
|
||||
(!this.source && this.checkTerminal(graph, target, edge))) {
|
||||
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)
|
||||
{
|
||||
error += this.typeError + '\n';
|
||||
if (this.validNeighbors != null && this.typeError != null && this.validNeighbors.length > 0) {
|
||||
var isValid = this.checkNeighbors(graph, edge, source, target);
|
||||
|
||||
if (!isValid) {
|
||||
error += this.typeError + '\n';
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return (error.length > 0) ? error : null;
|
||||
};
|
||||
return (error.length > 0) ? error : null;
|
||||
};
|
||||
|
||||
/**
|
||||
* Function: checkNeighbors
|
||||
*
|
||||
* Checks if there are any valid neighbours in <validNeighbors>. This is only
|
||||
* called if <validNeighbors> is a non-empty array.
|
||||
*/
|
||||
checkNeighbors = (graph, edge, source, target)=>
|
||||
{
|
||||
var sourceValue = graph.model.getValue(source);
|
||||
var targetValue = graph.model.getValue(target);
|
||||
var isValid = !this.validNeighborsAllowed;
|
||||
var valid = this.validNeighbors;
|
||||
/**
|
||||
* Function: checkNeighbors
|
||||
*
|
||||
* Checks if there are any valid neighbours in <validNeighbors>. This is only
|
||||
* called if <validNeighbors> is a non-empty array.
|
||||
*/
|
||||
checkNeighbors = (graph, edge, source, target) => {
|
||||
var sourceValue = graph.model.getValue(source);
|
||||
var targetValue = graph.model.getValue(target);
|
||||
var isValid = !this.validNeighborsAllowed;
|
||||
var valid = this.validNeighbors;
|
||||
|
||||
for (var j = 0; j < valid.length; j++)
|
||||
{
|
||||
if (this.source &&
|
||||
this.checkType(graph, targetValue, valid[j]))
|
||||
{
|
||||
isValid = this.validNeighborsAllowed;
|
||||
break;
|
||||
for (var j = 0; j < valid.length; j++) {
|
||||
if (this.source &&
|
||||
this.checkType(graph, targetValue, valid[j])) {
|
||||
isValid = this.validNeighborsAllowed;
|
||||
break;
|
||||
} else if (!this.source &&
|
||||
this.checkType(graph, sourceValue, valid[j])) {
|
||||
isValid = this.validNeighborsAllowed;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (!this.source &&
|
||||
this.checkType(graph, sourceValue, valid[j]))
|
||||
{
|
||||
isValid = this.validNeighborsAllowed;
|
||||
break;
|
||||
|
||||
return isValid;
|
||||
};
|
||||
|
||||
/**
|
||||
* 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;
|
||||
};
|
||||
|
||||
/**
|
||||
* 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;
|
||||
};
|
||||
export default mxMultiplicity;
|
||||
|
|
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, Gaudenz Alder
|
||||
*/
|
||||
var mxStyleRegistry =
|
||||
{
|
||||
|
||||
import mxConstants from "../util/mxConstants";
|
||||
|
||||
var mxStyleRegistry = {
|
||||
/**
|
||||
* Class: mxStyleRegistry
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
*
|
||||
* Variable: values
|
||||
*
|
||||
* Maps from strings to objects.
|
||||
|
@ -21,8 +23,7 @@ var mxStyleRegistry =
|
|||
*
|
||||
* Puts the given object into the registry under the given name.
|
||||
*/
|
||||
putValue: (name, obj)=>
|
||||
{
|
||||
putValue: (name, obj) => {
|
||||
mxStyleRegistry.values[name] = obj;
|
||||
},
|
||||
|
||||
|
@ -31,29 +32,23 @@ var mxStyleRegistry =
|
|||
*
|
||||
* Returns the value associated with the given name.
|
||||
*/
|
||||
getValue: (name)=>
|
||||
{
|
||||
getValue: (name) => {
|
||||
return mxStyleRegistry.values[name];
|
||||
},
|
||||
|
||||
|
||||
/**
|
||||
* Function: getName
|
||||
*
|
||||
*
|
||||
* Returns the name for the given value.
|
||||
*/
|
||||
getName: (value)=>
|
||||
{
|
||||
for (var key in mxStyleRegistry.values)
|
||||
{
|
||||
if (mxStyleRegistry.values[key] == value)
|
||||
{
|
||||
getName: (value) => {
|
||||
for (var key in mxStyleRegistry.values) {
|
||||
if (mxStyleRegistry.values[key] === value) {
|
||||
return key;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
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_TRIANGLE, mxPerimeter.TrianglePerimeter);
|
||||
mxStyleRegistry.putValue(mxConstants.PERIMETER_HEXAGON, mxPerimeter.HexagonPerimeter);
|
||||
|
||||
export default mxStyleRegistry;
|
||||
|
|
|
@ -7,127 +7,121 @@
|
|||
*
|
||||
* 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
|
||||
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);
|
||||
}
|
||||
class 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;
|
||||
|
||||
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
|
||||
view.validateCellState = (cell, resurse)=>
|
||||
{
|
||||
if (cell == null || isCellVisibleFn == null || isCellVisibleFn(cell))
|
||||
{
|
||||
return self.oldValidateCellState.apply(view, arguments);
|
||||
// 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
|
||||
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
|
||||
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);
|
||||
}
|
||||
}
|
||||
/**
|
||||
* 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;
|
||||
};
|
||||
}
|
||||
|
||||
view.setGraphBounds(bbox || new mxRectangle());
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* 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;
|
||||
};
|
||||
export default mxTemporaryCellStates;
|
||||
|
|
Loading…
Reference in New Issue