Skip to content

Instantly share code, notes, and snippets.

@russellsamora
Created February 6, 2014 18:47
Show Gist options
  • Save russellsamora/8850218 to your computer and use it in GitHub Desktop.
Save russellsamora/8850218 to your computer and use it in GitHub Desktop.
{
"libraries": [
"JointJS"
],
"mode": "javascript",
"layout": "fullscreen mode (vertical)",
"resolution": "reset"
}
/*! JointJS v0.8.0 - JavaScript diagramming library 2014-01-22
This Source Code Form is subject to the terms of the Mozilla Public
License, v. 2.0. If a copy of the MPL was not distributed with this
file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
.viewport{-webkit-user-select:none;-moz-user-select:none;user-select:none}[magnet=true]:not(.element){cursor:crosshair}[magnet=true]:not(.element):hover{opacity:.7}.element{cursor:move}.element *{vector-effect:non-scaling-stroke;-moz-user-select:none;user-drag:none}.connection-wrap{fill:none;stroke:#000;stroke-width:15;stroke-linecap:round;stroke-linejoin:round;opacity:0;cursor:move}.connection-wrap:hover{opacity:.4;stroke-opacity:.4}.connection{fill:none;stroke-linejoin:round}.marker-source,.marker-target{vector-effect:non-scaling-stroke}.marker-vertices{opacity:0;cursor:move}.marker-arrowheads{opacity:0;cursor:move;cursor:-webkit-grab;cursor:-moz-grab}.link-tools{opacity:0;cursor:pointer}.link-tools .tool-options{display:none}.link-tools .tool-remove circle{fill:red}.link-tools .tool-remove path{fill:#fff}.link:hover .marker-vertices,.link:hover .marker-arrowheads,.link:hover .link-tools{opacity:1}.marker-vertex{fill:#1ABC9C}.marker-vertex:hover{fill:#34495E;stroke:none}.marker-arrowhead{fill:#1ABC9C}.marker-arrowhead:hover{fill:#F39C12;stroke:none}.marker-vertex-remove{cursor:pointer;opacity:.1;fill:#fff}.marker-vertex-group:hover .marker-vertex-remove{opacity:1}.marker-vertex-remove-area{opacity:.1;cursor:pointer}.marker-vertex-group:hover .marker-vertex-remove-area{opacity:1}text.highlighted{fill:red}.highlighted{outline:2px solid red;opacity:.7 \9}@-moz-document url-prefix(){.highlighted{opacity:.7}}doesnotexist:-o-prefocus,.highlighted{opacity:.7}.TextBlock .fobj body{background-color:transparent;margin:0}.TextBlock .fobj div{text-align:center;vertical-align:middle;display:table-cell;padding:0 5px}
button {
z-index: 1000;
position: relative;
}
#paper {
position: absolute;
top: 0;
bottom: 20%;
background: #C7C7C7;
width: 100%;
font-size: 0.77em;
}
#log {
position: absolute;
width: 100%;
top: 80%;
bottom: 0;
margin: 0em 0em 0em 0em;
font-family: monospace;
overflow-y: scroll;
}
<button id='read'>Read from JSON</button>
<button id='write'>Write to JSON (modify any code tab for write to actually happen)</button>
<div id='paper'></div>
<pre id='log'></pre>
var graph = new joint.dia.Graph;
$('#read').click(function(e) {
livecoding.json.cells && graph.fromJSON(livecoding.json);
});
$('#write').click(function(e) {
livecoding.json = graph.toJSON();
generateFSM(livecoding.json);
});
function generateFSM(graphJson) {
var json = {};
json.initial = _(graphJson.cells)
.find({type: 'fsa.StartState'}).attrs.text.text;
json.events = _(graphJson.cells)
.where({type: 'fsa.Arrow'})
.map(function(v, i) {
var name = v;
var from = _.find(graphJson.cells, {id: v.source.id});
var to = _.find(graphJson.cells, {id: v.target.id});
return {
name: name.labels[0].attrs.text.text,
from: from.attrs.text.text,
to: to.attrs.text.text
};
})
.groupBy('to')
.map(function(v, i) {
var group = _(v)
.groupBy('name')
.map(function(v, i) {
var froms = _.pluck(v, 'from');
var from = froms.length > 1 ?
froms :
froms[0];
return {
name: i,
from: from,
to: v[0].to
};
})
.value();
return {
state: i,
events: group
};
})
.pluck('events')
.flatten()
.value();
$('#log').html(JSON.stringify(json, null, 4));
}
var paper = new joint.dia.Paper({
el: $('#paper'),
width: '100%',
height: '100%',
gridSize: 1,
model: graph
});
function createStart(x, y, label) {
var cell = new joint.shapes.fsa.StartState({
position: { x: 50, y: 75 },
attrs: { text : { text: label }}
});
graph.addCell(cell);
return cell;
}
function createState(x, y, label) {
var cell = new joint.shapes.fsa.State({
position: { x: x, y: y },
size: { width: 85, height: 50 },
attrs: { text : { text: label }}
});
graph.addCell(cell);
return cell;
};
function createEvent(source, target, label, vertices) {
var cell = new joint.shapes.fsa.Arrow({
source: { id: source.id },
target: { id: target.id },
labels: [{ position: .5, attrs: { text: { text: label || '', 'font-weight': 'bold' } } }],
vertices: vertices || []
});
graph.addCell(cell);
return cell;
}
var loading = createStart(50, 75, 'loading');
var intro = createState(200, 75, 'intro');
var rent = createState(400, 75, 'rent');
var simulation = createState(400, 200, 'simulation');
var fact = createState(300, 300, 'fact');
var issue = createState(200, 200, 'issue');
var violation = createState(500, 300, 'violation');
var highscores = createState(700, 100, 'highscores');
var yearend = createState(600, 205, 'yearend');
createEvent(loading, intro, 'loaded');
createEvent(intro, rent, 'userInput');
createEvent(rent, simulation, 'userInput');
createEvent(simulation, issue, 'chance');
createEvent(simulation, violation, 'chance');
createEvent(fact, simulation, 'bypass');
createEvent(fact, simulation, 'userInput', [{x: 400, y: 300}]);
createEvent(issue, fact, 'userInput');
createEvent(violation, fact, 'userInput');
createEvent(simulation, yearend, 'time');
createEvent(yearend, rent, 'userInput');
createEvent(yearend, highscores, 'userInput');
createEvent(highscores, intro, 'userInput', [{x: 500, y: 25}]);
{
"cells": [
{
"type": "fsa.StartState",
"size": {
"width": 20,
"height": 20
},
"position": {
"x": 56,
"y": 115
},
"angle": 0,
"id": "0ac41d69-e6f2-49bb-bb3c-23d56a95e76a",
"z": 0,
"attrs": {
"text": {
"text": "loading"
}
}
},
{
"type": "fsa.State",
"size": {
"width": 85,
"height": 50
},
"position": {
"x": 202,
"y": 102
},
"angle": 0,
"id": "e13ff98c-7ce5-43e5-8e00-4360b234861a",
"z": 1,
"attrs": {
"text": {
"text": "intro"
}
}
},
{
"type": "fsa.State",
"size": {
"width": 85,
"height": 50
},
"position": {
"x": 401,
"y": 100
},
"angle": 0,
"id": "455237d3-ef08-49fd-ba9d-7dd7d6ea0426",
"z": 2,
"attrs": {
"text": {
"text": "rent"
}
}
},
{
"type": "fsa.State",
"size": {
"width": 85,
"height": 50
},
"position": {
"x": 399,
"y": 239
},
"angle": 0,
"id": "9fa0a596-f7e5-4af0-ad9d-a6cb0985d977",
"z": 3,
"attrs": {
"text": {
"text": "simulation"
}
}
},
{
"type": "fsa.State",
"size": {
"width": 85,
"height": 50
},
"position": {
"x": 295,
"y": 385
},
"angle": 0,
"id": "1492baf8-c9c4-4ea9-9980-e345482fd331",
"z": 4,
"attrs": {
"text": {
"text": "fact"
}
}
},
{
"type": "fsa.State",
"size": {
"width": 85,
"height": 50
},
"position": {
"x": 202,
"y": 245
},
"angle": 0,
"id": "317ad395-3831-4224-9e9b-0b4a93deaf4e",
"z": 5,
"attrs": {
"text": {
"text": "issue"
}
}
},
{
"type": "fsa.State",
"size": {
"width": 85,
"height": 50
},
"position": {
"x": 517,
"y": 396
},
"angle": 0,
"id": "1b27af3d-c85d-4aed-94f1-4697d91b1eca",
"z": 6,
"attrs": {
"text": {
"text": "violation"
}
}
},
{
"type": "fsa.State",
"size": {
"width": 85,
"height": 50
},
"position": {
"x": 620,
"y": 132
},
"angle": 0,
"id": "194d8f8a-003b-4080-bdb9-a91e84a8ca38",
"z": 7,
"attrs": {
"text": {
"text": "highscores"
}
}
},
{
"type": "fsa.State",
"size": {
"width": 85,
"height": 50
},
"position": {
"x": 615,
"y": 255
},
"angle": 0,
"id": "7b6f7d15-d8b9-41d7-ac06-2c3156d8c6e7",
"z": 8,
"attrs": {
"text": {
"text": "yearend"
}
}
},
{
"type": "fsa.Arrow",
"smooth": true,
"source": {
"id": "0ac41d69-e6f2-49bb-bb3c-23d56a95e76a"
},
"target": {
"id": "e13ff98c-7ce5-43e5-8e00-4360b234861a"
},
"labels": [
{
"position": 0.5,
"attrs": {
"text": {
"text": "loaded",
"font-weight": "bold"
}
}
}
],
"vertices": [],
"id": "951eaa94-1dcd-4a05-bfa0-5176dd264d07",
"z": 9,
"attrs": {}
},
{
"type": "fsa.Arrow",
"smooth": true,
"source": {
"id": "e13ff98c-7ce5-43e5-8e00-4360b234861a"
},
"target": {
"id": "455237d3-ef08-49fd-ba9d-7dd7d6ea0426"
},
"labels": [
{
"position": 0.5,
"attrs": {
"text": {
"text": "userInput",
"font-weight": "bold"
}
}
}
],
"vertices": [],
"id": "5cf092ef-3b42-4da6-a891-09aa5470fcf8",
"z": 10,
"attrs": {}
},
{
"type": "fsa.Arrow",
"smooth": true,
"source": {
"id": "455237d3-ef08-49fd-ba9d-7dd7d6ea0426"
},
"target": {
"id": "9fa0a596-f7e5-4af0-ad9d-a6cb0985d977"
},
"labels": [
{
"position": 0.5,
"attrs": {
"text": {
"text": "userInput",
"font-weight": "bold"
}
}
}
],
"vertices": [],
"id": "01f1c555-f349-422d-a469-da5182fb1f2e",
"z": 11,
"attrs": {}
},
{
"type": "fsa.Arrow",
"smooth": true,
"source": {
"id": "9fa0a596-f7e5-4af0-ad9d-a6cb0985d977"
},
"target": {
"id": "317ad395-3831-4224-9e9b-0b4a93deaf4e"
},
"labels": [
{
"position": 0.5,
"attrs": {
"text": {
"text": "chance",
"font-weight": "bold"
}
}
}
],
"vertices": [],
"id": "90828ed9-42e3-42cc-a139-d01e058d949f",
"z": 12,
"attrs": {}
},
{
"type": "fsa.Arrow",
"smooth": true,
"source": {
"id": "9fa0a596-f7e5-4af0-ad9d-a6cb0985d977"
},
"target": {
"id": "1b27af3d-c85d-4aed-94f1-4697d91b1eca"
},
"labels": [
{
"position": 0.5,
"attrs": {
"text": {
"text": "chance",
"font-weight": "bold"
}
}
}
],
"vertices": [],
"id": "c16b9618-b450-4f88-b66c-810233a00dcc",
"z": 13,
"attrs": {}
},
{
"type": "fsa.Arrow",
"smooth": true,
"source": {
"id": "1492baf8-c9c4-4ea9-9980-e345482fd331"
},
"target": {
"id": "9fa0a596-f7e5-4af0-ad9d-a6cb0985d977"
},
"labels": [
{
"position": 0.5,
"attrs": {
"text": {
"text": "bypass",
"font-weight": "bold"
}
}
}
],
"vertices": [
{
"x": 422,
"y": 334
}
],
"id": "9eb69735-aea8-4bde-8745-cf3e50e59a25",
"z": 14,
"attrs": {}
},
{
"type": "fsa.Arrow",
"smooth": true,
"source": {
"id": "1492baf8-c9c4-4ea9-9980-e345482fd331"
},
"target": {
"id": "9fa0a596-f7e5-4af0-ad9d-a6cb0985d977"
},
"labels": [
{
"position": 0.5,
"attrs": {
"text": {
"text": "userInput",
"font-weight": "bold"
}
}
}
],
"vertices": [
{
"x": 360,
"y": 329
},
{
"x": 400,
"y": 300
}
],
"id": "bfd990f0-4a94-46ad-966e-ba20c5ede0c1",
"z": 15,
"attrs": {}
},
{
"type": "fsa.Arrow",
"smooth": true,
"source": {
"id": "317ad395-3831-4224-9e9b-0b4a93deaf4e"
},
"target": {
"id": "1492baf8-c9c4-4ea9-9980-e345482fd331"
},
"labels": [
{
"position": 0.5,
"attrs": {
"text": {
"text": "userInput",
"font-weight": "bold"
}
}
}
],
"vertices": [],
"id": "489d0df4-c0e2-4d0b-a15c-602dc87ebf65",
"z": 16,
"attrs": {}
},
{
"type": "fsa.Arrow",
"smooth": true,
"source": {
"id": "1b27af3d-c85d-4aed-94f1-4697d91b1eca"
},
"target": {
"id": "1492baf8-c9c4-4ea9-9980-e345482fd331"
},
"labels": [
{
"position": 0.5,
"attrs": {
"text": {
"text": "userInput",
"font-weight": "bold"
}
}
}
],
"vertices": [],
"id": "80efc041-5431-458f-8b95-4ffab98c81cf",
"z": 17,
"attrs": {}
},
{
"type": "fsa.Arrow",
"smooth": true,
"source": {
"id": "9fa0a596-f7e5-4af0-ad9d-a6cb0985d977"
},
"target": {
"id": "7b6f7d15-d8b9-41d7-ac06-2c3156d8c6e7"
},
"labels": [
{
"position": 0.5,
"attrs": {
"text": {
"text": "time",
"font-weight": "bold"
}
}
}
],
"vertices": [],
"id": "c7f19aed-c8e9-4add-8ec4-5ed251387ff8",
"z": 18,
"attrs": {}
},
{
"type": "fsa.Arrow",
"smooth": true,
"source": {
"id": "7b6f7d15-d8b9-41d7-ac06-2c3156d8c6e7"
},
"target": {
"id": "455237d3-ef08-49fd-ba9d-7dd7d6ea0426"
},
"labels": [
{
"position": 0.5,
"attrs": {
"text": {
"text": "userInput",
"font-weight": "bold"
}
}
}
],
"vertices": [],
"id": "4df24017-c58c-441f-85a0-576bcd4a15c5",
"z": 19,
"attrs": {}
},
{
"type": "fsa.Arrow",
"smooth": true,
"source": {
"id": "7b6f7d15-d8b9-41d7-ac06-2c3156d8c6e7"
},
"target": {
"id": "194d8f8a-003b-4080-bdb9-a91e84a8ca38"
},
"labels": [
{
"position": 0.5,
"attrs": {
"text": {
"text": "userInput",
"font-weight": "bold"
}
}
}
],
"vertices": [],
"id": "a167633c-94ec-42e1-823e-f4fa878de3cf",
"z": 20,
"attrs": {}
},
{
"type": "fsa.Arrow",
"smooth": true,
"source": {
"id": "194d8f8a-003b-4080-bdb9-a91e84a8ca38"
},
"target": {
"id": "e13ff98c-7ce5-43e5-8e00-4360b234861a"
},
"labels": [
{
"position": 0.5,
"attrs": {
"text": {
"text": "userInput",
"font-weight": "bold"
}
}
}
],
"vertices": [
{
"x": 482,
"y": 54
}
],
"id": "5e0fcc11-7583-4616-bfc3-0ff206131e29",
"z": 21,
"attrs": {}
}
]
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment