ngx-timeline-vertical

What is Angular Timline Vertical? * Dependencies * Install * Example * Create a timeline * Add an event * Add a point * Add a line * Wrapping up * FAQ * Troubleshooting * How to Contribute * License

Usage no npm install needed!

<script type="module">
  import ngxTimelineVertical from 'https://cdn.skypack.dev/ngx-timeline-vertical';
</script>

README

ngx-timeline-vertical - Angular vertical timeline widget

version build minified

Table of Contents

What is Angular Timeline Vertical?

ngx-timeline-vertical is an Angular library that can be imported into any Angular application for quick creation of a vertical timeline. ngx-timeline-vertical is responsive and lightweight. The code can be viewed on github. Created by Alec Kendall.

Dependencies

ngx-timeline-vertical Angular
current >=9.x

Install

Navigate to your project directory:

cd example-app

Install ngx-timeline-vertical through npm:

npm install --save ngx-timeline-vertical

Example

Create a timeline

Create an Angular application:

ng new example-app

Navigate to the project directory:

cd example-app

Install ngx-timeline-vertical through npm:

npm install --save ngx-timeline-vertical

Import the NgxTimelineVerticalModule into your AppModule.ts:

import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { AppRoutingModule } from './app-routing.module';

//Import the NgxTimelineVerticalModule
import { NgxTimelineVerticalModule } from 'ngx-timeline-vertical';
import { AppComponent } from './app.component';

