Loading...
The Timebar plugin is an important tool for exploring time-series data. It can display the time distribution of data in the form of a timeline or trend chart, and supports interactions such as time interval filtering and dynamic playback, helping users better understand the changes in data over time.
Below is a simple example of initializing the Timebar plugin:
const graph = new Graph({plugins: [{type: 'timebar',data: timeData, // Time datawidth: 450, // Timebar widthheight: 60, // Timebar heightposition: 'bottom', // Positionloop: false, // Whether to loop playback},],});
createGraph({data: {nodes: new Array(25).fill(0).map((_, index) => ({id: `node-${index}`,data: {timestamp: new Date('2023-08-01').getTime() + (index % 5) * 3600 * 24 * 1000,value: index % 10,label: new Date(new Date('2023-08-01').getTime() + (index % 5) * 3600 * 24 * 1000).toLocaleString(),},})),edges: new Array(25).fill(0).map((_, i) => ({id: `edge-${i}`,source: `node-${i % 12}`,target: `node-${(i % 10) + 15}`,data: {edgeType: 'e1',},})),},layout: { type: 'grid', cols: 5 },node: {style: { size: 24, fill: '#7e3feb' },palette: { field: 'cluster' },},edge: { style: { stroke: '#8b9baf' } },behaviors: ['drag-canvas'],plugins: ['grid-line',{type: 'timebar',key: 'timebar',data: [10, 2, 3, 4, 15].map((value, index) => ({time: new Date(new Date('2023-08-01').getTime() + index * 3600 * 24 * 1000),value,label: new Date(new Date('2023-08-01').getTime() + index * 3600 * 24 * 1000).toLocaleString(),})),timebarType: 'time',height: 100,},],autoFit: 'view',padding: [10, 0, 100, 0],},{ width: 600, height: 400 },(gui, graph) => {const options = {type: 'timebar',position: 'bottom',enable: true,timebarType: 'time',className: 'g6-timebar',width: 450,height: 100,zIndex: 3,elementTypes: ['node'],mode: 'modify',loop: false,};const optionFolder = gui.addFolder('Timebar Options');optionFolder.add(options, 'type').disable(true);optionFolder.add(options, 'height', 40, 100, 1);optionFolder.add(options, 'width', 200, 800, 1);optionFolder.add(options, 'position', ['bottom', 'top']);optionFolder.add(options, 'timebarType', ['time', 'chart']);optionFolder.add(options, 'loop');optionFolder.onChange(({ property, value }) => {graph.updatePlugin({key: 'timebar',[property]: value,});graph.render();});const apiFolder = gui.addFolder('Timebar API');const instance = graph.getPluginInstance('timebar');apiFolder.add(instance, 'play');apiFolder.add(instance, 'pause');apiFolder.add(instance, 'forward');apiFolder.add(instance, 'backward');apiFolder.add(instance, 'reset');},);
Property | Description | Type | Default Value | Required |
---|---|---|---|---|
type | Plugin type | string | timebar | ✓ |
key | Unique identifier for the plugin, can be used to get the plugin instance or update plugin options | string | - | |
className | Additional class name for the toolbar DOM | string | g6-timebar | |
x | X position (position will be invalid if set) | number | - | |
y | Y position (position will be invalid if set) | number | - | |
width | Timebar width | number | 450 | |
height | Timebar height | number | 60 | |
position | Timebar position | bottom | top | bottom | |
padding | Padding | number | number[] | 10 | |
data | Time data | number[] | { time: number; value: number }[] | - | ✓ |
timebarType | Timebar display type | time | chart | time | |
elementTypes | Filter element types | (node | edge | combo )[] | [node ] | |
mode | Control element filtering method, supports the following two configurations: - modify : filter by modifying graph data - visibility : filter by modifying element visibility | modify | visibility | modify | |
values | Current time value | number | [number, number] | Date | [Date, Date] | - | |
loop | Whether to loop playback | boolean | false | |
getTime | Method to get element time | (datum: ElementDatum) => number | - | |
labelFormatter | Custom time formatting in chart mode | (time: number | Date) => string | - | |
onChange | Callback when the time interval changes | (values: number | [number, number]) => void | - | |
onReset | Callback when reset | () => void | - | |
onSpeedChange | Callback when playback speed changes | (speed: number) => void | - | |
onPlay | Callback when playback starts | () => void | - | |
onPause | Callback when paused | () => void | - | |
onBackward | Callback when moving backward | () => void | - | |
onForward | Callback when moving forward | () => void | - |
The timebarType
property is used to control the display type of the timebar, supporting the following two configurations:
time
: Displayed as a timeline, refer to Time Mode Examplechart
: Displayed as a trend chart, at this time the data
configuration item under timebar
needs to pass an additional value
field as chart data, refer to Chart Mode ExampleThe simplest configuration method:
const graph = new Graph({layout: { type: 'grid', cols: 5 },plugins: [{type: 'timebar',data: [{time: new Date('2023-08-01').getTime(),value: 5,},{time: new Date('2023-08-02').getTime(),value: 10,},{time: new Date('2023-08-03').getTime(),value: 15,},],},],data: {nodes: [{id: 'node1',label: 'Node 1',// By default, elementTypes=['node'], so nodes need to set data.timestamp to display sequentially according to the timelinedata: {timestamp: new Date('2023-08-01').getTime(),},},{id: 'node2',label: 'Node 2',data: {timestamp: new Date('2023-08-02').getTime(),},},{id: 'node3',label: 'Node 3',data: {timestamp: new Date('2023-08-03').getTime(),},},],edges: [{id: 'edge1',source: 'node1',target: 'node2',// Scenario 1: By default, elementTypes = ['node']// - Edges do not need to set data.timestamp, the display/hide of edges depends entirely on whether the two connected nodes are visible// Scenario 2: If elementTypes includes 'edge', for example, elementTypes = ['node', 'edge']// - At this time, edges must set data.timestamp, and the display of edges is controlled by it// data: {// timestamp: new Date('2023-08-01').getTime()// }},{id: 'edge2',source: 'node2',target: 'node3',},{id: 'edge3',source: 'node3',target: 'node1',},],},});
The effect is as follows:
createGraph({width: 600,height: 400,layout: { type: 'grid', cols: 5 },plugins: [{type: 'timebar',data: [{time: new Date('2023-08-01').getTime(),value: 5,},{time: new Date('2023-08-02').getTime(),value: 10,},{time: new Date('2023-08-03').getTime(),value: 15,},],},],data: {nodes: [{id: 'node1',label: 'Node 1',data: {timestamp: new Date('2023-08-01').getTime(),},},{id: 'node2',label: 'Node 2',data: {timestamp: new Date('2023-08-02').getTime(),},},{id: 'node3',label: 'Node 3',data: {timestamp: new Date('2023-08-03').getTime(),},},],edges: [{id: 'edge1',source: 'node1',target: 'node2',},{id: 'edge2',source: 'node2',target: 'node3',},{id: 'edge3',source: 'node3',target: 'node1',},],},},{ width: 600, height: 400 },);
width
, height
, padding
, className
can customize the display effect of the timebar, but note that className
only acts on the outer DOM container and cannot affect the internal Canvas rendering content of the timebar (timeline, chart, play button, etc.).
const graph = new Graph({plugins: [{type: 'timebar',className: 'custom-timebar', // Note: Since the content is Canvas rendered, CSS styles cannot affect the internal content of the timebarwidth: 400, // Set timebar widthheight: 80, // Set timebar heightpadding: [20, 20, 10, 20], // Set padding [top, right, bottom, left]position: 'bottom', // Keep position at the bottomdata: timeData,// labelFormatter: (time) => {// return new Date(time).toLocaleDateString();// }},],});
CSS can only set the style of the timebar container:
.custom-timebar {background-color: #f0f0f0;border: 1px solid #ccc;border-radius: 5px;box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);}
The effect is as follows:
createGraph({data: () => {return {nodes: [{id: 'node1',style: { x: 100, y: 100, label: 'Node 1' },data: {timestamp: new Date('2023-08-01').getTime(),},},{id: 'node2',style: { x: 200, y: 100, label: 'Node 2' },data: {timestamp: new Date('2023-08-01').getTime() + 3600 * 24 * 1000,},},{id: 'node3',style: { x: 150, y: 200, label: 'Node 3' },data: {timestamp: new Date('2023-08-01').getTime() + 3600 * 24 * 1000 * 2,},},],edges: [{ id: 'edge1', source: 'node1', target: 'node2' },{ id: 'edge2', source: 'node2', target: 'node3' },{ id: 'edge3', source: 'node3', target: 'node1' },],};},node: {style: {size: 20,label: true,},},edge: {style: {stroke: '#91d5ff',lineWidth: 1,},},plugins: [{type: 'timebar',className: 'custom-timebar',width: 400,height: 80,padding: [20, 20, 10, 20],position: 'bottom',data: [{time: new Date('2023-08-01').getTime(),value: 5,},{time: new Date('2023-08-01').getTime() + 3600 * 24 * 1000,value: 10,},{time: new Date('2023-08-01').getTime() + 3600 * 24 * 1000 * 2,value: 15,},],labelFormatter: (time) => {return new Date(time).toLocaleDateString();},},],},{ width: 600, height: 400 },(gui, graph) => {gui?.hide();const style = document.createElement('style');style.innerHTML = `.custom-timebar {background-color: #f0f0f0;border: 1px solid #ccc;border-radius: 5px;box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);}`;document.head.appendChild(style);},);