mirror of
https://gitee.com/antv/g6.git
synced 2024-11-30 10:48:24 +08:00
fix: timebar date undefined problem. docs: update the english version plugins docs and the demos about timebar.
This commit is contained in:
parent
a159b69307
commit
9416d34827
@ -2,8 +2,9 @@
|
||||
|
||||
#### 3.6.0
|
||||
- feat: fisheye lens plugin;
|
||||
- feat: TimeBar & ToolBar plugin;
|
||||
- feat: lasso-select behavior.
|
||||
- feat: lasso-select behavior;
|
||||
- feat: TimeBar plugin;
|
||||
- feat: ToolBar plugin.
|
||||
|
||||
#### 3.5.12
|
||||
- fix: node:click is triggered twice while clicking a node;
|
||||
|
@ -174,39 +174,39 @@ const graph = new G6.Graph({
|
||||
|
||||
## ToolBar
|
||||
|
||||
ToolBar 集成了以下常见的操作:
|
||||
- 重做;
|
||||
- 撤销;
|
||||
- 放大;
|
||||
- 缩小;
|
||||
- 适应屏幕;
|
||||
- 实际大小。
|
||||
ToolBar has the following operations by default:
|
||||
- Undo;
|
||||
- Redo;
|
||||
- Zoom-in;
|
||||
- Zoom-out;
|
||||
- Fit the View;
|
||||
- Actual Size.
|
||||
|
||||
### Configuration
|
||||
|
||||
| 名称 | 类型 | 默认值 | 描述 |
|
||||
| Name | Type | Default | Description |
|
||||
| --- | --- | --- | --- |
|
||||
| container | HTMLDivElement | null | ToolBar 容器,如果不设置,则默认使用 canvas 的 DOM 容器 |
|
||||
| className | string | null | ToolBar 内容元素的 class 类名 |
|
||||
| getContent | (graph?: IGraph) => HTMLDivElement | string | <img src='https://gw.alipayobjects.com/mdn/rms_f8c6a0/afts/img/A*7QSRRJwAWxQAAAAAAAAAAABkARQnAQ' width=80 alt='img'/> | ToolBar 内容,支持 DOM 元素或字符串 |
|
||||
| handleClick | (code: string, graph: IGraph) => void | undefined | 点击 ToolBar 中每个图标的回调函数 |
|
||||
| position | Point | null | ToolBar 的位置坐标 |
|
||||
| container | HTMLDivElement | null | The container of the ToolBar. It will take use the DOM of the canvas by default |
|
||||
| className | string | null | The class name of the sub DOM nodes of the ToolBar |
|
||||
| getContent | (graph?: IGraph) => HTMLDivElement / string | <img src='https://gw.alipayobjects.com/mdn/rms_f8c6a0/afts/img/A*7QSRRJwAWxQAAAAAAAAAAABkARQnAQ' width=80 alt='img'/> | The content of the ToolBar |
|
||||
| handleClick | (code: string, graph: IGraph) => void | undefined | The callback functions for the icons of the ToolBar |
|
||||
| position | Point | null | The position of the ToolBar |
|
||||
|
||||
### Usage
|
||||
|
||||
#### Default Usage
|
||||
默认的 ToolBar 提供了撤销、重做、放大等功能。
|
||||
ToolBar provides some default operations above.
|
||||
|
||||
```
|
||||
const toolbar = new G6.ToolBar();
|
||||
|
||||
const graph = new G6.Graph({
|
||||
//... 其他配置项
|
||||
plugins: [toolbar], // 配置 Menu 插件
|
||||
//... Other configurations
|
||||
plugins: [toolbar], // Use the ToolBar plugin
|
||||
});
|
||||
```
|
||||
|
||||
#### String ToolBar
|
||||
#### Custom ToolBar by String
|
||||
|
||||
```
|
||||
const tc = document.createElement('div');
|
||||
@ -218,8 +218,8 @@ const toolbar = new G6.ToolBar({
|
||||
getContent: () => {
|
||||
return `
|
||||
<ul>
|
||||
<li code='add'>测试</li>
|
||||
<li code='undo'>撤销</li>
|
||||
<li code='add'>Add Node</li>
|
||||
<li code='undo'>Undo</li>
|
||||
</ul>
|
||||
`
|
||||
},
|
||||
@ -238,12 +238,12 @@ const toolbar = new G6.ToolBar({
|
||||
});
|
||||
|
||||
const graph = new G6.Graph({
|
||||
//... 其他配置项
|
||||
plugins: [toolbar], // 配置 Menu 插件
|
||||
//... Other configurations
|
||||
plugins: [toolbar], // Use the ToolBar plugin
|
||||
});
|
||||
```
|
||||
|
||||
#### DOM ToolBar
|
||||
#### Custom ToolBar by DOM
|
||||
|
||||
```
|
||||
const toolbar = new G6.ToolBar({
|
||||
@ -251,11 +251,11 @@ const toolbar = new G6.ToolBar({
|
||||
const outDiv = document.createElement('div');
|
||||
outDiv.style.width = '180px';
|
||||
outDiv.innerHTML = `<ul>
|
||||
<li>测试01</li>
|
||||
<li>测试01</li>
|
||||
<li>测试01</li>
|
||||
<li>测试01</li>
|
||||
<li>测试01</li>
|
||||
<li>example 01</li>
|
||||
<li>example 02</li>
|
||||
<li>example 03</li>
|
||||
<li>example 04</li>
|
||||
<li>example 05</li>
|
||||
</ul>`
|
||||
return outDiv
|
||||
},
|
||||
@ -265,33 +265,33 @@ const toolbar = new G6.ToolBar({
|
||||
});
|
||||
|
||||
const graph = new G6.Graph({
|
||||
//... 其他配置项
|
||||
plugins: [toolbar], // 配置 Menu 插件
|
||||
//... Other configurations
|
||||
plugins: [toolbar], // Use the ToolBar plugin
|
||||
});
|
||||
```
|
||||
|
||||
## TimeBar
|
||||
|
||||
目前 G6 内置的 TimeBar 主要有以下功能:
|
||||
- 改变时间范围,过滤图上的数据;
|
||||
- TimeBar 上展示指定字段随时间推移的变化趋势。
|
||||
The built-in TimeBar plugin has the following abilities:
|
||||
- Filtering the data of the graph by changing the time range;
|
||||
- Demonstrating the trending of the data by an attribute on the TimeBar.
|
||||
|
||||
<img src='https://gw.alipayobjects.com/mdn/rms_f8c6a0/afts/img/A*HJjmT7uQwjAAAAAAAAAAAABkARQnAQ' width=700 alt='img'/>
|
||||
|
||||
**说明:** 目前的 TimeBar 功能还比较简单,不能用于较为复杂的时序分析。
|
||||
**Description:** It is a beta version of TimeBar, which will support complex time series graph and analysis in the future.
|
||||
|
||||
### Configuration
|
||||
|
||||
| 名称 | 类型 | 默认值 | 描述 |
|
||||
| Name | Type | Default | Description |
|
||||
| --- | --- | --- | --- |
|
||||
| container | HTMLDivElement | null | TimeBar 容器,如果不设置,则默认创建 className 为 g6-component-timebar 的 DOM 容器 |
|
||||
| width | number | 400 | TimeBar 容器宽度 |
|
||||
| height | number | 400 | TimeBar 容器高度 |
|
||||
| timebar | TimeBarOption | {} | TimeBar 样式配置项 |
|
||||
| rangeChange | (graph: IGraph, min: number, max: number) => void | null | 改变时间范围后的回调函数 |
|
||||
| container | HTMLDivElement | null | The container of the TimeBar. A DOM container with className 'g6-component-timebar' will be used by default |
|
||||
| width | number | 400 | The width of the TimeBar's container |
|
||||
| height | number | 400 | The height of the TimeBar's container |
|
||||
| timebar | TimeBarOption | {} | The style configurations for TimeBar |
|
||||
| rangeChange | (graph: IGraph, min: number, max: number) => void | null | The callback function after changing the time range |
|
||||
|
||||
|
||||
**TimeBarOption 配置项**
|
||||
**TimeBarOption for timebar**
|
||||
|
||||
```
|
||||
interface HandleStyle {
|
||||
@ -301,25 +301,25 @@ interface HandleStyle {
|
||||
}
|
||||
```
|
||||
|
||||
| 名称 | 类型 | 默认值 | 描述 |
|
||||
| Name | Type | Default | Description |
|
||||
| --- | --- | --- | --- |
|
||||
| x | number | 0 | TimeBar 起始 x 坐标 |
|
||||
| y | number | 0 | TimeBar 起始 y 坐标 |
|
||||
| width | number | 400 | TimeBar 宽度 |
|
||||
| height | number | 400 | TimeBar 高度 |
|
||||
| backgroundStyle | ShapeStyle | {} | TimeBar 背景样式配置项 |
|
||||
| foregroundStyle | ShapeStyle | {} | TimeBar 选中部分样式配置项 |
|
||||
| handlerStyle | HandleStyle | null | 滑块样式设置 |
|
||||
| textStyle | ShapeStyle | null | 文本样式 |
|
||||
| minLimit | number | 0 | 允许滑块最左边(最小)位置,范围 0-1 |
|
||||
| maxLimit | number | 1 | 允许滑块最右边(最大)位置,范围 0-1 |
|
||||
| start | number | 0 | 滑块初始开始位置 |
|
||||
| end | number | 1 | 滑块初始结束位置 |
|
||||
| minText | string | null | 滑块最小值时显示的文本 |
|
||||
| maxText | string | null | 滑块最大值时显示的文本 |
|
||||
| trend | TrendConfig | null | 滑块上趋势图配置 |
|
||||
| x | number | 0 | The begining x of the TimeBar |
|
||||
| y | number | 0 | The begining y of the TimeBar |
|
||||
| width | number | 400 | The width of the TimeBar |
|
||||
| height | number | 400 | The height of the TimeBar |
|
||||
| backgroundStyle | ShapeStyle | {} | The background style of the TimeBar |
|
||||
| foregroundStyle | ShapeStyle | {} | The foreground style of the TimeBar, which indicates the selected area |
|
||||
| handlerStyle | HandleStyle | null | The style of the slider handler |
|
||||
| textStyle | ShapeStyle | null | The style of the texts |
|
||||
| minLimit | number | 0 | The minimum position for the slider on the left, range from 0 to 1 |
|
||||
| maxLimit | number | 1 | The maximum position for the slider on the right, range from 0 to 1 |
|
||||
| start | number | 0 | The initial start position of the slider |
|
||||
| end | number | 1 | The initial end position of the slider |
|
||||
| minText | string | null | The text for the minimum value |
|
||||
| maxText | string | null | The text for the maximum value |
|
||||
| trend | TrendConfig | null | The configuration of the trend chart on the TimeBar |
|
||||
|
||||
**TrendConfig 配置项**
|
||||
**TrendConfig for trend**
|
||||
|
||||
```
|
||||
interface Data {
|
||||
@ -328,30 +328,29 @@ interface Data {
|
||||
}
|
||||
```
|
||||
|
||||
| 名称 | 类型 | 默认值 | 描述 |
|
||||
| Name | Type | Default | Description |
|
||||
| --- | --- | --- | --- |
|
||||
| data | Data[] | [] | 滑块上的数据源 |
|
||||
| smooth | boolean | false | 是否是平滑的曲线 |
|
||||
| isArea | boolean | false | 是否显示面积图 |
|
||||
| lineStyle | ShapeStyle | null | 折线的样式 |
|
||||
| areaStyle | ShapeStyle | null | 面积的样式,只有当 isArea 为 true 时生效 |
|
||||
| data | Data[] | [] | The data of the TimeBar |
|
||||
| smooth | boolean | false | Whether use the smooth curve instead of polylines for the trend chart |
|
||||
| isArea | boolean | false | Whether use the area chart instead of line chart |
|
||||
| lineStyle | ShapeStyle | null | The style of the line for line chart, takes effect when `isArea` is `false` |
|
||||
| areaStyle | ShapeStyle | null | The style of the area for area chart, takes effect when `isArea` is `true` |
|
||||
|
||||
### 用法
|
||||
### Usage
|
||||
|
||||
#### 默认用法
|
||||
G6 内置的默认的 TimeBar 有默认的样式及交互功能。
|
||||
#### Default Usage
|
||||
|
||||
```
|
||||
const timebar = new G6.TimeBar();
|
||||
|
||||
const graph = new G6.Graph({
|
||||
//... 其他配置项
|
||||
plugins: [timebar], // 配置 timebar 插件
|
||||
//... Other configurations
|
||||
plugins: [timebar], // Use timebar plugin
|
||||
});
|
||||
```
|
||||
|
||||
##### 配置样式
|
||||
可以个性化定制 TimeBar 的样式,也可以自己定义时间范围改变后的处理方式。
|
||||
##### Style Configuration
|
||||
It is free to configure the style for the TimeBar, and listen to the value changing to do some response.
|
||||
|
||||
```
|
||||
const timebar = new G6.TimeBar({
|
||||
@ -376,34 +375,34 @@ const timebar = new G6.TimeBar({
|
||||
}
|
||||
},
|
||||
rangeChange: (graph, min, max) => {
|
||||
// 拿到 Graph 实例和 timebar 上范围,自己可以控制图上的渲染逻辑
|
||||
// Get the instance of the graph and the range of the timebar, you can control the rendering of the graph by yourself here
|
||||
console.log(graph, min, max)
|
||||
}
|
||||
});
|
||||
|
||||
const graph = new G6.Graph({
|
||||
//... 其他配置项
|
||||
plugins: [timebar], // 配置 timebar 插件
|
||||
//... Other configurations
|
||||
plugins: [timebar], // Use timebar plugin
|
||||
});
|
||||
```
|
||||
|
||||
|
||||
## ToolTip
|
||||
|
||||
ToolTip 插件主要用于在节点和边上展示一些辅助信息,G6 4.0 以后,Tooltip 插件将会替换 Behavior 中的 tooltip。
|
||||
ToolTip helps user to explore detail infomations on the node and edge. Do note that, This Tooltip Plugins will replace the tooltip in the built-in behavior after G6 4.0.
|
||||
|
||||
### Configuration
|
||||
|
||||
| 名称 | 类型 | 默认值 | 描述 |
|
||||
| Name | Type | Default | Description |
|
||||
| --- | --- | --- | --- |
|
||||
| className | string | null | tooltip 容器的 class 类名 |
|
||||
| container | HTMLDivElement | null | Tooltip 容器,如果不设置,则默认使用 canvas 的 DOM 容器 |
|
||||
| getContent | (graph?: IGraph) => HTMLDivElement / string | <img src='https://gw.alipayobjects.com/mdn/rms_f8c6a0/afts/img/A*aPPuQquN5Q0AAAAAAAAAAABkARQnAQ' width=80 alt='img'/> | Tooltip 内容,支持 DOM 元素或字符串 |
|
||||
| offset | number | 6 | tooltip 的偏移值,作用于 x y 两个方向上 |
|
||||
| className | string | null | Tge class name of the tooltip's container |
|
||||
| container | HTMLDivElement | null | The container of the Tooltip. The canvas DOM will be used by default |
|
||||
| getContent | (graph?: IGraph) => HTMLDivElement / string | <img src='https://gw.alipayobjects.com/mdn/rms_f8c6a0/afts/img/A*aPPuQquN5Q0AAAAAAAAAAABkARQnAQ' width=80 alt='img'/> | The content of the Tooltip |
|
||||
| offset | number | 6 | The offset of the tooltip, takes effect both on x and y axis |
|
||||
|
||||
### 用法
|
||||
### Usage
|
||||
|
||||
默认的 Tooltip 只展示元素类型和 ID,一般情况下都需要用户自己定义 Tooltip 上面展示的内容。
|
||||
The content of the Tooltip is the type and id of the item by default. Users are free to custom the content of the Tooltip by configuring `getContent`:
|
||||
|
||||
#### Dom Tooltip
|
||||
```
|
||||
@ -413,7 +412,7 @@ const tooltip = new G6.Tooltip({
|
||||
const outDiv = document.createElement('div');
|
||||
outDiv.style.width = '180px';
|
||||
outDiv.innerHTML = `
|
||||
<h4>自定义tooltip</h4>
|
||||
<h4>Custom Tooltip</h4>
|
||||
<ul>
|
||||
<li>Label: ${e.item.getModel().label || e.item.getModel().id}</li>
|
||||
</ul>`
|
||||
@ -422,8 +421,8 @@ const tooltip = new G6.Tooltip({
|
||||
});
|
||||
|
||||
const graph = new G6.Graph({
|
||||
//... 其他配置项
|
||||
plugins: [tooltip], // 配置 Menu 插件
|
||||
//... Other configurations
|
||||
plugins: [tooltip], // Use Tooltip plugin
|
||||
});
|
||||
```
|
||||
|
||||
@ -433,18 +432,18 @@ const tooltip = new G6.Tooltip({
|
||||
getContent(e) {
|
||||
return `<div style='width: 180px;'>
|
||||
<ul id='menu'>
|
||||
<li title='1'>测试02</li>
|
||||
<li title='2'>测试02</li>
|
||||
<li>测试02</li>
|
||||
<li>测试02</li>
|
||||
<li>测试02</li>
|
||||
<li title='1'>example 01</li>
|
||||
<li title='2'>example 02</li>
|
||||
<li>example 03</li>
|
||||
<li>example 04</li>
|
||||
<li>example 05</li>
|
||||
</ul>
|
||||
</div>`;
|
||||
},
|
||||
});
|
||||
|
||||
const graph = new G6.Graph({
|
||||
//... 其他配置项
|
||||
plugins: [tooltip], // 配置 Menu 插件
|
||||
//... Other configurations
|
||||
plugins: [tooltip], // Use Tooltip plugin
|
||||
});
|
||||
```
|
||||
|
@ -199,11 +199,11 @@ const toolbar = new G6.ToolBar();
|
||||
|
||||
const graph = new G6.Graph({
|
||||
//... 其他配置项
|
||||
plugins: [toolbar], // 配置 Menu 插件
|
||||
plugins: [toolbar], // 配置 ToolBar 插件
|
||||
});
|
||||
```
|
||||
|
||||
#### String ToolBar
|
||||
#### 使用 String 自定义 ToolBar 功能
|
||||
|
||||
```
|
||||
const tc = document.createElement('div');
|
||||
@ -215,7 +215,7 @@ const toolbar = new G6.ToolBar({
|
||||
getContent: () => {
|
||||
return `
|
||||
<ul>
|
||||
<li code='add'>测试</li>
|
||||
<li code='add'>增加节点</li>
|
||||
<li code='undo'>撤销</li>
|
||||
</ul>
|
||||
`
|
||||
@ -236,11 +236,11 @@ const toolbar = new G6.ToolBar({
|
||||
|
||||
const graph = new G6.Graph({
|
||||
//... 其他配置项
|
||||
plugins: [toolbar], // 配置 Menu 插件
|
||||
plugins: [toolbar], // 配置 ToolBar 插件
|
||||
});
|
||||
```
|
||||
|
||||
#### DOM ToolBar
|
||||
#### 使用 DOM 自定义 ToolBar 功能
|
||||
|
||||
```
|
||||
const toolbar = new G6.ToolBar({
|
||||
@ -249,10 +249,10 @@ const toolbar = new G6.ToolBar({
|
||||
outDiv.style.width = '180px';
|
||||
outDiv.innerHTML = `<ul>
|
||||
<li>测试01</li>
|
||||
<li>测试01</li>
|
||||
<li>测试01</li>
|
||||
<li>测试01</li>
|
||||
<li>测试01</li>
|
||||
<li>测试02</li>
|
||||
<li>测试03</li>
|
||||
<li>测试04</li>
|
||||
<li>测试05</li>
|
||||
</ul>`
|
||||
return outDiv
|
||||
},
|
||||
@ -263,7 +263,7 @@ const toolbar = new G6.ToolBar({
|
||||
|
||||
const graph = new G6.Graph({
|
||||
//... 其他配置项
|
||||
plugins: [toolbar], // 配置 Menu 插件
|
||||
plugins: [toolbar], // 配置 ToolBar 插件
|
||||
});
|
||||
```
|
||||
|
||||
@ -420,7 +420,7 @@ const tooltip = new G6.Tooltip({
|
||||
|
||||
const graph = new G6.Graph({
|
||||
//... 其他配置项
|
||||
plugins: [tooltip], // 配置 Menu 插件
|
||||
plugins: [tooltip], // 配置 Tooltip 插件
|
||||
});
|
||||
```
|
||||
|
||||
@ -442,7 +442,7 @@ const tooltip = new G6.Tooltip({
|
||||
|
||||
const graph = new G6.Graph({
|
||||
//... 其他配置项
|
||||
plugins: [tooltip], // 配置 Menu 插件
|
||||
plugins: [tooltip], // 配置 Tooltip 插件
|
||||
});
|
||||
```
|
||||
|
||||
|
@ -1,6 +1,9 @@
|
||||
import G6 from '@antv/g6';
|
||||
import insertCss from 'insert-css';
|
||||
|
||||
// 我们用 insert-css 演示引入自定义样式
|
||||
// 推荐将样式添加到自己的样式文件中
|
||||
// 若拷贝官方代码,别忘了 npm install insert-css
|
||||
insertCss(`
|
||||
#g6-component-timebar {
|
||||
top: 540px;
|
||||
@ -13,11 +16,10 @@ const data = {
|
||||
edges: [],
|
||||
};
|
||||
|
||||
for(let i = 0; i < 100; i++) {
|
||||
for (let i = 0; i < 100; i++) {
|
||||
const id = `node-${i}`
|
||||
data.nodes.push({
|
||||
id,
|
||||
label: `node${i}`,
|
||||
date: `2020${i}`,
|
||||
value: Math.round(Math.random() * 300)
|
||||
})
|
||||
@ -33,32 +35,51 @@ const height = document.getElementById('container').scrollHeight || 500;
|
||||
|
||||
const timeBarData = []
|
||||
|
||||
for(let i = 0; i < 100; i++) {
|
||||
for (let i = 0; i < 100; i++) {
|
||||
timeBarData.push({
|
||||
date: `2020${i}`,
|
||||
value: Math.round(Math.random() * 300)
|
||||
})
|
||||
}
|
||||
|
||||
const nodeSize = 20;
|
||||
|
||||
const timebar = new G6.TimeBar({
|
||||
width: 600,
|
||||
timebar: {
|
||||
width: 600,
|
||||
width: 580,
|
||||
minLimit: 0,
|
||||
maxLimit: 1,
|
||||
start: 0,
|
||||
end: 0.5,
|
||||
backgroundStyle: {
|
||||
fill: '#08979c',
|
||||
opacity: 0.3
|
||||
fill: '#ddd',
|
||||
opacity: 0.2,
|
||||
lineWidth: 1,
|
||||
stroke: '#aaa'
|
||||
},
|
||||
foregroundStyle: {
|
||||
fill: '#40a9ff',
|
||||
opacity: 0.4
|
||||
fill: '#f00',
|
||||
opacity: 0.1
|
||||
},
|
||||
trend: {
|
||||
data: timeBarData,
|
||||
isArea: false,
|
||||
smooth: true,
|
||||
lineStyle: {
|
||||
stroke: '#9254de'
|
||||
stroke: '#f00',
|
||||
lineWidth: 2,
|
||||
opacity: 0.5
|
||||
}
|
||||
},
|
||||
textStyle: {
|
||||
fontWeight: 500,
|
||||
fill: '#000',
|
||||
fontSize: 14
|
||||
},
|
||||
handlerStyle: {
|
||||
width: 10,
|
||||
height: 35,
|
||||
}
|
||||
},
|
||||
rangeChange: (graph, min, max) => {
|
||||
@ -66,27 +87,57 @@ const timebar = new G6.TimeBar({
|
||||
console.log(graph, min, max)
|
||||
}
|
||||
});
|
||||
// constrained the layout inside the area
|
||||
const constrainBox = { x: 10, y: 10, width: 580, height: 450 };
|
||||
|
||||
const onTick = () => {
|
||||
let minx = 99999999;
|
||||
let maxx = -99999999;
|
||||
let miny = 99999999;
|
||||
let maxy = -99999999;
|
||||
let maxsize = -9999999;
|
||||
data.nodes.forEach(node => {
|
||||
if (minx > node.x) {
|
||||
minx = node.x;
|
||||
}
|
||||
if (maxx < node.x) {
|
||||
maxx = node.x;
|
||||
}
|
||||
if (miny > node.y) {
|
||||
miny = node.y;
|
||||
}
|
||||
if (maxy < node.y) {
|
||||
maxy = node.y;
|
||||
}
|
||||
});
|
||||
const scalex = (constrainBox.width - nodeSize / 2) / (maxx - minx);
|
||||
const scaley = (constrainBox.height - nodeSize / 2) / (maxy - miny);
|
||||
data.nodes.forEach(node => {
|
||||
node.x = (node.x - minx) * scalex + constrainBox.x;
|
||||
node.y = (node.y - miny) * scaley + constrainBox.y;
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
const graph = new G6.Graph({
|
||||
container: 'container',
|
||||
width,
|
||||
height,
|
||||
height: height - 50,
|
||||
linkCenter: true,
|
||||
plugins: [timebar],
|
||||
layout: {
|
||||
type: 'force',
|
||||
preventOverlap: true,
|
||||
onTick
|
||||
},
|
||||
defaultNode: {
|
||||
size: 40,
|
||||
size: nodeSize,
|
||||
type: 'circle',
|
||||
style: {
|
||||
fill: '#DEE9FF',
|
||||
stroke: '#5B8FF9',
|
||||
},
|
||||
},
|
||||
defaultEdge: {
|
||||
style: {
|
||||
stroke: '#b5b5b5',
|
||||
lineAppendWidth: 3,
|
||||
},
|
||||
},
|
||||
modes: {
|
||||
default: [
|
||||
'drag-node'
|
||||
|
@ -10,7 +10,7 @@
|
||||
"zh": "时间轴",
|
||||
"en": "ToolBar"
|
||||
},
|
||||
"screenshot": "https://gw.alipayobjects.com/mdn/rms_f8c6a0/afts/img/A*xj85R7loNvMAAAAAAAAAAABkARQnAQ"
|
||||
"screenshot": "https://gw.alipayobjects.com/mdn/rms_f8c6a0/afts/img/A*eq2kQ4N-pNcAAAAAAAAAAABkARQnAQ"
|
||||
},
|
||||
{
|
||||
"filename": "configTimebar.js",
|
||||
@ -18,7 +18,7 @@
|
||||
"zh": "定义时间轴样式",
|
||||
"en": "ToolBar"
|
||||
},
|
||||
"screenshot": "https://gw.alipayobjects.com/mdn/rms_f8c6a0/afts/img/A*AG3AQ7PyHSMAAAAAAAAAAABkARQnAQ"
|
||||
"screenshot": "https://gw.alipayobjects.com/mdn/rms_f8c6a0/afts/img/A*eq2kQ4N-pNcAAAAAAAAAAABkARQnAQ"
|
||||
}
|
||||
]
|
||||
}
|
@ -1,6 +1,10 @@
|
||||
|
||||
import G6 from '@antv/g6';
|
||||
import insertCss from 'insert-css';
|
||||
|
||||
// 我们用 insert-css 演示引入自定义样式
|
||||
// 推荐将样式添加到自己的样式文件中
|
||||
// 若拷贝官方代码,别忘了 npm install insert-css
|
||||
insertCss(`
|
||||
#g6-component-timebar {
|
||||
top: 540px;
|
||||
@ -13,11 +17,10 @@ const data = {
|
||||
edges: [],
|
||||
};
|
||||
|
||||
for(let i = 0; i < 100; i++) {
|
||||
for (let i = 0; i < 100; i++) {
|
||||
const id = `node-${i}`
|
||||
data.nodes.push({
|
||||
id,
|
||||
label: `node${i}`,
|
||||
date: `2020${i}`,
|
||||
value: Math.round(Math.random() * 300)
|
||||
})
|
||||
@ -27,13 +30,16 @@ for(let i = 0; i < 100; i++) {
|
||||
target: `node-${Math.round(Math.random() * 90)}`
|
||||
})
|
||||
}
|
||||
const graphDiv = document.getElementById('container');
|
||||
|
||||
const width = document.getElementById('container').scrollWidth;
|
||||
const height = document.getElementById('container').scrollHeight || 500;
|
||||
|
||||
const timeBarData = []
|
||||
|
||||
for(let i = 0; i < 100; i++) {
|
||||
const nodeSize = 20;
|
||||
|
||||
for (let i = 0; i < 100; i++) {
|
||||
timeBarData.push({
|
||||
date: `2020${i}`,
|
||||
value: Math.round(Math.random() * 300)
|
||||
@ -43,35 +49,68 @@ for(let i = 0; i < 100; i++) {
|
||||
const timebar = new G6.TimeBar({
|
||||
width: 600,
|
||||
timebar: {
|
||||
width: 600,
|
||||
width: 550,
|
||||
trend: {
|
||||
data: timeBarData,
|
||||
isArea: false,
|
||||
smooth: true,
|
||||
}
|
||||
},
|
||||
start: 0.4,
|
||||
end: 0.5,
|
||||
}
|
||||
});
|
||||
|
||||
// constrained the layout inside the area
|
||||
const constrainBox = { x: 10, y: 10, width: 580, height: 450 };
|
||||
|
||||
const onTick = () => {
|
||||
let minx = 99999999;
|
||||
let maxx = -99999999;
|
||||
let miny = 99999999;
|
||||
let maxy = -99999999;
|
||||
let maxsize = -9999999;
|
||||
data.nodes.forEach(node => {
|
||||
if (minx > node.x) {
|
||||
minx = node.x;
|
||||
}
|
||||
if (maxx < node.x) {
|
||||
maxx = node.x;
|
||||
}
|
||||
if (miny > node.y) {
|
||||
miny = node.y;
|
||||
}
|
||||
if (maxy < node.y) {
|
||||
maxy = node.y;
|
||||
}
|
||||
});
|
||||
const scalex = (constrainBox.width - nodeSize / 2) / (maxx - minx);
|
||||
const scaley = (constrainBox.height - nodeSize / 2) / (maxy - miny);
|
||||
data.nodes.forEach(node => {
|
||||
node.x = (node.x - minx) * scalex + constrainBox.x;
|
||||
node.y = (node.y - miny) * scaley + constrainBox.y;
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
const graph = new G6.Graph({
|
||||
container: 'container',
|
||||
width,
|
||||
height,
|
||||
height: height - 50,
|
||||
linkCenter: true,
|
||||
plugins: [timebar],
|
||||
layout: {
|
||||
type: 'force',
|
||||
preventOverlap: true,
|
||||
onTick
|
||||
},
|
||||
defaultNode: {
|
||||
size: 40,
|
||||
size: nodeSize,
|
||||
type: 'circle',
|
||||
style: {
|
||||
fill: '#DEE9FF',
|
||||
stroke: '#5B8FF9',
|
||||
},
|
||||
},
|
||||
defaultEdge: {
|
||||
style: {
|
||||
stroke: '#b5b5b5',
|
||||
lineAppendWidth: 3,
|
||||
},
|
||||
},
|
||||
modes: {
|
||||
default: [
|
||||
'drag-node'
|
||||
|
@ -1,11 +1,11 @@
|
||||
---
|
||||
title: TimeBar
|
||||
order: 0
|
||||
order: 5
|
||||
---
|
||||
|
||||
TimeBar is a build-in component in G6.
|
||||
|
||||
## Usage
|
||||
|
||||
The demo below show how to use TimeBar on graph.
|
||||
The demo below shows how to use TimeBar on graph. The second demo demonstrates the configurations for the TimeBar.
|
||||
|
||||
|
@ -1,11 +1,11 @@
|
||||
---
|
||||
title: 时间轴
|
||||
order: 0
|
||||
order: 5
|
||||
---
|
||||
|
||||
G6 中内置的 TimeBar 组件。
|
||||
|
||||
## 使用指南
|
||||
|
||||
下面的代码演示展示了如何在图上使用 TimeBar。TimeBar 的样式可以使用 G6 内置的,也可以完全自定义。
|
||||
下面的代码演示展示了如何在图上使用 TimeBar。TimeBar 的样式可以参考 demo 2 进行配置。
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
---
|
||||
title: ToolBar
|
||||
order: 0
|
||||
order: 4
|
||||
---
|
||||
|
||||
ToolBar is a build-in Component in G6.
|
||||
|
@ -1,6 +1,6 @@
|
||||
---
|
||||
title: 工具栏
|
||||
order: 0
|
||||
order: 4
|
||||
---
|
||||
|
||||
G6 中内置的 ToolBar 组件。
|
||||
|
@ -1,3 +1,3 @@
|
||||
// window.g6 = require('./src/index.ts'); // import the source for debugging
|
||||
window.g6 = require('./dist/g6.min.js'); // import the package for webworker
|
||||
window.g6 = require('./src/index.ts'); // import the source for debugging
|
||||
// window.g6 = require('./dist/g6.min.js'); // import the package for webworker
|
||||
window.insertCss = require('insert-css');
|
||||
|
@ -50,7 +50,7 @@
|
||||
"site:deploy": "npm run site:build && gh-pages -d public",
|
||||
"start": "npm run site:develop",
|
||||
"test": "jest",
|
||||
"test-live": "DEBUG_MODE=1 jest --watch ./tests/unit/behavior/tooltip-spec.ts",
|
||||
"test-live": "DEBUG_MODE=1 jest --watch ./tests/unit/plugins/timebar-spec.ts",
|
||||
"lint-staged:js": "eslint --ext .js,.jsx,.ts,.tsx",
|
||||
"watch": "father build -w",
|
||||
"cdn": "antv-bin upload -n @antv/g6"
|
||||
|
@ -1,5 +1,5 @@
|
||||
import { G6Event, IG6GraphEvent, IPoint, Item } from '../types';
|
||||
import { isPolygonsIntersect } from '@antv/path-util';
|
||||
import isPolygonsIntersect from '@antv/path-util/lib/is-polygons-intersect';
|
||||
import { pathToPoints } from '../util/path'
|
||||
|
||||
const DEFAULT_TRIGGER = 'shift';
|
||||
|
@ -1,6 +1,5 @@
|
||||
import modifyCSS from '@antv/dom-util/lib/modify-css';
|
||||
import createDOM from '@antv/dom-util/lib/create-dom';
|
||||
import isString from '@antv/util/lib/is-string'
|
||||
import { IGroup } from '@antv/g-base'
|
||||
import { Canvas } from '@antv/g-canvas'
|
||||
import { Slider } from '@antv/component'
|
||||
@ -80,10 +79,10 @@ export default class TimeBar extends Base {
|
||||
timebar: {
|
||||
x: 10,
|
||||
y: 10,
|
||||
width: 400,
|
||||
width: 380,
|
||||
height: 26,
|
||||
minLimit: 0.05,
|
||||
maxLimit: 0.95,
|
||||
minLimit: 0,
|
||||
maxLimit: 1,
|
||||
start: 0.1,
|
||||
end: 0.9,
|
||||
}
|
||||
@ -151,8 +150,13 @@ export default class TimeBar extends Base {
|
||||
data: trendData
|
||||
}
|
||||
|
||||
config.minText = data[0].date
|
||||
config.maxText = data[data.length - 1].date
|
||||
|
||||
const min = Math.round(data.length * option.start)
|
||||
let max = Math.round(data.length * option.end)
|
||||
max = max >= data.length ? (data.length - 1) : max
|
||||
|
||||
config.minText = data[min].date
|
||||
config.maxText = data[max].date
|
||||
|
||||
this.set('trendData', data)
|
||||
|
||||
@ -170,49 +174,60 @@ export default class TimeBar extends Base {
|
||||
* 当滑动时,最小值和最大值会变化,变化以后触发相应事件
|
||||
*/
|
||||
private bindEvent() {
|
||||
const graph: IGraph = this.get('graph')
|
||||
const slider = this.get('slider')
|
||||
const rangeChange = this.get('rangeChange')
|
||||
const trendData: Data[] = this.get('trendData')
|
||||
const { start, end } = this.get('timebar');
|
||||
const graph: IGraph = this.get('graph')
|
||||
graph.on('afterrender', e => {
|
||||
this.filterData({ value: [start, end] });
|
||||
});
|
||||
|
||||
slider.on('valuechanged', (evt: Callback) => {
|
||||
const { value } = evt
|
||||
|
||||
const min = Math.round(trendData.length * value[0])
|
||||
let max = Math.round(trendData.length * value[1])
|
||||
max = max > trendData.length ? trendData.length : max
|
||||
const minText = trendData[min].date
|
||||
const maxText = trendData[max].date
|
||||
|
||||
slider.set('minText', minText)
|
||||
slider.set('maxText', maxText)
|
||||
|
||||
if (rangeChange) {
|
||||
rangeChange(graph, minText, maxText)
|
||||
} else {
|
||||
// 自动过滤数据,并渲染 graph
|
||||
const graphData = graph.save() as GraphData
|
||||
|
||||
if (!this.cacheGraphData) {
|
||||
this.cacheGraphData = graphData
|
||||
}
|
||||
|
||||
// 过滤不在 min 和 max 范围内的节点
|
||||
const filterData = this.cacheGraphData.nodes.filter((d: any) => d.date >= minText && d.date <= maxText)
|
||||
|
||||
const nodeIds = filterData.map(node => node.id)
|
||||
|
||||
// 过滤 source 或 target 不在 min 和 max 范围内的边
|
||||
const fileterEdges = this.cacheGraphData.edges.filter(edge => nodeIds.includes(edge.source) && nodeIds.includes(edge.target))
|
||||
|
||||
graph.changeData({
|
||||
nodes: filterData,
|
||||
edges: fileterEdges
|
||||
})
|
||||
|
||||
}
|
||||
this.filterData(evt);
|
||||
})
|
||||
}
|
||||
|
||||
private filterData(evt) {
|
||||
const { value } = evt
|
||||
|
||||
const trendData: Data[] = this.get('trendData')
|
||||
const rangeChange = this.get('rangeChange')
|
||||
const graph: IGraph = this.get('graph')
|
||||
const slider = this.get('slider')
|
||||
const min = Math.round(trendData.length * value[0])
|
||||
let max = Math.round(trendData.length * value[1])
|
||||
max = max >= trendData.length ? (trendData.length - 1) : max
|
||||
|
||||
const minText = trendData[min].date
|
||||
const maxText = trendData[max].date
|
||||
|
||||
slider.set('minText', minText)
|
||||
slider.set('maxText', maxText)
|
||||
|
||||
if (rangeChange) {
|
||||
rangeChange(graph, minText, maxText)
|
||||
} else {
|
||||
// 自动过滤数据,并渲染 graph
|
||||
const graphData = graph.save() as GraphData
|
||||
|
||||
if (!this.cacheGraphData || (this.cacheGraphData.nodes && this.cacheGraphData.nodes.length === 0)) {
|
||||
this.cacheGraphData = graphData
|
||||
}
|
||||
|
||||
// 过滤不在 min 和 max 范围内的节点
|
||||
const filterData = this.cacheGraphData.nodes.filter((d: any) => d.date >= minText && d.date <= maxText)
|
||||
|
||||
const nodeIds = filterData.map(node => node.id)
|
||||
|
||||
// 过滤 source 或 target 不在 min 和 max 范围内的边
|
||||
const fileterEdges = this.cacheGraphData.edges.filter(edge => nodeIds.includes(edge.source) && nodeIds.includes(edge.target))
|
||||
|
||||
graph.changeData({
|
||||
nodes: filterData,
|
||||
edges: fileterEdges
|
||||
})
|
||||
|
||||
}
|
||||
}
|
||||
public show() {
|
||||
const slider = this.get('slider')
|
||||
slider.show()
|
||||
|
@ -86,13 +86,13 @@ describe('TimeBar', () => {
|
||||
expect(timebarPlugin.get('trendData')).toEqual(timeBarData)
|
||||
expect(timebarPlugin.get('timebar').x).toBe(10)
|
||||
expect(timebarPlugin.get('timebar').y).toBe(10)
|
||||
expect(timebarPlugin.get('timebar').width).toBe(400)
|
||||
expect(timebarPlugin.get('timebar').width).toBe(380)
|
||||
expect(timebarPlugin.get('timebar').start).toBe(0.1)
|
||||
|
||||
const slider = timebarPlugin.get('slider')
|
||||
expect(slider.get('name')).toEqual('slider')
|
||||
expect(slider.get('maxText')).toEqual('202099')
|
||||
expect(slider.get('minText')).toEqual('20200')
|
||||
expect(slider.get('maxText')).toEqual('202090') // 0.9
|
||||
expect(slider.get('minText')).toEqual('202010') // 0.1
|
||||
expect(slider.get('height')).toBe(26)
|
||||
graph.destroy()
|
||||
})
|
||||
@ -108,6 +108,8 @@ describe('TimeBar', () => {
|
||||
}
|
||||
const timebar = new G6.TimeBar({
|
||||
timebar: {
|
||||
start: 0,
|
||||
end: 1,
|
||||
backgroundStyle: {
|
||||
fill: '#08979c',
|
||||
opacity: 0.3
|
||||
@ -157,8 +159,8 @@ describe('TimeBar', () => {
|
||||
expect(timebarPlugin.get('trendData')).toEqual(timeBarData)
|
||||
expect(timeBar.x).toBe(10)
|
||||
expect(timeBar.y).toBe(10)
|
||||
expect(timeBar.width).toBe(400)
|
||||
expect(timeBar.start).toBe(0.1)
|
||||
expect(timeBar.width).toBe(380)
|
||||
expect(timeBar.start).toBe(0)
|
||||
|
||||
const backgroundStyle = timeBar.backgroundStyle
|
||||
expect(backgroundStyle.fill).toEqual('#08979c')
|
||||
|
Loading…
Reference in New Issue
Block a user