Browse Source

Renamed parameter `timeline` to `body`, passing an explicit `body` Object to all component constructors now

css_transitions
jos 10 years ago
parent
commit
43912f5d9b
8 changed files with 87 additions and 81 deletions
  1. +24
    -24
      src/timeline/Range.js
  2. +16
    -12
      src/timeline/Timeline.js
  3. +3
    -1
      src/timeline/component/Component.js
  4. +5
    -5
      src/timeline/component/CurrentTime.js
  5. +6
    -6
      src/timeline/component/CustomTime.js
  6. +1
    -1
      src/timeline/component/Group.js
  7. +20
    -20
      src/timeline/component/ItemSet.js
  8. +12
    -12
      src/timeline/component/TimeAxis.js

+ 24
- 24
src/timeline/Range.js View File

@ -3,31 +3,31 @@
* A Range controls a numeric range with a start and end value.
* The Range adjusts the range based on mouse events or programmatic changes,
* and triggers events when the range is changing or has been changed.
* @param {{dom: Object, props: Object, emitter: Emitter, range: Range}} timeline
* @param {{dom: Object, props: Object, emitter: Emitter}} body
* @param {Object} [options] See description at Range.setOptions
*/
function Range(timeline, options) {
function Range(body, options) {
this.start = null; // Number
this.end = null; // Number
this.timeline = timeline;
this.body = body;
this.options = options || {};
// drag listeners for dragging
this.timeline.emitter.on('dragstart', this._onDragStart.bind(this));
this.timeline.emitter.on('drag', this._onDrag.bind(this));
this.timeline.emitter.on('dragend', this._onDragEnd.bind(this));
this.body.emitter.on('dragstart', this._onDragStart.bind(this));
this.body.emitter.on('drag', this._onDrag.bind(this));
this.body.emitter.on('dragend', this._onDragEnd.bind(this));
// ignore dragging when holding
this.timeline.emitter.on('hold', this._onHold.bind(this));
this.body.emitter.on('hold', this._onHold.bind(this));
// mouse wheel for zooming
this.timeline.emitter.on('mousewheel', this._onMouseWheel.bind(this));
this.timeline.emitter.on('DOMMouseScroll', this._onMouseWheel.bind(this)); // For FF
this.body.emitter.on('mousewheel', this._onMouseWheel.bind(this));
this.body.emitter.on('DOMMouseScroll', this._onMouseWheel.bind(this)); // For FF
// pinch to zoom
this.timeline.emitter.on('touch', this._onTouch.bind(this));
this.timeline.emitter.on('pinch', this._onPinch.bind(this));
this.body.emitter.on('touch', this._onTouch.bind(this));
this.body.emitter.on('pinch', this._onPinch.bind(this));
this.setOptions(options);
}
@ -74,8 +74,8 @@ Range.prototype.setRange = function(start, end) {
start: new Date(this.start),
end: new Date(this.end)
};
this.timeline.emitter.emit('rangechange', params);
this.timeline.emitter.emit('rangechanged', params);
this.body.emitter.emit('rangechange', params);
this.body.emitter.emit('rangechanged', params);
}
};
@ -252,8 +252,8 @@ Range.prototype._onDragStart = function(event) {
touchParams.start = this.start;
touchParams.end = this.end;
if (this.timeline.dom.root) {
this.timeline.dom.root.style.cursor = 'move';
if (this.body.dom.root) {
this.body.dom.root.style.cursor = 'move';
}
};
@ -275,12 +275,12 @@ Range.prototype._onDrag = function (event) {
var delta = (direction == 'horizontal') ? event.gesture.deltaX : event.gesture.deltaY,
interval = (touchParams.end - touchParams.start),
width = (direction == 'horizontal') ? this.timeline.props.center.width : this.timeline.props.center.height,
width = (direction == 'horizontal') ? this.body.props.center.width : this.body.props.center.height,
diffRange = -delta / width * interval;
this._applyRange(touchParams.start + diffRange, touchParams.end + diffRange);
this.timeline.emitter.emit('rangechange', {
this.body.emitter.emit('rangechange', {
start: new Date(this.start),
end: new Date(this.end)
});
@ -298,12 +298,12 @@ Range.prototype._onDragEnd = function (event) {
// TODO: reckon with option movable
if (this.timeline.dom.root) {
this.timeline.dom.root.style.cursor = 'auto';
if (this.body.dom.root) {
this.body.dom.root.style.cursor = 'auto';
}
// fire a rangechanged event
this.timeline.emitter.emit('rangechanged', {
this.body.emitter.emit('rangechanged', {
start: new Date(this.start),
end: new Date(this.end)
});
@ -346,7 +346,7 @@ Range.prototype._onMouseWheel = function(event) {
// calculate center, the date to zoom around
var gesture = util.fakeGesture(this, event),
pointer = getPointer(gesture.center, this.timeline.dom.center),
pointer = getPointer(gesture.center, this.body.dom.center),
pointerDate = this._pointerToDate(pointer);
this.zoom(scale, pointerDate);
@ -395,7 +395,7 @@ Range.prototype._onPinch = function (event) {
if (event.gesture.touches.length > 1) {
if (!touchParams.center) {
touchParams.center = getPointer(event.gesture.center, this.timeline.dom.center);
touchParams.center = getPointer(event.gesture.center, this.body.dom.center);
}
var scale = 1 / event.gesture.scale,
@ -423,12 +423,12 @@ Range.prototype._pointerToDate = function (pointer) {
validateDirection(direction);
if (direction == 'horizontal') {
var width = this.timeline.props.center.width;
var width = this.body.props.center.width;
conversion = this.conversion(width);
return pointer.x / conversion.scale + conversion.offset;
}
else {
var height = this.timeline.props.center.height;
var height = this.body.props.center.height;
conversion = this.conversion(height);
return pointer.y / conversion.scale + conversion.offset;
}

+ 16
- 12
src/timeline/Timeline.js View File

@ -89,31 +89,38 @@ function Timeline (container, items, options) {
// all components listed here will be repainted automatically
this.components = [];
this.body = {
dom: this.dom,
props: this.props,
emitter: this
};
// range
this.range = new Range(this, this.options);
this.range = new Range(this.body, this.options);
this.range.setRange(
now.clone().add('days', -3).valueOf(),
now.clone().add('days', 4).valueOf()
);
this.body.range = this.range;
// time axis
this.timeAxis = new TimeAxis(this, this.options);
this.timeAxis = new TimeAxis(this.body, this.options);
this.components.push(this.timeAxis);
this.options.snap = this.timeAxis.snap.bind(this.timeAxis); // TODO: not nice adding snap to options
// current time bar
this.currentTime = new CurrentTime(this, this.options);
this.currentTime = new CurrentTime(this.body, this.options);
this.components.push(this.currentTime);
// custom time bar
// Note: time bar will be attached in this.setOptions when selected
this.customTime = new CustomTime(this, this.options);
this.customTime = new CustomTime(this.body, this.options);
this.components.push(this.customTime);
// item set
this.itemSet = new ItemSet(this, this.options);
this.itemSet = new ItemSet(this.body, this.options);
this.components.push(this.itemSet);
this.emitter.on('change', this.redraw.bind(this));
this.on('change', this.redraw.bind(this));
this.itemsData = null; // DataSet
this.groupsData = null; // DataSet
@ -178,10 +185,7 @@ Timeline.prototype._create = function () {
this.dom.leftContainer.appendChild(this.dom.left);
this.dom.rightContainer.appendChild(this.dom.right);
// create a central event bus
this.emitter = this;
this.emitter.on('rangechange', this.redraw.bind(this));
this.on('rangechange', this.redraw.bind(this));
// create event listeners for all interesting events, these events will be
// emitted via emitter
@ -200,7 +204,7 @@ Timeline.prototype._create = function () {
events.forEach(function (event) {
var listener = function () {
var args = [event].concat(Array.prototype.slice.call(arguments, 0));
me.emitter.emit.apply(me.emitter, args);
me.emit.apply(me, args);
};
me.hammer.on(event, listener);
me.listeners[event] = listener;
@ -730,7 +734,7 @@ Timeline.prototype._startAutoResize = function () {
me.props.lastWidth = me.dom.root.clientWidth;
me.props.lastHeight = me.dom.root.clientHeight;
me.emitter.emit('change');
me.emit('change');
}
}
}

+ 3
- 1
src/timeline/component/Component.js View File

@ -1,7 +1,9 @@
/**
* Prototype for visual components
* @param {{dom: Object, props: Object, emitter: Emitter, range: Range}} body
* @param {Object} [options]
*/
function Component () {
function Component (body, options) {
this.options = null;
this.props = null;
}

+ 5
- 5
src/timeline/component/CurrentTime.js View File

@ -1,14 +1,14 @@
/**
* A current time bar
* @param {{range: Range, dom: Object}} timeline
* @param {{range: Range, dom: Object}} body
* @param {Object} [options] Available parameters:
* {Boolean} [showCurrentTime]
* @constructor CurrentTime
* @extends Component
*/
function CurrentTime (timeline, options) {
this.timeline = timeline;
function CurrentTime (body, options) {
this.body = body;
this.options = options || {};
@ -37,7 +37,7 @@ CurrentTime.prototype._create = function() {
*/
CurrentTime.prototype.redraw = function() {
if (this.options.showCurrentTime) {
var parent = this.timeline.dom.backgroundVertical;
var parent = this.body.dom.backgroundVertical;
if (this.bar.parentNode != parent) {
// attach to the dom
if (this.bar.parentNode) {
@ -75,7 +75,7 @@ CurrentTime.prototype.start = function() {
me.stop();
// determine interval to refresh
var scale = me.timeline.range.conversion(me.timeline.props.center.width).scale;
var scale = me.body.range.conversion(me.body.props.center.width).scale;
var interval = 1 / scale / 10;
if (interval < 30) interval = 30;
if (interval > 1000) interval = 1000;

+ 6
- 6
src/timeline/component/CustomTime.js View File

@ -1,14 +1,14 @@
/**
* A custom time bar
* @param {{range: Range, dom: Object}} timeline
* @param {{range: Range, dom: Object}} body
* @param {Object} [options] Available parameters:
* {Boolean} [showCustomTime]
* @constructor CustomTime
* @extends Component
*/
function CustomTime (timeline, options) {
this.timeline = timeline;
function CustomTime (body, options) {
this.body = body;
this.options = options || {};
this.customTime = new Date();
@ -55,7 +55,7 @@ CustomTime.prototype._create = function() {
*/
CustomTime.prototype.redraw = function () {
if (this.options.showCustomTime) {
var parent = this.timeline.dom.backgroundVertical;
var parent = this.body.dom.backgroundVertical;
if (this.bar.parentNode != parent) {
// attach to the dom
if (this.bar.parentNode) {
@ -124,7 +124,7 @@ CustomTime.prototype._onDrag = function (event) {
this.setCustomTime(time);
// fire a timechange event
this.timeline.emitter.emit('timechange', {
this.body.emitter.emit('timechange', {
time: new Date(this.customTime.valueOf())
});
@ -141,7 +141,7 @@ CustomTime.prototype._onDragEnd = function (event) {
if (!this.eventParams.dragging) return;
// fire a timechanged event
this.timeline.emitter.emit('timechanged', {
this.body.emitter.emit('timechanged', {
time: new Date(this.customTime.valueOf())
});

+ 1
- 1
src/timeline/component/Group.js View File

@ -231,7 +231,7 @@ Group.prototype.add = function(item) {
item.setParent(this);
if (item instanceof ItemRange && this.visibleItems.indexOf(item) == -1) {
var range = this.itemSet.timeline.range; // TODO: not nice accessing the range like this
var range = this.itemSet.body.range; // TODO: not nice accessing the range like this
this._checkIfVisible(item, this.visibleItems, range);
}
};

+ 20
- 20
src/timeline/component/ItemSet.js View File

@ -4,13 +4,13 @@ var UNGROUPED = '__ungrouped__'; // reserved group id for ungrouped items
* An ItemSet holds a set of items and ranges which can be displayed in a
* range. The width is determined by the parent of the ItemSet, and the height
* is determined by the size of the items.
* @param {{dom: Object}} timeline
* @param {{dom: Object, props: Object, emitter: Emitter, range: Range}} body
* @param {Object} [options] See ItemSet.setOptions for the available options.
* @constructor ItemSet
* @extends Component
*/
function ItemSet(timeline, options) {
this.timeline = timeline;
function ItemSet(body, options) {
this.body = body;
// one options object is shared by this itemset and all its items
this.options = options || {};
@ -194,17 +194,17 @@ ItemSet.prototype.hide = function() {
ItemSet.prototype.show = function() {
// show frame containing the items
if (!this.dom.frame.parentNode) {
this.timeline.dom.center.appendChild(this.dom.frame);
this.body.dom.center.appendChild(this.dom.frame);
}
// show axis with dots
if (!this.dom.axis.parentNode) {
this.timeline.dom.backgroundVertical.appendChild(this.dom.axis);
this.body.dom.backgroundVertical.appendChild(this.dom.axis);
}
// show labelset containing labels
if (!this.dom.labelSet.parentNode) {
this.timeline.dom.left.appendChild(this.dom.labelSet);
this.body.dom.left.appendChild(this.dom.labelSet);
}
};
@ -272,7 +272,7 @@ ItemSet.prototype._deselect = function(id) {
*/
ItemSet.prototype.redraw = function() {
var margin = this.options.margin,
range = this.timeline.range,
range = this.body.range,
asSize = util.option.asSize,
options = this.options,
orientation = options.orientation,
@ -337,9 +337,9 @@ ItemSet.prototype.redraw = function() {
// reposition axis
this.dom.axis.style.top = asSize((orientation == 'top') ?
(this.timeline.props.top.height + this.timeline.props.border.top) :
(this.timeline.props.top.height + this.timeline.props.centerContainer.height));
this.dom.axis.style.left = this.timeline.props.border.left + 'px';
(this.body.props.top.height + this.body.props.border.top) :
(this.body.props.top.height + this.body.props.centerContainer.height));
this.dom.axis.style.left = this.body.props.border.left + 'px';
// check if this component is resized
resized = this._isResized() || resized;
@ -506,7 +506,7 @@ ItemSet.prototype.setGroups = function(groups) {
// update the order of all items in each group
this._order();
this.timeline.emitter.emit('change');
this.body.emitter.emit('change');
};
/**
@ -584,7 +584,7 @@ ItemSet.prototype._onUpdate = function(ids) {
this._order();
this.stackDirty = true; // force re-stacking of all items next redraw
this.timeline.emitter.emit('change');
this.body.emitter.emit('change');
};
/**
@ -614,7 +614,7 @@ ItemSet.prototype._onRemove = function(ids) {
// update order
this._order();
this.stackDirty = true; // force re-stacking of all items next redraw
this.timeline.emitter.emit('change');
this.body.emitter.emit('change');
}
};
@ -684,7 +684,7 @@ ItemSet.prototype._onAddGroups = function(ids) {
}
});
this.timeline.emitter.emit('change');
this.body.emitter.emit('change');
};
/**
@ -705,7 +705,7 @@ ItemSet.prototype._onRemoveGroups = function(ids) {
this.markDirty();
this.timeline.emitter.emit('change');
this.body.emitter.emit('change');
};
/**
@ -912,7 +912,7 @@ ItemSet.prototype._onDragStart = function (event) {
*/
ItemSet.prototype._onDrag = function (event) {
if (this.touchParams.itemProps) {
var range = this.timeline.range,
var range = this.body.range,
snap = this.options.snap || null,
deltaX = event.gesture.deltaX,
scale = (this.props.width / (range.end - range.start)),
@ -948,7 +948,7 @@ ItemSet.prototype._onDrag = function (event) {
// TODO: implement onMoving handler
this.stackDirty = true; // force re-stacking of all items next redraw
this.timeline.emitter.emit('change');
this.body.emitter.emit('change');
event.stopPropagation();
}
@ -998,7 +998,7 @@ ItemSet.prototype._onDragEnd = function (event) {
if ('end' in props) props.item.data.end = props.end;
me.stackDirty = true; // force re-stacking of all items next redraw
me.timeline.emitter.emit('change');
me.body.emitter.emit('change');
}
});
}
@ -1040,7 +1040,7 @@ ItemSet.prototype._onSelectItem = function (event) {
// emit a select event,
// except when old selection is empty and new selection is still empty
if (newSelection.length > 0 || oldSelection.length > 0) {
this.timeline.emitter.emit('select', {
this.body.emitter.emit('select', {
items: this.getSelection()
});
}
@ -1131,7 +1131,7 @@ ItemSet.prototype._onMultiSelectItem = function (event) {
}
this.setSelection(selection);
this.timeline.emitter.emit('select', {
this.body.emitter.emit('select', {
items: this.getSelection()
});

+ 12
- 12
src/timeline/component/TimeAxis.js View File

@ -1,12 +1,12 @@
/**
* A horizontal time axis
* @param {{dom: Object, props: Object, emitter: Emitter, range: Range}} timeline
* @param {{dom: Object, props: Object, emitter: Emitter, range: Range}} body
* @param {Object} [options] See TimeAxis.setOptions for the available
* options.
* @constructor TimeAxis
* @extends Component
*/
function TimeAxis (timeline, options) {
function TimeAxis (body, options) {
this.dom = {
foreground: null,
majorLines: [],
@ -37,7 +37,7 @@ function TimeAxis (timeline, options) {
showMajorLabels: true
};
this.timeline = timeline;
this.body = body;
// create the HTML DOM
this._create();
@ -77,7 +77,7 @@ TimeAxis.prototype.redraw = function () {
background = this.dom.background;
// determine the correct parent DOM element (depending on option orientation)
var parent = (options.orientation == 'top') ? this.timeline.dom.top : this.timeline.dom.bottom;
var parent = (options.orientation == 'top') ? this.body.dom.top : this.body.dom.bottom;
var parentChanged = (foreground.parentNode !== parent);
// calculate character width and height
@ -94,8 +94,8 @@ TimeAxis.prototype.redraw = function () {
props.height = props.minorLabelHeight + props.majorLabelHeight;
props.width = foreground.offsetWidth;
props.minorLineHeight = this.timeline.props.root.height - props.majorLabelHeight -
(options.orientation == 'top' ? this.timeline.props.bottom.height : this.timeline.props.top.height);
props.minorLineHeight = this.body.props.root.height - props.majorLabelHeight -
(options.orientation == 'top' ? this.body.props.bottom.height : this.body.props.top.height);
props.minorLineWidth = 1; // TODO: really calculate width
props.majorLineHeight = props.minorLineHeight + props.majorLabelHeight;
props.majorLineWidth = 1; // TODO: really calculate width
@ -118,10 +118,10 @@ TimeAxis.prototype.redraw = function () {
parent.appendChild(foreground)
}
if (backgroundNextSibling) {
this.timeline.dom.backgroundVertical.insertBefore(background, backgroundNextSibling);
this.body.dom.backgroundVertical.insertBefore(background, backgroundNextSibling);
}
else {
this.timeline.dom.backgroundVertical.appendChild(background)
this.body.dom.backgroundVertical.appendChild(background)
}
return this._isResized() || parentChanged;
@ -135,8 +135,8 @@ TimeAxis.prototype._repaintLabels = function () {
var orientation = this.getOption('orientation');
// calculate range and step (step such that we have space for 7 characters per label)
var start = util.convert(this.timeline.range.start, 'Number'),
end = util.convert(this.timeline.range.end, 'Number'),
var start = util.convert(this.body.range.start, 'Number'),
end = util.convert(this.body.range.end, 'Number'),
minimumStep = this.options.toTime((this.props.minorCharWidth || 10) * 7).valueOf()
-this.options.toTime(0).valueOf();
var step = new TimeStep(new Date(start), new Date(end), minimumStep);
@ -301,7 +301,7 @@ TimeAxis.prototype._repaintMinorLine = function (x, orientation) {
line.style.top = props.majorLabelHeight + 'px';
}
else {
line.style.top = this.timeline.props.top.height + 'px';
line.style.top = this.body.props.top.height + 'px';
}
line.style.height = props.minorLineHeight + 'px';
line.style.left = (x - props.minorLineWidth / 2) + 'px';
@ -330,7 +330,7 @@ TimeAxis.prototype._repaintMajorLine = function (x, orientation) {
line.style.top = '0';
}
else {
line.style.top = this.timeline.props.top.height + 'px';
line.style.top = this.body.props.top.height + 'px';
}
line.style.left = (x - props.majorLineWidth / 2) + 'px';
line.style.height = props.majorLineHeight + 'px';

Loading…
Cancel
Save