Scroll Timeline Chart – foreignObject(SVG) and brush component
Use HTML element in SVG to create Timeline Chart
My recent extension for SAP Lumira was developed based on the requirements of several different customers. This extension creates a standard timeline chart with some extra features. A timeline chart is a way of displaying a list of events in chronological order, sometimes described as a project artifact. It is typically a graphic design showing a long bar labelled with dates alongside itself and usually events labelled on points where they would have happened.
The Scroll & Zoom Timeline Bar Chart create a horizontal bar chart that depicts how a set of resources are used over time. This extension creates a beautiful timeline chart to shows a series of events in a horizontal time-sorted rectangle. The Y Axis present the name for each project or phase (including multiple projects). This visualization can’t show more than eight rows in the same view, and if there are more rows, it will automatically generate a vertical scroll bar. The vertical scrolling bar can fit for more content.
The X Axis plot each row’s term as one or more bars. The layout of the bars is determined solely by the start times and arranged in ascending order of start times. The dataset for this extension has to include a numeric column as a measure in Lumira, which could be any random number without particular meaning. This extension could display each project per row or each phase (including multiple projects) per row.
There is a scaling controller on the bottom of the chart, which zooms timeline chart in the horizontal direction. – The vertical scrolling bar can make sure visible and clear if there are a large number of projects. The extension also including a horizontal controller use D3’s brush component to implement focus and context zooming. Click and drag the small gray rectangle below to pan or zoom. Hovering over a bar brings up a tooltip with more detailed information.
Step 1 What is foreignObject
The foreignObject element allows for the inclusion of a foreign XML namespace which has its graphical content drawn by a different user agent. The included foreign graphical content is subject to SVG transformations and compositing.
The contents of foreignObject are assumed to be from a different namespace. Any SVG elements within a foreignObject will not be drawn, except in the situation where a properly defined SVG subdocument with a proper xmlns attribute specification is embedded recursively.
Step 2 Mapping data
The data set for Timeline chart need to including three key elements. Start Date, End Date and Phase/project name.
The “Duration” is necessary for Lumira, but you can use Excel or Lumira to calculate the date. You need to make sure that the end date has to later than the start date of each row.
Step 3 Create container of components
There are three key components in this extension:
- Y axis of phase name and all bars,
- X axis of date
- selectable date overview controller
Each of the components will append inside an independent g element, which is a container used to group other SVG elements. To make sure the y-axis can be synchronized scroll with all of other bars, the group of y-axis and chart bars will append inside the foreignobject element. There is the HTML structure of three components in the visual room of Lumira.
(Click image to show the gif animation)
In this extension, it only needs render scrollbar on the y-axis. So, I assign the overflow-x and overflow-y properties with the different value.
See the following graph to deeply understand the structure of the extension.
Step 4 Define axis, date overview controller and max rows
Define the container for the x-axis, y-axis, and date overview.
Declare the d3 scale function to invokes the specified xDateoverviewGrid to build the dateoverview controller.
The dataBrush() is the key function to define the date overview controller and a brushed() function to redraw the x.scale(), timeline bars and the x-axis.
Another critical step is to calculate the maxHeight of y.scale() function.
Step 5 Call the d3.gantt() and create timeline bars
The rest part of the code just append “rect” in the SVG to create bars for timeline chart. You can check the extension in SAP/lumira-extension-viz · GitHub for more details.