Browse Source

GroupSet now neatly handling chances in groups data

css_transitions
josdejong 11 years ago
parent
commit
dd8aa76b6c
10 changed files with 238 additions and 168 deletions
  1. +1
    -1
      examples/timeline/05_groups.html
  2. +0
    -1
      src/component/css/groupset.css
  3. +6
    -9
      src/component/css/itemset.css
  4. +87
    -56
      src/component/groupset.js
  5. +5
    -10
      src/component/item/itembox.js
  6. +5
    -4
      src/component/itemset.js
  7. +3
    -2
      src/util.js
  8. +13
    -4
      src/visualization/timeline.js
  9. +114
    -77
      vis.js
  10. +4
    -4
      vis.min.js

+ 1
- 1
examples/timeline/05_groups.html View File

@ -46,7 +46,7 @@
var container = document.getElementById('visualization');
var options = {
start: now.clone().add('days', -3),
end: now.clone().add('days', 7),
end: now.clone().add('days', 7)
//height: '100%'
};

+ 0
- 1
src/component/css/groupset.css View File

@ -3,5 +3,4 @@
position: absolute;
padding: 0;
margin: 0;
overflow: hidden;
}

+ 6
- 9
src/component/css/itemset.css View File

@ -6,13 +6,6 @@
overflow: hidden;
}
.graph .groupset .itemset {
position: relative;
padding: 0;
margin: 0;
overflow: hidden;
}
.graph .background {
}
@ -24,5 +17,9 @@
}
.graph .groupset .itemset-axis {
position: relative;
}
border-top: 1px solid #bfbfbf;
}
.graph .groupset .itemset-axis:last-child {
border-top: none;
}

+ 87
- 56
src/component/groupset.js View File

