@ -0,0 +1,219 @@ | |||||
<!DOCTYPE html> | |||||
<html> | |||||
<head lang="en"> | |||||
<meta charset="UTF-8"> | |||||
<title></title> | |||||
<script src="./js/hammer.js"></script> | |||||
<script src="./js/es6-shim.min.js"></script> | |||||
<script src="./js/eve.js"></script> | |||||
<script src="./js/inputAgent.js"></script> | |||||
<script src="./js/jquery.min.js"></script> | |||||
<script src="./js/bootstrap.min.js"></script> | |||||
<script language="JavaScript"> | |||||
var inputProxy; | |||||
</script> | |||||
<script src="./js/init.js"></script> | |||||
<script language="JavaScript"> | |||||
// to run this, also have webHttp.js running in node. | |||||
eve.system.init({ | |||||
transports: [ | |||||
{ | |||||
type: 'ws', | |||||
url: 'ws://agents/:id' | |||||
}, | |||||
{ | |||||
type: 'http' | |||||
} | |||||
] | |||||
}); | |||||
var proxyAddress = 'ws://afternoon-beyond-2302.herokuapp.com/agents/proxy'; | |||||
var proxyAddressHTTP = 'https://afternoon-beyond-2302.herokuapp.com/agents/proxy'; | |||||
// proxyAddress = 'ws://127.0.0.1:5000/agents/proxy'; | |||||
// proxyAddressHTTP = 'http://127.0.0.1:5000/agents/proxy'; | |||||
inputProxy = new inputAgent('inputAgent', proxyAddress); | |||||
inputProxy.wakeProxy(proxyAddressHTTP); | |||||
inputProxy.connectToProxy(); | |||||
inputProxy.getEventTypes().then(function (reply) { | |||||
initButtons(reply); | |||||
}).catch(function (err) { | |||||
console.error(err); | |||||
}); | |||||
inputProxy.getTimelineEvents().then(function (reply) { | |||||
console.log(reply); | |||||
}).catch(function (err) { | |||||
console.error(err); | |||||
}); | |||||
</script> | |||||
<link rel="stylesheet" href="./css/bootstrap.min.css"> | |||||
<style> | |||||
div.newEvent { | |||||
position: relative; | |||||
margin: 10px; | |||||
padding: 10px; | |||||
width: 300px; | |||||
border: 1px solid #dddddd; | |||||
border-radius: 5px; | |||||
height: 200px; | |||||
background-color: #ffffff; | |||||
} | |||||
div.timelineEvent { | |||||
position: relative; | |||||
margin: 10px; | |||||
padding: 10px; | |||||
width: 300px; | |||||
border: 1px solid #dddddd; | |||||
border-radius: 5px; | |||||
height: 140px; | |||||
background-color: #ffffff; | |||||
} | |||||
div.resetEvents { | |||||
margin: -210px 10px 10px 320px; | |||||
padding: 10px; | |||||
width: 160px; | |||||
border: 1px solid #dddddd; | |||||
border-radius: 5px; | |||||
height: 200px; | |||||
} | |||||
p.alabel { | |||||
display: inline-block; | |||||
width: 90px; | |||||
} | |||||
div.content { | |||||
margin: 10px; | |||||
} | |||||
button { | |||||
margin: 5px; | |||||
} | |||||
#buttonBunch { | |||||
} | |||||
h3 { | |||||
margin-left: 10px; | |||||
} | |||||
div.overlay { | |||||
position: absolute; | |||||
top: 0px; | |||||
left: 0px; | |||||
display: none; | |||||
width: 100%; | |||||
height: 100%; | |||||
background-color: rgba(0, 0, 0, 0.5); | |||||
z-index: 12; | |||||
} | |||||
html, body { | |||||
width: 100%; | |||||
height: 100%; | |||||
} | |||||
h1 { | |||||
color: #ffffff; | |||||
} | |||||
div.colors { | |||||
display: inline-block; | |||||
width: 30px; | |||||
height: 20px; | |||||
border: 0px solid #dddddd; | |||||
border-radius: 3px; | |||||
} | |||||
div.colors.red {background-color: #ff0000;} | |||||
div.colors.white {border-width:1px; background-color: #ffffff;} | |||||
div.colors.magenta {background-color: #ff21cb;} | |||||
div.colors.orange {background-color: #ffa42a;} | |||||
div.colors.green {background-color: #00ce34;} | |||||
button.red {background-color: #ff0000;} | |||||
button.white {color:#aaaaaa;border-width:1px; background-color: #ffffff;} | |||||
button.magenta {background-color: #ff21cb;} | |||||
button.orange {background-color: #ffa42a;} | |||||
button.green {background-color: #00ce34;} | |||||
div.colors.selected { | |||||
box-shadow: 0px 0px 5px #0bd1ff; | |||||
} | |||||
</style> | |||||
</head> | |||||
<body> | |||||
<div class="overlay" id="overlayNC"> | |||||
<h1>Connection has been lost. Please refresh the page.</h1> | |||||
</div> | |||||
<div class="overlay" id="overlay"> | |||||
<div class="timelineEvent" id="newTimelineEvent"> | |||||
<h4>When does the event start?</h4> | |||||
Start event: <select id="delaySelect"> | |||||
<option value="0">Now</option> | |||||
<option value="5">5 minutes</option> | |||||
<option value="15">15 minutes</option> | |||||
<option value="30">30 minutes</option> | |||||
<option value="45">45 minutes</option> | |||||
<option value="60">1 hour</option> | |||||
<option value="120">2 hours</option> | |||||
<option value="180">3 hours</option> | |||||
</select> | |||||
<br/> | |||||
<br/> | |||||
<button type="button" class="btn btn-danger pull-left" onclick="hideOverlay()"> | |||||
cancel | |||||
</button> | |||||
<button type="button" class="btn btn-primary pull-right" onclick="newTimelineEvent()"> | |||||
create Event | |||||
</button> | |||||
</div> | |||||
</div> | |||||
<div class="newEvent"> | |||||
<h4>create new event type:</h4> | |||||
<p class="alabel">Name:</p><input id="newEvent"><br/> | |||||
<p class="alabel">Color:</p> | |||||
<div class="colors red" onclick="selectColor('red','colorRed');" id="colorRed"></div> | |||||
<div class="colors white selected" onclick="selectColor('white','colorWhite');" id="colorWhite"></div> | |||||
<div class="colors green" onclick="selectColor('green','colorGreen');" id="colorGreen"></div> | |||||
<div class="colors orange" onclick="selectColor('orange','colorOrange');" id="colorOrange"></div> | |||||
<div class="colors magenta" onclick="selectColor('magenta','colorMagenta');" id="colorMagenta"></div> | |||||
<br/> | |||||
<!--<p class="alabel">range:</p><input type="checkbox" id="range"><br />--> | |||||
<button type="button" class="btn btn-primary pull-right" onclick="newEvent()"> | |||||
create | |||||
</button> | |||||
</div> | |||||
<div class="resetEvents"> | |||||
<button type="button" class="btn btn-danger" onclick="resetEvents()"> | |||||
Reset all events | |||||
</button> | |||||
<br/> | |||||
<br/> | |||||
<button type="button" class="btn btn-danger" onclick="resetTimelineData()"> | |||||
Remove data | |||||
</button> | |||||
</div> | |||||
<h3>cick one of the buttons to create a new event on the timeline</h3> | |||||
<div class='content' id="buttonBunch"> | |||||
</div> | |||||
</body> | |||||
</html> |
@ -0,0 +1,92 @@ | |||||
body { | |||||
background: #222; | |||||
font-family: "Fira Sans","Helvetica Neue",Helvetica,Arial,sans-serif; | |||||
font-size: 15pt; | |||||
line-height: 1.42857; | |||||
color: white; | |||||
} | |||||
/* timeline background */ | |||||
.vis.timeline.root { | |||||
border: none; | |||||
background: #3e647e url(../img/background-moche.png); /* blue2 */ | |||||
background: #e1953f url(../img/background-moche.png); /* orange */ | |||||
background: #422a6c url(../img/background-moche.png); /* purple */ | |||||
background: #3145B1 url(../img/background-moche.png); /* blue */ | |||||
} | |||||
/* grid styling */ | |||||
.vis.timeline .timeaxis .text { | |||||
color: white; | |||||
padding-top: 6px; | |||||
padding-left: 6px; | |||||
} | |||||
.vis.timeline .timeaxis .text.major { | |||||
font-weight: bold; | |||||
} | |||||
.vis.timeline .timeaxis .grid.minor { | |||||
border-width: 1px; | |||||
border-color: rgba(255,255,255, 0.2); | |||||
} | |||||
.vis.timeline .timeaxis .grid.major { | |||||
border-width: 1px; | |||||
border-color: rgba(255,255,255, 0.5); | |||||
} | |||||
/* default item class */ | |||||
.vis.timeline .item, | |||||
.vis.timeline .item.line { | |||||
border-width: 2px; | |||||
} | |||||
.vis.timeline .item.dot { | |||||
border-width: 6px; | |||||
border-radius: 6px; | |||||
} | |||||
.vis.timeline .item { | |||||
border-color: lightgray; | |||||
background-color: white; | |||||
color: #222; | |||||
} | |||||
.vis.timeline .item.selected { | |||||
border-color: lightgray; | |||||
background-color: white; | |||||
box-shadow: 0 0 16px rgba(255,255,255, 0.7); | |||||
} | |||||
/* custom item classes */ | |||||
.vis.timeline .item.green { | |||||
background-color: #6dd22f; | |||||
border-color: green; | |||||
color: white; | |||||
} | |||||
.vis.timeline .item.orange { | |||||
background-color: #ffdb07; | |||||
border-color: orange; | |||||
} | |||||
.vis.timeline .item.red { | |||||
background-color: #ce0000; | |||||
border-color: darkred; | |||||
color: white; | |||||
} | |||||
.vis.timeline .item.magenta { | |||||
background-color: #ff00ff; | |||||
border-color: darkmagenta; | |||||
color: white; | |||||
} |
@ -1,68 +1,84 @@ | |||||
<!DOCTYPE HTML> | |||||
<html> | <html> | ||||
<head> | <head> | ||||
<title>Timeline | Basic demo</title> | |||||
<title>Timeline | Bridge</title> | |||||
<style type="text/css"> | |||||
body, html { | |||||
font-family: sans-serif; | |||||
} | |||||
</style> | |||||
<script src="js/vis/vis.js"></script> | |||||
<script src="js/eve.js"></script> | |||||
<script src="js/timelineAgent.js"></script> | |||||
<link href="js/vis/vis.css" rel="stylesheet" type="text/css" /> | |||||
<link href="./css/timelineStyle.css" rel="stylesheet" type="text/css" /> | |||||
<script src="./js/vis.js"></script> | |||||
<link href="./css/vis.css" rel="stylesheet" type="text/css" /> | |||||
</head> | </head> | ||||
<body> | <body> | ||||
<span id="status">Loading data...</span> | |||||
<div id="visualization"></div> | |||||
<p>This page demonstrates the Timeline with custom css classes for individual items.</p> | |||||
<div id="mytimeline"></div> | |||||
<script type="text/javascript"> | <script type="text/javascript"> | ||||
var connected = false; | |||||
// create data | |||||
// note that months are zero-based in the JavaScript Date object | |||||
var data = new vis.DataSet(); | |||||
// called from agent | |||||
function addToDataset(item) { | |||||
console.log(item) | |||||
data.add(item); | |||||
} | |||||
// called from agent | |||||
function clearDataset() { | |||||
data.clear(); | |||||
} | |||||
function sessionClosed() { | |||||
if (connected === true) { | |||||
document.getElementById("overlayNC").style.display = 'block'; | |||||
} | |||||
} | |||||
// specify options | |||||
var options = { | |||||
editable: true | |||||
}; | |||||
// to run this, also have webHttp.js running in node. | |||||
eve.system.init({ | |||||
transports: [ | |||||
{ | |||||
type: 'ws', | |||||
url: 'ws://agents/:id' | |||||
}, | |||||
{ | |||||
type: 'http' | |||||
} | |||||
] | |||||
}); | |||||
var proxyAddress = 'ws://afternoon-beyond-2302.herokuapp.com/agents/proxy'; | |||||
var proxyAddressHTTP = 'https://afternoon-beyond-2302.herokuapp.com/agents/proxy'; | |||||
// proxyAddress = 'ws://127.0.0.1:5000/agents/proxy'; | |||||
// proxyAddressHTTP = 'http://127.0.0.1:5000/agents/proxy'; | |||||
timelineProxy = new timelineAgent('timelineAgent', proxyAddress); | |||||
timelineProxy.wakeProxy(proxyAddressHTTP); | |||||
timelineProxy.connectToProxy(); | |||||
timelineProxy.getTimelineEvents().then(function (reply) { | |||||
addToDataset(reply); | |||||
}).catch(function (err) { | |||||
console.error(err); | |||||
}); | |||||
function loadJSON(path, success, error) { | |||||
selectedFile = path; | |||||
var xhr = new XMLHttpRequest(); | |||||
xhr.onreadystatechange = function() { | |||||
if (xhr.readyState === 4) { | |||||
if (xhr.status === 200) { | |||||
success(JSON.parse(xhr.responseText), path); | |||||
} | |||||
else { | |||||
if (error === undefined) { | |||||
console.error("ERROR:", path) | |||||
} | |||||
else { | |||||
error(); | |||||
} | |||||
} | |||||
} | |||||
}; | |||||
xhr.open("GET", path, true); | |||||
xhr.send(); | |||||
} | |||||
function draw(data) { | |||||
document.getElementById("status").innerHTML = ""; | |||||
// Create a DataSet (allows two way data-binding) | |||||
var items = new vis.DataSet(data.data); | |||||
var groups = new vis.DataSet(data.groups); | |||||
// create visualization | |||||
var container = document.getElementById('visualization'); | |||||
var options = { | |||||
stack:false, | |||||
groupOrder: 'content' // groupOrder can be a property name or a sorting function | |||||
}; | |||||
var timeline = new vis.Timeline(container); | |||||
timeline.setOptions(options); | |||||
timeline.setGroups(groups); | |||||
timeline.setItems(items); | |||||
} | |||||
setTimeout(function () {loadJSON("./timeline.json",draw);}, 50); | |||||
// create the timeline | |||||
var container = document.getElementById('mytimeline'); | |||||
timeline = new vis.Timeline(container, data, options); | |||||
</script> | </script> | ||||
</body> | </body> | ||||
</html> | |||||
</html> |
@ -0,0 +1,106 @@ | |||||
/** | |||||
* Created by Alex on 3/5/2015. | |||||
*/ | |||||
var eventTypes = {}; | |||||
var buttonHammers = []; | |||||
var createType = undefined; | |||||
var connected = false; | |||||
var selectedColor = 'white'; | |||||
function initButtons(data) { | |||||
console.log(data) | |||||
eventTypes = data; | |||||
var keys = Object.keys(data); | |||||
for (var i = 0; i < keys.length; i++) { | |||||
createButton(keys[i]) | |||||
} | |||||
} | |||||
function selectColor(color,id) { | |||||
selectedColor = color; | |||||
var colors = ['colorRed','colorWhite','colorGreen','colorOrange','colorMagenta']; | |||||
for (var i = 0; i < colors.length; i++) { | |||||
var classname = document.getElementById(colors[i]).className.replace("selected",""); | |||||
document.getElementById(colors[i]).className = classname; | |||||
} | |||||
document.getElementById(id).className = document.getElementById(id).className += " selected"; | |||||
} | |||||
function createButton(name) { | |||||
var container = document.getElementById("buttonBunch"); | |||||
var button = document.createElement("button"); | |||||
button.type = "button"; | |||||
button.className = "btn btn-primary " + eventTypes[name].class; | |||||
button.innerHTML = name; | |||||
container.appendChild(button); | |||||
var hammer = Hammer(button, {prevent_default: true}); | |||||
hammer.on('tap', showOverlay.bind(this,name)); | |||||
buttonHammers.push(hammer); | |||||
} | |||||
function showOverlay(name,event) { | |||||
createType = name; | |||||
document.getElementById("overlay").style.display = 'block'; | |||||
var optionsWindow = document.getElementById("newTimelineEvent"); | |||||
optionsWindow.style.top = event.pointers[0].pageY -100 + 'px'; | |||||
optionsWindow.style.left = event.pointers[0].pageX + 10 + 'px'; | |||||
} | |||||
function newTimelineEvent() { | |||||
var minutesDelay = document.getElementById("delaySelect").value; | |||||
var date = new Date().valueOf() + 60 * minutesDelay * 1000; | |||||
var item = {content: createType, className:eventTypes[createType].class, start:date}; | |||||
inputProxy.addTimelineEvent(item); | |||||
hideOverlay(); | |||||
} | |||||
function sessionClosed() { | |||||
if (connected === true) { | |||||
document.getElementById("overlayNC").style.display = 'block'; | |||||
} | |||||
} | |||||
function hideOverlay() { | |||||
document.getElementById("overlay").style.display = 'none'; | |||||
} | |||||
function newEvent() { | |||||
var name = document.getElementById('newEvent').value; | |||||
var range = false;//document.getElementById('range').checked; | |||||
if (name !== "") { | |||||
var data = {name: name, class: selectedColor, range: range}; | |||||
eventTypes[name] = data; | |||||
createButton(name); | |||||
inputProxy.addEventType(data); | |||||
} | |||||
else { | |||||
alert("Name is required"); | |||||
} | |||||
document.getElementById('newEvent').value = ""; | |||||
//document.getElementById('range').checked = false; | |||||
} | |||||
function resetEvents() { | |||||
var r = confirm("Really delete all event types? (buttons below)"); | |||||
if (r == true) { | |||||
inputProxy.resetEventTypes(); | |||||
document.getElementById("buttonBunch").innerHTML = ""; | |||||
} | |||||
for (var i = 0; i < buttonHammers.length; i++) { | |||||
buttonHammers[i].dispose(); | |||||
} | |||||
buttonHammers = []; | |||||
} | |||||
function resetTimelineData() { | |||||
var r = confirm("Really delete all data on the timeline?"); | |||||
if (r == true) { | |||||
inputProxy.resetTimelineEvents(); | |||||
} | |||||
} |
@ -0,0 +1,77 @@ | |||||
function inputAgent(id, proxyAddress) { | |||||
// execute super constructor | |||||
eve.Agent.call(this, id); | |||||
this.proxyAddress = proxyAddress; | |||||
this.eventTypes = {}; | |||||
this.timelineEvents = []; | |||||
this.timelineClient = undefined; | |||||
this.inputClient = undefined; | |||||
// extend the agent with RPC functionality | |||||
this.rpc = this.loadModule('rpc', this.rpcFunctions, {timeout:2000}); // option 1 | |||||
// connect to all transports provided by the system | |||||
this.connect(eve.system.transports.getAll()); | |||||
} | |||||
// extend the eve.Agent prototype | |||||
inputAgent.prototype = Object.create(eve.Agent.prototype); | |||||
inputAgent.prototype.constructor = inputAgent; | |||||
inputAgent.prototype.rpcFunctions = {}; | |||||
inputAgent.prototype.rpcFunctions.close = function() { | |||||
sessionClosed(); | |||||
}; | |||||
inputAgent.prototype.connectToProxy = function() { | |||||
this.rpc.request(this.proxyAddress, {method:'setInputClient',params:{}}).done(function () { | |||||
connected = true; | |||||
}); | |||||
}; | |||||
inputAgent.prototype.addEventType = function(data) { | |||||
this.rpc.request(this.proxyAddress, {method:'addEventType',params:data}).done(); | |||||
}; | |||||
inputAgent.prototype.addTimelineEvent = function(item) { | |||||
this.rpc.request(this.proxyAddress, {method:'addTimelineEvent',params:{item:item}}).done(); | |||||
}; | |||||
inputAgent.prototype.wakeProxy = function(httpAddress) { | |||||
this.rpc.request(httpAddress, {method:'wakeUp',params:{}}).done(); | |||||
}; | |||||
inputAgent.prototype.resetEventTypes = function(data) { | |||||
this.rpc.request(this.proxyAddress, {method:'resetEventTypes',params:data}).done(); | |||||
}; | |||||
inputAgent.prototype.resetTimelineEvents = function(data) { | |||||
this.rpc.request(this.proxyAddress, {method:'resetTimelineEvents',params:data}).done(); | |||||
}; | |||||
inputAgent.prototype.getEventTypes = function (params, sender) { | |||||
var me = this; | |||||
return new Promise(function(resolve,reject) { | |||||
me.rpc.request(me.proxyAddress, {method: 'getEventTypes', params: {}}) | |||||
.then(function (reply) { | |||||
resolve(reply); | |||||
}) | |||||
.catch(function(err) {reject(err);}); | |||||
}) | |||||
}; | |||||
inputAgent.prototype.getTimelineEvents = function (params, sender) { | |||||
var me = this; | |||||
return new Promise(function(resolve,reject) { | |||||
me.rpc.request(me.proxyAddress, {method: 'getTimelineEvents', params: {}}) | |||||
.then(function (reply) { | |||||
resolve(reply); | |||||
}) | |||||
.catch(function(err) {reject(err);}); | |||||
}) | |||||
}; |
@ -0,0 +1,61 @@ | |||||
function timelineAgent(id, proxyAddress) { | |||||
// execute super constructor | |||||
eve.Agent.call(this, id); | |||||
this.proxyAddress = proxyAddress; | |||||
this.eventTypes = {}; | |||||
this.timelineEvents = []; | |||||
this.timelineClient = undefined; | |||||
this.inputClient = undefined; | |||||
// extend the agent with RPC functionality | |||||
this.rpc = this.loadModule('rpc', this.rpcFunctions, {timeout:2000}); // option 1 | |||||
// connect to all transports provided by the system | |||||
this.connect(eve.system.transports.getAll()); | |||||
} | |||||
// extend the eve.Agent prototype | |||||
timelineAgent.prototype = Object.create(eve.Agent.prototype); | |||||
timelineAgent.prototype.constructor = timelineAgent; | |||||
timelineAgent.prototype.rpcFunctions = {}; | |||||
timelineAgent.prototype.rpcFunctions.close = function() { | |||||
sessionClosed(); | |||||
}; | |||||
timelineAgent.prototype.connectToProxy = function() { | |||||
this.rpc.request(this.proxyAddress, {method:'setTimelineClient',params:{}}).done(function () { | |||||
connected = true; | |||||
}); | |||||
}; | |||||
timelineAgent.prototype.rpcFunctions.addTimelineEvent = function(params,sender) { | |||||
addToDataset(params); | |||||
}; | |||||
timelineAgent.prototype.rpcFunctions.resetTimelineEvents = function(params,sender) { | |||||
clearDataset(); | |||||
}; | |||||
timelineAgent.prototype.wakeProxy = function(httpAddress) { | |||||
this.rpc.request(httpAddress, {method:'wakeUp',params:{}}).done(); | |||||
}; | |||||
timelineAgent.prototype.getTimelineEvents = function (params, sender) { | |||||
var me = this; | |||||
return new Promise(function(resolve,reject) { | |||||
me.rpc.request(me.proxyAddress, {method: 'getTimelineEvents', params: {}}) | |||||
.then(function (reply) { | |||||
resolve(reply); | |||||
}) | |||||
.catch(function(err) {reject(err);}); | |||||
}) | |||||
}; |
@ -0,0 +1,810 @@ | |||||
.vis .overlay { | |||||
position: absolute; | |||||
top: 0; | |||||
left: 0; | |||||
width: 100%; | |||||
height: 100%; | |||||
/* Must be displayed above for example selected Timeline items */ | |||||
z-index: 10; | |||||
} | |||||
.vis-active { | |||||
box-shadow: 0 0 10px #86d5f8; | |||||
} | |||||
/* override some bootstrap styles screwing up the timelines css */ | |||||
.vis [class*="span"] { | |||||
min-height: 0; | |||||
width: auto; | |||||
} | |||||
.vis.timeline { | |||||
} | |||||
.vis.timeline.root { | |||||
position: relative; | |||||
border: 1px solid #bfbfbf; | |||||
overflow: hidden; | |||||
padding: 0; | |||||
margin: 0; | |||||
box-sizing: border-box; | |||||
} | |||||
.vis.timeline .vispanel { | |||||
position: absolute; | |||||
padding: 0; | |||||
margin: 0; | |||||
box-sizing: border-box; | |||||
} | |||||
.vis.timeline .vispanel.center, | |||||
.vis.timeline .vispanel.left, | |||||
.vis.timeline .vispanel.right, | |||||
.vis.timeline .vispanel.top, | |||||
.vis.timeline .vispanel.bottom { | |||||
border: 1px #bfbfbf; | |||||
} | |||||
.vis.timeline .vispanel.center, | |||||
.vis.timeline .vispanel.left, | |||||
.vis.timeline .vispanel.right { | |||||
border-top-style: solid; | |||||
border-bottom-style: solid; | |||||
overflow: hidden; | |||||
} | |||||
.vis.timeline .vispanel.center, | |||||
.vis.timeline .vispanel.top, | |||||
.vis.timeline .vispanel.bottom { | |||||
border-left-style: solid; | |||||
border-right-style: solid; | |||||
} | |||||
.vis.timeline .background { | |||||
overflow: hidden; | |||||
} | |||||
.vis.timeline .vispanel > .content { | |||||
position: relative; | |||||
} | |||||
.vis.timeline .vispanel .shadow { | |||||
position: absolute; | |||||
width: 100%; | |||||
height: 1px; | |||||
box-shadow: 0 0 10px rgba(0,0,0,0.8); | |||||
/* TODO: find a nice way to ensure shadows are drawn on top of items | |||||
z-index: 1; | |||||
*/ | |||||
} | |||||
.vis.timeline .vispanel .shadow.top { | |||||
top: -1px; | |||||
left: 0; | |||||
} | |||||
.vis.timeline .vispanel .shadow.bottom { | |||||
bottom: -1px; | |||||
left: 0; | |||||
} | |||||
.vis.timeline .labelset { | |||||
position: relative; | |||||
overflow: hidden; | |||||
box-sizing: border-box; | |||||
} | |||||
.vis.timeline .labelset .vlabel { | |||||
position: relative; | |||||
left: 0; | |||||
top: 0; | |||||
width: 100%; | |||||
color: #4d4d4d; | |||||
box-sizing: border-box; | |||||
} | |||||
.vis.timeline .labelset .vlabel { | |||||
border-bottom: 1px solid #bfbfbf; | |||||
} | |||||
.vis.timeline .labelset .vlabel:last-child { | |||||
border-bottom: none; | |||||
} | |||||
.vis.timeline .labelset .vlabel .inner { | |||||
display: inline-block; | |||||
padding: 5px; | |||||
} | |||||
.vis.timeline .labelset .vlabel .inner.hidden { | |||||
padding: 0; | |||||
} | |||||
.vis.timeline .itemset { | |||||
position: relative; | |||||
padding: 0; | |||||
margin: 0; | |||||
box-sizing: border-box; | |||||
} | |||||
.vis.timeline .itemset .background, | |||||
.vis.timeline .itemset .foreground { | |||||
position: absolute; | |||||
width: 100%; | |||||
height: 100%; | |||||
overflow: visible; | |||||
} | |||||
.vis.timeline .axis { | |||||
position: absolute; | |||||
width: 100%; | |||||
height: 0; | |||||
left: 0; | |||||
z-index: 1; | |||||
} | |||||
.vis.timeline .foreground .group { | |||||
position: relative; | |||||
box-sizing: border-box; | |||||
border-bottom: 1px solid #bfbfbf; | |||||
} | |||||
.vis.timeline .foreground .group:last-child { | |||||
border-bottom: none; | |||||
} | |||||
.vis.timeline .item { | |||||
position: absolute; | |||||
color: #1A1A1A; | |||||
border-color: #97B0F8; | |||||
border-width: 1px; | |||||
background-color: #D5DDF6; | |||||
display: inline-block; | |||||
padding: 5px; | |||||
} | |||||
.vis.timeline .item.selected { | |||||
border-color: #FFC200; | |||||
background-color: #FFF785; | |||||
/* z-index must be higher than the z-index of custom time bar and current time bar */ | |||||
z-index: 2; | |||||
} | |||||
.vis.timeline .editable .item.selected { | |||||
cursor: move; | |||||
} | |||||
.vis.timeline .item.point.selected { | |||||
background-color: #FFF785; | |||||
} | |||||
.vis.timeline .item.box { | |||||
text-align: center; | |||||
border-style: solid; | |||||
border-radius: 2px; | |||||
} | |||||
.vis.timeline .item.point { | |||||
background: none; | |||||
} | |||||
.vis.timeline .item.dot { | |||||
position: absolute; | |||||
padding: 0; | |||||
border-width: 4px; | |||||
border-style: solid; | |||||
border-radius: 4px; | |||||
} | |||||
.vis.timeline .item.range { | |||||
border-style: solid; | |||||
border-radius: 2px; | |||||
box-sizing: border-box; | |||||
} | |||||
.vis.timeline .item.background { | |||||
overflow: hidden; | |||||
border: none; | |||||
background-color: rgba(213, 221, 246, 0.4); | |||||
box-sizing: border-box; | |||||
padding: 0; | |||||
margin: 0; | |||||
} | |||||
.vis.timeline .item.range .content { | |||||
position: relative; | |||||
display: inline-block; | |||||
max-width: 100%; | |||||
overflow: hidden; | |||||
} | |||||
.vis.timeline .item.background .content { | |||||
position: absolute; | |||||
display: inline-block; | |||||
overflow: hidden; | |||||
max-width: 100%; | |||||
margin: 5px; | |||||
} | |||||
.vis.timeline .item.line { | |||||
padding: 0; | |||||
position: absolute; | |||||
width: 0; | |||||
border-left-width: 1px; | |||||
border-left-style: solid; | |||||
} | |||||
.vis.timeline .item .content { | |||||
white-space: nowrap; | |||||
overflow: hidden; | |||||
} | |||||
.vis.timeline .item .delete { | |||||
background: url('img/timeline/delete.png') no-repeat top center; | |||||
position: absolute; | |||||
width: 24px; | |||||
height: 24px; | |||||
top: 0; | |||||
right: -24px; | |||||
cursor: pointer; | |||||
} | |||||
.vis.timeline .item.range .drag-left { | |||||
position: absolute; | |||||
width: 24px; | |||||
max-width: 20%; | |||||
height: 100%; | |||||
top: 0; | |||||
left: -4px; | |||||
cursor: w-resize; | |||||
} | |||||
.vis.timeline .item.range .drag-right { | |||||
position: absolute; | |||||
width: 24px; | |||||
max-width: 20%; | |||||
height: 100%; | |||||
top: 0; | |||||
right: -4px; | |||||
cursor: e-resize; | |||||
} | |||||
.vis.timeline .timeaxis { | |||||
position: relative; | |||||
overflow: hidden; | |||||
} | |||||
.vis.timeline .timeaxis.foreground { | |||||
top: 0; | |||||
left: 0; | |||||
width: 100%; | |||||
} | |||||
.vis.timeline .timeaxis.background { | |||||
position: absolute; | |||||
top: 0; | |||||
left: 0; | |||||
width: 100%; | |||||
height: 100%; | |||||
} | |||||
.vis.timeline .timeaxis .text { | |||||
position: absolute; | |||||
color: #4d4d4d; | |||||
padding: 3px; | |||||
white-space: nowrap; | |||||
} | |||||
.vis.timeline .timeaxis .text.measure { | |||||
position: absolute; | |||||
padding-left: 0; | |||||
padding-right: 0; | |||||
margin-left: 0; | |||||
margin-right: 0; | |||||
visibility: hidden; | |||||
} | |||||
.vis.timeline .timeaxis .grid.vertical { | |||||
position: absolute; | |||||
border-left: 1px solid; | |||||
} | |||||
.vis.timeline .timeaxis .grid.minor { | |||||
border-color: #e5e5e5; | |||||
} | |||||
.vis.timeline .timeaxis .grid.major { | |||||
border-color: #bfbfbf; | |||||
} | |||||
.vis.timeline .currenttime { | |||||
background-color: #FF7F6E; | |||||
width: 2px; | |||||
z-index: 1; | |||||
} | |||||
.vis.timeline .customtime { | |||||
background-color: #6E94FF; | |||||
width: 2px; | |||||
cursor: move; | |||||
z-index: 1; | |||||
} | |||||
.vis.timeline.root { | |||||
/* | |||||
-webkit-transition: height .4s ease-in-out; | |||||
transition: height .4s ease-in-out; | |||||
*/ | |||||
} | |||||
.vis.timeline .vispanel { | |||||
/* | |||||
-webkit-transition: height .4s ease-in-out, top .4s ease-in-out; | |||||
transition: height .4s ease-in-out, top .4s ease-in-out; | |||||
*/ | |||||
} | |||||
.vis.timeline .axis { | |||||
/* | |||||
-webkit-transition: top .4s ease-in-out; | |||||
transition: top .4s ease-in-out; | |||||
*/ | |||||
} | |||||
/* TODO: get animation working nicely | |||||
.vis.timeline .item { | |||||
-webkit-transition: top .4s ease-in-out; | |||||
transition: top .4s ease-in-out; | |||||
} | |||||
.vis.timeline .item.line { | |||||
-webkit-transition: height .4s ease-in-out, top .4s ease-in-out; | |||||
transition: height .4s ease-in-out, top .4s ease-in-out; | |||||
} | |||||
/**/ | |||||
.vis.timeline .vispanel.background.horizontal .grid.horizontal { | |||||
position: absolute; | |||||
width: 100%; | |||||
height: 0; | |||||
border-bottom: 1px solid; | |||||
} | |||||
.vis.timeline .vispanel.background.horizontal .grid.minor { | |||||
border-color: #e5e5e5; | |||||
} | |||||
.vis.timeline .vispanel.background.horizontal .grid.major { | |||||
border-color: #bfbfbf; | |||||
} | |||||
.vis.timeline .dataaxis .yAxis.major { | |||||
width: 100%; | |||||
position: absolute; | |||||
color: #4d4d4d; | |||||
white-space: nowrap; | |||||
} | |||||
.vis.timeline .dataaxis .yAxis.major.measure{ | |||||
padding: 0px 0px 0px 0px; | |||||
margin: 0px 0px 0px 0px; | |||||
border: 0px; | |||||
visibility: hidden; | |||||
width: auto; | |||||
} | |||||
.vis.timeline .dataaxis .yAxis.minor{ | |||||
position: absolute; | |||||
width: 100%; | |||||
color: #bebebe; | |||||
white-space: nowrap; | |||||
} | |||||
.vis.timeline .dataaxis .yAxis.minor.measure{ | |||||
padding: 0px 0px 0px 0px; | |||||
margin: 0px 0px 0px 0px; | |||||
border: 0px; | |||||
visibility: hidden; | |||||
width: auto; | |||||
} | |||||
.vis.timeline .dataaxis .yAxis.title{ | |||||
position: absolute; | |||||
color: #4d4d4d; | |||||
white-space: nowrap; | |||||
bottom: 20px; | |||||
text-align: center; | |||||
} | |||||
.vis.timeline .dataaxis .yAxis.title.measure{ | |||||
padding: 0px 0px 0px 0px; | |||||
margin: 0px 0px 0px 0px; | |||||
visibility: hidden; | |||||
width: auto; | |||||
} | |||||
.vis.timeline .dataaxis .yAxis.title.left { | |||||
bottom: 0px; | |||||
-webkit-transform-origin: left top; | |||||
-moz-transform-origin: left top; | |||||
-ms-transform-origin: left top; | |||||
-o-transform-origin: left top; | |||||
transform-origin: left bottom; | |||||
-webkit-transform: rotate(-90deg); | |||||
-moz-transform: rotate(-90deg); | |||||
-ms-transform: rotate(-90deg); | |||||
-o-transform: rotate(-90deg); | |||||
transform: rotate(-90deg); | |||||
} | |||||
.vis.timeline .dataaxis .yAxis.title.right { | |||||
bottom: 0px; | |||||
-webkit-transform-origin: right bottom; | |||||
-moz-transform-origin: right bottom; | |||||
-ms-transform-origin: right bottom; | |||||
-o-transform-origin: right bottom; | |||||
transform-origin: right bottom; | |||||
-webkit-transform: rotate(90deg); | |||||
-moz-transform: rotate(90deg); | |||||
-ms-transform: rotate(90deg); | |||||
-o-transform: rotate(90deg); | |||||
transform: rotate(90deg); | |||||
} | |||||
.vis.timeline .legend { | |||||
background-color: rgba(247, 252, 255, 0.65); | |||||
padding: 5px; | |||||
border-color: #b3b3b3; | |||||
border-style:solid; | |||||
border-width: 1px; | |||||
box-shadow: 2px 2px 10px rgba(154, 154, 154, 0.55); | |||||
} | |||||
.vis.timeline .legendText { | |||||
/*font-size: 10px;*/ | |||||
white-space: nowrap; | |||||
display: inline-block | |||||
} | |||||
.vis.timeline .graphGroup0 { | |||||
fill:#4f81bd; | |||||
fill-opacity:0; | |||||
stroke-width:2px; | |||||
stroke: #4f81bd; | |||||
} | |||||
.vis.timeline .graphGroup1 { | |||||
fill:#f79646; | |||||
fill-opacity:0; | |||||
stroke-width:2px; | |||||
stroke: #f79646; | |||||
} | |||||
.vis.timeline .graphGroup2 { | |||||
fill: #8c51cf; | |||||
fill-opacity:0; | |||||
stroke-width:2px; | |||||
stroke: #8c51cf; | |||||
} | |||||
.vis.timeline .graphGroup3 { | |||||
fill: #75c841; | |||||
fill-opacity:0; | |||||
stroke-width:2px; | |||||
stroke: #75c841; | |||||
} | |||||
.vis.timeline .graphGroup4 { | |||||
fill: #ff0100; | |||||
fill-opacity:0; | |||||
stroke-width:2px; | |||||
stroke: #ff0100; | |||||
} | |||||
.vis.timeline .graphGroup5 { | |||||
fill: #37d8e6; | |||||
fill-opacity:0; | |||||
stroke-width:2px; | |||||
stroke: #37d8e6; | |||||
} | |||||
.vis.timeline .graphGroup6 { | |||||
fill: #042662; | |||||
fill-opacity:0; | |||||
stroke-width:2px; | |||||
stroke: #042662; | |||||
} | |||||
.vis.timeline .graphGroup7 { | |||||
fill:#00ff26; | |||||
fill-opacity:0; | |||||
stroke-width:2px; | |||||
stroke: #00ff26; | |||||
} | |||||
.vis.timeline .graphGroup8 { | |||||
fill:#ff00ff; | |||||
fill-opacity:0; | |||||
stroke-width:2px; | |||||
stroke: #ff00ff; | |||||
} | |||||
.vis.timeline .graphGroup9 { | |||||
fill: #8f3938; | |||||
fill-opacity:0; | |||||
stroke-width:2px; | |||||
stroke: #8f3938; | |||||
} | |||||
.vis.timeline .fill { | |||||
fill-opacity:0.1; | |||||
stroke: none; | |||||
} | |||||
.vis.timeline .bar { | |||||
fill-opacity:0.5; | |||||
stroke-width:1px; | |||||
} | |||||
.vis.timeline .point { | |||||
stroke-width:2px; | |||||
fill-opacity:1.0; | |||||
} | |||||
.vis.timeline .legendBackground { | |||||
stroke-width:1px; | |||||
fill-opacity:0.9; | |||||
fill: #ffffff; | |||||
stroke: #c2c2c2; | |||||
} | |||||
.vis.timeline .outline { | |||||
stroke-width:1px; | |||||
fill-opacity:1; | |||||
fill: #ffffff; | |||||
stroke: #e5e5e5; | |||||
} | |||||
.vis.timeline .iconFill { | |||||
fill-opacity:0.3; | |||||
stroke: none; | |||||
} | |||||
div.network-manipulationDiv { | |||||
border-width: 0; | |||||
border-bottom: 1px; | |||||
border-style:solid; | |||||
border-color: #d6d9d8; | |||||
background: #ffffff; /* Old browsers */ | |||||
background: -moz-linear-gradient(top, #ffffff 0%, #fcfcfc 48%, #fafafa 50%, #fcfcfc 100%); /* FF3.6+ */ | |||||
background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#ffffff), color-stop(48%,#fcfcfc), color-stop(50%,#fafafa), color-stop(100%,#fcfcfc)); /* Chrome,Safari4+ */ | |||||
background: -webkit-linear-gradient(top, #ffffff 0%,#fcfcfc 48%,#fafafa 50%,#fcfcfc 100%); /* Chrome10+,Safari5.1+ */ | |||||
background: -o-linear-gradient(top, #ffffff 0%,#fcfcfc 48%,#fafafa 50%,#fcfcfc 100%); /* Opera 11.10+ */ | |||||
background: -ms-linear-gradient(top, #ffffff 0%,#fcfcfc 48%,#fafafa 50%,#fcfcfc 100%); /* IE10+ */ | |||||
background: linear-gradient(to bottom, #ffffff 0%,#fcfcfc 48%,#fafafa 50%,#fcfcfc 100%); /* W3C */ | |||||
filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#ffffff', endColorstr='#fcfcfc',GradientType=0 ); /* IE6-9 */ | |||||
position: absolute; | |||||
left: 0; | |||||
top: 0; | |||||
width: 100%; | |||||
height: 30px; | |||||
} | |||||
div.network-manipulation-editMode { | |||||
position:absolute; | |||||
left: 0; | |||||
top: 15px; | |||||
height: 30px; | |||||
} | |||||
div.network-manipulation-closeDiv { | |||||
position:absolute; | |||||
right: 0; | |||||
top: 0; | |||||
width: 30px; | |||||
height: 30px; | |||||
background-position: 20px 3px; | |||||
background-repeat: no-repeat; | |||||
background-image: url("img/network/cross.png"); | |||||
cursor: pointer; | |||||
-webkit-touch-callout: none; | |||||
-webkit-user-select: none; | |||||
-khtml-user-select: none; | |||||
-moz-user-select: none; | |||||
-ms-user-select: none; | |||||
user-select: none; | |||||
} | |||||
div.network-manipulation-closeDiv:hover { | |||||
opacity: 0.6; | |||||
} | |||||
div.network-manipulationUI { | |||||
position:relative; | |||||
top:-7px; | |||||
font-family: verdana; | |||||
font-size: 12px; | |||||
-moz-border-radius: 15px; | |||||
border-radius: 15px; | |||||
display:inline-block; | |||||
background-position: 0px 0px; | |||||
background-repeat:no-repeat; | |||||
height:24px; | |||||
margin: 0px 0px 0px 10px; | |||||
vertical-align:middle; | |||||
cursor: pointer; | |||||
padding: 0px 8px 0px 8px; | |||||
-webkit-touch-callout: none; | |||||
-webkit-user-select: none; | |||||
-khtml-user-select: none; | |||||
-moz-user-select: none; | |||||
-ms-user-select: none; | |||||
user-select: none; | |||||
} | |||||
div.network-manipulationUI:hover { | |||||
box-shadow: 1px 1px 8px rgba(0, 0, 0, 0.20); | |||||
} | |||||
div.network-manipulationUI:active { | |||||
box-shadow: 1px 1px 8px rgba(0, 0, 0, 0.50); | |||||
} | |||||
div.network-manipulationUI.back { | |||||
background-image: url("img/network/backIcon.png"); | |||||
} | |||||
div.network-manipulationUI.none:hover { | |||||
box-shadow: 1px 1px 8px rgba(0, 0, 0, 0.0); | |||||
cursor: default; | |||||
} | |||||
div.network-manipulationUI.none:active { | |||||
box-shadow: 1px 1px 8px rgba(0, 0, 0, 0.0); | |||||
} | |||||
div.network-manipulationUI.none { | |||||
padding: 0; | |||||
} | |||||
div.network-manipulationUI.notification{ | |||||
margin: 2px; | |||||
font-weight: bold; | |||||
} | |||||
div.network-manipulationUI.add { | |||||
background-image: url("img/network/addNodeIcon.png"); | |||||
} | |||||
div.network-manipulationUI.edit { | |||||
background-image: url("img/network/editIcon.png"); | |||||
} | |||||
div.network-manipulationUI.edit.editmode { | |||||
background-color: #fcfcfc; | |||||
border-style:solid; | |||||
border-width:1px; | |||||
border-color: #cccccc; | |||||
} | |||||
div.network-manipulationUI.connect { | |||||
background-image: url("img/network/connectIcon.png"); | |||||
} | |||||
div.network-manipulationUI.delete { | |||||
background-image: url("img/network/deleteIcon.png"); | |||||
} | |||||
/* top right bottom left */ | |||||
div.network-manipulationLabel { | |||||
margin: 0px 0px 0px 23px; | |||||
line-height: 25px; | |||||
} | |||||
div.network-seperatorLine { | |||||
display:inline-block; | |||||
width:1px; | |||||
height:20px; | |||||
background-color: #bdbdbd; | |||||
margin: 5px 7px 0px 15px; | |||||
} | |||||
div.network-navigation_wrapper { | |||||
position: absolute; | |||||
left: 0; | |||||
top: 0; | |||||
width: 100%; | |||||
height: 100%; | |||||
} | |||||
div.network-navigation { | |||||
width:34px; | |||||
height:34px; | |||||
-moz-border-radius: 17px; | |||||
border-radius: 17px; | |||||
position:absolute; | |||||
display:inline-block; | |||||
background-position: 2px 2px; | |||||
background-repeat:no-repeat; | |||||
cursor: pointer; | |||||
-webkit-touch-callout: none; | |||||
-webkit-user-select: none; | |||||
-khtml-user-select: none; | |||||
-moz-user-select: none; | |||||
-ms-user-select: none; | |||||
user-select: none; | |||||
} | |||||
div.network-navigation:hover { | |||||
box-shadow: 0px 0px 3px 3px rgba(56, 207, 21, 0.30); | |||||
} | |||||
div.network-navigation:active { | |||||
box-shadow: 0px 0px 1px 3px rgba(56, 207, 21, 0.95); | |||||
} | |||||
div.network-navigation.up { | |||||
background-image: url("img/network/upArrow.png"); | |||||
bottom:50px; | |||||
left:55px; | |||||
} | |||||
div.network-navigation.down { | |||||
background-image: url("img/network/downArrow.png"); | |||||
bottom:10px; | |||||
left:55px; | |||||
} | |||||
div.network-navigation.left { | |||||
background-image: url("img/network/leftArrow.png"); | |||||
bottom:10px; | |||||
left:15px; | |||||
} | |||||
div.network-navigation.right { | |||||
background-image: url("img/network/rightArrow.png"); | |||||
bottom:10px; | |||||
left:95px; | |||||
} | |||||
div.network-navigation.zoomIn { | |||||
background-image: url("img/network/plus.png"); | |||||
bottom:10px; | |||||
right:15px; | |||||
} | |||||
div.network-navigation.zoomOut { | |||||
background-image: url("img/network/minus.png"); | |||||
bottom:10px; | |||||
right:55px; | |||||
} | |||||
div.network-navigation.zoomExtends { | |||||
background-image: url("img/network/zoomExtends.png"); | |||||
bottom:50px; | |||||
right:15px; | |||||
} | |||||
div.network-tooltip { | |||||
position: absolute; | |||||
visibility: hidden; | |||||
padding: 5px; | |||||
white-space: nowrap; | |||||
-moz-border-radius: 3px; | |||||
-webkit-border-radius: 3px; | |||||
border-radius: 3px; | |||||
border: 1px solid; | |||||
box-shadow: 3px 3px 10px rgba(128, 128, 128, 0.5); | |||||
} |
@ -1,53 +0,0 @@ | |||||
/** | |||||
* Created by Alex on 2/2/2015. | |||||
*/ | |||||
fs = require('fs') | |||||
function writeToFile(data, outputFilename, callback) { | |||||
fs.writeFile(outputFilename, JSON.stringify(data), function (err) { | |||||
if (err) { | |||||
console.log(err); | |||||
} else { | |||||
console.log("JSON saved to " + outputFilename); | |||||
callback(); | |||||
//getNewAssignment(); | |||||
} | |||||
}); | |||||
} | |||||
function parse(data, callback) { | |||||
var objects = Object.keys(data.things); | |||||
var timelineData = []; | |||||
var groups = []; | |||||
var groupsObj = {}; | |||||
for (var i = 0; i < objects.length; i++) { | |||||
var thing = data.things[objects[i]]; | |||||
if (thing.properties.description && thing.properties.date) { | |||||
timelineData.push({ | |||||
id:i, | |||||
content: thing.type, | |||||
start: new Date(thing.properties.date.value).valueOf(), | |||||
group: thing.type | |||||
}); | |||||
if (groupsObj[thing.type] === undefined) { | |||||
groupsObj[thing.type] = true; | |||||
groups.push({id:thing.type, content:thing.type}); | |||||
} | |||||
} | |||||
} | |||||
console.log("amont of data", timelineData.length, "amount of groups:", groups.length) | |||||
var dataToWrite = {data: timelineData, groups:groups}; | |||||
writeToFile(dataToWrite, "timeline.json", function(){}); | |||||
} | |||||
fs.readFile('./data.json', 'utf8', function (err, data) { | |||||
if (err) { | |||||
return console.log(err); | |||||
} | |||||
parse(JSON.parse(data)); | |||||
}); | |||||