Timeline VerticalScrollbar

From SIMILE Widgets
Jump to: navigation, search

Add a vertical scrollbar to your timeline

Add the following CSS to your timeline container.

.your-timeline-container { overflow-x:hidden; overflow-y:scroll;}

This will enabled a vertical scrollbar when you have many events but you will notice that timeline doesn't draw itself completely in the lower part like so: Before.jpg

it's because its height is calculated with the container's starting height. If you take a quick look in the DOM using Firebug, you'll notice the height is within the container's style attribute. Bingo! now we just need to find the function that does the calculation or that adds the height to the container.

Find the setBandShiftAndWidth function in the timeline.js file and modify the following line :

this._div.style.height = width + "px";


this._div.style.height = "100%";

Change the mouseWheel setting in your theme to 'default' See MouseWheelScrollingAndZooming and Timeline_ThemeClass

thats it!

here's what it looks like now:

Really now.jpg

Scroll Horizontally and Vertically

This will enable you to scroll in both directions you just click and drag in any direction. And allow you to still have an overview band on the screen.

2 files need to be changed the band.js and ether-painter.js Just add the code to the bottom of the files.

band.js code

// Holds the original MoveEther method to be called before wo carry out our modified method
Timeline._Band.prototype._oldMoveEther = Timeline._Band.prototype._moveEther;

// The top position of the band in the viewable area
Timeline._Band.prototype._viewOffsetY = null;

// the starting position of the top of the band in the viewable area..
// this is as the overview band is displayed at the bottom of the viewable area
// and this is done by modifying the style.top on the band
Timeline._Band.prototype._startViewOffsetY = null;

// move the either unless it was called with only 1 param then
// call the original code.
Timeline._Band.prototype._moveEther = function(shiftX, shiftY) {
    if (typeof (shiftY) == 'undefined') {


    // A positive shift means back in time
    // Check that we're not moving beyond Timeline's limits
    if (!this._timeline.shiftOK(this._index, shiftX)) {
        return; // early return

    // if the start position is at the top then keep it there.
    if (this._viewOffsetY == null) {
        this._viewOffsetY = $(this._div).position().top;
        this._startViewOffsetY = this._viewOffsetY;

    this._viewOffset += shiftX;
    this._ether.shiftPixels(-shiftX); //Horizontal Shifting

    this._div.style.left = this._viewOffset + "px";
    if ((-(this._viewOffsetY + shiftY)) > 0) {
        // dont allow move if past the last tape on the screen
        if ((-(this._viewOffsetY + shiftY)) <= this.maxHeight) {
            this._viewOffsetY += shiftY; //Total Pixels Moved Vertically
            this._div.style.top = this._viewOffsetY + "px";
        } else {
            // if trying to put past last tape set to last tape position
            this._viewOffsetY = -this.maxHeight; //Total Pixels Moved Vertically
            this._div.style.top = this._viewOffsetY + "px";
    } else {
        this._viewOffsetY = this._startViewOffsetY;
        this._div.style.top = this._startViewOffsetY + "px";

    if (this._viewOffset > -this._viewLength * 0.5 ||
        this._viewOffset < -this._viewLength * (Timeline._Band.SCROLL_MULTIPLES - 1.5)) {

    } else {


Timeline._Band.prototype._onMouseMove = function(innerFrame, evt, target) {
    if (this._dragging) {

        var diffX = evt.clientX - this._dragX;
        var diffY = evt.clientY - this._dragY;

        this._dragX = evt.clientX;
        this._dragY = evt.clientY;

        this._moveEther(diffX, diffY);

        // moveBy the lines and the interval markers i.e 1980 1990



/// The maximum height of the control based on the last tapes position and height.
Timeline._Band.prototype.maxHeight = 0;

//  This will load up a previously saved position and zoom and show the save detail as before
//  This data would have been saved using the navigate method on a click event from the timeline bubble.
/// minDate = minimum visible date
/// maxDate = maximum visible date
/// curDate = center the control on this date
/// zoomLevel = the zoom level to return to
/// offsetY = the position from the top of the control.
Timeline._Band.prototype.setPosition = function(minDate, maxDate, centerDate, zoomLevel, viewOffsetY) {
    var x, y;
    x = 0;
    y = 0;

    var currentZoom = this._zoomIndex;
    this._viewOffsetY = parseInt(viewOffsetY);
    this._startViewOffsetY = 0;
    // will zoom in to the correct level.. done this way to prevent duplicating 
    // lots of the controls code..
    for (cou = currentZoom; cou > zoomLevel; cou--) {
        this.zoom(true, x, y, this._div);

    if (currentZoom == zoomLevel) {
        this.zoom(true, x, y, this._div);
        this.zoom(false, x, y, this._div);


    // After painting the ether reposition the band to its offsetY
    // this it to bypass the protection against positioning off screen by user.
    this._div.style.top = this._viewOffsetY + "px";


// This gets the current view position and zoom lovel
/// url = the url to append the attributes to
Timeline._Band.prototype.currentPositionURL = function(url) {
    var minDate = this.getMinVisibleDate();
    var maxDate = this.getMaxVisibleDate()
    var curDate = this.getCenterVisibleDate()

    var zoomIndex = this._zoomIndex;

    url = addParameter(url, 'minDate', minDate.getTime());
    url = addParameter(url, 'maxDate', maxDate.getTime());
    url = addParameter(url, 'curDate', curDate.getTime());
    url = addParameter(url, 'zoomIndex', zoomIndex);
    url = addParameter(url, 'viewOffsetY', this._viewOffsetY);
    return url;

ether-painter.js code:

Timeline.GregorianEtherPainter.prototype.oldPaint = Timeline.GregorianEtherPainter.prototype.paint;

// this is done to move the lines and markers when you zoom in as after it
// changes the position of the lines and markers on the zoom it repaints
// which removes and adds back the markers.
Timeline.GregorianEtherPainter.prototype.paint = function() {

// Redraws the lines and markers and background at the new position using the bands top offset.
Timeline.GregorianEtherPainter.prototype.redrawLinesAndMarkers = function() {
    if ((-(this._band._viewOffsetY)) > 0) {
        // moveBy the lines and the interval markers i.e 1980 1990
        this._lineLayer.style.top = (-(this._band._viewOffsetY)) + "px";
        this._markerLayer.style.top = (-(this._band._viewOffsetY)) + "px";

        // change the background height using 5000px as a default in case we haven't worked out the 
		// max required height should never be called for the current sample tho..
        if (this.maxHeight > 0) {
            var viewHeight = $(this._eventLayer).height();
            this._backgroundLayer.style.height = (this._band.maxHeight + viewHeight) + "px";
        } else {
            this._backgroundLayer.style.height = "5000px";

[Editor's Note: Comments from the code.google wiki that were of the "this doesn't work" variety, or feature requests have been omited.]
Personal tools