@NgModule({
  declarations: [
    AppComponent
  ],
  //Add the NgxTimelineVerticalModule
  imports: [
    BrowserModule,
    AppRoutingModule,
    NgxTimelineVerticalModule
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }

Import the Event, Point, Line, TimelineProperties, TimelineSegment types into app.component.ts:

import { Event, Point, Line, TimelineProperties, TimlineSegment } from 'ngx-timeline-vertical';

Add the NgxTimelineComponent selector to app.component.html:

<ngx-timeline></ngx-timeline>

NgxTimelineComponent has four Input properties:

timelineThickness: string;
startpoint: Point;
endpoint: Point;
timelineSegments: TimelineSegment[]

startpoint and endpoint are optional Input properties.

In app.component.ts, create the variables to pass to NgxTimelineComponent's Input properties. You can give them a name of your choice. In this example, each variable name mirrors the Input property it will be binded to.

Your app.component.ts should now contain:

import { Component } from '@angular/core';
import { Event, Point, Line, TimelineProperties, TimlineSegment } from 'ngx-timeline-vertical';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent {
  title = 'example-app';
  
  timelineThickness: string;
  startpoint: Point;
  endpoint: Point;
  //Ensure timelineSegments is initialized to an empty array. You will later push a TimelineSegment 
  //to this array. If the variable isn't initialized, Angular will throw an error.
  timelineSegments: TimelineSegment[] = [];

  ngOnInit() {
    
  }
}

Create a function to initialize startpoint and endpoint:

ngxPointInit(): void {
    //The Point constructor takes _size: string, _color: string, _borderRadius: string
    this.startpoint = new Point('40px', '#B10CC8', '30px');
    this.endpoint = new Point('40px', '#B10CC8', '30px');
}

Create a function to initialize timelineThickness:

ngxTimelineThicknessInit(): void {
    this.timelineThickness = '20px';
}

Create a function to populate timelineSegments. Leave it blank for now:

ngxTimelineSegmentsInit(): void {
    
}

The TimelineSegment constructor takes four fields, in order of appearance:

_timelineProperties: TimelineProperties;
_Point: Point;
_Event: Event;
_Line: Line;

By default these fields are set to:

_timelineProperties: TimelineProperties = new TimelineProperties();
_Point: Point = null;
_Event: Event = new Event();
_Line: Line = null;

Create a default TimelineSegment in ngxTimelineSegmentsInit():

ngxTimelineSegmentsInit(): void {
    //The constructor is left empty, creating a default TimelineSegment
    let timelineSegment: TimelineSegment = new TimelineSegment();
}

Push the created TimelineSegment onto the timelineSegments array:

ngxTimelineSegmentsInit(): void {
    //The constructor is left empty, creating a default TimelineSegment
    let timelineSegment: TimelineSegment = new TimelineSegment();
    this.timelineSegments.push(timelineSegment);
}

Call ngxPointInit(), ngxTimelineThicknessInit(), and ngxTimelineSegmentsInit() from within ngOnInit():

ngOnInit() {
  this.ngxPointInit();
  this.ngxTimelineThicknessInit();
  this.ngxTimelineSegmentsInit();
}

Your app.component.ts should now contain:

import { Component } from '@angular/core';
import { Point, TimelineSegment, Line, Event } from 'ngx-timeline-vertical';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent {
  title = 'example-app';

  endpoint: Point;
  startpoint: Point;
  timelineThickness: string;
  timelineSegments: TimelineSegment[] = [];

  ngOnInit() {
    this.ngxPointInit();
    this.ngxTimelineThicknessInit();
    this.ngxTimelineSegmentsInit();
  }

  ngxPointInit(): void {
    //The Point constructor takes _size: string, _color: string, _borderRadius: string
    this.startpoint = new Point('40px', '#B10CC8', '30px');
    this.endpoint = new Point('40px', '#B10CC8', '30px');
  }
  
  ngxTimelineThicknessInit(): void {
    this.timelineThickness = '20px';
  }

  ngxTimelineSegmentsInit(): void {
      //The constructor is left empty, creating a default TimelineSegment
      let timelineSegment: TimelineSegment = new TimelineSegment();
      this.timelineSegments.push(timelineSegment);
  }
}

In app.component.html, bind your app.component.ts variables to <ngx-timeline></ngx-timline> Input properties:

<ngx-timeline
[timelineThickness]="timelineThickness"
[startpoint]="startpoint"
[endpoint]="endpoint"
[timelineSegments]="timelineSegments"
></ngx-timeline>

Serve your Angular application:

ng serve

Open a browser and navigate to the link provided by Angular:

localhost:4200

You should see:

ngx-timeline-vertical

Add an event

This section builds off of Create a timeline.

The Event constructor takes four fields, in order of appearance:

_fontColor: string;
_fontSize: string;
_side: string;
_text: string;

By default these values are set to:

_fontColor: string = '#5D21D0'
_fontSize: string  = '16px', 
_side: string = 'right'
_text: string = ''

Create a function in app.component.ts named addEvent():

addEvent(): void {

}

Create a default TimelineSegment in addEvent():

addEvent(): void {
    let timelineSegment: TimelineSegment = new TimelineSegment();
}

If an Event is not passed to the constructor, TimelineSegment will initialize Event to a its default values. You can access the Event of a TimelineSegment by calling getEvent() on the corresponding TimlineSegment. From there, you can change any of the four fields within the Event by calling the desired field's setter function: setFontColor(), setFontSize(), setSide(), and setText().

Change your Event's text to the string 'This event was added':

addEvent(): void {
    let timelineSegment: TimelineSegment = new TimelineSegment();
    
    //Set the text to 'This event was added'.
    timelineSegment.getEvent().setText('This event was added');
}

By default, an Event will be displayed on the right side of a timeline. The Event's side field accepts the strings 'left' or 'right'.

Change your Event's side field to display text on the left side of the timeline:

addEvent(): void {
    let timelineSegment: TimelineSegment = new TimelineSegment();
    
    //Set the text to 'This event was added'.
    timelineSegment.getEvent().setText('This event was added');
    
    //Set the Event side to be on the 'left' of the timeline.
    timelineSegment.getEvent().setSide('left');
}

Add a point

This section builds off of Add an event.

The Point constructor takes three fields, in order of appearance:

_size: string;
_color: string;
_borderRadius: string;

By default these values are set to:

_size: string  = '30px';
_color: string = '#39CCCC';
_borderRadius: string = '30px';

If a Point is not passed to the constructor, TimelineSegment will set it to null. You can set the Point of a TimelineSegment by calling setPoint() and passing as an argument to setPoint() a Point. You can then access the Point by calling getPoint() on TimelineSegment. From there, you can change any of the three fields within Point by calling the desired field's setter function: setSize(), setColor(), and setBorderRadius().

Create a Point in the function addEvent(). Set size to '20px', color to 'red', and borderRadius to '30px':

addEvent(): void {
    let timelineSegment: TimelineSegment = new TimelineSegment();
    
    //Set the text to 'This event was added'.
    timelineSegment.getEvent().setText('This event was added');
    
    //Set the Event side to be on the 'left' of the timeline.
    timelineSegment.getEvent().setSide('left');
    
    //Create a new point with a size of '20px', color of 'red', and borderRadius of '30px'. 
    let point: Point = new Point('20px', 'red', '30px');
}

Add the Point to timelineSegment:

addEvent(): void {
    let timelineSegment: TimelineSegment = new TimelineSegment();
    
    //Set the text to 'This event was added'.
    timelineSegment.getEvent().setText('This event was added');
    
    //Set the Event side to be on the 'left' of the timeline.
    timelineSegment.getEvent().setSide('left');
    
    //Create a new point with a size of '20px', color of 'red', and borderRadius of '30px'. 
    let point: Point = new Point('20px', 'red', '30px');
    
    //Set timelineSegment's point to point.
    timelineSegment.setPoint(point);
}

Add a line

This section builds off of Add a point.

The Line constructor takes three fields, in order of appearance:

_style: string;
_color: string;
_thickness: string;

By default these values are set to:

_style: string = 'solid';
_color: string = '#39CCCC';
_thickness: string  = '2px';

If a Line is not passed to the constructor, TimelineSegment will set it to null. You can set the Line of a TimelineSegment by calling setLine() and passing as an argument to setLine() a Line. You can then access the Line by calling getLine() on TimelineSegment. From there, you can change any of the three fields within Line by calling the desired field's setter function: setStyle(), setColor(), and setThickness().

Create a default Line in function addEvent():

addEvent(): void {
    let timelineSegment: TimelineSegment = new TimelineSegment();

    //Set the text to 'This event was added'.
    timelineSegment.getEvent().setText('This event was added');

    //Set the Event side to be on the 'left' of the timeline.
    timelineSegment.getEvent().setSide('left');

    //Create a new point with a size of '20px', color of 'red', and borderRadius of '30px'. 
    let point: Point = new Point('20px', 'red', '30px');

    //Set timelineSegment's point to point.
    timelineSegment.setPoint(point);

    //Create a default line
    let line: Line = new Line();
}

Change the Line style to 'dashed':

addEvent(): void {
    let timelineSegment: TimelineSegment = new TimelineSegment();
           
    //Set the text to 'This event was added'.
    timelineSegment.getEvent().setText('This event was added');

    //Set the Event side to be on the 'left' of the timeline.
    timelineSegment.getEvent().setSide('left');

    //Create a new point with a size of '20px', color of 'red', and borderRadius of '30px'. 
    let point: Point = new Point('20px', 'red', '30px');

    //Set timelineSegment's point to point.
    timelineSegment.setPoint(point);

    //Create a default line
    let line: Line = new Line();

    //Change the line style to 'dashed'
    line.setStyle('dashed');
}

Add the Line to timelineSegment:

addEvent(): void {
    let timelineSegment: TimelineSegment = new TimelineSegment();
           
    //Set the text to 'This event was added'.
    timelineSegment.getEvent().setText('This event was added');

    //Set the Event side to be on the 'left' of the timeline.
    timelineSegment.getEvent().setSide('left');

    //Create a new point with a size of '20px', color of 'red', and borderRadius of '30px'. 
    let point: Point = new Point('20px', 'red', '30px');

    //Set timelineSegment's point to point.
    timelineSegment.setPoint(point);

    //Create a default line
    let line: Line = new Line();

    //Change the line style to 'dashed'
    line.setStyle('dashed');

    //Add line to timelineSegment
    timelineSegment.setLine(line);
}

Your app.component.ts should now look like:

import { Component } from '@angular/core';
import { Point, TimelineSegment, Line, Event } from 'ngx-timeline-vertical';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent {
  title = 'example-app';

  endpoint: Point;
  startpoint: Point;
  timelineThickness: string;
  timelineSegments: TimelineSegment[] = [];

  ngOnInit() {
    this.ngxPointInit();
    this.ngxTimelineThicknessInit();
    this.ngxTimelineSegmentsInit();
  }

  ngxPointInit(): void {
    //The Point constructor takes _size: string, _color: string, _borderRadius: string
    this.startpoint = new Point('40px', '#B10CC8', '30px');
    this.endpoint = new Point('40px', '#B10CC8', '30px');
  }
  
  ngxTimelineThicknessInit(): void {
    this.timelineThickness = '20px';
  }

  ngxTimelineSegmentsInit(): void {
    //The constructor is left empty, creating a default TimelineSegment
    let timelineSegment: TimelineSegment = new TimelineSegment();
    this.timelineSegments.push(timelineSegment);
  }
  
  addEvent(): void {
    let timelineSegment: TimelineSegment = new TimelineSegment();
             
    //Set the text to 'This event was added'.
    timelineSegment.getEvent().setText('This event was added');

    //Set the Event side to be on the 'left' of the timeline.
    timelineSegment.getEvent().setSide('left');

    //Create a new point with a size of '20px', color of 'red', and borderRadius of '30px'. 
    let point: Point = new Point('20px', 'red', '30px');

    //Set timelineSegment's point to point.
    timelineSegment.setPoint(point);

    //Create a default line
    let line: Line = new Line();

    //Change the line style to 'dashed'
    line.setStyle('dashed');

    //Add line to timelineSegment
    timelineSegment.setLine(line);
  }
}

Wrapping up

Within addEvent(), push timelineSegment to timelineSegments:

addEvent(): void {
    let timelineSegment: TimelineSegment = new TimelineSegment();
             
    //Set the text to 'This event was added'.
    timelineSegment.getEvent().setText('This event was added');

    //Set the Event side to be on the 'left' of the timeline.
    timelineSegment.getEvent().setSide('left');

    //Create a new point with a size of '20px', color of 'red', and borderRadius of '30px'. 
    let point: Point = new Point('20px', 'red', '30px');

    //Set timelineSegment's point to point.
    timelineSegment.setPoint(point);

    //Create a default line
    let line: Line = new Line();

    //Change the line style to 'dashed'
    line.setStyle('dashed');

    //Add line to timelineSegment
    timelineSegment.setLine(line);
    
    //Push timelineSegment to timelineSegments
    this.timelineSegments.push(timelineSegment);
}

Add a button to app.component.html and bind it's (click) listener to addEvent():

<ngx-timeline
[timelineThickness]="timelineThickness"
[startpoint]="startpoint"
[endpoint]="endpoint"
[timelineSegments]="timelineSegments"
></ngx-timeline>
<button (click)="addEvent()">Click Me!</button>

Your app.component.ts, without comments, should now look like this:

import { Component } from '@angular/core';
import { Point, TimelineSegment, Line, Event } from 'ngx-timeline-vertical';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent {
  title = 'example-app';

  endpoint: Point;
  startpoint: Point;
  timelineThickness: string;
  timelineSegments: TimelineSegment[] = [];

  ngOnInit() {
    this.ngxPointInit();
    this.ngxTimelineThicknessInit();
    this.ngxTimelineSegmentsInit();
  }

  ngxPointInit(): void {
    this.startpoint = new Point('40px', '#B10CC8', '30px');
    this.endpoint = new Point('40px', '#B10CC8', '30px');
  }
  
  ngxTimelineThicknessInit(): void {
    this.timelineThickness = '20px';
  }

  ngxTimelineSegmentsInit(): void {
    let timelineSegment: TimelineSegment = new TimelineSegment();
    this.timelineSegments.push(timelineSegment);
  }
  
  addEvent(): void {
    let timelineSegment: TimelineSegment = new TimelineSegment();
    timelineSegment.getEvent().setText('This event was added');
    timelineSegment.getEvent().setSide('left');
    let point: Point = new Point('20px', 'red', '30px');
    timelineSegment.setPoint(point);
    let line: Line = new Line();
    line.setStyle('dashed');
    timelineSegment.setLine(line);
    this.timelineSegments.push(timelineSegment);
  }
}

Run your application:

ng serve

Open a browser and navigate to the link provided by Angular:

localhost:4200

Click the button and you should now see:

demo

FAQs

  1. Can I change the timeline thickness?

    • Yes. The timeline thickness is an Input property of the NgxTimelineComponent. It can be changed by passing a value to [timelineThickness]:

    <ngx-timeline [timelineThickness]="{{ your_thickness_variable }}"></ngx-timeline>

  2. Can I change the font color or size?

    • Yes. The font size and color can be changed by calling setFontSize() and setFontColor() on the corresponding Event.
  3. Can I change the timeline height?

    • Yes. Timeline segments have a minimum height. It can be set by calling setHeight() on the corresponding timelineProperties.
  4. Can I change the timeline color?

    • Yes. The timeline color can be changed by calling setColor() on the corresponding timelineProperties.
  5. Can I make the timeline horizontal?

    • Not currently.

Troubleshooting

  1. Report an issue on github.
  2. Reach out to me directly.

How to Contribute

Contributions are not currently being accepted (but will be). If you enjoy the library, check out my site and follow along with my other projects. You can also contact me on my contact page if you have any recommendations or just want to chat. This is the first Angular library I've ever made so please do not hesitate to reach out to me with any suggestions you have!

License

Licensed under the MIT license.