@ -19,9 +19,9 @@ function GroupSet(parent, depends, options) {
this.items = null; // dataset with items
this.groups = null; // dataset with groups
this.contents = {}; // object with an ItemSet for every group
this.contents = []; // array with groups
// changes in groups are queued
// changes in groups are queued key/value map containing id/action
this.queue = {};
var me = this;
@ -53,6 +53,11 @@ GroupSet.prototype.setOptions = function setOptions(options) {
util.extend(this.options, options);
// TODO: implement options
var me = this;
util.forEach(this.contents, function (group) {
group.itemset.setOptions(me.options);
});
};
GroupSet.prototype.setRange = function (range) {
@ -67,9 +72,8 @@ GroupSet.prototype.setItems = function setItems(items) {
this.items = items;
util.forEach(this.contents, function (group) {
group.setItems(items);
group.itemset.setItems(items);
});
};
/**
@ -205,49 +209,88 @@ GroupSet.prototype.repaint = function repaint() {
};
// show/hide added/changed/removed items
Object.keys(queue).forEach(function (id) {
var entry = queue[id];
var group = entry.item;
//noinspection FallthroughInSwitchStatementJS
switch (entry.action) {
case 'add':
// TODO: create group
group = new ItemSet(me);
group.setRange(me.range);
group.setItems(me.items);
// update lists
contents[id] = group;
delete queue[id];
break;
case 'update':
// TODO: update group
// update lists
contents[id] = group;
delete queue[id];
break;
case 'remove':
if (group) {
// remove DOM of the group
changed += group.hide();
var ids = Object.keys(queue);
if (ids.length) {
ids.forEach(function (id) {
var action = queue[id];
// find group
var group = null;
var groupIndex = -1;
for (var i = 0; i < contents.length; i++) {
if (contents[i].id == id) {
group = contents[i];
groupIndex = i;
break;
}
}
// update lists
delete contents[id];
delete queue[id];
break;
//noinspection FallthroughInSwitchStatementJS
switch (action) {
case 'add':
case 'update':
// group does not yet exist
if (!group) {
var itemset = new ItemSet(me);
itemset.setOptions(util.extend({
top: function () {
return 0; // TODO
}
}, me.options));
itemset.setRange(me.range);
itemset.setItems(me.items);
me.controller.add(itemset);
group = {
id: id,
data: groups.get(id),
itemset: itemset
};
contents.push(group);
}
delete queue[id];
break;
case 'remove':
if (group) {
// remove DOM of the group
changed += group.itemset.hide();
group.itemset.setItems();
me.controller.remove(group.itemset);
// remove group itself
contents.splice(groupIndex, 1);
}
// update lists
delete queue[id];
break;
default:
console.log('Error: unknown action "' + action + '"');
}
});
default:
console.log('Error: unknown action "' + entry.action + '"');
}
});
// update the top position (TODO: optimize, needed only when groups are added/removed/reordered
var prevGroup = null;
util.forEach(this.contents, function (group) {
var prevItemset = prevGroup && prevGroup.itemset;
if (prevItemset) {
group.itemset.options.top = function () {
return prevItemset.top + prevItemset.height;
}
}
else {
group.itemset.options.top = 0;
}
prevGroup = group;
});
}
// reposition all groups
util.forEach(this.contents, function (group) {
changed += group.repaint();
changed += group.itemset.repaint();
});
return (changed > 0);
@ -276,7 +319,7 @@ GroupSet.prototype.reflow = function reflow() {
if (frame) {
// reposition all groups
util.forEach(this.contents, function (group) {
changed += group.reflow();
changed += group.itemset.reflow();
});
var maxHeight = asNumber(options.maxHeight);
@ -288,7 +331,7 @@ GroupSet.prototype.reflow = function reflow() {
// height is not specified, calculate the sum of the height of all groups
height = 0;
util.forEach(this.contents, function (group) {
height += group.height;
height += group.itemset.height;
});
}
if (maxHeight != null) {
@ -365,21 +408,9 @@ GroupSet.prototype._onRemove = function _onRemove(ids) {
* @param {String} action can be 'add', 'update', 'remove'
*/
GroupSet.prototype._toQueue = function _toQueue(ids, action) {
var groups = this.groups;
var queue = this.queue;
ids.forEach(function (id) {
var entry = queue[id];
if (entry) {
// already queued, update the action of the entry
entry.action = action;
}
else {
// not yet queued, add an entry to the queue
queue[id] = {
item: groups[id] || null,
action: action
};
}
queue[id] = action;
});
if (this.controller) {

+ 5
- 10
src/component/item/itembox.js View File

@ -207,7 +207,8 @@ ItemBox.prototype.reflow = function reflow() {
changed += update(props.dot, 'height', dom.dot.offsetHeight);
changed += update(props.dot, 'width', dom.dot.offsetWidth);
changed += update(props.line, 'width', dom.line.offsetWidth);
changed += update(props.line, 'width', dom.line.offsetWidth);
changed += update(props.line, 'height', dom.line.offsetHeight);
changed += update(props.line, 'top', dom.line.offsetTop);
changed += update(this, 'width', dom.box.offsetWidth);
changed += update(this, 'height', dom.box.offsetHeight);
if (align == 'right') {
@ -224,13 +225,11 @@ ItemBox.prototype.reflow = function reflow() {
update(props.line, 'left', start - props.line.width / 2);
update(props.dot, 'left', start - props.dot.width / 2);
update(props.dot, 'top', -props.dot.height / 2);
if (orientation == 'top') {
top = options.margin.axis;
update(this, 'top', top);
update(props.line, 'top', 0);
update(props.line, 'height', top);
update(props.dot, 'top', -props.dot.height / 2);
}
else {
// default or 'bottom'
@ -238,9 +237,6 @@ ItemBox.prototype.reflow = function reflow() {
top = parentHeight - this.height - options.margin.axis;
update(this, 'top', top);
update(props.line, 'top', top + this.height);
update(props.line, 'height', Math.max(options.margin.axis, 0));
update(props.dot, 'top', parentHeight - props.dot.height / 2);
}
}
else {
@ -304,10 +300,9 @@ ItemBox.prototype.reposition = function reposition() {
}
else {
// orientation 'bottom'
line.style.top = props.line.top + 'px';
line.style.top = (this.top + this.height) + 'px';
line.style.height = Math.max(props.dot.top - this.top - this.height, 0) + 'px';
line.style.height = Math.max(this.parent.height - this.top - this.height +
this.props.dot.height / 2, 0) + 'px';
}
dot.style.left = props.dot.left + 'px';

+ 5
- 4
src/component/itemset.js View File

@ -168,13 +168,15 @@ ItemSet.prototype.repaint = function repaint() {
}
// reposition frame
changed += update(frame.style, 'height', asSize(options.height, this.height + 'px'));
changed += update(frame.style, 'top', asSize(options.top, '0px'));
changed += update(frame.style, 'left', asSize(options.left, '0px'));
changed += update(frame.style, 'top', asSize(options.top, '0px'));
changed += update(frame.style, 'width', asSize(options.width, '100%'));
changed += update(frame.style, 'height', asSize(options.height, this.height + 'px'));
// reposition axis
changed += update(this.dom.axis.style, 'top', asSize(options.top, '0px'));
changed += update(this.dom.axis.style, 'left', asSize(options.left, '0px'));
changed += update(this.dom.axis.style, 'top', (this.height + this.top) + 'px');
changed += update(this.dom.axis.style, 'width', asSize(options.width, '100%'));
this._updateConversion();
@ -436,7 +438,6 @@ ItemSet.prototype.getItems = function getItems() {
* @private
*/
ItemSet.prototype._onUpdate = function _onUpdate(ids) {
console.log('onUpdate', ids)
this._toQueue(ids, 'update');
};

+ 3
- 2
src/util.js View File

@ -78,14 +78,15 @@ util.randomUUID = function randomUUID () {
};
/**
* Extend object a with the properties of object b
* Extend object a with the properties of object b.
* Only properties with defined values are copied
* @param {Object} a
* @param {Object} b
* @return {Object} a
*/
util.extend = function (a, b) {
for (var prop in b) {
if (b.hasOwnProperty(prop)) {
if (b.hasOwnProperty(prop) && b[prop] !== undefined) {
a[prop] = b[prop];
}
}

+ 13
- 4
src/visualization/timeline.js View File

@ -80,10 +80,19 @@ Timeline.prototype.setOptions = function (options) {
util.extend(this.options, options);
// update options the timeaxis
this.timeaxis.setOptions(this.options);
this.timeaxis.setOptions({
orientation: this.options.orientation,
showMinorLabels: this.options.showMinorLabels,
showMajorLabels: this.options.showMajorLabels
});
// update options for the range
this.range.setOptions(this.options);
this.range.setOptions({
min: this.options.min,
max: this.options.max,
zoomMin: this.options.zoomMin,
zoomMax: this.options.zoomMax
});
// update options the content
var itemsTop,
@ -213,10 +222,10 @@ Timeline.prototype.setGroups = function(groups) {
if (this.content) {
this.content.hide();
if (this.content.setItems) {
this.content.setItems();
this.content.setItems(); // disconnect from items
}
if (this.content.setGroups) {
this.content.setGroups();
this.content.setGroups(); // disconnect from groups
}
this.controller.remove(this.content);
}

+ 114
- 77
vis.js View File

@ -5,7 +5,7 @@
* A dynamic, browser-based visualization library.
*
* @version 0.0.8
* @date 2013-05-10
* @date 2013-05-14
*
* @license
* Copyright (C) 2011-2013 Almende B.V, http://almende.com
@ -109,14 +109,15 @@ util.randomUUID = function randomUUID () {
};
/**
* Extend object a with the properties of object b
* Extend object a with the properties of object b.
* Only properties with defined values are copied
* @param {Object} a
* @param {Object} b
* @return {Object} a
*/
util.extend = function (a, b) {
for (var prop in b) {
if (b.hasOwnProperty(prop)) {
if (b.hasOwnProperty(prop) && b[prop] !== undefined) {
a[prop] = b[prop];
}
}
@ -3925,7 +3926,7 @@ TimeAxis.prototype._repaintMeasureChars = function () {
var dom = this.dom,
text;
if (!dom.characterMinor) {
if (!dom.measureCharMinor) {
text = document.createTextNode('0');
var measureCharMinor = document.createElement('DIV');
measureCharMinor.className = 'text minor measure';
@ -3935,7 +3936,7 @@ TimeAxis.prototype._repaintMeasureChars = function () {
dom.measureCharMinor = measureCharMinor;
}
if (!dom.characterMajor) {
if (!dom.measureCharMajor) {
text = document.createTextNode('0');
var measureCharMajor = document.createElement('DIV');
measureCharMajor.className = 'text major measure';
@ -4237,13 +4238,15 @@ ItemSet.prototype.repaint = function repaint() {
}
// reposition frame
changed += update(frame.style, 'height', asSize(options.height, this.height + 'px'));
changed += update(frame.style, 'top', asSize(options.top, '0px'));
changed += update(frame.style, 'left', asSize(options.left, '0px'));
changed += update(frame.style, 'top', asSize(options.top, '0px'));
changed += update(frame.style, 'width', asSize(options.width, '100%'));
changed += update(frame.style, 'height', asSize(options.height, this.height + 'px'));
// reposition axis
changed += update(this.dom.axis.style, 'top', asSize(options.top, '0px'));
changed += update(this.dom.axis.style, 'left', asSize(options.left, '0px'));
changed += update(this.dom.axis.style, 'top', (this.height + this.top) + 'px');
changed += update(this.dom.axis.style, 'width', asSize(options.width, '100%'));
this._updateConversion();
@ -4505,7 +4508,6 @@ ItemSet.prototype.getItems = function getItems() {
* @private
*/
ItemSet.prototype._onUpdate = function _onUpdate(ids) {
console.log('onUpdate', ids)
this._toQueue(ids, 'update');
};
@ -4869,7 +4871,8 @@ ItemBox.prototype.reflow = function reflow() {
changed += update(props.dot, 'height', dom.dot.offsetHeight);
changed += update(props.dot, 'width', dom.dot.offsetWidth);
changed += update(props.line, 'width', dom.line.offsetWidth);
changed += update(props.line, 'width', dom.line.offsetWidth);
changed += update(props.line, 'height', dom.line.offsetHeight);
changed += update(props.line, 'top', dom.line.offsetTop);
changed += update(this, 'width', dom.box.offsetWidth);
changed += update(this, 'height', dom.box.offsetHeight);
if (align == 'right') {
@ -4886,13 +4889,11 @@ ItemBox.prototype.reflow = function reflow() {
update(props.line, 'left', start - props.line.width / 2);
update(props.dot, 'left', start - props.dot.width / 2);
update(props.dot, 'top', -props.dot.height / 2);
if (orientation == 'top') {
top = options.margin.axis;
update(this, 'top', top);
update(props.line, 'top', 0);
update(props.line, 'height', top);
update(props.dot, 'top', -props.dot.height / 2);
}
else {
// default or 'bottom'
@ -4900,9 +4901,6 @@ ItemBox.prototype.reflow = function reflow() {
top = parentHeight - this.height - options.margin.axis;
update(this, 'top', top);
update(props.line, 'top', top + this.height);
update(props.line, 'height', Math.max(options.margin.axis, 0));
update(props.dot, 'top', parentHeight - props.dot.height / 2);
}
}
else {
@ -4966,10 +4964,9 @@ ItemBox.prototype.reposition = function reposition() {
}
else {
// orientation 'bottom'
line.style.top = props.line.top + 'px';
line.style.top = (this.top + this.height) + 'px';
line.style.height = Math.max(props.dot.top - this.top - this.height, 0) + 'px';
line.style.height = Math.max(this.parent.height - this.top - this.height +
this.props.dot.height / 2, 0) + 'px';
}
dot.style.left = props.dot.left + 'px';
@ -5508,9 +5505,9 @@ function GroupSet(parent, depends, options) {
this.items = null; // dataset with items
this.groups = null; // dataset with groups
this.contents = {}; // object with an ItemSet for every group
this.contents = []; // array with groups
// changes in groups are queued
// changes in groups are queued key/value map containing id/action
this.queue = {};
var me = this;
@ -5542,6 +5539,11 @@ GroupSet.prototype.setOptions = function setOptions(options) {
util.extend(this.options, options);
// TODO: implement options
var me = this;
util.forEach(this.contents, function (group) {
group.itemset.setOptions(me.options);
});
};
GroupSet.prototype.setRange = function (range) {
@ -5556,9 +5558,8 @@ GroupSet.prototype.setItems = function setItems(items) {
this.items = items;
util.forEach(this.contents, function (group) {
group.setItems(items);
group.itemset.setItems(items);
});
};
/**
@ -5694,49 +5695,88 @@ GroupSet.prototype.repaint = function repaint() {
};
// show/hide added/changed/removed items
Object.keys(queue).forEach(function (id) {
var entry = queue[id];
var group = entry.item;
//noinspection FallthroughInSwitchStatementJS
switch (entry.action) {
case 'add':
// TODO: create group
group = new ItemSet(me);
group.setRange(me.range);
group.setItems(me.items);
var ids = Object.keys(queue);
if (ids.length) {
ids.forEach(function (id) {
var action = queue[id];
// find group
var group = null;
var groupIndex = -1;
for (var i = 0; i < contents.length; i++) {
if (contents[i].id == id) {
group = contents[i];
groupIndex = i;
break;
}
}
// update lists
contents[id] = group;
delete queue[id];
break;
//noinspection FallthroughInSwitchStatementJS
switch (action) {
case 'add':
case 'update':
// group does not yet exist
if (!group) {
var itemset = new ItemSet(me);
itemset.setOptions(util.extend({
top: function () {
return 0; // TODO
}
}, me.options));
itemset.setRange(me.range);
itemset.setItems(me.items);
me.controller.add(itemset);
group = {
id: id,
data: groups.get(id),
itemset: itemset
};
contents.push(group);
}
case 'update':
// TODO: update group
delete queue[id];
break;
// update lists
contents[id] = group;
delete queue[id];
break;
case 'remove':
if (group) {
// remove DOM of the group
changed += group.itemset.hide();
group.itemset.setItems();
me.controller.remove(group.itemset);
case 'remove':
if (group) {
// remove DOM of the group
changed += group.hide();
}
// remove group itself
contents.splice(groupIndex, 1);
}
// update lists
delete contents[id];
delete queue[id];
break;
// update lists
delete queue[id];
break;
default:
console.log('Error: unknown action "' + entry.action + '"');
}
});
default:
console.log('Error: unknown action "' + action + '"');
}
});
// update the top position (TODO: optimize, needed only when groups are added/removed/reordered
var prevGroup = null;
util.forEach(this.contents, function (group) {
var prevItemset = prevGroup && prevGroup.itemset;
if (prevItemset) {
group.itemset.options.top = function () {
return prevItemset.top + prevItemset.height;
}
}
else {
group.itemset.options.top = 0;
}
prevGroup = group;
});
}
// reposition all groups
util.forEach(this.contents, function (group) {
changed += group.repaint();
changed += group.itemset.repaint();
});
return (changed > 0);
@ -5765,7 +5805,7 @@ GroupSet.prototype.reflow = function reflow() {
if (frame) {
// reposition all groups
util.forEach(this.contents, function (group) {
changed += group.reflow();
changed += group.itemset.reflow();
});
var maxHeight = asNumber(options.maxHeight);
@ -5777,7 +5817,7 @@ GroupSet.prototype.reflow = function reflow() {
// height is not specified, calculate the sum of the height of all groups
height = 0;
util.forEach(this.contents, function (group) {
height += group.height;
height += group.itemset.height;
});
}
if (maxHeight != null) {
@ -5854,21 +5894,9 @@ GroupSet.prototype._onRemove = function _onRemove(ids) {
* @param {String} action can be 'add', 'update', 'remove'
*/
GroupSet.prototype._toQueue = function _toQueue(ids, action) {
var groups = this.groups;
var queue = this.queue;
ids.forEach(function (id) {
var entry = queue[id];
if (entry) {
// already queued, update the action of the entry
entry.action = action;
}
else {
// not yet queued, add an entry to the queue
queue[id] = {
item: groups[id] || null,
action: action
};
}
queue[id] = action;
});
if (this.controller) {
@ -5959,10 +5987,19 @@ Timeline.prototype.setOptions = function (options) {
util.extend(this.options, options);
// update options the timeaxis
this.timeaxis.setOptions(this.options);
this.timeaxis.setOptions({
orientation: this.options.orientation,
showMinorLabels: this.options.showMinorLabels,
showMajorLabels: this.options.showMajorLabels
});
// update options for the range
this.range.setOptions(this.options);
this.range.setOptions({
min: this.options.min,
max: this.options.max,
zoomMin: this.options.zoomMin,
zoomMax: this.options.zoomMax
});
// update options the content
var itemsTop,
@ -6092,10 +6129,10 @@ Timeline.prototype.setGroups = function(groups) {
if (this.content) {
this.content.hide();
if (this.content.setItems) {
this.content.setItems();
this.content.setItems(); // disconnect from items
}
if (this.content.setGroups) {
this.content.setGroups();
this.content.setGroups(); // disconnect from groups
}
this.controller.remove(this.content);
}
@ -6215,7 +6252,7 @@ if (typeof window !== 'undefined') {
}
// inject css
util.loadCss("/* vis.js stylesheet */\n\n.graph {\n position: relative;\n border: 1px solid #bfbfbf;\n}\n\n.graph .panel {\n position: absolute;\n}\n\n.graph .groupset {\n position: absolute;\n padding: 0;\n margin: 0;\n overflow: hidden;\n}\n\n\n.graph .itemset {\n position: absolute;\n padding: 0;\n margin: 0;\n overflow: hidden;\n}\n\n.graph .groupset .itemset {\n position: relative;\n padding: 0;\n margin: 0;\n overflow: hidden;\n}\n\n.graph .background {\n}\n\n.graph .foreground {\n}\n\n.graph .itemset-axis {\n position: absolute;\n}\n\n.graph .groupset .itemset-axis {\n position: relative;\n}\n\n.graph .item {\n position: absolute;\n color: #1A1A1A;\n border-color: #97B0F8;\n background-color: #D5DDF6;\n display: inline-block;\n}\n\n.graph .item.selected {\n border-color: #FFC200;\n background-color: #FFF785;\n z-index: 999;\n}\n\n.graph .item.cluster {\n /* TODO: use another color or pattern? */\n background: #97B0F8 url('img/cluster_bg.png');\n color: white;\n}\n.graph .item.cluster.point {\n border-color: #D5DDF6;\n}\n\n.graph .item.box {\n text-align: center;\n border-style: solid;\n border-width: 1px;\n border-radius: 5px;\n -moz-border-radius: 5px; /* For Firefox 3.6 and older */\n}\n\n.graph .item.point {\n background: none;\n}\n\n.graph .dot {\n border: 5px solid #97B0F8;\n position: absolute;\n border-radius: 5px;\n -moz-border-radius: 5px; /* For Firefox 3.6 and older */\n}\n\n.graph .item.range {\n overflow: hidden;\n border-style: solid;\n border-width: 1px;\n border-radius: 2px;\n -moz-border-radius: 2px; /* For Firefox 3.6 and older */\n}\n\n.graph .item.range .drag-left {\n cursor: w-resize;\n z-index: 1000;\n}\n\n.graph .item.range .drag-right {\n cursor: e-resize;\n z-index: 1000;\n}\n\n.graph .item.range .content {\n position: relative;\n display: inline-block;\n}\n\n.graph .item.line {\n position: absolute;\n width: 0;\n border-left-width: 1px;\n border-left-style: solid;\n}\n\n.graph .item .content {\n margin: 5px;\n white-space: nowrap;\n overflow: hidden;\n}\n\n/* TODO: better css name, 'graph' is way to generic */\n\n.graph {\n overflow: hidden;\n}\n\n.graph .axis {\n position: relative;\n}\n\n.graph .axis .text {\n position: absolute;\n color: #4d4d4d;\n padding: 3px;\n white-space: nowrap;\n}\n\n.graph .axis .text.measure {\n position: absolute;\n padding-left: 0;\n padding-right: 0;\n margin-left: 0;\n margin-right: 0;\n visibility: hidden;\n}\n\n.graph .axis .grid.vertical {\n position: absolute;\n width: 0;\n border-right: 1px solid;\n}\n\n.graph .axis .grid.horizontal {\n position: absolute;\n left: 0;\n width: 100%;\n height: 0;\n border-bottom: 1px solid;\n}\n\n.graph .axis .grid.minor {\n border-color: #e5e5e5;\n}\n\n.graph .axis .grid.major {\n border-color: #bfbfbf;\n}\n\n");
util.loadCss("/* vis.js stylesheet */\n\n.graph {\n position: relative;\n border: 1px solid #bfbfbf;\n}\n\n.graph .panel {\n position: absolute;\n}\n\n.graph .groupset {\n position: absolute;\n padding: 0;\n margin: 0;\n}\n\n\n.graph .itemset {\n position: absolute;\n padding: 0;\n margin: 0;\n overflow: hidden;\n}\n\n.graph .background {\n}\n\n.graph .foreground {\n}\n\n.graph .itemset-axis {\n position: absolute;\n}\n\n.graph .groupset .itemset-axis {\n border-top: 1px solid #bfbfbf;\n}\n\n.graph .groupset .itemset-axis:last-child {\n border-top: none;\n}\n\n\n.graph .item {\n position: absolute;\n color: #1A1A1A;\n border-color: #97B0F8;\n background-color: #D5DDF6;\n display: inline-block;\n}\n\n.graph .item.selected {\n border-color: #FFC200;\n background-color: #FFF785;\n z-index: 999;\n}\n\n.graph .item.cluster {\n /* TODO: use another color or pattern? */\n background: #97B0F8 url('img/cluster_bg.png');\n color: white;\n}\n.graph .item.cluster.point {\n border-color: #D5DDF6;\n}\n\n.graph .item.box {\n text-align: center;\n border-style: solid;\n border-width: 1px;\n border-radius: 5px;\n -moz-border-radius: 5px; /* For Firefox 3.6 and older */\n}\n\n.graph .item.point {\n background: none;\n}\n\n.graph .dot {\n border: 5px solid #97B0F8;\n position: absolute;\n border-radius: 5px;\n -moz-border-radius: 5px; /* For Firefox 3.6 and older */\n}\n\n.graph .item.range {\n overflow: hidden;\n border-style: solid;\n border-width: 1px;\n border-radius: 2px;\n -moz-border-radius: 2px; /* For Firefox 3.6 and older */\n}\n\n.graph .item.range .drag-left {\n cursor: w-resize;\n z-index: 1000;\n}\n\n.graph .item.range .drag-right {\n cursor: e-resize;\n z-index: 1000;\n}\n\n.graph .item.range .content {\n position: relative;\n display: inline-block;\n}\n\n.graph .item.line {\n position: absolute;\n width: 0;\n border-left-width: 1px;\n border-left-style: solid;\n}\n\n.graph .item .content {\n margin: 5px;\n white-space: nowrap;\n overflow: hidden;\n}\n\n/* TODO: better css name, 'graph' is way to generic */\n\n.graph {\n overflow: hidden;\n}\n\n.graph .axis {\n position: relative;\n}\n\n.graph .axis .text {\n position: absolute;\n color: #4d4d4d;\n padding: 3px;\n white-space: nowrap;\n}\n\n.graph .axis .text.measure {\n position: absolute;\n padding-left: 0;\n padding-right: 0;\n margin-left: 0;\n margin-right: 0;\n visibility: hidden;\n}\n\n.graph .axis .grid.vertical {\n position: absolute;\n width: 0;\n border-right: 1px solid;\n}\n\n.graph .axis .grid.horizontal {\n position: absolute;\n left: 0;\n width: 100%;\n height: 0;\n border-bottom: 1px solid;\n}\n\n.graph .axis .grid.minor {\n border-color: #e5e5e5;\n}\n\n.graph .axis .grid.major {\n border-color: #bfbfbf;\n}\n\n");
},{"moment":2}],2:[function(require,module,exports){
(function(){// moment.js

+ 4
- 4
vis.min.js
File diff suppressed because it is too large
View File


Loading…
Cancel
Save