Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

diagram-js

Package Overview
Dependencies
Maintainers
1
Versions
285
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

diagram-js - npm Package Compare versions

Comparing version 0.0.1 to 0.0.2

example/traffic-light.html

8

Gruntfile.js

@@ -17,2 +17,10 @@ module.exports = function(grunt) {

release: {
options: {
tagName: 'v<%= version %>',
commitMessage: 'chore(project): release v<%= version %>',
tagMessage: 'chore(project): tag v<%= version %>'
}
},
jshint: {

@@ -19,0 +27,0 @@ src: [

3

package.json
{
"name": "diagram-js",
"version": "0.0.1",
"version": "0.0.2",
"description": "A modeling framework for the web",

@@ -40,2 +40,3 @@ "main": "src/Diagram.js",

"grunt-contrib-jshint": "~0.7.0",
"grunt-release": "~0.7.0",
"grunt-jsdoc": "~0.5.1",

@@ -42,0 +43,0 @@ "grunt-concurrent": "~0.4.0",

var diagramModule = require('../di').defaultModule;
var IdGenerator = require('../util/IdGenerator'),
shapeUtil = require('../util/shapeUtil');
var AddShapeHandler = require('../commands/AddShape');

@@ -28,94 +27,20 @@ var _ = require('lodash');

var ids = new IdGenerator('s');
var paper = graphicsFactory.createPaper(options);
// holds id -> { element, gfx } mappings
var elementMap = {};
// Todo remove addShape/addConnection from public API?
// should only be called over command stack
(function registerCommands() {
commandStack.register('addShape', {
do: function addShapeDo(shape) {
internalAddShape(shape);
return true;
},
undo: function addShapeUndo(shape) {
internalUndoAddShape(shape);
return true;
},
canDo: function canUndoShape() {
return true;
}
});
commandStack.register('moveShape', {
do: function moveShapeDo(param) {
var dragCtx = param.event.dragCtx;
if(dragCtx) {
_.forEach(dragCtx.allDraggedGfx, function(gfx) {
//Update Viewport
var actualTMatrix = gfx.transform().local;
gfx.attr({
transform: actualTMatrix + (actualTMatrix ? 'T' : 't') + [dragCtx.dx, dragCtx.dy]
});
//Update model
var model = shapes.getShapeByGraphics(gfx);
shapeUtil.translateShape(model, dragCtx.dx, dragCtx.dy);
});
}
return true;
},
undo: function moveShapeUndo(param) {
var dragCtx = param.event.dragCtx;
if(dragCtx) {
_.forEach(dragCtx.allDraggedGfx, function(gfx) {
//Update Viewport
var actualTMatrix = gfx.transform().local;
gfx.attr({
transform: actualTMatrix + (actualTMatrix ? 'T' : 't') + [(-1)*dragCtx.dx, (-1)*dragCtx.dy]
});
//Update model
var model = shapes.getShapeByGraphics(gfx);
shapeUtil.translateShape(model,(-1)*dragCtx.dx, (-1)*dragCtx.dy);
});
}
return true;
},
canDo: function canUndoMoveShape() {
return true;
}
});
})();
/**
* Only register shape in Canvas' ElementMap.
* Adds a shape to the canvas
*
* @method Canvas#addShape
*
* @param {djs.ShapeDescriptor} shape a descriptor for the shape
*
* @return {Canvas} the canvas api
*/
function checkId(e, gfx) {
if (!e.id) {
e.id = ids.next();
}
}
function addShape(shape) {
/**
* Add shape to DOM
*/
function addChild(parent, child) {
if (parent.children) {
parent.children.push(child);
} else {
parent.children = [ child ];
if (!shape.id) {
throw new Error('shape must have an id');
}
}
function internalAddShape(shape) {
var gfx = graphicsFactory.createShape(paper, shape);
checkId(shape, gfx);
if (shape.parent) {
addChild(shape.parent, shape);
}
/**

@@ -131,27 +56,13 @@ * An event indicating that a new shape has been added to the canvas.

*/
events.fire('shape.added', { element: shape, gfx: gfx });
commandStack.execute('shape.add', { shape: shape });
return this;
}
function internalUndoAddShape(shape) {
var gfx = getGraphics(shape);
gfx.remove();
// register shape add handlers
commandStack.registerHandler('shape.add', AddShapeHandler);
events.fire('shape.removed', { element: shape, gfx: gfx });
}
/**
* Adds a shape to the canvas
*
* @method Canvas#addShape
*
* @param {djs.ShapeDescriptor} shape a descriptor for the shape
*
* @return {Canvas} the canvas api
*/
function addShape(param) {
commandStack.execute('addShape', param);
return this;
}
/**
* Adds a connection to the canvas

@@ -166,6 +77,9 @@ *

function addConnection(connection) {
if (!connection.id) {
throw new Error('connection must have an id');
}
var gfx = graphicsFactory.createConnection(paper, connection);
checkId(connection, gfx);
/**

@@ -172,0 +86,0 @@ * An event indicating that a new connection has been added to the canvas.

@@ -17,3 +17,3 @@ var diagramModule = require('../di').defaultModule;

*/
function CommandStack() {
function CommandStack(injector) {
'use strict';

@@ -71,3 +71,3 @@

_.forEach(commandListeners, function(commandListener) {
if(commandListener.do(ctx)) {
if(commandListener.execute(ctx)) {
pushAction(id, ctx);

@@ -89,3 +89,3 @@ if(!saveRedoStack) {

_.forEach(commandListeners, function(commandListener) {
commandListener.undo(lastAction.param);
commandListener.revert(lastAction.param);
});

@@ -157,2 +157,12 @@ pushActionToRedoStack(lastAction);

function registerHandler(command, handlerCls) {
if (!command || !handlerCls) {
throw new Error('command and handlerCls must be defined');
}
var handler = injector.instantiate(handlerCls);
registerCommand(command, handler);
}
return {

@@ -166,8 +176,9 @@ register: registerCommand,

redoStack: getRedoStack,
clearStack: clearActionStack
clearStack: clearActionStack,
registerHandler: registerHandler
};
}
diagramModule.type('commandStack', CommandStack);
diagramModule.type('commandStack', [ 'injector', CommandStack ]);
module.exports = CommandStack;

@@ -33,7 +33,7 @@ var diagramModule = require('../di').defaultModule;

if (graphicsMap[gfx.id]) {
throw new Error('[mod] graphics with id ' + gfx.id + ' already registered');
throw new Error('graphics with id ' + gfx.id + ' already registered');
}
if (shapeMap[shape.id]) {
throw new Error('[mod] shape with id ' + shape.id + ' already added');
throw new Error('shape with id ' + shape.id + ' already added');
}

@@ -40,0 +40,0 @@

@@ -5,2 +5,3 @@ var diagramModule = require('../di').defaultModule;

require('../core/Events');
require('./Styles');

@@ -26,20 +27,20 @@

* @param {Events} events
* @param {Styles} styles
*/
function Renderer(events) {
function Renderer(events, styles) {
this.CONNECTION_STYLE = styles.style([ 'no-fill' ]);
this.SHAPE_STYLE = styles.style({ fill: 'fuchsia' });
}
function drawShape(paper, data) {
return paper.rect(0, 0, data.width, data.height).attr('fill', 'fuchsia');
}
Renderer.prototype.drawShape = function drawShape(paper, data) {
return paper.rect(0, 0, data.width, data.height, 10, 10).attr(this.SHAPE_STYLE);
};
function drawConnection(paper, data) {
var points = flattenPoints(data.waypoints);
return paper.polyline(points);
}
Renderer.prototype.drawConnection = function drawConnection(paper, data) {
var points = flattenPoints(data.waypoints);
return paper.polyline(points).attr(this.CONNECTION_STYLE);
};
// API
this.drawShape = drawShape;
this.drawConnection = drawConnection;
}
diagramModule.type('renderer', [ 'events', Renderer ]);
diagramModule.type('renderer', [ 'events', 'styles', Renderer ]);

@@ -46,0 +47,0 @@

require('../core/Events');
require('../draw/Styles');
var Diagram = require('../Diagram'),

@@ -15,5 +17,8 @@ _ = require('lodash'),

* @param {Events} events the event bus to attach to
* @param {Styles} styles to build the interaction shape on
*/
function Interactivity(events) {
function Interactivity(events, styles) {
var HIT_STYLE = styles.cls('djs-hit', [ 'no-fill', 'no-border' ]);
function isCtxSwitch(e) {

@@ -37,3 +42,3 @@ return !e.relatedTarget || e.target.parentNode !== e.relatedTarget.parentNode;

// add a slightly bigger event rect
visual.clone().attr('class', 'djs-hit').prependTo(gfx);
visual.clone().attr(HIT_STYLE).prependTo(gfx);

@@ -80,4 +85,4 @@ gfx.hover(function(e) {

Diagram.plugin('basicInteractionEvents', [ 'events', Interactivity ]);
Diagram.plugin('basicInteractionEvents', [ 'events', 'styles', Interactivity ]);
module.exports = Interactivity;

@@ -9,3 +9,4 @@ require('../core/Events');

var Diagram = require('../Diagram'),
var MoveShapesHandler = require('../commands/MoveShapes'),
Diagram = require('../Diagram'),
_ = require('lodash');

@@ -33,2 +34,28 @@

///// execution of actual move ///////////////////////////
function executeMove(ctx) {
var moveContext = {
dx: ctx.dx,
dy: ctx.dy,
shapes: ctx.shapes
};
var hoverGfx = ctx.hoverGfx;
if (hoverGfx) {
moveContext.newParent = shapes.getShapeByGraphics(hoverGfx);
}
commandStack.execute('shape.move', moveContext);
}
// commandStack default move handler registration
commandStack.registerHandler('shape.move', MoveShapesHandler);
///// draggable implementation ////////////////////////////
function makeDraggable(shape, gfx) {

@@ -55,3 +82,3 @@

dragCtx.hover = event.gfx;
dragCtx.hoverGfx = event.gfx;
}

@@ -77,3 +104,3 @@

delete dragCtx.hover;
delete dragCtx.hoverGfx;
}

@@ -176,3 +203,3 @@

if (!event.isDefaultPrevented()) {
commandStack.execute('moveShape', { event: event });
executeMove(event.dragCtx);
}

@@ -179,0 +206,0 @@ }

@@ -6,2 +6,3 @@ require('../core/Events');

require('../draw/Snap');
require('../draw/Styles');

@@ -28,5 +29,7 @@ require('./services/Selection');

* @param {Canvas} canvas the drawing canvas
* @param {SnapSVG} snap
* @param {Styles} styles
* @param {Rules} the rule engine
*/
function DragUI(events, selection, shapes, canvas, snap, rules) {
function DragUI(events, selection, shapes, canvas, snap, styles, rules) {

@@ -63,7 +66,6 @@ var paper = canvas.getContext();

dragger.attr({
'class': 'djs-dragger',
'x': bbox.x,
'y': bbox.y
});
dragger.attr(styles.cls('djs-dragger', [], {
x: bbox.x,
y: bbox.y
}));

@@ -140,4 +142,4 @@ dragGroup.add(dragger);

if (dragCtx.hover) {
removeDropMarkers(dragCtx.hover);
if (dragCtx.hoverGfx) {
removeDropMarkers(dragCtx.hoverGfx);
}

@@ -150,4 +152,6 @@

Diagram.plugin('dragUI', [ 'events', 'selection', 'shapes', 'canvas', 'snap', 'rules', 'dragEvents', DragUI ]);
Diagram.plugin('dragUI', [
'events', 'selection', 'shapes', 'canvas', 'snap', 'styles', 'rules', 'dragEvents', DragUI
]);
module.exports = DragUI;

@@ -1,4 +0,5 @@

require('../core/Canvas');
require('../core/Events');
require('../draw/Styles');
var Diagram = require('../Diagram'),

@@ -17,11 +18,11 @@ svgUtil = require('../util/svgUtil');

*/
function Outline(events, canvas) {
function Outline(events, styles) {
var OUTLINE_OFFSET = 10;
var paper = canvas.getContext();
var OUTLINE_STYLE = styles.cls('djs-outline', [ 'no-fill' ]);
function createOutline(gfx) {
return paper.rect(0, 0, 0, 0)
.attr('class', 'djs-outline')
return gfx.rect(0, 0, 0, 0)
.attr(OUTLINE_STYLE)
.prependTo(gfx);

@@ -58,4 +59,4 @@ }

Diagram.plugin('outline', [ 'events', 'canvas', Outline ]);
Diagram.plugin('outline', [ 'events', 'styles', Outline ]);
module.exports = Outline;

@@ -110,3 +110,3 @@ (function(require) {

if (!definition) {
throw new Error('[mod] no definition for resize handle #' + id);
throw new Error('no definition for resize handle #' + id);
}

@@ -113,0 +113,0 @@

@@ -64,3 +64,3 @@ require('../../core/Events');

function deselect(element) {
throw new Error('[mod] not implemented');
throw new Error('not implemented');
}

@@ -67,0 +67,0 @@

@@ -100,2 +100,26 @@ var _ = require('lodash');

function setParent(shape, newParent) {
// TODO(nre): think about parent->child magic
var old = shape.parent;
if (old && old.children) {
var idx = old.children.indexOf(shape);
if (idx !== -1) {
old.children.splice(idx, 1);
}
}
if (newParent) {
if (!newParent.children) {
newParent.children = [];
}
newParent.children.push(shape);
}
shape.parent = newParent;
return old;
}
module.exports.eachShape = each;

@@ -105,1 +129,2 @@ module.exports.selfAndDirectChildren = selfAndDirectChildren;

module.exports.translateShape = translateShape;
module.exports.setParent = setParent;

@@ -11,6 +11,7 @@

beforeEach(bootstrapDiagram());
describe('add shape', function() {
beforeEach(bootstrapDiagram());
it('should fire <shape.added> event', inject(function(canvas, events) {

@@ -23,18 +24,3 @@

// when
canvas.addShape({
id: 'a',
children: [
{ id: 'a.0', children: [] },
{ id: 'a.1', children: [
{ id: 'a.1.0' },
{ id: 'a.1.1' }
]},
{ id: 'a.2', children: [
{ id: 'a.2.0' },
{ id: 'a.2.1', children: [
{ id: 'a.2.1.0' }
]}
]}
]
});
canvas.addShape({ id: 'a', x: 10, y: 20 });

@@ -45,3 +31,85 @@ // then

it('should fail when shape#id is not set', inject(function(canvas) {
// given
var s = { x: 10, y: 20};
expect(function() {
// when
canvas.addShape(s);
fail('expected exception');
}).toThrowError('shape must have an id');
}));
it('should fail when adding shape#id twice', inject(function(canvas) {
// given
var s = { id: 'FOO', x: 10, y: 10 };
expect(function() {
// when
canvas.addShape(s);
canvas.addShape(s);
fail('expected exception');
}).toThrowError('shape with id FOO already added');
}));
it('should undo add of shape', inject(function(canvas, commandStack, shapes) {
// given
var s1 = { id: 's1', x: 10, y: 20 };
var s2 = { id: 's2', x: 10, y: 20, parent: s1 };
var s3 = { id: 's3', x: 10, y: 20, parent: s1 };
canvas
.addShape(s1)
.addShape(s2)
.addShape(s3);
// when
commandStack.undo();
commandStack.undo();
// then
expect(shapes.getShapeById('s2')).not.toBeDefined();
expect(shapes.getShapeById('s3')).not.toBeDefined();
}));
it('should redo add of shape', inject(function(canvas, commandStack, shapes) {
// given
var s1 = { id: 's1', x: 10, y: 20 };
var s2 = { id: 's2', x: 10, y: 20, parent: s1 };
var s3 = { id: 's3', x: 10, y: 20, parent: s1 };
canvas
.addShape(s1)
.addShape(s2)
.addShape(s3);
// when
commandStack.undo();
commandStack.undo();
commandStack.redo();
commandStack.undo();
commandStack.redo();
commandStack.redo();
// then
expect(shapes.getShapeById('s2')).toEqual(s2);
expect(shapes.getShapeById('s3')).toEqual(s3);
expect(s2.parent).toEqual(s1);
expect(s3.parent).toEqual(s1);
}));
});
});

@@ -9,3 +9,3 @@ var Command = require('../../../src/core/CommandStack');

var f1 = {
do: function f1_do(param) {
execute: function f1_execute(param) {

@@ -15,8 +15,8 @@ param.test = 'do_A';

},
undo: function f1_undo(param) {
revert: function f1_revert(param) {
param.test = 'undo_A';
return true;
},
canDo: function f1_canDo(param) {
param.test = 'canDo_A';
canExecute: function f1_canExecute(param) {
param.test = 'canExecute_A';
return true;

@@ -26,12 +26,12 @@ }

var f2 = {
do: function f2_do(param) {
execute: function f2_execute(param) {
param.test = 'do_B';
return true;
},
undo: function f2_undo(param) {
revert: function f2_revert(param) {
param.test = 'undo_B';
return true;
},
canDo: function f2_canDo(param) {
param.test = 'canDo_B';
canExecute: function f2_canExecute(param) {
param.test = 'canExecute_B';
return true;

@@ -41,12 +41,12 @@ }

var f3 = {
do: function f3_do(param) {
execute: function f3_execute(param) {
param.test = 'do_C';
return true;
},
undo: function f3_undo(param) {
revert: function f3_revert(param) {
param.test = 'undo_C';
return true;
},
canDo: function f3_canDo(param) {
param.test = 'canDo_C';
canExecute: function f3_canExecute(param) {
param.test = 'canExecute_C';
return true;

@@ -56,10 +56,10 @@ }

var f4 = {
do: function f4_do(param) {
execute: function f4_execute(param) {
param.test = 'do_D';
},
undo: function f4_undo(param) {
revert: function f4_revert(param) {
param.test = 'undo_D';
},
canDo: function f4_canDo(param) {
param.test = 'canDo_D';
canExecute: function f4_canExecute(param) {
param.test = 'canExecute_D';
}

@@ -66,0 +66,0 @@ };

@@ -5,34 +5,57 @@ var Diagram = require('../../src/Diagram');

it('should offer #plugin API', function() {
expect(Diagram.plugin).toBeDefined();
var container;
beforeEach(function() {
container = document.createElement('div');
document.getElementsByTagName('body')[0].appendChild(container);
});
it('should bootstrap app', function() {
afterEach(function() {
container.parentNode.removeChild(container);
});
var diagram = new Diagram({
canvas: {
container: undefined,
width: 700,
height: 500
}
describe('static', function() {
it('should offer #plugin API', function() {
expect(Diagram.plugin).toBeDefined();
});
});
it('should expose diagram services', function() {
var diagram = new Diagram({
canvas: {
container: undefined,
width: 700,
height: 500
}
describe('runtime', function() {
it('should bootstrap app', function() {
var diagram = new Diagram({
canvas: {
container: container,
width: 700,
height: 500
}
});
});
diagram.invoke([ 'canvas', function(canvas) {
canvas.addShape({x: 10, y: 10, width: 30, height: 30 });
canvas.addShape({x: 100, y: 100, width: 30, height: 30 });
canvas.addConnection({ waypoints: [ { x: 25, y: 25 }, {x: 115, y: 115} ]});
}]);
it('should expose diagram services', function() {
var diagram = new Diagram({
canvas: {
container: container,
width: 700,
height: 500
}
});
diagram.invoke([ 'canvas', function(canvas) {
canvas
.addShape({ id: 's1', x: 10, y: 10, width: 30, height: 30 })
.addShape({ id: 's2', x: 100, y: 100, width: 30, height: 30 });
canvas.addConnection({ id: 'c1', waypoints: [ { x: 25, y: 25 }, {x: 115, y: 115} ]});
}]);
});
});
});

@@ -103,7 +103,60 @@ var shapeUtil = require('../../../src/util/shapeUtil');

describe('translateShape should', function() {
it('move shape correctly', function() {
describe('setParent', function() {
it('should initialize parent', function() {
// given
var shape = { };
var parent = { };
// when
shapeUtil.setParent(shape, parent);
// then
expect(shape.parent).toBe(parent);
expect(parent.children).toEqual([ shape ]);
});
it('should handle undefined parent#children', function() {
// given
var oldParent = {};
var newParent = {};
var s = { parent: oldParent };
// when
shapeUtil.setParent(s, newParent);
// then
expect(s.parent).toBe(newParent);
});
it('should unwire old parent relationship', function() {
// given
var shape = { };
var oldParent = { };
var newParent = { };
shapeUtil.setParent(shape, oldParent);
// when
shapeUtil.setParent(shape, newParent);
// then
expect(shape.parent).toBe(newParent);
expect(newParent.children).toEqual([ shape ]);
expect(oldParent.children.indexOf(shape)).toBe(-1);
});
});
describe('translateShape', function() {
it('should move shape correctly', function() {
// given
var shape = {x: 11, y: 23};

@@ -110,0 +163,0 @@

@@ -41,3 +41,3 @@ var _ = require('lodash');

if (!locals) {
if (!locals && _.isFunction(options)) {
locals = options;

@@ -44,0 +44,0 @@ options = null;

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc