mirror of
https://gitee.com/antv/g6.git
synced 2024-12-05 05:09:07 +08:00
feat: timebar plugin refine (#3320)
* fix: simple timebar silder text position strategy and expand the lineAppendWidth for the slider; feat: timebar supports filterItemTypes to configure the types of the graph items to be filtered; only nodes can be filtered before; feat: timebar supports to configure the rotate of the tick labels by tickLabelStyle[dot]rotate; feat: timebar supports container CSS configuration by containerCSS; feat: timebar supports a function getDate to returns the date value according to each node or edge by user; feat: timebar supports afunction getValue to returns the value (for trend line of trend timebar) according to each node or edge by user; feat: timebar supports to configure a boolean changeData to control the filter way, true means filters by graph[dot]changeData, false means filters by graph[dot]showItem and graph[dot]hideItem; feat: timebar supports to configure a function shouldIgnore to return true or false by user to decide whether the node or the edge should be ignored while filtering; * fix: missing event with animated zoom (#3316) * docs: update dagre docs * feat: add translate animation (#3315) * feat: add translate animation * fix: add item type to the parameter of afterremoveitem event; (#3314) * fix: add item type to the parameter of afterremoveitem event; * fix: typo (#3311) Co-authored-by: qinggniq <livewithblank@outlook.com> * fix: use move for animated translate * fix: interface signatures Co-authored-by: Yanyan Wang <yanyanwang93@gmail.com> Co-authored-by: qinggniq <livewithblank@outlook.com> * fix: edge label padding bug, closes: #3346;fix: update node with iconfont icon, the icon is updated to a wrong position, closes: #3348; * fix: test problems * chore: update version nums * chore: update version nums after publishing Co-authored-by: Fabio Tacchelli <fabio.tacchelli@gmail.com> Co-authored-by: qinggniq <livewithblank@outlook.com>
This commit is contained in:
parent
ea03f39028
commit
65a029de6a
16
CHANGELOG.md
16
CHANGELOG.md
@ -1,5 +1,21 @@
|
||||
# ChangeLog
|
||||
|
||||
#### 4.5.1
|
||||
|
||||
- feat: translate graph with animation;
|
||||
- feat: zoom graph with animation;
|
||||
- feat: timebar supports filterItemTypes to configure the types of the graph items to be filtered; only nodes can be filtered before;
|
||||
- feat: timebar supports to configure the rotate of the tick labels by tickLabelStyle[dot]rotate;
|
||||
- feat: timebar supports container CSS configuration by containerCSS;
|
||||
- feat: timebar supports a function getDate to returns the date value according to each node or edge by user;
|
||||
- feat: timebar supports afunction getValue to returns the value (for trend line of trend timebar) according to each node or edge by user;
|
||||
- feat: timebar supports to configure a boolean changeData to control the filter way, true means filters by graph[dot]changeData, false means filters by graph[dot]showItem and graph[dot]hideItem;
|
||||
- feat: timebar supports to configure a function shouldIgnore to return true or false by user to decide whether the node or the edge should be ignored while filtering;
|
||||
- fix: simple timebar silder text position strategy and expand the lineAppendWidth for the slider;
|
||||
- fix: edge label padding bug, closes: #3346;
|
||||
- fix: update node with iconfont icon, the icon is updated to a wrong position, closes: #3348;
|
||||
|
||||
|
||||
#### 4.5.0
|
||||
|
||||
- fix: add item type to the parameter of afterremoveitem event;
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@antv/g6-core",
|
||||
"version": "0.4.1",
|
||||
"version": "0.5.1",
|
||||
"description": "A Graph Visualization Framework in JavaScript",
|
||||
"keywords": [
|
||||
"antv",
|
||||
@ -96,4 +96,4 @@
|
||||
"typescript": "^3.9.5",
|
||||
"stats-js": "^1.0.1"
|
||||
}
|
||||
}
|
||||
}
|
@ -170,7 +170,7 @@ const singleEdge: ShapeOptions = {
|
||||
};
|
||||
}
|
||||
style = { ...cfg.style };
|
||||
if (style.lineWidth === undefined) style.lineWdith = (isNumber(size) ? size: size?.[0]) || currentAttr.lineWidth
|
||||
if (style.lineWidth === undefined) style.lineWdith = (isNumber(size) ? size : size?.[0]) || currentAttr.lineWidth
|
||||
if (style.path === undefined) style.path = path;
|
||||
if (style.stroke === undefined) style.stroke = currentAttr.stroke || cfg.color;
|
||||
}
|
||||
@ -224,9 +224,7 @@ const singleEdge: ShapeOptions = {
|
||||
},
|
||||
getLabelBgStyleByPosition(
|
||||
label: IElement,
|
||||
cfg: EdgeConfig,
|
||||
labelCfg?: ILabelConfig,
|
||||
group?: IGroup,
|
||||
) {
|
||||
if (!label) {
|
||||
return {};
|
||||
@ -239,60 +237,22 @@ const singleEdge: ShapeOptions = {
|
||||
const { padding } = backgroundStyle;
|
||||
const backgroundWidth = bbox.width + padding[1] + padding[3];
|
||||
const backgroundHeight = bbox.height + padding[0] + padding[2];
|
||||
const labelPosition = labelCfg.position || this.labelPosition;
|
||||
|
||||
const style = {
|
||||
...backgroundStyle,
|
||||
width: backgroundWidth,
|
||||
height: backgroundHeight,
|
||||
x: bbox.minX - padding[2],
|
||||
x: bbox.minX - padding[3],
|
||||
y: bbox.minY - padding[0],
|
||||
rotate: 0,
|
||||
matrix: [1, 0, 0, 0, 1, 0, 0, 0, 1]
|
||||
};
|
||||
let autoRotate;
|
||||
if (isNil(labelCfg.autoRotate)) autoRotate = this.labelAutoRotate;
|
||||
else autoRotate = labelCfg.autoRotate;
|
||||
|
||||
const pathShape = group?.['shapeMap'][CLS_SHAPE]; // group?.find((element) => element.get('className') === CLS_SHAPE);
|
||||
|
||||
// 不对 pathShape 进行判空,如果线不存在,说明有问题了
|
||||
let pointPercent;
|
||||
if (labelPosition === 'start') {
|
||||
pointPercent = 0;
|
||||
} else if (labelPosition === 'end') {
|
||||
pointPercent = 1;
|
||||
} else {
|
||||
pointPercent = 0.5;
|
||||
}
|
||||
// 偏移量
|
||||
const offsetX = labelCfg.refX || (this.refX as number);
|
||||
const offsetY = labelCfg.refY || (this.refY as number);
|
||||
// // 如果两个节点重叠,线就变成了一个点,这时候label的位置,就是这个点 + 绝对偏移
|
||||
if (cfg.startPoint!.x === cfg.endPoint!.x && cfg.startPoint!.y === cfg.endPoint!.y) {
|
||||
style.x = cfg.startPoint!.x + offsetX - backgroundWidth / 2;
|
||||
style.y = cfg.startPoint!.y + offsetY - backgroundHeight / 2;
|
||||
return style;
|
||||
}
|
||||
|
||||
let bgOffsetX = offsetX - backgroundWidth / 2;
|
||||
if (labelCfg.position === 'start') {
|
||||
bgOffsetX = offsetX - padding[2];
|
||||
} else if (labelCfg.position === 'end') {
|
||||
bgOffsetX = offsetX - backgroundWidth;
|
||||
}
|
||||
|
||||
let offsetStyle = getLabelPosition(
|
||||
pathShape,
|
||||
pointPercent,
|
||||
bgOffsetX,
|
||||
offsetY + backgroundHeight / 2,
|
||||
autoRotate,
|
||||
);
|
||||
|
||||
if (autoRotate) {
|
||||
style.x = offsetStyle.x;
|
||||
style.y = offsetStyle.y;
|
||||
style.matrix = label.attr('matrix') || [1, 0, 0, 0, 1, 0, 0, 0, 1];
|
||||
}
|
||||
style.rotate = offsetStyle.rotate;
|
||||
return style;
|
||||
},
|
||||
// 获取文本对齐方式
|
||||
@ -379,11 +339,9 @@ const singleEdge: ShapeOptions = {
|
||||
const { labelCfg: defaultLabelCfg } = this.options as ModelConfig;
|
||||
const labelCfg = deepMix({}, defaultLabelCfg, cfg.labelCfg);
|
||||
|
||||
const style = this.getLabelBgStyleByPosition(label, cfg, labelCfg, group);
|
||||
delete style.rotate;
|
||||
const style = this.getLabelBgStyleByPosition(label, labelCfg);
|
||||
const rect = group.addShape('rect', { name: 'text-bg-shape', attrs: style });
|
||||
group['shapeMap']['text-bg-shape'] = rect;
|
||||
if (!isNaN(rotate)) rect.rotateAtStart(rotate);
|
||||
return rect;
|
||||
},
|
||||
};
|
||||
|
@ -33,7 +33,7 @@ const singleNode: ShapeOptions = {
|
||||
* @return {Array} 宽高
|
||||
*/
|
||||
getSize(cfg: ModelConfig): number[] {
|
||||
let size: number | number[] = this.mergeStyle?.size || cfg.size ||this.getOptions({})!.size || Global.defaultNode.size; // Global.defaultNode.size; //
|
||||
let size: number | number[] = this.mergeStyle?.size || cfg.size || this.getOptions({})!.size || Global.defaultNode.size; // Global.defaultNode.size; //
|
||||
|
||||
// size 是数组,但长度为1,则补长度为2
|
||||
if (isArray(size) && size.length === 1) {
|
||||
@ -99,9 +99,7 @@ const singleNode: ShapeOptions = {
|
||||
},
|
||||
getLabelBgStyleByPosition(
|
||||
label: IElement,
|
||||
cfg: ModelConfig,
|
||||
labelCfg?: ILabelConfig,
|
||||
group?: IGroup,
|
||||
) {
|
||||
if (!label) return {};
|
||||
const backgroundStyle = labelCfg.style?.background;
|
||||
@ -301,7 +299,11 @@ const singleNode: ShapeOptions = {
|
||||
if (show || show === undefined) {
|
||||
// 若传入 show: true, 或没有设置,则更新原有的 icon 样式
|
||||
const iconConfig = mix({}, iconShape.attr(), icon);
|
||||
const { width: w = 20, height: h = 20 } = iconConfig;
|
||||
let { width: w = 20, height: h = 20 } = iconConfig;
|
||||
if (iconConfig.fontFamily === 'iconfont' || iconConfig.hasOwnProperty('text')) {
|
||||
w = 0;
|
||||
h = 0;
|
||||
}
|
||||
iconShape.attr({
|
||||
...iconConfig,
|
||||
x: -w / 2,
|
||||
@ -313,7 +315,11 @@ const singleNode: ShapeOptions = {
|
||||
}
|
||||
} else if (show) {
|
||||
// 如果原先不存在 icon,但传入了 show: true,则新增 icon
|
||||
const { width: w, height: h } = icon;
|
||||
let { width: w, height: h } = icon;
|
||||
if (icon.fontFamily === 'iconfont') {
|
||||
w = 0;
|
||||
h = 0;
|
||||
}
|
||||
const name = `${this.type}-icon`;
|
||||
group['shapeMap'][name] = group.addShape('image', {
|
||||
attrs: {
|
||||
|
@ -115,7 +115,7 @@ export const shapeBase: ShapeOptions = {
|
||||
* @param group
|
||||
* @param keyShape
|
||||
*/
|
||||
afterDraw(cfg?: ModelConfig, group?: IGroup, keyShape?: IShape) {},
|
||||
afterDraw(cfg?: ModelConfig, group?: IGroup, keyShape?: IShape) { },
|
||||
drawShape(cfg?: ModelConfig, group?: IGroup): IShape {
|
||||
return null as any;
|
||||
},
|
||||
@ -188,7 +188,7 @@ export const shapeBase: ShapeOptions = {
|
||||
drawLabelBg(cfg: ModelConfig, group: IGroup, label: IElement) {
|
||||
const { labelCfg: defaultLabelCfg } = this.options as ModelConfig;
|
||||
const labelCfg = mix({}, defaultLabelCfg, cfg.labelCfg) as ILabelConfig;
|
||||
const style = this.getLabelBgStyleByPosition(label, cfg, labelCfg, group);
|
||||
const style = this.getLabelBgStyleByPosition(label, labelCfg);
|
||||
const rect = group.addShape('rect', { name: 'text-bg-shape', attrs: style });
|
||||
group['shapeMap']['text-bg-shape'] = rect;
|
||||
return rect;
|
||||
@ -198,9 +198,7 @@ export const shapeBase: ShapeOptions = {
|
||||
},
|
||||
getLabelBgStyleByPosition(
|
||||
label: IElement,
|
||||
cfg: ModelConfig,
|
||||
labelCfg?: ILabelConfig,
|
||||
group?: IGroup,
|
||||
): LabelStyle {
|
||||
return {};
|
||||
},
|
||||
@ -257,7 +255,7 @@ export const shapeBase: ShapeOptions = {
|
||||
// 防止 cfg.label = "" 的情况
|
||||
if (cfg.label || cfg.label === '') {
|
||||
const group = item.getContainer();
|
||||
let { labelCfg = {} } = this.mergeStyle || this.getOptions({}, updateType) as ModelConfig || {};
|
||||
let { labelCfg = {} } = this.mergeStyle || this.getOptions({}, updateType) as ModelConfig || {};
|
||||
const labelClassName = this.itemType + CLS_LABEL_SUFFIX;
|
||||
const label = group['shapeMap'][labelClassName] || group.find(ele => ele.get('className') === labelClassName);
|
||||
const labelBgClassname = this.itemType + CLS_LABEL_BG_SUFFIX;
|
||||
@ -315,23 +313,9 @@ export const shapeBase: ShapeOptions = {
|
||||
} else if (labelStyle.background) {
|
||||
const calculateBgStyle = (this as any).getLabelBgStyleByPosition(
|
||||
label,
|
||||
cfg,
|
||||
labelCfg,
|
||||
group,
|
||||
);
|
||||
const labelBgStyle = calculateBgStyle;
|
||||
if (!isNaN(rotate) && rotate !== '') {
|
||||
let bgRotateMatrix = [1, 0, 0, 0, 1, 0, 0, 0, 1];
|
||||
bgRotateMatrix = transform(bgRotateMatrix, [
|
||||
['t', -labelBgStyle.x, -labelBgStyle.y],
|
||||
['r', rotate],
|
||||
['t', labelBgStyle.x, labelBgStyle.y],
|
||||
]);
|
||||
labelBgStyle.matrix = bgRotateMatrix;
|
||||
} else {
|
||||
labelBg.resetMatrix();
|
||||
}
|
||||
labelBg.attr(labelBgStyle);
|
||||
labelBg.attr(calculateBgStyle);
|
||||
} else {
|
||||
group.removeChild(labelBg);
|
||||
}
|
||||
@ -340,7 +324,7 @@ export const shapeBase: ShapeOptions = {
|
||||
},
|
||||
|
||||
// update(cfg, item) // 默认不定义
|
||||
afterUpdate(cfg?: ModelConfig, item?: Item) {},
|
||||
afterUpdate(cfg?: ModelConfig, item?: Item) { },
|
||||
/**
|
||||
* 设置节点的状态,主要是交互状态,业务状态请在 draw 方法中实现
|
||||
* 单图形的节点仅考虑 selected、active 状态,有其他状态需求的用户自己复写这个方法
|
||||
@ -558,7 +542,7 @@ export const shapeBase: ShapeOptions = {
|
||||
* @return {Array|null} 锚点的数组,如果为 null,则没有锚点
|
||||
*/
|
||||
getAnchorPoints(cfg: ModelConfig): number[][] | undefined {
|
||||
const anchorPoints = cfg?.anchorPoints || this.getCustomConfig(cfg)?.anchorPoints || this.options?.anchorPoints ;
|
||||
const anchorPoints = cfg?.anchorPoints || this.getCustomConfig(cfg)?.anchorPoints || this.options?.anchorPoints;
|
||||
return anchorPoints;
|
||||
},
|
||||
};
|
||||
|
@ -64,7 +64,7 @@ const colorSet = {
|
||||
};
|
||||
|
||||
export default {
|
||||
version: '0.4.1',
|
||||
version: '0.5.1',
|
||||
rootContainerClassName: 'root-container',
|
||||
nodeContainerClassName: 'node-container',
|
||||
edgeContainerClassName: 'edge-container',
|
||||
@ -251,6 +251,6 @@ export default {
|
||||
},
|
||||
windowFontFamily: typeof window !== 'undefined' && window.getComputedStyle
|
||||
? window.getComputedStyle(document.body, null).getPropertyValue('font-family') ||
|
||||
'Arial, sans-serif'
|
||||
'Arial, sans-serif'
|
||||
: 'Arial, sans-serif'
|
||||
};
|
||||
|
@ -353,13 +353,14 @@ export default class ItemController {
|
||||
return;
|
||||
}
|
||||
const model = combo.getModel();
|
||||
const comboBBox = getComboBBox(model.collapsed ? [] : children, graph);
|
||||
const { x: comboX, y: comboY } = model.collapsed ? getComboBBox(children, graph) : comboBBox;
|
||||
|
||||
const comboBBox = getComboBBox(children, graph, combo);
|
||||
const { x: comboX, y: comboY } = comboBBox;
|
||||
|
||||
combo.set('bbox', comboBBox);
|
||||
combo.update({
|
||||
x: comboX,
|
||||
y: comboY,
|
||||
x: comboX || model.x,
|
||||
y: comboY || model.y,
|
||||
});
|
||||
|
||||
const shapeFactory = combo.get('shapeFactory');
|
||||
|
@ -552,30 +552,77 @@ export default abstract class AbstractGraph extends EventEmitter implements IAbs
|
||||
return this.findAll(type, item => item.hasState(state));
|
||||
}
|
||||
|
||||
private getAnimateCfgWithCallback({
|
||||
animateCfg,
|
||||
callback
|
||||
}: {
|
||||
animateCfg: GraphAnimateConfig;
|
||||
callback: () => void;
|
||||
}): GraphAnimateConfig {
|
||||
let animateConfig: GraphAnimateConfig;
|
||||
if (!animateCfg) {
|
||||
animateConfig = {
|
||||
duration: 500,
|
||||
callback
|
||||
};
|
||||
} else {
|
||||
animateConfig = clone(animateCfg);
|
||||
if (animateCfg.callback) {
|
||||
const animateCfgCallback = animateCfg.callback;
|
||||
animateConfig.callback = () => {
|
||||
callback();
|
||||
animateCfgCallback();
|
||||
}
|
||||
} else {
|
||||
animateConfig.callback = callback;
|
||||
}
|
||||
}
|
||||
return animateConfig;
|
||||
}
|
||||
|
||||
/**
|
||||
* 平移画布
|
||||
* @param dx 水平方向位移
|
||||
* @param dy 垂直方向位移
|
||||
* @param {boolean} animate 是否带有动画地移动
|
||||
* @param {GraphAnimateConfig} animateCfg 若带有动画,动画的配置项
|
||||
*/
|
||||
public translate(dx: number, dy: number): void {
|
||||
public translate(dx: number, dy: number, animate?: boolean, animateCfg?: GraphAnimateConfig): void {
|
||||
const group: IGroup = this.get('group');
|
||||
|
||||
let matrix = clone(group.getMatrix());
|
||||
if (!matrix) {
|
||||
matrix = [1, 0, 0, 0, 1, 0, 0, 0, 1];
|
||||
}
|
||||
matrix = transform(matrix, [['t', dx, dy]]);
|
||||
if (animate) {
|
||||
const animateConfig = this.getAnimateCfgWithCallback({
|
||||
animateCfg,
|
||||
callback: () => this.emit('viewportchange', { action: 'translate', matrix: group.getMatrix() })
|
||||
});
|
||||
|
||||
group.setMatrix(matrix);
|
||||
move(group, {
|
||||
x: group.getCanvasBBox().x + dx,
|
||||
y: group.getCanvasBBox().y + dy
|
||||
}, animate, animateConfig || {
|
||||
duration: 500,
|
||||
easing: 'easeCubic'
|
||||
});
|
||||
} else {
|
||||
matrix = transform(matrix, [['t', dx, dy]]);
|
||||
|
||||
this.emit('viewportchange', { action: 'translate', matrix: group.getMatrix() });
|
||||
this.autoPaint();
|
||||
group.setMatrix(matrix);
|
||||
|
||||
this.emit('viewportchange', { action: 'translate', matrix });
|
||||
this.autoPaint();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 平移画布到某点
|
||||
* @param {number} x 水平坐标
|
||||
* @param {number} y 垂直坐标
|
||||
* @param {boolean} animate 是否带有动画地移动
|
||||
* @param {GraphAnimateConfig} animateCfg 若带有动画,动画的配置项
|
||||
*/
|
||||
public moveTo(x: number, y: number, animate?: boolean, animateCfg?: GraphAnimateConfig): void {
|
||||
const group: IGroup = this.get('group');
|
||||
@ -705,25 +752,10 @@ export default abstract class AbstractGraph extends EventEmitter implements IAbs
|
||||
const initialRatio = aniMatrix[0];
|
||||
const targetRatio = initialRatio * ratio;
|
||||
|
||||
let animateConfig: GraphAnimateConfig;
|
||||
if (!animateCfg) {
|
||||
animateConfig = {
|
||||
duration: 500,
|
||||
callback: () => {
|
||||
this.emit('viewportchange', { action: 'zoom', matrix: aniMatrix });
|
||||
}
|
||||
};
|
||||
} else if (animateCfg.callback) {
|
||||
// This is to prevent modifying the original animateCfg.callback
|
||||
const { callback } = animateCfg;
|
||||
animateConfig = clone(animateCfg);
|
||||
animateConfig.callback = () => {
|
||||
this.emit('viewportchange', { action: 'zoom', matrix: aniMatrix });
|
||||
callback();
|
||||
}
|
||||
} else {
|
||||
animateConfig = animateCfg;
|
||||
}
|
||||
const animateConfig = this.getAnimateCfgWithCallback({
|
||||
animateCfg,
|
||||
callback: () => this.emit('viewportchange', { action: 'zoom', matrix: group.getMatrix() })
|
||||
});
|
||||
|
||||
group.animate((ratio: number) => {
|
||||
if (ratio === 1) {
|
||||
@ -2963,11 +2995,11 @@ export default abstract class AbstractGraph extends EventEmitter implements IAbs
|
||||
// 清空栈数据
|
||||
this.clearStack();
|
||||
|
||||
this.get('itemController').destroy();
|
||||
this.get('modeController').destroy();
|
||||
this.get('viewController').destroy();
|
||||
this.get('stateController').destroy();
|
||||
this.get('canvas').destroy();
|
||||
this.get('itemController')?.destroy();
|
||||
this.get('modeController')?.destroy();
|
||||
this.get('viewController')?.destroy();
|
||||
this.get('stateController')?.destroy();
|
||||
this.get('canvas')?.destroy();
|
||||
|
||||
(this.cfg as any) = null;
|
||||
this.destroyed = true;
|
||||
|
@ -31,8 +31,8 @@ export interface IAbstractGraph extends EventEmitter {
|
||||
get: <T = any>(key: string) => T;
|
||||
set: <T = any>(key: string | object, value?: T) => Graph;
|
||||
findById: (id: string) => Item;
|
||||
translate: (dx: number, dy: number) => void;
|
||||
zoom: (ratio: number, center?: Point) => boolean;
|
||||
translate: (dx: number, dy: number, animate?: boolean, animateCfg?: GraphAnimateConfig) => void;
|
||||
zoom: (ratio: number, center?: Point, animate?: boolean, animateCfg?: GraphAnimateConfig) => boolean;
|
||||
|
||||
/**
|
||||
* 获取 graph 的根图形分组
|
||||
|
@ -10,6 +10,7 @@ import {
|
||||
NodeConfig,
|
||||
ComboTree,
|
||||
ComboConfig,
|
||||
ICombo
|
||||
} from '../types';
|
||||
import { applyMatrix } from './math';
|
||||
import letterAspectRatio from './letterAspectRatio';
|
||||
@ -591,7 +592,7 @@ export const reconstructTree = (
|
||||
return trees;
|
||||
};
|
||||
|
||||
export const getComboBBox = (children: ComboTree[], graph: IAbstractGraph): BBox => {
|
||||
export const getComboBBox = (children: ComboTree[], graph: IAbstractGraph, combo?: ICombo): BBox => {
|
||||
const comboBBox = {
|
||||
minX: Infinity,
|
||||
minY: Infinity,
|
||||
@ -606,7 +607,18 @@ export const getComboBBox = (children: ComboTree[], graph: IAbstractGraph): BBox
|
||||
};
|
||||
|
||||
if (!children || children.length === 0) {
|
||||
return comboBBox;
|
||||
const comboModel = combo?.getModel();
|
||||
const { x, y } = comboModel || {};
|
||||
return {
|
||||
minX: x,
|
||||
minY: y,
|
||||
maxX: x,
|
||||
maxY: y,
|
||||
x: x,
|
||||
y: y,
|
||||
width: undefined,
|
||||
height: undefined
|
||||
};
|
||||
}
|
||||
|
||||
children.forEach((child) => {
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@antv/g6-element",
|
||||
"version": "0.4.1",
|
||||
"version": "0.5.1",
|
||||
"description": "A Graph Visualization Framework in JavaScript",
|
||||
"keywords": [
|
||||
"antv",
|
||||
@ -61,7 +61,7 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@antv/g-base": "^0.5.1",
|
||||
"@antv/g6-core": "0.4.1",
|
||||
"@antv/g6-core": "0.5.1",
|
||||
"@antv/util": "~2.0.5"
|
||||
},
|
||||
"devDependencies": {
|
||||
@ -87,6 +87,6 @@
|
||||
"ts-jest": "^24.1.0",
|
||||
"ts-loader": "^7.0.3",
|
||||
"typescript": "^3.9.5",
|
||||
"@antv/g6": "4.3.11"
|
||||
"@antv/g6": "4.5.1"
|
||||
}
|
||||
}
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@antv/g6",
|
||||
"version": "4.4.1",
|
||||
"version": "4.5.1",
|
||||
"description": "A Graph Visualization Framework in JavaScript",
|
||||
"keywords": [
|
||||
"antv",
|
||||
@ -66,7 +66,7 @@
|
||||
]
|
||||
},
|
||||
"dependencies": {
|
||||
"@antv/g6-pc": "0.4.1"
|
||||
"@antv/g6-pc": "0.5.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/core": "^7.7.7",
|
||||
@ -90,4 +90,4 @@
|
||||
"webpack": "^4.41.4",
|
||||
"webpack-cli": "^3.3.10"
|
||||
}
|
||||
}
|
||||
}
|
@ -1,7 +1,7 @@
|
||||
import G6 from '@antv/g6-pc';
|
||||
|
||||
G6.version = '4.4.1';
|
||||
G6.version = '4.5.1';
|
||||
|
||||
export * from '@antv/g6-pc';
|
||||
export default G6;
|
||||
export const version = '4.4.1';
|
||||
export const version = '4.5.1';
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@antv/g6-pc",
|
||||
"version": "0.4.1",
|
||||
"version": "0.5.1",
|
||||
"description": "A Graph Visualization Framework in JavaScript",
|
||||
"keywords": [
|
||||
"antv",
|
||||
@ -74,12 +74,12 @@
|
||||
"@antv/g-canvas": "^0.5.2",
|
||||
"@antv/g-math": "^0.1.1",
|
||||
"@antv/g-svg": "^0.5.1",
|
||||
"@antv/g6-core": "0.4.1",
|
||||
"@antv/g6-plugin": "0.4.1",
|
||||
"@antv/g6-element": "0.4.1",
|
||||
"@antv/g6-core": "0.5.1",
|
||||
"@antv/g6-plugin": "0.5.1",
|
||||
"@antv/g6-element": "0.5.1",
|
||||
"@antv/algorithm": "^0.1.8",
|
||||
"@antv/hierarchy": "^0.6.7",
|
||||
"@antv/layout": "0.1.19-beta.5",
|
||||
"@antv/layout": "^0.1.22",
|
||||
"@antv/matrix-util": "^3.1.0-beta.3",
|
||||
"@antv/path-util": "^2.0.3",
|
||||
"@antv/util": "~2.0.5",
|
||||
@ -124,4 +124,4 @@
|
||||
"worker-loader": "^3.0.0",
|
||||
"stats-js": "1.0.1"
|
||||
}
|
||||
}
|
||||
}
|
@ -7,7 +7,7 @@ const textColor = 'rgb(0, 0, 0)';
|
||||
const colorSet = getColorsWithSubjectColor(subjectColor, backColor);
|
||||
|
||||
export default {
|
||||
version: '0.4.1',
|
||||
version: '0.5.1',
|
||||
rootContainerClassName: 'root-container',
|
||||
nodeContainerClassName: 'node-container',
|
||||
edgeContainerClassName: 'edge-container',
|
||||
|
138
packages/pc/tests/unit/element/edge-label-back-spec.ts
Normal file
138
packages/pc/tests/unit/element/edge-label-back-spec.ts
Normal file
@ -0,0 +1,138 @@
|
||||
import { Canvas, Shape } from '@antv/g-canvas';
|
||||
import { Graph } from '../../../src';
|
||||
import '../../../src';
|
||||
|
||||
const div = document.createElement('div');
|
||||
div.id = 'edge-shape';
|
||||
document.body.appendChild(div);
|
||||
|
||||
const canvas = new Canvas({
|
||||
container: 'edge-shape',
|
||||
width: 600,
|
||||
height: 600,
|
||||
});
|
||||
|
||||
describe('text background label', () => {
|
||||
it('text background label', done => {
|
||||
const data = {
|
||||
nodes: [
|
||||
{
|
||||
id: 'node1',
|
||||
x: 150,
|
||||
y: 50,
|
||||
label: 'node1',
|
||||
},
|
||||
{
|
||||
id: 'node2',
|
||||
x: 250,
|
||||
y: 200,
|
||||
label: 'node2',
|
||||
},
|
||||
{
|
||||
id: 'node3',
|
||||
x: 100,
|
||||
y: 350,
|
||||
label: 'node3',
|
||||
},
|
||||
],
|
||||
edges: [
|
||||
{
|
||||
source: 'node1',
|
||||
target: 'node2',
|
||||
label: 'edge 1',
|
||||
},
|
||||
{
|
||||
source: 'node2',
|
||||
target: 'node3',
|
||||
label: 'edge 2asdfasdfasdfasdf',
|
||||
labelCfg: {
|
||||
position: 'end',
|
||||
refX: 10,
|
||||
refY: -20,
|
||||
style: {
|
||||
textBaseline: 'bottom'
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
source: 'node3',
|
||||
target: 'node1',
|
||||
label: 'edge 3',
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
const graph = new Graph({
|
||||
container: 'edge-shape',
|
||||
width: 500,
|
||||
height: 500,
|
||||
// translate the graph to align the canvas's center, support by v3.5.1
|
||||
// fitCenter: true,
|
||||
defaultNode: {
|
||||
type: 'circle',
|
||||
labelCfg: {
|
||||
position: 'bottom',
|
||||
},
|
||||
},
|
||||
defaultEdge: {
|
||||
labelCfg: {
|
||||
autoRotate: true,
|
||||
style: {
|
||||
fill: '#1890ff',
|
||||
fontSize: 14,
|
||||
background: {
|
||||
fill: '#ffffff',
|
||||
stroke: '#9EC9FF',
|
||||
padding: [2, 2, 2, 2],
|
||||
radius: 2,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
modes: {
|
||||
default: ['drag-canvas', 'drag-node'],
|
||||
},
|
||||
nodeStateStyles: {
|
||||
// style configurations for hover state
|
||||
hover: {
|
||||
fillOpacity: 0.8,
|
||||
},
|
||||
// style configurations for selected state
|
||||
selected: {
|
||||
lineWidth: 5,
|
||||
},
|
||||
},
|
||||
});
|
||||
graph.data(data);
|
||||
graph.render();
|
||||
const edge1bg = graph.getEdges()[1].getContainer().find(ele => ele.get('classname') === 'edge-label-bg');
|
||||
let edge1bgMatrix = edge1bg.getMatrix();
|
||||
expect(edge1bgMatrix[0]).toBe(0.7071067811865476);
|
||||
expect(edge1bgMatrix[6]).toBe(-223.7023625196221);
|
||||
expect(edge1bgMatrix[7]).toBe(187.5118869365008);
|
||||
|
||||
graph.updateItem('node3', {
|
||||
x: 110,
|
||||
y: 250,
|
||||
});
|
||||
setTimeout(() => {
|
||||
edge1bgMatrix = edge1bg.getMatrix();
|
||||
expect(edge1bgMatrix[0]).toBe(0.9417419115948376);
|
||||
expect(edge1bgMatrix[6]).toBe(-83.53467171518344);
|
||||
expect(edge1bgMatrix[7]).toBe(55.06982476376146);
|
||||
graph.updateItem('node3', {
|
||||
x: 250,
|
||||
y: 200,
|
||||
})
|
||||
setTimeout(() => {
|
||||
edge1bgMatrix = edge1bg.getMatrix();
|
||||
expect(edge1bgMatrix[0]).toBe(1);
|
||||
expect(edge1bgMatrix[6]).toBe(0);
|
||||
expect(edge1bgMatrix[7]).toBe(0);
|
||||
expect(edge1bg.attr('x')).toBe(258);
|
||||
expect(edge1bg.attr('y')).toBe(164);
|
||||
done()
|
||||
}, 30);
|
||||
}, 100)
|
||||
});
|
||||
});
|
@ -34,4 +34,9 @@ describe('icon with iconfont', () => {
|
||||
|
||||
expect(graph.getNodes()[0].get('group').find(e => e.get('name') === 'circle-icon').attr('text')).toBe('xxx');
|
||||
});
|
||||
it('update iconfont node', () => {
|
||||
graph.updateItem('node', {});
|
||||
expect(graph.getNodes()[0].get('group').find(e => e.get('name') === 'circle-icon').attr('x')).toBe(0);
|
||||
expect(graph.getNodes()[0].get('group').find(e => e.get('name') === 'circle-icon').attr('y')).toBe(0);
|
||||
});
|
||||
});
|
||||
|
@ -1576,7 +1576,7 @@ describe('layouts', () => {
|
||||
graph.destroy();
|
||||
});
|
||||
});
|
||||
it('change layout', () => {
|
||||
it('change layout', (done) => {
|
||||
const graph = new Graph({
|
||||
container: div,
|
||||
width: 500,
|
||||
@ -1596,10 +1596,11 @@ describe('layouts', () => {
|
||||
type: 'force',
|
||||
});
|
||||
|
||||
Promise.resolve().then(() => {
|
||||
setTimeout(() => {
|
||||
expect(graph.get('layoutController').layoutMethods[0].type).toBe('force');
|
||||
graph.destroy();
|
||||
});
|
||||
done();
|
||||
}, 100);
|
||||
});
|
||||
it('subgraph layout', () => {
|
||||
const graph = new Graph({
|
||||
@ -2024,14 +2025,13 @@ describe('plugins', () => {
|
||||
setTimeout(() => {
|
||||
const minimapGroup = minimap2.get('canvas').get('children')[0];
|
||||
expect(minimapGroup.get('children').length).toBe(10);
|
||||
|
||||
const viewport = minimap2.get('viewport');
|
||||
expect(viewport.style.width).toBe('39.8406px');
|
||||
expect(viewport.style.height).toBe('39.8406px');
|
||||
expect(viewport.style.left).toBe('42.8287px');
|
||||
expect(viewport.style.top).toBe('25.6574px');
|
||||
expect(viewport.style.width).toBe('41.3907px');
|
||||
expect(viewport.style.height).toBe('37.351px');
|
||||
expect(viewport.style.left).toBe('58.6093px');
|
||||
expect(viewport.style.top).toBe('42.649px');
|
||||
graph2.destroy();
|
||||
}, 100);
|
||||
}, 150);
|
||||
});
|
||||
it('minimap keyShape', () => {
|
||||
const minimap = new G6.Minimap({
|
||||
@ -2057,15 +2057,13 @@ describe('plugins', () => {
|
||||
setTimeout(() => {
|
||||
const minimapGroup = minimap.get('canvas').get('children')[0];
|
||||
expect(minimapGroup.get('children').length).toBe(10);
|
||||
|
||||
const viewport = minimap.get('viewport');
|
||||
|
||||
expect(viewport.style.width).toBe('39.8406px');
|
||||
expect(viewport.style.height).toBe('39.8406px');
|
||||
expect(viewport.style.left).toBe('41.5787px');
|
||||
expect(viewport.style.top).toBe('29.5618px');
|
||||
expect(viewport.style.width).toBe('42.8115px');
|
||||
expect(viewport.style.height).toBe('30.6977px');
|
||||
expect(viewport.style.left).toBe('57.1885px');
|
||||
expect(viewport.style.top).toBe('49.3023px');
|
||||
graph.destroy();
|
||||
}, 100);
|
||||
}, 150);
|
||||
});
|
||||
|
||||
it('edge bundling', () => {
|
||||
|
@ -53,26 +53,27 @@ describe('graph', () => {
|
||||
stats.showPanel(0);
|
||||
document.body.appendChild(stats.dom);
|
||||
|
||||
|
||||
|
||||
it.only('first render', done => {
|
||||
fetch('https://gw.alipayobjects.com/os/basement_prod/da5a1b47-37d6-44d7-8d10-f3e046dabf82.json')
|
||||
.then((res) => res.json())
|
||||
.then((data) => {
|
||||
data.nodes.forEach(node => {
|
||||
node.label = node.olabel
|
||||
})
|
||||
const begin = performance.now();
|
||||
graph.once('afterrender', e => {
|
||||
console.log('first render time:', performance.now() - begin);
|
||||
})
|
||||
graph.data(data);
|
||||
graph.render();
|
||||
done();
|
||||
});
|
||||
.then((res) => res.json())
|
||||
.then((data) => {
|
||||
data.nodes.forEach(node => {
|
||||
node.label = node.olabel
|
||||
})
|
||||
const begin = performance.now();
|
||||
graph.once('afterrender', e => {
|
||||
console.log('first render time:', performance.now() - begin);
|
||||
})
|
||||
graph.data(data);
|
||||
graph.render();
|
||||
done();
|
||||
});
|
||||
setTimeout(() => done(), 1000);
|
||||
});
|
||||
it.only('global refresh: drag', done => {
|
||||
let begin, duration = 0;
|
||||
for (let i = 0; i < TIMES; i ++) {
|
||||
for (let i = 0; i < TIMES; i++) {
|
||||
begin = performance.now();
|
||||
graph.emit('dragstart', { clientX: 150, clientY: 150, target: graph.get('canvas') });
|
||||
graph.emit('drag', { clientX: 200, clientY: 200, target: graph.get('canvas') });
|
||||
@ -89,20 +90,20 @@ describe('graph', () => {
|
||||
stats.update();
|
||||
graph.emit('dragstart', { clientX: currentPos, clientY: currentPos, target: graph.get('canvas') });
|
||||
if (Math.round(count / 100) % 2) currentPos += 5;
|
||||
else currentPos -= 5;
|
||||
else currentPos -= 5;
|
||||
graph.emit('drag', { clientX: currentPos, clientY: currentPos, target: graph.get('canvas') });
|
||||
graph.emit('dragend', { clientX: currentPos, clientY: currentPos });
|
||||
count ++;
|
||||
requestAnimationFrame( animate );
|
||||
count++;
|
||||
requestAnimationFrame(animate);
|
||||
}
|
||||
requestAnimationFrame( animate );
|
||||
requestAnimationFrame(animate);
|
||||
done()
|
||||
});
|
||||
it('global refresh: zoom', done => {
|
||||
const eIn = createWheelEvent(graph.get('canvas').get('el'), 1, 100, 100);
|
||||
const eOut = createWheelEvent(graph.get('canvas').get('el'), -1, 100, 100);
|
||||
let begin, duration = 0;
|
||||
for (let i = 0; i < TIMES; i ++) {
|
||||
for (let i = 0; i < TIMES; i++) {
|
||||
begin = performance.now();
|
||||
graph.emit('wheel', i > TIMES / 2 ? eIn : eOut);
|
||||
duration += (performance.now() - begin);
|
||||
@ -144,11 +145,11 @@ describe('graph', () => {
|
||||
let begin, duration = 0;
|
||||
const nodeNum = graph.getNodes().length;
|
||||
const edgeNum = graph.getEdges().length;
|
||||
for (let i = 0; i < TIMES; i ++) {
|
||||
for (let i = 0; i < TIMES; i++) {
|
||||
const item = i < TIMES / 2 ?
|
||||
graph.getNodes()[Math.floor(Math.random() * nodeNum)] :
|
||||
graph.getEdges()[Math.floor(Math.random() * edgeNum)];
|
||||
const config = i < TIMES / 2 ? {...nodeTargetConfig} : {...edgeTargetConfig};
|
||||
const config = i < TIMES / 2 ? { ...nodeTargetConfig } : { ...edgeTargetConfig };
|
||||
begin = performance.now();
|
||||
graph.updateItem(item, config);
|
||||
duration += (performance.now() - begin);
|
||||
@ -182,7 +183,7 @@ describe('graph', () => {
|
||||
const items = [];
|
||||
const nodeNum = graph.getNodes().length;
|
||||
const edgeNum = graph.getEdges().length;
|
||||
for (let i = 0; i < TIMES; i ++) {
|
||||
for (let i = 0; i < TIMES; i++) {
|
||||
const item = i < TIMES / 2 ?
|
||||
graph.getNodes()[Math.floor(Math.random() * nodeNum)] :
|
||||
graph.getEdges()[Math.floor(Math.random() * edgeNum)];
|
||||
@ -201,7 +202,7 @@ describe('graph', () => {
|
||||
duration += (performance.now() - begin);
|
||||
})
|
||||
console.log(`ave time (${TIMES} times) for clearing one item with one state: `, duration / TIMES, 'ms')
|
||||
|
||||
|
||||
duration = 0;
|
||||
items.forEach(item => {
|
||||
begin = performance.now();
|
||||
@ -231,7 +232,7 @@ describe('graph', () => {
|
||||
graph.updateLayout({
|
||||
type: 'force',
|
||||
tick: () => {
|
||||
funcs.push(() => {});
|
||||
funcs.push(() => { });
|
||||
}
|
||||
});
|
||||
|
||||
@ -240,7 +241,7 @@ describe('graph', () => {
|
||||
stats.update();
|
||||
const func = funcs.pop();
|
||||
if (func) func();
|
||||
requestAnimationFrame( animate );
|
||||
requestAnimationFrame(animate);
|
||||
}
|
||||
requestAnimationFrame(animate);
|
||||
done();
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@antv/g6-plugin",
|
||||
"version": "0.4.1",
|
||||
"version": "0.5.1",
|
||||
"description": "G6 Plugin",
|
||||
"main": "lib/index.js",
|
||||
"module": "es/index.js",
|
||||
@ -22,7 +22,7 @@
|
||||
"@antv/g-base": "^0.5.1",
|
||||
"@antv/g-canvas": "^0.5.2",
|
||||
"@antv/g-svg": "^0.5.2",
|
||||
"@antv/g6-core": "0.4.1",
|
||||
"@antv/g6-core": "0.5.1",
|
||||
"@antv/matrix-util": "^3.1.0-beta.3",
|
||||
"@antv/scale": "^0.3.4",
|
||||
"@antv/util": "^2.0.9",
|
||||
@ -57,6 +57,6 @@
|
||||
"jquery": "^3.5.1",
|
||||
"rimraf": "^3.0.2",
|
||||
"ts-jest": "^26.4.4",
|
||||
"@antv/g6": "4.3.11"
|
||||
"@antv/g6": "4.5.1"
|
||||
}
|
||||
}
|
@ -115,6 +115,8 @@ export type ControllerCfg = Partial<{
|
||||
readonly nextBtnStyle?: ExtendedShapeStyle;
|
||||
/** ‘播放’ 与 ‘暂停’ 按钮的样式,同时可以为其配置 scale、offsetX、offsetY 单独控制该控制器的缩放以及平移 */
|
||||
readonly playBtnStyle?: ExtendedShapeStyle;
|
||||
/** 控制栏背景方框的样式 */
|
||||
readonly containerStyle?: ExtendedShapeStyle;
|
||||
|
||||
/** ‘速度控制器’ 的样式,包括速度的指针、速度指示滚轮(横线)、文本的样式,以及整个速度控制器的缩放(scale)与左右偏移(offsetX,offsetY) */
|
||||
readonly speedControllerStyle?: {
|
||||
@ -233,6 +235,7 @@ export default class ControllerBtn {
|
||||
hideTimeTypeController,
|
||||
fill = DEFAULT_RECT_FILL,
|
||||
stroke = DEFAULT_RECT_STROKE,
|
||||
containerStyle = {}
|
||||
} = controllerCfg;
|
||||
|
||||
const playBtnStyle = {
|
||||
@ -260,6 +263,7 @@ export default class ControllerBtn {
|
||||
height,
|
||||
stroke,
|
||||
fill,
|
||||
...containerStyle
|
||||
},
|
||||
name: 'container-rect',
|
||||
});
|
||||
@ -392,6 +396,7 @@ export default class ControllerBtn {
|
||||
fontFamily: this.fontFamily || 'Arial, sans-serif',
|
||||
...text,
|
||||
} as any,
|
||||
name: 'speed-text'
|
||||
});
|
||||
|
||||
this.speedPoint = speedGroup.addShape('path', {
|
||||
@ -403,6 +408,7 @@ export default class ControllerBtn {
|
||||
matrix: [1, 0, 0, 0, 1, 0, 0, this.speedAxisY[4], 1],
|
||||
...pointer,
|
||||
},
|
||||
name: 'speed-pointer'
|
||||
});
|
||||
|
||||
// 根据配置在 speedControllerStyle 中的 scale offsetX offsetY 缩放和移动速度控制器
|
||||
@ -463,6 +469,7 @@ export default class ControllerBtn {
|
||||
...check,
|
||||
},
|
||||
capture: false,
|
||||
name: 'check-icon'
|
||||
});
|
||||
|
||||
this.checkedIcon.hide();
|
||||
@ -479,6 +486,7 @@ export default class ControllerBtn {
|
||||
: 'Arial, sans-serif',
|
||||
...text,
|
||||
} as any,
|
||||
name: 'checked-text'
|
||||
});
|
||||
|
||||
// 根据配置在 timeTypeControllerStyle 中的 scale offsetX offsetY 缩放和移动速度控制器
|
||||
|
@ -150,6 +150,7 @@ export default class Handler {
|
||||
radius,
|
||||
opacity,
|
||||
cursor,
|
||||
lineAppendWidth: 12,
|
||||
},
|
||||
name: `${name}-handler`,
|
||||
});
|
||||
|
@ -73,9 +73,29 @@ interface TimeBarConfig extends IPluginBaseConfig {
|
||||
|
||||
// 是否过滤边,若为 true,则需要配合边数据上有 date 字段,过滤节点同时将不满足 date 在选中范围内的边也过滤出去
|
||||
// 若为 false,则仅过滤节点以及两端节点都被过滤出去的边
|
||||
//【deprecate】,由 filterItemTypes 替代
|
||||
readonly filterEdge?: boolean;
|
||||
|
||||
// 过滤的类型, ['node', 'edge'], 默认为 ['node']
|
||||
readonly filterItemTypes?: string[];
|
||||
|
||||
// 容器的 CSS 样式
|
||||
readonly containerCSS?: Object;
|
||||
|
||||
// 是否通过 changeData 来进行筛选,false 则使用 hideItem
|
||||
readonly changeData?: boolean;
|
||||
|
||||
// 当时间轴范围发生变化时的回调函数
|
||||
rangeChange?: (graph: IGraph, minValue: string, maxValue: string) => void;
|
||||
|
||||
// 用户根据节点/边数据返回对应时间值的方法
|
||||
getDate?: (d: any) => number;
|
||||
|
||||
// 用户根据节点/边数据返回对应 value 的方法。value 用于在 type 为 trend 的时间轴上显示趋势线
|
||||
getValue?: (d: any) => number;
|
||||
|
||||
// 在过滤图元素时是否要忽略某些元素,范围 true,则忽略。否则按照正常过滤逻辑处理
|
||||
shouldIgnore?: (itemType: 'node' | 'edge', model: any, dateRage: { min: number, max: number }) => boolean;
|
||||
}
|
||||
|
||||
export default class TimeBar extends Base {
|
||||
@ -111,7 +131,9 @@ export default class TimeBar extends Base {
|
||||
data: [],
|
||||
},
|
||||
textStyle: {},
|
||||
filterEdge: false,
|
||||
filterEdge: false, // deprecate,由 filterItemTypes 替代
|
||||
filterItemTypes: ['node'],
|
||||
containerCSS: {}
|
||||
};
|
||||
}
|
||||
|
||||
@ -157,6 +179,8 @@ export default class TimeBar extends Base {
|
||||
height,
|
||||
});
|
||||
}
|
||||
// 根据传入的参数修改容器 CSS 样式
|
||||
if (this.get('containerCSS')) modifyCSS(timeBarContainer, this.get('containerCSS'));
|
||||
this.set('canvas', canvas);
|
||||
}
|
||||
|
||||
@ -175,7 +199,7 @@ export default class TimeBar extends Base {
|
||||
const fontFamily =
|
||||
typeof window !== 'undefined'
|
||||
? window.getComputedStyle(document.body, null).getPropertyValue('font-family') ||
|
||||
'Arial, sans-serif'
|
||||
'Arial, sans-serif'
|
||||
: 'Arial, sans-serif';
|
||||
this.set('fontFamily', fontFamily);
|
||||
}
|
||||
@ -206,6 +230,7 @@ export default class TimeBar extends Base {
|
||||
|
||||
let timebar = null;
|
||||
if (type === 'trend' || type === 'simple') {
|
||||
const getValue = this.get('getValue');
|
||||
timebar = new TrendTimeBar({
|
||||
graph,
|
||||
canvas,
|
||||
@ -220,7 +245,7 @@ export default class TimeBar extends Base {
|
||||
foregroundStyle,
|
||||
trendCfg: {
|
||||
...other,
|
||||
data: data.map((d) => d.value),
|
||||
data: data.map((d) => (getValue?.(d) || d.value)),
|
||||
},
|
||||
...slider,
|
||||
tick: {
|
||||
@ -244,9 +269,30 @@ export default class TimeBar extends Base {
|
||||
group,
|
||||
x: x + padding,
|
||||
y: y + padding,
|
||||
width,
|
||||
height: 42,
|
||||
padding: 2,
|
||||
...tick,
|
||||
});
|
||||
}
|
||||
// 鼠标按下左/右滑块或范围条后在任意地方释放,都触发暂停播放
|
||||
const handleMouseUp = () => {
|
||||
const timebarInstance = this.get('timebar');
|
||||
timebarInstance.draggingHandler = false;
|
||||
if (timebarInstance.isPlay) {
|
||||
timebarInstance.isPlay = false;
|
||||
timebarInstance.currentHandler = timebarInstance.maxHandlerShape;
|
||||
timebarInstance.changePlayStatus();
|
||||
}
|
||||
document.removeEventListener('mouseup', handleMouseUp)
|
||||
}
|
||||
canvas.on('mousedown', e => {
|
||||
if (e.target.get('name') === 'maxHandlerShape-handler' ||
|
||||
e.target.get('name') === 'minHandlerShape-handler' ||
|
||||
e.target === timebar.foregroundShape) {
|
||||
document.addEventListener('mouseup', handleMouseUp);
|
||||
}
|
||||
});
|
||||
|
||||
this.set('timebar', timebar);
|
||||
}
|
||||
@ -295,31 +341,70 @@ export default class TimeBar extends Base {
|
||||
this.cacheGraphData = graph.get('data'); // graph.save() as GraphData;
|
||||
}
|
||||
|
||||
const filterItemTypes = this.get('filterItemTypes');
|
||||
|
||||
const changeData = this.get('changeData');
|
||||
|
||||
// 过滤不在 min 和 max 范围内的节点
|
||||
const filterData = this.cacheGraphData.nodes.filter(
|
||||
(d: any) => d.date >= trendData[min].date && d.date <= trendData[max].date,
|
||||
);
|
||||
|
||||
const nodeIds = filterData.map((node) => node.id);
|
||||
|
||||
let fileterEdges = [];
|
||||
if (this.cacheGraphData.edges) {
|
||||
// 过滤 source 或 target 不在 min 和 max 范围内的边
|
||||
fileterEdges = this.cacheGraphData.edges.filter(
|
||||
(edge) => nodeIds.includes(edge.source) && nodeIds.includes(edge.target),
|
||||
);
|
||||
|
||||
if (this.get('filterEdge')) {
|
||||
fileterEdges = fileterEdges.filter(
|
||||
(edge) => edge.date >= trendData[min].date && edge.date <= trendData[max].date,
|
||||
const getDate = this.get('getDate');
|
||||
const shouldIgnore = this.get('shouldIgnore');
|
||||
const minDate = trendData[min].date, maxDate = trendData[max].date;
|
||||
if (changeData || changeData === undefined) {
|
||||
let filterNodes = this.cacheGraphData.nodes;
|
||||
let filterEdges = this.cacheGraphData.edges;
|
||||
if (filterItemTypes.includes('node')) {
|
||||
filterNodes = filterNodes.filter((node: any) => {
|
||||
const date = +(getDate?.(node) || node.date);
|
||||
return (date >= minDate && date <= maxDate) || shouldIgnore?.('node', node, { min: minDate, max: maxDate });
|
||||
}
|
||||
);
|
||||
const nodeIds = filterNodes.map((node) => node.id);
|
||||
if (filterEdges) {
|
||||
// 过滤 source 或 target 不在 min 和 max 范围内的边
|
||||
filterEdges = filterEdges.filter((edge) => (
|
||||
(nodeIds.includes(edge.source) && nodeIds.includes(edge.target)) ||
|
||||
shouldIgnore?.('edge', edge, { min: minDate, max: maxDate })
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
if (this.get('filterEdge') || filterItemTypes.includes('edge')) {
|
||||
filterEdges = filterEdges.filter((edge) => {
|
||||
const date = +(getDate?.(edge) || edge.date);
|
||||
return (date >= minDate && date <= maxDate) || shouldIgnore?.('edge', edge, { min: minDate, max: maxDate });
|
||||
});
|
||||
}
|
||||
|
||||
graph.changeData({
|
||||
nodes: filterNodes,
|
||||
edges: filterEdges,
|
||||
});
|
||||
} else {
|
||||
if (filterItemTypes.includes('node')) {
|
||||
graph.getNodes().forEach(node => {
|
||||
const model = node.getModel();
|
||||
if (shouldIgnore?.('node', model, { min: minDate, max: maxDate })) return;
|
||||
const date = +(getDate?.(model) || model.date);
|
||||
if (date < minDate || date > maxDate) {
|
||||
graph.hideItem(node);
|
||||
} else {
|
||||
graph.showItem(node);
|
||||
}
|
||||
});
|
||||
}
|
||||
if (this.get('filterEdge') || filterItemTypes.includes('edge')) {
|
||||
graph.getEdges().forEach(edge => {
|
||||
const model = edge.getModel();
|
||||
if (shouldIgnore?.('edge', model, { min: trendData[min].date, max: trendData[max].date })) return;
|
||||
const date = +(getDate?.(model) || model.date);
|
||||
if (date < trendData[min].date || date > trendData[max].date) {
|
||||
graph.hideItem(edge);
|
||||
} else {
|
||||
graph.showItem(edge);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
graph.changeData({
|
||||
nodes: filterData,
|
||||
edges: fileterEdges,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,8 +1,10 @@
|
||||
/**
|
||||
* 基于 G 的刻度时间轴组件
|
||||
*/
|
||||
import { ext } from '@antv/matrix-util';
|
||||
import { ICanvas, IGroup } from '@antv/g-base';
|
||||
import { isString } from '@antv/util';
|
||||
import { isNumber, isString } from '@antv/util';
|
||||
import { ShapeStyle, IAbstractGraph as IGraph } from '@antv/g6-core';
|
||||
import TimeBarTooltip from './timeBarTooltip';
|
||||
import ControllerBtn from './controllerBtn';
|
||||
import {
|
||||
@ -15,7 +17,7 @@ import {
|
||||
TIMEBAR_CONFIG_CHANGE,
|
||||
} from './constant';
|
||||
|
||||
import { ShapeStyle, IAbstractGraph as IGraph } from '@antv/g6-core';
|
||||
const transform = ext.transform;
|
||||
|
||||
const DEFAULT_SELECTEDTICK_STYLE = {
|
||||
fill: '#5B8FF9',
|
||||
@ -60,6 +62,7 @@ export interface TimeBarSliceConfig extends TimeBarSliceOption {
|
||||
// style
|
||||
readonly x: number;
|
||||
readonly y: number;
|
||||
readonly tickLabelStyle?: Object;
|
||||
}
|
||||
|
||||
export default class TimeBarSlice {
|
||||
@ -97,6 +100,8 @@ export default class TimeBarSlice {
|
||||
|
||||
private tickLabelFormatter: (d: any) => string | boolean;
|
||||
|
||||
private tickLabelStyle?: ShapeStyle;
|
||||
|
||||
private tickRects: any[];
|
||||
|
||||
private tickWidth: number;
|
||||
@ -145,6 +150,7 @@ export default class TimeBarSlice {
|
||||
unselectedTickStyle = DEFAULT_UNSELECTEDTICK_STYLE,
|
||||
tooltipBackgroundColor,
|
||||
tooltipFomatter,
|
||||
tickLabelStyle
|
||||
} = cfgs;
|
||||
|
||||
this.graph = graph;
|
||||
@ -160,6 +166,7 @@ export default class TimeBarSlice {
|
||||
this.start = start;
|
||||
this.end = end;
|
||||
this.tickLabelFormatter = tickLabelFormatter;
|
||||
this.tickLabelStyle = tickLabelStyle || {};
|
||||
this.selectedTickStyle = selectedTickStyle;
|
||||
this.unselectedTickStyle = unselectedTickStyle;
|
||||
|
||||
@ -191,6 +198,7 @@ export default class TimeBarSlice {
|
||||
tickLabelFormatter,
|
||||
selectedTickStyle,
|
||||
unselectedTickStyle,
|
||||
tickLabelStyle
|
||||
} = this;
|
||||
|
||||
const realWidth = width - 2 * padding;
|
||||
@ -216,6 +224,8 @@ export default class TimeBarSlice {
|
||||
this.startTickRectId = startTickId;
|
||||
this.endTickRectId = endTickId;
|
||||
|
||||
const rotate = tickLabelStyle.rotate;
|
||||
delete tickLabelStyle.rotate;
|
||||
data.forEach((d, i) => {
|
||||
// draw the tick rects
|
||||
const selected = i >= startTickId && i <= endTickId;
|
||||
@ -279,6 +289,7 @@ export default class TimeBarSlice {
|
||||
x2: centerX,
|
||||
y2: lineStartY + labelLineHeight,
|
||||
},
|
||||
name: 'tick-line'
|
||||
});
|
||||
|
||||
const labelStartY = lineStartY + labelLineHeight + padding;
|
||||
@ -294,8 +305,10 @@ export default class TimeBarSlice {
|
||||
textBaseline: 'top',
|
||||
fontSize: 10,
|
||||
fontFamily: this.fontFamily || 'Arial, sans-serif',
|
||||
...tickLabelStyle
|
||||
},
|
||||
capture: false,
|
||||
name: 'tick-label'
|
||||
});
|
||||
const textBBox = text.getBBox();
|
||||
if (textBBox.maxX > width) {
|
||||
@ -303,6 +316,29 @@ export default class TimeBarSlice {
|
||||
} else if (textBBox.minX < 0) {
|
||||
text.attr('textAlign', 'left');
|
||||
}
|
||||
if (isNumber(rotate) && labels.length !== 10) {
|
||||
const matrix = transform(
|
||||
[1, 0, 0, 0, 1, 0, 0, 0, 1],
|
||||
[
|
||||
['t', -centerX!, -labelStartY!],
|
||||
['r', rotate],
|
||||
['t', centerX - 5, labelStartY + 2],
|
||||
],
|
||||
);
|
||||
text.attr({
|
||||
textAlign: 'left',
|
||||
matrix,
|
||||
});
|
||||
}
|
||||
if (labels.length === 1) {
|
||||
text.attr({
|
||||
textAlign: 'left',
|
||||
});
|
||||
} else if (labels.length === 10) {
|
||||
text.attr({
|
||||
textAlign: 'right',
|
||||
});
|
||||
}
|
||||
// draw tick labels
|
||||
}
|
||||
});
|
||||
|
@ -78,6 +78,7 @@ export default class Button {
|
||||
path: this.getStartMarkerPath(x, y, scale),
|
||||
fill: style.stroke || '#aaa',
|
||||
},
|
||||
name: 'start-marker'
|
||||
});
|
||||
|
||||
this.pauseMarkerGroup = buttonGroup.addGroup({
|
||||
|
@ -126,6 +126,7 @@ export default class Trend {
|
||||
path,
|
||||
...lineStyle,
|
||||
},
|
||||
name: 'trend-line'
|
||||
});
|
||||
// 在 line 的基础上,绘制面积图
|
||||
if (isArea) {
|
||||
@ -135,6 +136,7 @@ export default class Trend {
|
||||
path: areaPath,
|
||||
...areaStyle,
|
||||
},
|
||||
name: 'trend-area'
|
||||
});
|
||||
}
|
||||
}
|
||||
@ -146,6 +148,7 @@ export default class Trend {
|
||||
path: dataToRectPath(this.intervalConfig.data, width, height, this.intervalConfig.style.barWidth),
|
||||
...this.intervalConfig.style,
|
||||
},
|
||||
name: 'trend-interval'
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -1,10 +1,10 @@
|
||||
import { Event, IGroup, ICanvas, IShape } from '@antv/g-base';
|
||||
import { get, size, assign, each } from '@antv/util';
|
||||
import { get, size, assign, each, isNumber } from '@antv/util';
|
||||
import { ext } from '@antv/matrix-util';
|
||||
import Trend, { TrendCfg } from './trend';
|
||||
import Handler from './handler';
|
||||
import { isString } from '@antv/util';
|
||||
import ControllerBtn, { ControllerCfg } from './controllerBtn';
|
||||
|
||||
import { ShapeStyle, IAbstractGraph as IGraph } from '@antv/g6-core';
|
||||
import {
|
||||
VALUE_CHANGE,
|
||||
@ -16,6 +16,8 @@ import {
|
||||
TIMELINE_END,
|
||||
} from './constant';
|
||||
|
||||
const transform = ext.transform;
|
||||
|
||||
/**
|
||||
* 一些默认的样式配置
|
||||
*/
|
||||
@ -277,7 +279,7 @@ export default class TrendTimeBar {
|
||||
this.fontFamily =
|
||||
typeof window !== 'undefined'
|
||||
? window.getComputedStyle(document.body, null).getPropertyValue('font-family') ||
|
||||
'Arial, sans-serif'
|
||||
'Arial, sans-serif'
|
||||
: 'Arial, sans-serif';
|
||||
|
||||
this.renderSlider();
|
||||
@ -347,6 +349,7 @@ export default class TrendTimeBar {
|
||||
height,
|
||||
...this.backgroundStyle,
|
||||
},
|
||||
name: 'background'
|
||||
});
|
||||
|
||||
const textGroup = this.group.addGroup();
|
||||
@ -361,9 +364,12 @@ export default class TrendTimeBar {
|
||||
text: this.minText,
|
||||
silent: false,
|
||||
fontFamily: this.fontFamily || 'Arial, sans-serif',
|
||||
stroke: '#fff',
|
||||
lineWidth: 5,
|
||||
...this.textStyle,
|
||||
},
|
||||
capture: false,
|
||||
name: 'min-text-shape'
|
||||
});
|
||||
|
||||
this.maxTextShape = textGroup.addShape('text', {
|
||||
@ -373,9 +379,12 @@ export default class TrendTimeBar {
|
||||
text: this.maxText,
|
||||
silent: false,
|
||||
fontFamily: this.fontFamily || 'Arial, sans-serif',
|
||||
stroke: '#fff',
|
||||
lineWidth: 5,
|
||||
...this.textStyle,
|
||||
},
|
||||
capture: false,
|
||||
name: 'max-text-shape'
|
||||
});
|
||||
} else {
|
||||
this.minTextShape = textGroup.addShape('text', {
|
||||
@ -386,9 +395,12 @@ export default class TrendTimeBar {
|
||||
text: this.minText,
|
||||
silent: false,
|
||||
fontFamily: this.fontFamily || 'Arial, sans-serif',
|
||||
stroke: '#fff',
|
||||
lineWidth: 5,
|
||||
...this.textStyle,
|
||||
},
|
||||
capture: false,
|
||||
name: 'min-text-shape'
|
||||
});
|
||||
this.maxTextShape = textGroup.addShape('text', {
|
||||
attrs: {
|
||||
@ -397,9 +409,12 @@ export default class TrendTimeBar {
|
||||
text: this.maxText,
|
||||
silent: false,
|
||||
fontFamily: this.fontFamily || 'Arial, sans-serif',
|
||||
stroke: '#fff',
|
||||
lineWidth: 5,
|
||||
...this.textStyle,
|
||||
},
|
||||
capture: false,
|
||||
name: 'max-text-shape'
|
||||
});
|
||||
}
|
||||
|
||||
@ -411,6 +426,7 @@ export default class TrendTimeBar {
|
||||
height,
|
||||
...this.foregroundStyle,
|
||||
},
|
||||
name: 'foreground-shape'
|
||||
});
|
||||
this.foregroundShape.on('mousedown', (e) => {
|
||||
e.target.attr('cursor', 'grabbing');
|
||||
@ -462,6 +478,8 @@ export default class TrendTimeBar {
|
||||
});
|
||||
}
|
||||
let lastX = -Infinity;
|
||||
const rotate = this.tickLabelStyle.rotate;
|
||||
delete this.tickLabelStyle.rotate;
|
||||
this.textList = tickData.map((data, index) => {
|
||||
this.tickPosList.push(this.x + index * interval);
|
||||
|
||||
@ -477,15 +495,40 @@ export default class TrendTimeBar {
|
||||
}
|
||||
|
||||
// 文本刻度
|
||||
const textX = this.x + index * interval, textY = this.y + height + 5;
|
||||
const text = this.group.addShape('text', {
|
||||
attrs: {
|
||||
x: this.x + index * interval,
|
||||
y: this.y + height + 5,
|
||||
x: textX,
|
||||
y: textY,
|
||||
text: label,
|
||||
fontFamily: this.fontFamily || 'Arial, sans-serif',
|
||||
...this.tickLabelStyle
|
||||
},
|
||||
name: 'tick-label'
|
||||
});
|
||||
if (isNumber(rotate) && index !== tickData.length - 1) {
|
||||
const matrix = transform(
|
||||
[1, 0, 0, 0, 1, 0, 0, 0, 1],
|
||||
[
|
||||
['t', -textX!, -textY!],
|
||||
['r', rotate],
|
||||
['t', textX - 5, textY + 2],
|
||||
],
|
||||
);
|
||||
text.attr({
|
||||
textAlign: 'left',
|
||||
matrix,
|
||||
});
|
||||
}
|
||||
if (index === 0) {
|
||||
text.attr({
|
||||
textAlign: 'left',
|
||||
});
|
||||
} else if (index !== tickData.length - 1) {
|
||||
text.attr({
|
||||
textAlign: 'right',
|
||||
});
|
||||
}
|
||||
|
||||
// 文本刻度上面的竖线
|
||||
const line = this.group.addShape('line', {
|
||||
@ -496,6 +539,7 @@ export default class TrendTimeBar {
|
||||
y2: this.y + height + 6,
|
||||
...this.tickLineStyle
|
||||
},
|
||||
name: 'tick-line'
|
||||
});
|
||||
line.toBack();
|
||||
|
||||
@ -730,8 +774,8 @@ export default class TrendTimeBar {
|
||||
const minData = this.ticks[this.adjustTickIndex(this.start * this.width)];
|
||||
const maxData = this.ticks[this.adjustTickIndex(this.end * this.width)];
|
||||
if (!this.currentHandler) {
|
||||
this.minText = this.tickLabelFormatter ? this.tickLabelFormatter(minData) : minData.date;
|
||||
this.maxText = this.tickLabelFormatter ? this.tickLabelFormatter(maxData) : maxData.date;
|
||||
this.minText = this.tickLabelFormatter ? this.tickLabelFormatter(minData) : minData?.date;
|
||||
this.maxText = this.tickLabelFormatter ? this.tickLabelFormatter(maxData) : maxData?.date;
|
||||
return;
|
||||
}
|
||||
// 操作不同的组件,反馈不一样
|
||||
@ -839,14 +883,14 @@ export default class TrendTimeBar {
|
||||
: { x: max + handlerWidth / 2 + TEXTPADDING, textAlign: 'left' };
|
||||
} else if (this.timeBarType === 'simple') {
|
||||
minAttrs =
|
||||
minBBox.width > min - TEXTPADDING
|
||||
? { x: min + handlerWidth / 2 + TEXTPADDING, textAlign: 'center' }
|
||||
: { x: min - handlerWidth / 2 - TEXTPADDING, textAlign: 'center' };
|
||||
minTextShape.attr('x') > minBBox.width // 左边滑块文本位置小于其宽度代表文字超过左边届
|
||||
? { x: min, textAlign: 'center' }
|
||||
: { x: min, textAlign: 'left' };
|
||||
|
||||
maxAttrs =
|
||||
maxBBox.width > this.width - max - TEXTPADDING
|
||||
? { x: max - handlerWidth / 2 - TEXTPADDING, textAlign: 'center' }
|
||||
: { x: max + handlerWidth / 2 + TEXTPADDING, textAlign: 'center' };
|
||||
maxTextShape.attr('x') > this.width - maxBBox.width // 有边滑块文本位置大于宽度代表文字超过右边界
|
||||
? { x: max, textAlign: 'right' }
|
||||
: { x: max, textAlign: 'center' };
|
||||
}
|
||||
|
||||
return !sorted ? [minAttrs, maxAttrs] : [maxAttrs, minAttrs];
|
||||
@ -855,21 +899,21 @@ export default class TrendTimeBar {
|
||||
private startPlay() {
|
||||
return typeof window !== 'undefined'
|
||||
? window.requestAnimationFrame(() => {
|
||||
const { ticks, width } = this;
|
||||
const speed = this.currentSpeed;
|
||||
const { ticks, width } = this;
|
||||
const speed = this.currentSpeed;
|
||||
|
||||
const tickInterval = width / ticks.length;
|
||||
const offsetX = tickInterval / (((10 - speed) * 1000) / 60);
|
||||
const tickInterval = width / ticks.length;
|
||||
const offsetX = tickInterval / (((10 - speed) * 1000) / 60);
|
||||
|
||||
const offsetXRange = this.adjustOffsetRange(offsetX / this.width);
|
||||
const offsetXRange = this.adjustOffsetRange(offsetX / this.width);
|
||||
|
||||
this.updateStartEnd(offsetXRange);
|
||||
this.updateUI();
|
||||
this.updateStartEnd(offsetXRange);
|
||||
this.updateUI();
|
||||
|
||||
if (this.isPlay) {
|
||||
this.playHandler = this.startPlay();
|
||||
}
|
||||
})
|
||||
if (this.isPlay) {
|
||||
this.playHandler = this.startPlay();
|
||||
}
|
||||
})
|
||||
: undefined;
|
||||
}
|
||||
|
||||
|
@ -389,15 +389,38 @@ describe('timeline play with timebar', () => {
|
||||
});
|
||||
|
||||
it('simple timebar', () => {
|
||||
|
||||
const data = {
|
||||
nodes: [
|
||||
{
|
||||
id: 'node1',
|
||||
x: 100,
|
||||
y: 100,
|
||||
},
|
||||
],
|
||||
nodes: [],
|
||||
edges: [],
|
||||
};
|
||||
|
||||
for (let i = 0; i < 100; i++) {
|
||||
const month = i < 30 ? '01' : '02';
|
||||
const day = i % 30 < 10 ? `0${i % 30}` : `${i % 30}`;
|
||||
const id = `node-${i}`;
|
||||
data.nodes.push({
|
||||
id,
|
||||
// date: parseInt(`2020${month}${day}`, 10),
|
||||
// value: Math.round(Math.random() * 300),
|
||||
properties: {
|
||||
date111: parseInt(`2020${month}${day}`, 10),
|
||||
value111: Math.round(Math.random() * 300),
|
||||
}
|
||||
});
|
||||
|
||||
data.edges.push({
|
||||
source: `node-${Math.round(Math.random() * 90)}`,
|
||||
target: `node-${Math.round(Math.random() * 90)}`,
|
||||
// date: parseInt(`2020${month}${day}`, 10),
|
||||
// value: Math.round(Math.random() * 300),
|
||||
properties: {
|
||||
date111: parseInt(`2020${month}${day}`, 10),
|
||||
value111: Math.round(Math.random() * 300),
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
const timeBarData = [];
|
||||
|
||||
for (let i = 1; i < 60; i++) {
|
||||
@ -423,25 +446,34 @@ describe('timeline play with timebar', () => {
|
||||
height: 150,
|
||||
padding: 10,
|
||||
type: 'simple',
|
||||
// filterEdge: true,
|
||||
filterItemTypes: ['edge'], // 'node',
|
||||
getDate: d => { return d.properties.date111 },
|
||||
containerCSS: {
|
||||
position: 'absolute',
|
||||
bottom: '50px'
|
||||
},
|
||||
trend: {
|
||||
data: timeBarData,
|
||||
isArea: true,
|
||||
// isArea: true,
|
||||
// areaStyle: {
|
||||
// fill: 'pink'
|
||||
// },
|
||||
lineStyle: {
|
||||
stroke: 'green',
|
||||
lineWidth: 1,
|
||||
},
|
||||
interval: {
|
||||
data: intervalData.map((d) => d.value),
|
||||
style: {
|
||||
// stroke: '#ccc',
|
||||
fill: '#ccc',
|
||||
},
|
||||
},
|
||||
// lineStyle: {
|
||||
// stroke: 'green',
|
||||
// lineWidth: 1,
|
||||
// },
|
||||
// interval: {
|
||||
// data: intervalData.map((d) => d.value),
|
||||
// style: {
|
||||
// // stroke: '#ccc',
|
||||
// fill: '#ccc',
|
||||
// },
|
||||
// },
|
||||
},
|
||||
slider: {
|
||||
start: 0,
|
||||
end: 1,
|
||||
// height: 50,
|
||||
|
||||
// backgroundStyle: {
|
||||
@ -462,13 +494,18 @@ describe('timeline play with timebar', () => {
|
||||
// }
|
||||
// }
|
||||
},
|
||||
tick: {
|
||||
tickLabelStyle: {
|
||||
rotate: Math.PI / 4
|
||||
}
|
||||
}
|
||||
// loop: true
|
||||
});
|
||||
const graph = new G6.Graph({
|
||||
container: div,
|
||||
width: 500,
|
||||
height: 500,
|
||||
// renderer: 'svg',
|
||||
// renderer: 'SVG',
|
||||
plugins: [timeLine],
|
||||
modes: {
|
||||
default: ['drag-node', 'zoom-canvas', 'drag-canvas'],
|
||||
|
@ -391,390 +391,6 @@ const graph = new G6.Graph({
|
||||
plugins: [toolbar], // Use the ToolBar plugin
|
||||
});
|
||||
```
|
||||
|
||||
## TimeBar
|
||||
|
||||
There are three types of built-in TimeBar in G6:
|
||||
|
||||
- Time bar with a line chart as background;
|
||||
- Simple time bar;
|
||||
- Time bar with descrete ticks.
|
||||
|
||||
All the three types of timebar supports play, fast forward, and fast backward.
|
||||
|
||||
<img src='https://gw.alipayobjects.com/mdn/rms_f8c6a0/afts/img/A*DOo6QpfFfMUAAAAAAAAAAAAAARQnAQ' width='500' />
|
||||
<br />Time bar with a line chart as background<br />
|
||||
|
||||
<img src='https://gw.alipayobjects.com/mdn/rms_f8c6a0/afts/img/A*bzGBQKkewZMAAAAAAAAAAAAAARQnAQ' width='500' />
|
||||
<br />Simple time bar<br />
|
||||
|
||||
<img src='https://gw.alipayobjects.com/mdn/rms_f8c6a0/afts/img/A*kHRkQpnvBmwAAAAAAAAAAAAAARQnAQ' width='500' />
|
||||
<br />Time bar with descrete ticks<br />
|
||||
|
||||
<br />Refer to the demos [HERE](https://g6.antv.vision/en/examples/tool/timebar#timebar)<br />
|
||||
|
||||
### Common Usage
|
||||
|
||||
Same to other plugins of G6, the users can initiate the TimeBar and assign it to the graph as:
|
||||
|
||||
```javascript
|
||||
import G6 from '@antv/g6';
|
||||
|
||||
const timebar = new G6.TimeBar({
|
||||
width: 500,
|
||||
height: 150,
|
||||
padding: 10,
|
||||
type: 'trend',
|
||||
trend: {
|
||||
data: timeBarData,
|
||||
},
|
||||
});
|
||||
|
||||
const graph = new G6.Graph({
|
||||
container: 'container',
|
||||
width,
|
||||
height,
|
||||
plugins: [timebar],
|
||||
});
|
||||
```
|
||||
|
||||
<br />If you want to use the TimeBar with line chart, assign the `type` to be `trend` when instantiating the TimeBar, which results in:
|
||||
|
||||
<img src='https://gw.alipayobjects.com/mdn/rms_f8c6a0/afts/img/A*lfvIQJYbs7oAAAAAAAAAAAAAARQnAQ' width='600' />
|
||||
|
||||
<br />Assigning the `type` to be `simple` results in:
|
||||
|
||||
<img src='https://gw.alipayobjects.com/mdn/rms_f8c6a0/afts/img/A*g2zhQqP6ruYAAAAAAAAAAAAAARQnAQ' width='600' />
|
||||
|
||||
<br />And assigning the `type` to be `tick` results in a TimeBar with descrete ticks. Note that it is different from the above two types of TimeBar, \*\*The TimeBar with decrete ticks is configured with the `tick` object but not the `trend` object.
|
||||
|
||||
```javascript
|
||||
const timebar = new G6.TimeBar({
|
||||
width,
|
||||
height: 150,
|
||||
type: 'tick',
|
||||
tick: {
|
||||
data: timeBarData,
|
||||
width,
|
||||
height: 42,
|
||||
tickLabelFormatter: d => {
|
||||
const dateStr = `${d.date}`;
|
||||
if ((count - 1) % 10 === 0) {
|
||||
return `${dateStr.substr(0, 4)}-${dateStr.substr(4, 2)}-${dateStr.substr(6, 2)}`;
|
||||
}
|
||||
return false;
|
||||
},
|
||||
tooltipFomatter: d => {
|
||||
const dateStr = `${d}`;
|
||||
return `${dateStr.substr(0, 4)}-${dateStr.substr(4, 2)}-${dateStr.substr(6, 2)}`;
|
||||
},
|
||||
},
|
||||
});
|
||||
```
|
||||
|
||||
<img src='https://gw.alipayobjects.com/mdn/rms_f8c6a0/afts/img/A*n6ECQ7Jn5pQAAAAAAAAAAAAAARQnAQ' width='600' />
|
||||
|
||||
|
||||
### Event Listener
|
||||
|
||||
TimeBar Plugin exposes several timing events. They could be listened by `graph.on('eventname', e => {})`.
|
||||
|
||||
| Event Name | Description |
|
||||
| --- | --- |
|
||||
| valuechange | Emitted when the value range of the timebar is chaged. |
|
||||
| timebarstartplay | Emitted when the timeline starts to play. |
|
||||
| timebarendplay | Emitted when the timeline ends playing. |
|
||||
|
||||
### Definition of the Configurations
|
||||
|
||||
#### Definition of the Interfaces
|
||||
|
||||
The complete interfaces for the TimeBar is shown below:
|
||||
|
||||
```javascript
|
||||
interface TimeBarConfig extends IPluginBaseConfig {
|
||||
// position size
|
||||
readonly x?: number;
|
||||
readonly y?: number;
|
||||
readonly width?: number;
|
||||
readonly height?: number;
|
||||
readonly padding?: number;
|
||||
|
||||
readonly type?: 'trend' | 'simple' | 'tick';
|
||||
// the configuration for the TimeBar with line chart and simple TimeBar, takes effect whtn the type is 'trend' or 'simple'
|
||||
readonly trend?: TrendConfig;
|
||||
|
||||
// the configurations for the two sliders
|
||||
readonly slider?: SliderOption;
|
||||
|
||||
// when the type is 'tick', it is the configuration for the TimeBar with descrete ticks
|
||||
// when the type is 'trend' or 'simpe', it is the configuration for the time tick labels under the timeBar
|
||||
readonly tick?: TimeBarSliceOption | TickCfg;
|
||||
|
||||
// the buttons for play, fast forward, and back forward
|
||||
readonly controllerCfg?: ControllerCfg;
|
||||
|
||||
// whether to consider the edge filtering. If it is false, only filter the nodes and the edges whose end nodes are filtered out while the selected range of the timeBar is changed. If it is true, there should be `date` properties on the edges data, and the timeBar will filter the edges which is not in the selected range in the same time
|
||||
readonly filterEdge?: boolean;
|
||||
|
||||
rangeChange?: (graph: IGraph, minValue: string, maxValue: string) => void;
|
||||
valueChange?: (graph: IGraph, value: string) => void;
|
||||
}
|
||||
```
|
||||
|
||||
#### The Parameters of the Interfaces
|
||||
|
||||
| Name | Type | Default Value | Description |
|
||||
| --- | --- | --- | --- |
|
||||
| container | HTMLDivElement | null | The DOM container of the TimeBar. By default, the plugin will create a container DOM with 'g6-component-timebar' as className |
|
||||
| x | number | 0 | The beginning x position of the TimeBar plugin |
|
||||
| y | number | 0 | The beginning y position of the TimeBar plugin |
|
||||
| width | number | | **Requred**, the width of the TimeBar |
|
||||
| height | number | | **Requred**, the height of the TimeBar |
|
||||
| padding | number/number[] | 10 | The padding of the container of the TimeBar |
|
||||
| type | 'trend' / 'simple' / 'tick' | trend | The type of the TimeBar, 'trend' by default |
|
||||
| trend | TrendConfig | null | The configuration for the TimeBar with line chart and simple TimeBar, takes effect whtn the type is 'trend' or 'simple' |
|
||||
| slider | SliderOption | null | The configurations for the two sliders |
|
||||
| tick | TimeBarSliceOption / TickCfg | null | If the type is 'tick', it is the configuration for the TimeBar with descrete ticks. If it the type is 'trend' or 'simple', it is the configuration for the time tick labels under the timeBar |
|
||||
| controllerCfg | ControllerCfg | null | The buttons for play, fast forward, and back forward |
|
||||
| filterEdge | boolean | false | Whether to consider the edge filtering. If it is false, only filter the nodes and the edges whose end nodes are filtered out while the selected range of the timeBar is changed. If it is true, there should be `date` properties on the edges data, and the timeBar will filter the edges which is not in the selected range in the same time |
|
||||
| rangeChange | Function | null | The callback function after the time range is changed. When it is not assigned, the graph elements will be filtered after the time range is changed |
|
||||
|
||||
#### Interface for TrendConfig
|
||||
|
||||
> Does not support the configurations for the style of the tick labels.
|
||||
|
||||
```javascript
|
||||
interface TrendConfig {
|
||||
// The data
|
||||
readonly data: {
|
||||
date: string;
|
||||
value: string;
|
||||
}[];
|
||||
// The position and size
|
||||
readonly x?: number;
|
||||
readonly y?: number;
|
||||
readonly width?: number;
|
||||
readonly height?: number;
|
||||
// The styles
|
||||
readonly smooth?: boolean;
|
||||
readonly isArea?: boolean;
|
||||
readonly lineStyle?: ShapeStyle;
|
||||
readonly areaStyle?: ShapeStyle;
|
||||
readonly interval?: Interval;
|
||||
}
|
||||
```
|
||||
|
||||
#### Parameters of the TrendConfig
|
||||
|
||||
| Name | Type | Default Value | Description |
|
||||
| --- | --- | --- | --- |
|
||||
| x | number | 0 | The beginning x position of the trend line chart |
|
||||
| y | number | 0 | The beginning y position of the trend line chart |
|
||||
| width | number | The width of the TimeBar | The width of the trend line chart of the TimeBar, we suggest to use the default value. If you wanna custom it, please assign the `width` of the slider in the same time |
|
||||
| height | number | 28 when type='trend'<br />8 when type='simple' | The height of the TimeBar | The width of the trend line chart of the TimeBar, we suggest to use the default value. If you wanna custom it, please assign the `height` of the slider in the same time |
|
||||
| smooth | boolean | false | Whether to show a smooth line on the trend line chart |
|
||||
| isArea | boolean | false | Whether to show a area chart instead |
|
||||
| lineStyle | ShapeStyle | null | The configurations for the style of the line in the line chart |
|
||||
| areaStyle | ShapeStyle | null | The configuration for the style of the area in the chart when `isArea` is `true` |
|
||||
| interval | Interval | null | The configuration for the style of the bars in the chart. When it is assigned, a mixed trend chart will take place. `Interval = { data: number[], style: ShapeStyle }`. Except the configurations in `ShapeStyle` for the style of the shapes in the bar charts, `barWidth` for the width of one bar is also configurable for `style` |
|
||||
|
||||
#### Interfaces of SliderOption
|
||||
|
||||
```javascript
|
||||
export type SliderOption = Partial<{
|
||||
readonly width?: number;
|
||||
readonly height?: number;
|
||||
readonly backgroundStyle?: ShapeStyle;
|
||||
readonly foregroundStyle?: ShapeStyle;
|
||||
// The style of the sliders
|
||||
readonly handlerStyle?: {
|
||||
width?: number;
|
||||
height?: number;
|
||||
style?: ShapeStyle;
|
||||
};
|
||||
readonly textStyle?: ShapeStyle;
|
||||
// The start and end position for the sliders, which indicate the data range for the filtering. Ranges from 0 to 1
|
||||
readonly start: number;
|
||||
readonly end: number;
|
||||
// The labels for the sliders
|
||||
readonly minText: string;
|
||||
readonly maxText: string;
|
||||
}>;
|
||||
```
|
||||
|
||||
#### Parameters for the SliderOption
|
||||
|
||||
| Name | Type | Default Value | Description |
|
||||
| --- | --- | --- | --- |
|
||||
| width | number | The width of the container of the TimeBar - 2 \* padding | The width of the background trend chart. We suggest to use the default value. If you wanna custom it, assign it the the `width` in the `trend` in the same time |
|
||||
| height | number | 28 when type='trend'<br />8 when type='simple' | The height of the background trend chart. We suggest to use the default value. If you wanna custom it, assign it the the `height` in the `trend` in the same time |
|
||||
| backgroundStyle | ShapeStyle | null | The configuration for the style of the background |
|
||||
| foregroundStyle | ShapeStyle | null | The configuration for the style of the forground |
|
||||
| handlerStyle | ShapeStyle | null | The configuration for the style of the two sliders |
|
||||
| textStyle | ShapeStyle | null | The configuration for the style of the labels on the two sliders |
|
||||
| start | number | 0.1 | The start position for the sliders, which indicate the start of the data range for the filtering. Ranges from 0 to `end` |
|
||||
| end | number | 0.9 | The end position for the sliders, which indicate the end of the data range for the filtering. Ranges from `start` to 1 |
|
||||
| minText | string | min | The label for the left slider |
|
||||
| maxText | string | max | The label for the right slider |
|
||||
|
||||
#### TimeBarSliceOption
|
||||
|
||||
```javascript
|
||||
export interface TimeBarSliceOption {
|
||||
// position size
|
||||
readonly x?: number;
|
||||
readonly y?: number;
|
||||
readonly width?: number;
|
||||
readonly height?: number;
|
||||
readonly padding?: number;
|
||||
|
||||
// styles
|
||||
readonly selectedTickStyle?: TickStyle;
|
||||
readonly unselectedTickStyle?: TickStyle
|
||||
readonly tooltipBackgroundColor?: string;
|
||||
|
||||
readonly start?: number;
|
||||
readonly end?: number;
|
||||
|
||||
// data
|
||||
readonly data: {
|
||||
date: string;
|
||||
value: string;
|
||||
}[];
|
||||
|
||||
// custom the formatter function for the tick labels
|
||||
readonly tickLabelFormatter?: (d: any) => string | boolean;
|
||||
// custom the formatter function for the tooltip
|
||||
readonly tooltipFomatter?: (d: any) => string;
|
||||
}
|
||||
```
|
||||
|
||||
#### Parameters for the TimeBarSliceOption
|
||||
|
||||
| Name | Type | Default Value | Description |
|
||||
| --- | --- | --- | --- |
|
||||
| x | number | 0 | The beginning x position for the TimeBar |
|
||||
| y | number | 0 | The beginning y position for the TimeBar |
|
||||
| width | number | | **Requred**, the width of the TimeBar |
|
||||
| height | number | | **Requred**, the height of the TimeBar |
|
||||
| padding | number / number[] | 0 | The padding of the container of the TimeBar |
|
||||
| selectedTickStyle | ShapeStyle | null | The style of the tick(s) which is(are) selected |
|
||||
| unselectedTickStyle | ShapeStyle | null | The style of the tick(s) which is(are) unselected |
|
||||
| tooltipBackgroundColor | ShapeStyle | null | The background style for the tooltip |
|
||||
| start | number | 0.1 | The start position for the sliders, which indicate the start of the data range for the filtering. Ranges from 0 to `end` |
|
||||
| end | number | 0.9 | The end position for the sliders, which indicate the end of the data range for the filtering. Ranges from `start` to 1 |
|
||||
| data | any[] | [] | **Requred**, the data for the ticks |
|
||||
| tickLabelFormatter | Function | null | The formatter function for customing the labels of the ticks |
|
||||
| tooltipFomatter | Function | null | The formatter function for customing the tooltip |
|
||||
|
||||
#### TickCfg
|
||||
|
||||
```javascript
|
||||
export interface TickCfg {
|
||||
// the fomatter for the time tick labels
|
||||
readonly tickLabelFormatter?: (d: any) => string | undefined;
|
||||
// the shape style for the time tick labels
|
||||
readonly tickLabelStyle?: ShapeStyle;
|
||||
// the shape style for the short vertical lines uppon the time tick labels
|
||||
readonly tickLineStyle?: ShapeStyle;
|
||||
}
|
||||
```
|
||||
|
||||
#### Parameters for TickCfg
|
||||
|
||||
| Name | Type | Default Value | Description |
|
||||
| --- | --- | --- | --- |
|
||||
| tickLabelFormatter | Function | null | The formatter function for customing the labels of the ticks |
|
||||
| tickLabelStyle | ShapeStyle | {} | The shape style for the time tick labels |
|
||||
| tickLineStyle | ShapeStyle | {} | The shape style for the short vertical lines uppon the time tick labels |
|
||||
|
||||
#### Interface of the ControllerCfg
|
||||
|
||||
> Does not support for now
|
||||
|
||||
> Does not support the style configuration for controller buttons
|
||||
|
||||
> Does not support loop play
|
||||
|
||||
```javascript
|
||||
type ControllerCfg = Partial<{
|
||||
/** the begining position and the size of the controller, the width and height will not scale the sub-controllers but only affects the positions of them. To change the size of the sub-controllers, try ControllerCfg.scale or the scale in the style of sub-controller */
|
||||
readonly x?: number;
|
||||
readonly y?: number;
|
||||
readonly width: number;
|
||||
readonly height: number;
|
||||
/** the scale of the whole controller */
|
||||
readonly scale?: number;
|
||||
/** the fill and stroke color of the background */
|
||||
readonly fill?: string;
|
||||
readonly stroke?: string;
|
||||
/** the font family for the whole controller, whose priority is lower than the fontFamily in the text style of each sub-controller */
|
||||
readonly fontFamily?: string;
|
||||
|
||||
/** the play spped, means the playing time for 1 tick */
|
||||
readonly speed?: number;
|
||||
/** whether play in loop */
|
||||
readonly loop?: boolean;
|
||||
/** whether hide the 'time type controller' on the right-bottom */
|
||||
readonly hideTimeTypeController: boolean;
|
||||
|
||||
/** style of the backward button. scale, offsetX, offsetY are also can be assigned to it to controll the size and position of the backward button */
|
||||
readonly preBtnStyle?: ShapeStyle;
|
||||
|
||||
/** style of the forward button. scale, offsetX, offsetY are also can be assigned to it to controll the size and position of the forward button */
|
||||
readonly nextBtnStyle?: ShapeStyle;
|
||||
|
||||
/** style of the play button. scale, offsetX, offsetY are also can be assigned to it to controll the size and position of the paly button */
|
||||
readonly playBtnStyle?: ShapeStyle;
|
||||
|
||||
/** style of the 'speed controller'. scale, offsetX, offsetY are also can be assigned to it and each sub-styles to controll the size and position of the speed controller and sub-shapes*/
|
||||
readonly speedControllerStyle?: {
|
||||
offsetX?: number,
|
||||
offsetY?: number;
|
||||
scale?: number
|
||||
pointer?: ShapeStyle,
|
||||
scroller?: ShapeStyle,
|
||||
text?: ShapeStyle
|
||||
};
|
||||
|
||||
/** style of the 'time type controller'. scale, offsetX, offsetY are also can be assigned to it and each sub-styles to controll the size and position of the speed controller and sub-shapes */
|
||||
readonly timeTypeControllerStyle?: {
|
||||
offsetX?: number,
|
||||
offsetY?: number;
|
||||
scale?: number
|
||||
check?: ShapeStyle,
|
||||
box?: ShapeStyle,
|
||||
text?: ShapeStyle
|
||||
};
|
||||
/** the text for the right-botton switch controlling play with single time point or time range */
|
||||
readonly timePointControllerText?: string;
|
||||
readonly timeRangeControllerText?: string
|
||||
}>
|
||||
```
|
||||
|
||||
#### Parameters for ControllerCfg
|
||||
|
||||
| Name | Type | Default Value | Description |
|
||||
| --- | --- | --- | --- |
|
||||
| x | number | 0 | The beginning x position for the buttons group of the TimeBar |
|
||||
| y | number | 0 | The beginning y position for the buttons group of the TimeBar |
|
||||
| width | number | The width of the TimeBar | The width of the buttons group of the TimeBar, do not scale the sub-controllers but only affects the positions of them |
|
||||
| height | number | 40 | The width of the buttons group of the TimeBar, do not scale the sub-controllers but only affects the positions of them |
|
||||
| scale | number | 1 | The scale of the whole controller |
|
||||
| speed | number | 1 | The play speed |
|
||||
| loop | boolean | false | _Does not support for now_, whether play in loop |
|
||||
| hideTimeTypeController | boolean | true | Whther hide the time type controller on the right bottom |
|
||||
| fill | string | | The fillling color for the background of the controller |
|
||||
| stroke | string | | The stroke color for the background of the buttons group |
|
||||
| preBtnStyle | ShapeStyle | null | The style of the backward button. `scale`, `offsetX`, `offsetY` are also can be assigned to it to controll the size and position of the backward button |
|
||||
| nextBtnStyle | ShapeStyle | null | The style of the forward button. `scale`, `offsetX`, `offsetY` are also can be assigned to it to controll the size and position of the forward button |
|
||||
| playBtnStyle | ShapeStyle | null | The style of the play button. `scale`, `offsetX`, `offsetY` are also can be assigned to it to controll the size and position of the paly button |
|
||||
| speedControllerStyle | { offsetX?: number, offsetY?: number, scale?: number, pointer?: ShapeStyle, text?: ShapeStyle, scroller?: ShapeStyle} | null | The style of the 'speed controller'. `scale`, `offsetX`, `offsetY` are also can be assigned to it and each sub-styles to controll the size and position of the speed controller and sub-shapes |
|
||||
| timeTypeControllerStyle | { offsetX?: number, offsetY?: number, scale?: number, box?: ShapeStyle, check?: ShapeStyle, text?: ShapeStyle } | null | The style of the 'time type controller'. `scale`, `offsetX`, `offsetY` are also can be assigned to it and each sub-styles to controll the size and position of the speed controller and sub-shapes |
|
||||
| timePointControllerText | string | "单一时间" | The text for the right-botton switch controlling play with single time point or time range |
|
||||
| timeRangeControllerText | string | "时间范围" | The text for the right-botton switch controlling play with single time point or time range |
|
||||
|
||||
## 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.
|
||||
@ -963,3 +579,413 @@ const graph = new G6.Graph({
|
||||
plugins: [filterLens], // configuring edge filter lens plugin
|
||||
});
|
||||
```
|
||||
|
||||
## TimeBar
|
||||
|
||||
There are three types of built-in TimeBar in G6:
|
||||
|
||||
- Time bar with a line chart as background;
|
||||
- Simple time bar;
|
||||
- Time bar with descrete ticks.
|
||||
|
||||
All the three types of timebar supports play, fast forward, and fast backward.
|
||||
|
||||
<img src='https://gw.alipayobjects.com/mdn/rms_f8c6a0/afts/img/A*DOo6QpfFfMUAAAAAAAAAAAAAARQnAQ' width='500' />
|
||||
<br />Time bar with a line chart as background<br />
|
||||
|
||||
<img src='https://gw.alipayobjects.com/mdn/rms_f8c6a0/afts/img/A*bzGBQKkewZMAAAAAAAAAAAAAARQnAQ' width='500' />
|
||||
<br />Simple time bar<br />
|
||||
|
||||
<img src='https://gw.alipayobjects.com/mdn/rms_f8c6a0/afts/img/A*kHRkQpnvBmwAAAAAAAAAAAAAARQnAQ' width='500' />
|
||||
<br />Time bar with descrete ticks<br />
|
||||
|
||||
<br />Refer to the demos [HERE](https://g6.antv.vision/en/examples/tool/timebar#timebar)<br />
|
||||
|
||||
### Common Usage
|
||||
|
||||
Same to other plugins of G6, the users can initiate the TimeBar and assign it to the graph as:
|
||||
|
||||
```javascript
|
||||
import G6 from '@antv/g6';
|
||||
|
||||
const timebar = new G6.TimeBar({
|
||||
width: 500,
|
||||
height: 150,
|
||||
padding: 10,
|
||||
type: 'trend',
|
||||
trend: {
|
||||
data: timeBarData,
|
||||
},
|
||||
});
|
||||
|
||||
const graph = new G6.Graph({
|
||||
container: 'container',
|
||||
width,
|
||||
height,
|
||||
plugins: [timebar],
|
||||
});
|
||||
```
|
||||
|
||||
<br />If you want to use the TimeBar with line chart, assign the `type` to be `trend` when instantiating the TimeBar, which results in:
|
||||
|
||||
<img src='https://gw.alipayobjects.com/mdn/rms_f8c6a0/afts/img/A*lfvIQJYbs7oAAAAAAAAAAAAAARQnAQ' width='600' />
|
||||
|
||||
<br />Assigning the `type` to be `simple` results in:
|
||||
|
||||
<img src='https://gw.alipayobjects.com/mdn/rms_f8c6a0/afts/img/A*g2zhQqP6ruYAAAAAAAAAAAAAARQnAQ' width='600' />
|
||||
|
||||
<br />And assigning the `type` to be `tick` results in a TimeBar with descrete ticks. Note that it is different from the above two types of TimeBar, \*\*The TimeBar with decrete ticks is configured with the `tick` object but not the `trend` object.
|
||||
|
||||
```javascript
|
||||
const timebar = new G6.TimeBar({
|
||||
width,
|
||||
height: 150,
|
||||
type: 'tick',
|
||||
tick: {
|
||||
data: timeBarData,
|
||||
width,
|
||||
height: 42,
|
||||
tickLabelFormatter: d => {
|
||||
const dateStr = `${d.date}`;
|
||||
if ((count - 1) % 10 === 0) {
|
||||
return `${dateStr.substr(0, 4)}-${dateStr.substr(4, 2)}-${dateStr.substr(6, 2)}`;
|
||||
}
|
||||
return false;
|
||||
},
|
||||
tooltipFomatter: d => {
|
||||
const dateStr = `${d}`;
|
||||
return `${dateStr.substr(0, 4)}-${dateStr.substr(4, 2)}-${dateStr.substr(6, 2)}`;
|
||||
},
|
||||
},
|
||||
});
|
||||
```
|
||||
|
||||
<img src='https://gw.alipayobjects.com/mdn/rms_f8c6a0/afts/img/A*n6ECQ7Jn5pQAAAAAAAAAAAAAARQnAQ' width='600' />
|
||||
|
||||
|
||||
### Event Listener
|
||||
|
||||
TimeBar Plugin exposes several timing events. They could be listened by `graph.on('eventname', e => {})`.
|
||||
|
||||
| Event Name | Description |
|
||||
| --- | --- |
|
||||
| valuechange | Emitted when the value range of the timebar is chaged. |
|
||||
| timebarstartplay | Emitted when the timeline starts to play. |
|
||||
| timebarendplay | Emitted when the timeline ends playing. |
|
||||
|
||||
### Definition of the Configurations
|
||||
|
||||
#### Definition of the Interfaces
|
||||
|
||||
The complete interfaces for the TimeBar is shown below:
|
||||
|
||||
```javascript
|
||||
interface TimeBarConfig extends IPluginBaseConfig {
|
||||
// position size
|
||||
readonly x?: number;
|
||||
readonly y?: number;
|
||||
readonly width?: number;
|
||||
readonly height?: number;
|
||||
readonly padding?: number;
|
||||
|
||||
readonly type?: 'trend' | 'simple' | 'tick';
|
||||
// the configuration for the TimeBar with line chart and simple TimeBar, takes effect whtn the type is 'trend' or 'simple'
|
||||
readonly trend?: TrendConfig;
|
||||
|
||||
// the configurations for the two sliders
|
||||
readonly slider?: SliderOption;
|
||||
|
||||
// when the type is 'tick', it is the configuration for the TimeBar with descrete ticks
|
||||
// when the type is 'trend' or 'simpe', it is the configuration for the time tick labels under the timeBar
|
||||
readonly tick?: TimeBarSliceOption | TickCfg;
|
||||
|
||||
// the buttons for play, fast forward, and back forward
|
||||
readonly controllerCfg?: ControllerCfg;
|
||||
|
||||
// [Supported from v4.5.1] the CSS style for the DOM container of the timebar
|
||||
readonly containerCSS?: Object;
|
||||
|
||||
// [Supported from v4.5.1] the item types that will be filtered by the timebar. e.g. ['node', 'edge']. The default value is ['node']
|
||||
readonly filterItemTypes?: string[];
|
||||
|
||||
// [Deprecated from v4.5.1, replaced by filterItemTypes] whether to consider the edge filtering. If it is false, only filter the nodes and the edges whose end nodes are filtered out while the selected range of the timeBar is changed. If it is true, there should be `date` properties on the edges data, and the timeBar will filter the edges which is not in the selected range in the same time
|
||||
readonly filterEdge?: boolean;
|
||||
|
||||
// [Supported from v4.5.1] whether filter the nodes and edges on the graph by graph.changeData, which means the data of the graph will be changed by the timebar. If it is false, the graph.hideItem and graph.showItem will be called to hide/show the nodes and edges instead of changeData
|
||||
readonly changeData?: boolean;
|
||||
|
||||
// the callback function after the time range is changed. When it is not assigned, the graph elements will be filtered after the time range is changed
|
||||
rangeChange?: (graph: IGraph, minValue: string, maxValue: string) => void;
|
||||
|
||||
// [Supported from v4.5.1] user returns the date value according to the data of a node or an edge
|
||||
getDate?: (d: any) => number;
|
||||
|
||||
// [Supported from v4.5.1] user returns the value according to the data of a node or an edge. The value is used to draw the trend line for timebar with type 'trend'
|
||||
getValue?: (d: any) => number;
|
||||
|
||||
// [Supported from v4.5.1] user returns true or false to decide whether to ignore the node or the edge while filtering. If it is true, the item with data model will be ignored. Or the item will be filtered according to the min and max date value
|
||||
shouldIgnore?: (itemType: 'node' | 'edge', model: any, dateRage: { min: number, max: number }) => boolean;
|
||||
}
|
||||
```
|
||||
|
||||
#### The Parameters of the Interfaces
|
||||
|
||||
| Name | Type | Default Value | Description |
|
||||
| --- | --- | --- | --- |
|
||||
| container | HTMLDivElement | null | The DOM container of the TimeBar. By default, the plugin will create a container DOM with 'g6-component-timebar' as className |
|
||||
| x | number | 0 | The beginning x position of the TimeBar plugin |
|
||||
| y | number | 0 | The beginning y position of the TimeBar plugin |
|
||||
| width | number | | **Requred**, the width of the TimeBar |
|
||||
| height | number | | **Requred**, the height of the TimeBar |
|
||||
| padding | number/number[] | 10 | The padding of the container of the TimeBar |
|
||||
| type | 'trend' / 'simple' / 'tick' | trend | The type of the TimeBar, 'trend' by default |
|
||||
| trend | TrendConfig | null | The configuration for the TimeBar with line chart and simple TimeBar, takes effect whtn the type is 'trend' or 'simple' |
|
||||
| slider | SliderOption | null | The configurations for the two sliders |
|
||||
| tick | TimeBarSliceOption / TickCfg | null | If the type is 'tick', it is the configuration for the TimeBar with descrete ticks. If it the type is 'trend' or 'simple', it is the configuration for the time tick labels under the timeBar |
|
||||
| controllerCfg | ControllerCfg | null | The buttons for play, fast forward, and back forward |
|
||||
| containerCSS | Object | null | [Supported from v4.5.1] The CSS style for the DOM container of the timebar |
|
||||
| filterItemTypes | string[] | null | [Supported from v4.5.1] The item types that will be filtered by the timebar. e.g. ['node', 'edge']. The default value is ['node'] |
|
||||
| filterEdge | boolean | false | [Deprecated from v4.5.1, replaced by filterItemTypes] Whether to consider the edge filtering. If it is false, only filter the nodes and the edges whose end nodes are filtered out while the selected range of the timeBar is changed. If it is true, there should be `date` properties on the edges data, and the timeBar will filter the edges which is not in the selected range in the same time |
|
||||
| changeData | boolean | null | [Supported from v4.5.1] Whether filter the nodes and edges on the graph by graph.changeData, which means the data of the graph will be changed by the timebar. If it is false, the graph.hideItem and graph.showItem will be called to hide/show the nodes and edges instead of changeData |
|
||||
| rangeChange | Function | null | The callback function after the time range is changed. When it is not assigned, the graph elements will be filtered after the time range is changed |
|
||||
| getDate | (d: any) => number | null | [Supported from v4.5.1] User returns the date value according to the data of a node or an edge |
|
||||
| getValue | (d: any) => number | null | [Supported from v4.5.1] User returns the value according to the data of a node or an edge. The value is used to draw the trend line for timebar with type 'trend' |
|
||||
| shouldIgnore | (itemType: 'node' | 'edge', model: any, dateRage: { min: number, max: number }) => boolean | null | [Supported from v4.5.1] User returns true or false to decide whether to ignore the node or the edge while filtering. If it is true, the item with data model will be ignored. Or the item will be filtered according to the min and max date value |
|
||||
|
||||
#### Interface for TrendConfig
|
||||
|
||||
> Does not support the configurations for the style of the tick labels.
|
||||
|
||||
```javascript
|
||||
interface TrendConfig {
|
||||
// The data
|
||||
readonly data: {
|
||||
date: string;
|
||||
value: string;
|
||||
}[];
|
||||
// The position and size
|
||||
readonly x?: number;
|
||||
readonly y?: number;
|
||||
readonly width?: number;
|
||||
readonly height?: number;
|
||||
// The styles
|
||||
readonly smooth?: boolean;
|
||||
readonly isArea?: boolean;
|
||||
readonly lineStyle?: ShapeStyle;
|
||||
readonly areaStyle?: ShapeStyle;
|
||||
readonly interval?: Interval;
|
||||
}
|
||||
```
|
||||
|
||||
#### Parameters of the TrendConfig
|
||||
|
||||
| Name | Type | Default Value | Description |
|
||||
| --- | --- | --- | --- |
|
||||
| x | number | 0 | The beginning x position of the trend line chart |
|
||||
| y | number | 0 | The beginning y position of the trend line chart |
|
||||
| width | number | The width of the TimeBar | The width of the trend line chart of the TimeBar, we suggest to use the default value. If you wanna custom it, please assign the `width` of the slider in the same time |
|
||||
| height | number | 28 when type='trend'<br />8 when type='simple' | The height of the TimeBar | The width of the trend line chart of the TimeBar, we suggest to use the default value. If you wanna custom it, please assign the `height` of the slider in the same time |
|
||||
| smooth | boolean | false | Whether to show a smooth line on the trend line chart |
|
||||
| isArea | boolean | false | Whether to show a area chart instead |
|
||||
| lineStyle | ShapeStyle | null | The configurations for the style of the line in the line chart |
|
||||
| areaStyle | ShapeStyle | null | The configuration for the style of the area in the chart when `isArea` is `true` |
|
||||
| interval | Interval | null | The configuration for the style of the bars in the chart. When it is assigned, a mixed trend chart will take place. `Interval = { data: number[], style: ShapeStyle }`. Except the configurations in `ShapeStyle` for the style of the shapes in the bar charts, `barWidth` for the width of one bar is also configurable for `style` |
|
||||
|
||||
#### Interfaces of SliderOption
|
||||
|
||||
```javascript
|
||||
export type SliderOption = Partial<{
|
||||
readonly width?: number;
|
||||
readonly height?: number;
|
||||
readonly backgroundStyle?: ShapeStyle;
|
||||
readonly foregroundStyle?: ShapeStyle;
|
||||
// The style of the sliders
|
||||
readonly handlerStyle?: {
|
||||
width?: number;
|
||||
height?: number;
|
||||
style?: ShapeStyle;
|
||||
};
|
||||
readonly textStyle?: ShapeStyle;
|
||||
// The start and end position for the sliders, which indicate the data range for the filtering. Ranges from 0 to 1
|
||||
readonly start: number;
|
||||
readonly end: number;
|
||||
// The labels for the sliders
|
||||
readonly minText: string;
|
||||
readonly maxText: string;
|
||||
}>;
|
||||
```
|
||||
|
||||
#### Parameters for the SliderOption
|
||||
|
||||
| Name | Type | Default Value | Description |
|
||||
| --- | --- | --- | --- |
|
||||
| width | number | The width of the container of the TimeBar - 2 \* padding | The width of the background trend chart. We suggest to use the default value. If you wanna custom it, assign it the the `width` in the `trend` in the same time |
|
||||
| height | number | 28 when type='trend'<br />8 when type='simple' | The height of the background trend chart. We suggest to use the default value. If you wanna custom it, assign it the the `height` in the `trend` in the same time |
|
||||
| backgroundStyle | ShapeStyle | null | The configuration for the style of the background |
|
||||
| foregroundStyle | ShapeStyle | null | The configuration for the style of the forground |
|
||||
| handlerStyle | ShapeStyle | null | The configuration for the style of the two sliders |
|
||||
| textStyle | ShapeStyle | null | The configuration for the style of the labels on the two sliders |
|
||||
| start | number | 0.1 | The start position for the sliders, which indicate the start of the data range for the filtering. Ranges from 0 to `end` |
|
||||
| end | number | 0.9 | The end position for the sliders, which indicate the end of the data range for the filtering. Ranges from `start` to 1 |
|
||||
| minText | string | min | The label for the left slider |
|
||||
| maxText | string | max | The label for the right slider |
|
||||
|
||||
#### TimeBarSliceOption
|
||||
|
||||
```javascript
|
||||
export interface TimeBarSliceOption {
|
||||
// position size
|
||||
readonly x?: number;
|
||||
readonly y?: number;
|
||||
readonly width?: number;
|
||||
readonly height?: number;
|
||||
readonly padding?: number;
|
||||
|
||||
// styles
|
||||
readonly selectedTickStyle?: TickStyle;
|
||||
readonly unselectedTickStyle?: TickStyle
|
||||
readonly tooltipBackgroundColor?: string;
|
||||
|
||||
readonly start?: number;
|
||||
readonly end?: number;
|
||||
|
||||
// data
|
||||
readonly data: {
|
||||
date: string;
|
||||
value: string;
|
||||
}[];
|
||||
|
||||
// custom the formatter function for the tick labels
|
||||
readonly tickLabelFormatter?: (d: any) => string | boolean;
|
||||
// custom the formatter function for the tooltip
|
||||
readonly tooltipFomatter?: (d: any) => string;
|
||||
}
|
||||
```
|
||||
|
||||
#### Parameters for the TimeBarSliceOption
|
||||
|
||||
| Name | Type | Default Value | Description |
|
||||
| --- | --- | --- | --- |
|
||||
| x | number | 0 | The beginning x position for the TimeBar |
|
||||
| y | number | 0 | The beginning y position for the TimeBar |
|
||||
| width | number | | **Requred**, the width of the TimeBar |
|
||||
| height | number | | **Requred**, the height of the TimeBar |
|
||||
| padding | number / number[] | 0 | The padding of the container of the TimeBar |
|
||||
| selectedTickStyle | ShapeStyle | null | The style of the tick(s) which is(are) selected |
|
||||
| unselectedTickStyle | ShapeStyle | null | The style of the tick(s) which is(are) unselected |
|
||||
| tooltipBackgroundColor | ShapeStyle | null | The background style for the tooltip |
|
||||
| start | number | 0.1 | The start position for the sliders, which indicate the start of the data range for the filtering. Ranges from 0 to `end` |
|
||||
| end | number | 0.9 | The end position for the sliders, which indicate the end of the data range for the filtering. Ranges from `start` to 1 |
|
||||
| data | any[] | [] | **Requred**, the data for the ticks |
|
||||
| tickLabelFormatter | Function | null | The formatter function for customing the labels of the ticks |
|
||||
| tooltipFomatter | Function | null | The formatter function for customing the tooltip |
|
||||
|
||||
#### TickCfg
|
||||
|
||||
```javascript
|
||||
export interface TickCfg {
|
||||
// the fomatter for the time tick labels
|
||||
readonly tickLabelFormatter?: (d: any) => string | undefined;
|
||||
// the shape style for the time tick labels. [Supported from v4.5.1] tickLabelStyle.rotate can be configured to controll the rotate of the tick label to avoid overlappings
|
||||
readonly tickLabelStyle?: ShapeStyle;
|
||||
// the shape style for the short vertical lines uppon the time tick labels
|
||||
readonly tickLineStyle?: ShapeStyle;
|
||||
}
|
||||
```
|
||||
|
||||
#### Parameters for TickCfg
|
||||
|
||||
| Name | Type | Default Value | Description |
|
||||
| --- | --- | --- | --- |
|
||||
| tickLabelFormatter | Function | null | The formatter function for customing the labels of the ticks |
|
||||
| tickLabelStyle | ShapeStyle | {} | The shape style for the time tick labels. [Supported from v4.5.1] tickLabelStyle.rotate can be configured to controll the rotate of the tick label to avoid overlappings |
|
||||
| tickLineStyle | ShapeStyle | {} | The shape style for the short vertical lines uppon the time tick labels |
|
||||
|
||||
#### Interface of the ControllerCfg
|
||||
|
||||
> Does not support for now
|
||||
|
||||
> Does not support the style configuration for controller buttons
|
||||
|
||||
> Does not support loop play
|
||||
|
||||
```javascript
|
||||
type ControllerCfg = Partial<{
|
||||
/** the begining position and the size of the controller, the width and height will not scale the sub-controllers but only affects the positions of them. To change the size of the sub-controllers, try ControllerCfg.scale or the scale in the style of sub-controller */
|
||||
readonly x?: number;
|
||||
readonly y?: number;
|
||||
readonly width: number;
|
||||
readonly height: number;
|
||||
/** the scale of the whole controller */
|
||||
readonly scale?: number;
|
||||
/** the fill and stroke color of the background */
|
||||
readonly fill?: string;
|
||||
readonly stroke?: string;
|
||||
/** the font family for the whole controller, whose priority is lower than the fontFamily in the text style of each sub-controller */
|
||||
readonly fontFamily?: string;
|
||||
|
||||
/** the play spped, means the playing time for 1 tick */
|
||||
readonly speed?: number;
|
||||
/** whether play in loop */
|
||||
readonly loop?: boolean;
|
||||
/** whether hide the 'time type controller' on the right-bottom */
|
||||
readonly hideTimeTypeController: boolean;
|
||||
|
||||
/** style of the backward button. scale, offsetX, offsetY are also can be assigned to it to controll the size and position of the backward button */
|
||||
readonly preBtnStyle?: ShapeStyle;
|
||||
|
||||
/** style of the forward button. scale, offsetX, offsetY are also can be assigned to it to controll the size and position of the forward button */
|
||||
readonly nextBtnStyle?: ShapeStyle;
|
||||
|
||||
/** style of the play button. scale, offsetX, offsetY are also can be assigned to it to controll the size and position of the paly button */
|
||||
readonly playBtnStyle?: ShapeStyle;
|
||||
|
||||
/** style of the 'speed controller'. scale, offsetX, offsetY are also can be assigned to it and each sub-styles to controll the size and position of the speed controller and sub-shapes*/
|
||||
readonly speedControllerStyle?: {
|
||||
offsetX?: number,
|
||||
offsetY?: number;
|
||||
scale?: number
|
||||
pointer?: ShapeStyle,
|
||||
scroller?: ShapeStyle,
|
||||
text?: ShapeStyle
|
||||
};
|
||||
|
||||
/** style of the 'time type controller'. scale, offsetX, offsetY are also can be assigned to it and each sub-styles to controll the size and position of the speed controller and sub-shapes */
|
||||
readonly timeTypeControllerStyle?: {
|
||||
offsetX?: number,
|
||||
offsetY?: number;
|
||||
scale?: number
|
||||
check?: ShapeStyle,
|
||||
box?: ShapeStyle,
|
||||
text?: ShapeStyle
|
||||
};
|
||||
/** [Supported from v4.5.1] The style of the background rect of the controller */
|
||||
readonly containerStyle?: ExtendedShapeStyle;
|
||||
/** the text for the right-botton switch controlling play with single time point or time range */
|
||||
readonly timePointControllerText?: string;
|
||||
readonly timeRangeControllerText?: string
|
||||
}>
|
||||
```
|
||||
|
||||
#### Parameters for ControllerCfg
|
||||
|
||||
| Name | Type | Default Value | Description |
|
||||
| --- | --- | --- | --- |
|
||||
| x | number | 0 | The beginning x position for the buttons group of the TimeBar |
|
||||
| y | number | 0 | The beginning y position for the buttons group of the TimeBar |
|
||||
| width | number | The width of the TimeBar | The width of the buttons group of the TimeBar, do not scale the sub-controllers but only affects the positions of them |
|
||||
| height | number | 40 | The width of the buttons group of the TimeBar, do not scale the sub-controllers but only affects the positions of them |
|
||||
| scale | number | 1 | The scale of the whole controller |
|
||||
| speed | number | 1 | The play speed |
|
||||
| loop | boolean | false | _Does not support for now_, whether play in loop |
|
||||
| hideTimeTypeController | boolean | true | Whther hide the time type controller on the right bottom |
|
||||
| fill | string | | The fillling color for the background of the controller |
|
||||
| stroke | string | | The stroke color for the background of the buttons group |
|
||||
| preBtnStyle | ShapeStyle | null | The style of the backward button. `scale`, `offsetX`, `offsetY` are also can be assigned to it to controll the size and position of the backward button |
|
||||
| nextBtnStyle | ShapeStyle | null | The style of the forward button. `scale`, `offsetX`, `offsetY` are also can be assigned to it to controll the size and position of the forward button |
|
||||
| playBtnStyle | ShapeStyle | null | The style of the play button. `scale`, `offsetX`, `offsetY` are also can be assigned to it to controll the size and position of the paly button |
|
||||
| speedControllerStyle | { offsetX?: number, offsetY?: number, scale?: number, pointer?: ShapeStyle, text?: ShapeStyle, scroller?: ShapeStyle} | null | The style of the 'speed controller'. `scale`, `offsetX`, `offsetY` are also can be assigned to it and each sub-styles to controll the size and position of the speed controller and sub-shapes |
|
||||
| timeTypeControllerStyle | { offsetX?: number, offsetY?: number, scale?: number, box?: ShapeStyle, check?: ShapeStyle, text?: ShapeStyle } | null | The style of the 'time type controller'. `scale`, `offsetX`, `offsetY` are also can be assigned to it and each sub-styles to controll the size and position of the speed controller and sub-shapes |
|
||||
| containerStyle | ShapeStyle | {} | [Supported from v4.5.1] The style of the background rect of the controller |
|
||||
| timePointControllerText | string | "单一时间" | The text for the right-botton switch controlling play with single time point or time range |
|
||||
| timeRangeControllerText | string | "时间范围" | The text for the right-botton switch controlling play with single time point or time range |
|
@ -711,11 +711,29 @@ interface TimeBarConfig extends IPluginBaseConfig {
|
||||
// 控制按钮
|
||||
readonly controllerCfg?: ControllerCfg;
|
||||
|
||||
// 是否过滤边,若为 true,则需要配合边数据上有 date 字段,过滤节点同时将不满足 date 在选中范围内的边也过滤出去;若为 false,则仅过滤节点以及两端节点都被过滤出去的边
|
||||
// [v4.5.1 起支持] 容器的 CSS 样式
|
||||
readonly containerCSS?: Object;
|
||||
|
||||
// [v4.5.1 起支持] 过滤的类型, ['node', 'edge'], 默认为 ['node']
|
||||
readonly filterItemTypes?: string[];
|
||||
|
||||
// [v4.5.1 起废弃,由 filterItemTypes 代替] 是否过滤边,若为 true,则需要配合边数据上有 date 字段,过滤节点同时将不满足 date 在选中范围内的边也过滤出去;若为 false,则仅过滤节点以及两端节点都被过滤出去的边
|
||||
readonly filterEdge?: boolean;
|
||||
|
||||
// [v4.5.1 起支持] 是否通过 graph.changeData 改变图上数据从而达到筛选目的。若为 false 则将使用 graph.hideItem 和 graph.showItem 以隐藏/展示图上元素从而达到筛选目的
|
||||
readonly changeData?: boolean;
|
||||
|
||||
// TimeBar 时间范围变化时的回调函数,当不定义该函数时,时间范围变化时默认过滤图上的数据
|
||||
rangeChange?: (graph: IGraph, minValue: string, maxValue: string) => void;
|
||||
valueChange?: (graph: IGraph, value: string) => void;
|
||||
|
||||
// [v4.5.1 起支持] 用户根据节点/边数据返回对应时间值的方法
|
||||
getDate?: (d: any) => number;
|
||||
|
||||
// [v4.5.1 起支持] 用户根据节点/边数据返回对应 value 的方法。value 用于在 type 为 trend 的时间轴上显示趋势线
|
||||
getValue?: (d: any) => number;
|
||||
|
||||
// [v4.5.1 起支持] 在过滤图元素时是否要忽略某些元素。返回 true,则忽略。否则按照正常过滤逻辑处理
|
||||
shouldIgnore?: (itemType: 'node' | 'edge', model: any, dateRage: { min: number, max: number }) => boolean;
|
||||
}
|
||||
```
|
||||
|
||||
@ -734,8 +752,14 @@ interface TimeBarConfig extends IPluginBaseConfig {
|
||||
| slider | SliderOption | null | TimeBar 组件背景及控制调节范围的滑块的配置项 |
|
||||
| tick | TimeBarSliceOption / TickCfg | null | 当 type 是 tick 时,这是 tick 类型时间轴的配置项,该字段必须按;当 type 是 trend 或 simple 时,这是时间轴下方时间刻度文本的配置项 |
|
||||
| controllerCfg | ControllerCfg | null | 控制按钮组配置项 |
|
||||
| filterEdge | boolean | false | 是否过滤边,若为 true,则需要配合边数据上有 date 字段,过滤节点同时将不满足 date 在选中范围内的边也过滤出去;若为 false,则仅过滤节点以及两端节点都被过滤出去的边 |
|
||||
| containerCSS | Object | null | [v4.5.1 起支持] 容器的 CSS 样式 |
|
||||
| filterItemTypes | string[] | null | [v4.5.1 起支持] 过滤的类型, ['node', 'edge'], 默认为 ['node'] |
|
||||
| filterEdge | boolean | false | [v4.5.1 起废弃,由 filterItemTypes 代替] 是否过滤边,若为 true,则需要配合边数据上有 date 字段,过滤节点同时将不满足 date 在选中范围内的边也过滤出去;若为 false,则仅过滤节点以及两端节点都被过滤出去的边 |
|
||||
| changeData | boolean | null | [v4.5.1 起支持] 是否通过 graph.changeData 改变图上数据从而达到筛选目的。若为 false 则将使用 graph.hideItem 和 graph.showItem 以隐藏/展示图上元素从而达到筛选目的 |
|
||||
| rangeChange | Function | null | TimeBar 时间范围变化时的回调函数,当不定义该函数时,时间范围变化时默认过滤图上的数据 |
|
||||
| getDate | (d: any) => number | null | [v4.5.1 起支持] 用户根据节点/边数据返回对应时间值的方法 |
|
||||
| getValue | (d: any) => number | null | [v4.5.1 起支持] 用户根据节点/边数据返回对应 value 的方法。value 用于在 type 为 trend 的时间轴上显示趋势线 |
|
||||
| shouldIgnore | (itemType: 'node' | 'edge', model: any, dateRage: { min: number, max: number }) => boolean | null | [v4.5.1 起支持] 在过滤图元素时是否要忽略某些元素。返回 true,则忽略。否则按照正常过滤逻辑处理 |
|
||||
|
||||
#### TrendConfig 接口定义
|
||||
|
||||
@ -872,7 +896,7 @@ export interface TimeBarSliceOption {
|
||||
export interface TickCfg {
|
||||
// 时间轴下方文本的格式化函数
|
||||
readonly tickLabelFormatter?: (d: any) => string | undefined;
|
||||
// 时间轴下方文本的图形样式
|
||||
// 时间轴下方文本的图形样式。[v4.5.1 起支持] 可配置 tickLabelStyle.rotate 以控制时间轴下方每个文本的旋转角度,可避免文本相互重叠
|
||||
readonly tickLabelStyle?: ShapeStyle;
|
||||
// 时间轴下方文本上的竖线图形样式
|
||||
readonly tickLineStyle?: ShapeStyle;
|
||||
@ -883,9 +907,9 @@ export interface TickCfg {
|
||||
|
||||
| Name | Type | Default Value | Description |
|
||||
| --- | --- | --- | --- |
|
||||
| tickLabelFormatter | Function | null | The formatter function for customing the labels of the ticks |
|
||||
| tickLabelStyle | ShapeStyle | {} | The shape style for the time tick labels |
|
||||
| tickLineStyle | ShapeStyle | {} | The shape style for the short vertical lines uppon the time tick labels |
|
||||
| tickLabelFormatter | Function | null | 时间轴下方文本的格式化函数 |
|
||||
| tickLabelStyle | ShapeStyle | {} | 时间轴下方文本的图形样式。[v4.5.1 起支持] 可配置 tickLabelStyle.rotate 以控制时间轴下方每个文本的旋转角度,可避免文本相互重叠 |
|
||||
| tickLineStyle | ShapeStyle | {} | 时间轴下方文本上方的竖线的图形样式 |
|
||||
|
||||
#### ControllerCfg 接口定义
|
||||
|
||||
@ -946,6 +970,8 @@ type ControllerCfg = Partial<{
|
||||
box?: ShapeStyle,
|
||||
text?: ShapeStyle
|
||||
};
|
||||
/** [v4.5.1 起支持] 控制栏背景方框的样式 */
|
||||
readonly containerStyle?: ExtendedShapeStyle;
|
||||
/** ‘播放时间类型切换器’单一文本时的文本,默认为‘单一时间’ */
|
||||
readonly timePointControllerText?: string;
|
||||
/** ‘播放时间类型切换器’单一文本时的文本,默认为‘时间范围’ */
|
||||
@ -973,5 +999,6 @@ type ControllerCfg = Partial<{
|
||||
| playBtnStyle | ShapeStyle | null | ‘播放’ 与 ‘暂停’ 按钮的样式,同时可以为其配置 `scale`、`offsetX`、`offsetY` 单独控制该控制器的缩放以及平移 |
|
||||
| speedControllerStyle | { offsetX?: number, offsetY?: number, scale?: number, pointer?: ShapeStyle, text?: ShapeStyle, scroller?: ShapeStyle} | null | ‘速度控制器’ 的样式,包括速度的指针、速度指示滚轮(横线)、文本的样式,同时可以为 `speedControllerStyle` 及其子图形样式配置 `scale`、`offsetX`、`offsetY` 单独控制该控制器及其子图形的缩放以及平移 |
|
||||
| timeTypeControllerStyle | { offsetX?: number, offsetY?: number, scale?: number, box?: ShapeStyle, check?: ShapeStyle, text?: ShapeStyle } | null | ‘播放时间类型切换器’ 的样式,包括 checkbox 的框、checkbox 的选中勾、文本的样式,同时可以为 `timeTypeControllerStyle` 及其子图形样式配置 `scale`、`offsetX`、`offsetY` 单独控制该控制器及其子图形的缩放以及平移 |
|
||||
| containerStyle | ShapeStyle | {} | 控制栏背景方框的样式 |
|
||||
| timePointControllerText | string | "单一时间" | 右下角“单一时间”文本,默认为”单一时间“ |
|
||||
| timePointControllerText | string | "时间范围" | 右下角“单一时间”文本,默认为”时间范围时间“ |
|
||||
|
@ -23,6 +23,12 @@ const graph = new G6.Graph({
|
||||
});
|
||||
```
|
||||
|
||||
## layoutCfg.begin
|
||||
|
||||
_Supported by G6 v4.5.1_
|
||||
|
||||
**Type**: Array<br />**Default**: undefined<br />**Required**: false<br />**Description**: The position for the left-top of the layout.
|
||||
|
||||
## layoutCfg.rankdir
|
||||
|
||||
**Type**: String<br />**Options**: 'TB' | 'BT' | 'LR' | 'RL'<br />**Default**: 'TB'<br />**Required**: false<br />**Description**: The layout direction. T:top; B:bottom; L:left; R:right.
|
||||
@ -91,3 +97,38 @@ const graph = new G6.Graph({
|
||||
## layoutCfg.sortByCombo
|
||||
|
||||
**Type**: Boolean<br />**Default**: false<br />**Required**: false<br />**Description**: Whether to sort the nodes in a level according to the `comboId` in their data. Enable `sortByCombo` to avoid combo overlappings
|
||||
|
||||
## layoutCfg.nodeOrder
|
||||
|
||||
_Supported by G6 v4.5.0_
|
||||
|
||||
**Type**: string[]<br />**Default** undefined<br />**Required**: false<br />**Description**: The refered order array for the nodes in the same layer. If it is not specified, the order of the nodes will be decided by the dagre algorithm.
|
||||
|
||||
|
||||
## layoutCfg.preset
|
||||
|
||||
_Supported by G6 v4.5.0_
|
||||
|
||||
**Type**:
|
||||
|
||||
|
||||
```javascript
|
||||
{
|
||||
nodes: {
|
||||
x: number, // position
|
||||
y: number, // position
|
||||
layer?: number, // specify the layer for the node, 0-indexed
|
||||
_order?: number // if the preset comes from last dagre layout, the _order will be generated to state the order of the nodes in one layer
|
||||
}[]
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
<br />**Default** undefined<br />**Required**: false<br />**Description**: The refered node positions and other infomations for layout computing. It is usually used to keep the consistancy for data changing, where you could specify it with the result data from last layout.
|
||||
|
||||
|
||||
## Specify the Layer for Node
|
||||
|
||||
_Supported by G6 v4.5.0_
|
||||
|
||||
Configurate `layer` (0-indexed) in the node data to specify the layout layer for it. Notice that the `layer` SHOULD NOT violate DAG's properties (e.g. DO NOT assign a layer value for a target node greater or equal to cresponding source node.). The layout will be failed otherwise.
|
||||
|
@ -23,6 +23,12 @@ const graph = new G6.Graph({
|
||||
});
|
||||
```
|
||||
|
||||
## layoutCfg.begin
|
||||
|
||||
_自 G6 v4.5.1 起支持。_
|
||||
|
||||
**类型**: Array<br />**示例**:[ 0, 0 ]<br />**默认值**:undefined<br />**是否必须**:false<br />**说明**:布局的左上角对齐位置。
|
||||
|
||||
## layoutCfg.rankdir
|
||||
|
||||
**类型**: String<br />**可选值**:'TB' | 'BT' | 'LR' | 'RL'<br />**默认值**:'TB'<br />**是否必须**:false<br />**说明**:布局的方向。T:top(上);B:bottom(下);L:left(左);R:right(右)。
|
||||
@ -89,3 +95,36 @@ const graph = new G6.Graph({
|
||||
## layoutCfg.sortByCombo
|
||||
|
||||
**类型**: Boolean<br />**默认值**: false<br />**是否必须**: false<br />**说明**: 同一层节点是否根据每个节点数据中的 `comboId` 进行排序,以防止 combo 重叠
|
||||
|
||||
## layoutCfg.nodeOrder
|
||||
|
||||
_自 G6 v4.5.0 起支持。_
|
||||
|
||||
**类型**: string[]<br />**默认值**: undefined<br />**是否必须**: false<br />**说明**: 同层节点顺序的参考数组。若未指定,则将按照 dagre 本身机制排列同层节点顺序。
|
||||
|
||||
|
||||
## layoutCfg.preset
|
||||
|
||||
_自 G6 v4.5.0 起支持。_
|
||||
|
||||
**类型**:
|
||||
|
||||
```javascript
|
||||
{
|
||||
nodes: {
|
||||
x: number, // 位置
|
||||
y: number, // 位置
|
||||
layer?: number, // 指定层级
|
||||
_order?: number // 若为上一次 dagre 布局的输出,则有该字段,代表同层节点的顺序
|
||||
}[]
|
||||
}
|
||||
```
|
||||
|
||||
<br />**默认值**: undefined<br />**是否必须**: false<br />**说明**: 布局计算时参考的节点位置,一般用于切换数据时保证重新布局的连续性,可使用上一次布局的结果数据作为输入。
|
||||
|
||||
|
||||
## 指定节点层级
|
||||
|
||||
_自 G6 v4.5.0 起支持。_
|
||||
|
||||
在节点数据中配置 `layer` 字段(从 0 开始计数),可以为节点指定层级。注意,`layer` 的指定不能违背图结构与层次布局原则,即每一条边的起点的 `layer` 一定小于终点的 `layer` 值。若违背该规则,则可能导致布局失败。
|
||||
|
@ -135,7 +135,7 @@ Change the layout.
|
||||
```javascript
|
||||
const layout = {
|
||||
type: 'mindmap',
|
||||
dirction: 'H',
|
||||
direction: 'H',
|
||||
getSubTreeSep: () => 20,
|
||||
getVGap: () => 25,
|
||||
getHeight: () => 30,
|
||||
|
@ -132,7 +132,7 @@ treeGraph.removeChild('sub');
|
||||
```javascript
|
||||
const layout = {
|
||||
type: 'mindmap',
|
||||
dirction: 'H',
|
||||
direction: 'H',
|
||||
getSubTreeSep: () => 20,
|
||||
getVGap: () => 25,
|
||||
getHeight: () => 30,
|
||||
|
@ -330,122 +330,6 @@ const graph = new G6.Graph({
|
||||
});
|
||||
```
|
||||
|
||||
## 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'/>
|
||||
|
||||
**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 | 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 for timebar**
|
||||
|
||||
```
|
||||
interface HandleStyle {
|
||||
width: number;
|
||||
height: number;
|
||||
style: ShapeStyle;
|
||||
}
|
||||
```
|
||||
|
||||
| Name | Type | Default | Description |
|
||||
| --- | --- | --- | --- |
|
||||
| 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 for trend**
|
||||
|
||||
```
|
||||
interface Data {
|
||||
date: string;
|
||||
value: number;
|
||||
}
|
||||
```
|
||||
|
||||
| Name | Type | Default | Description |
|
||||
| --- | --- | --- | --- |
|
||||
| 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
|
||||
|
||||
#### Default Usage
|
||||
|
||||
```
|
||||
const timebar = new G6.TimeBar();
|
||||
|
||||
const graph = new G6.Graph({
|
||||
//... Other configurations
|
||||
plugins: [timebar], // Use timebar plugin
|
||||
});
|
||||
```
|
||||
|
||||
##### 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({
|
||||
width: 600,
|
||||
timebar: {
|
||||
width: 600,
|
||||
backgroundStyle: {
|
||||
fill: '#08979c',
|
||||
opacity: 0.3
|
||||
},
|
||||
foregroundStyle: {
|
||||
fill: '#40a9ff',
|
||||
opacity: 0.4
|
||||
},
|
||||
trend: {
|
||||
data: timeBarData,
|
||||
isArea: false,
|
||||
smooth: true,
|
||||
lineStyle: {
|
||||
stroke: '#9254de'
|
||||
}
|
||||
}
|
||||
},
|
||||
rangeChange: (graph, min, max) => {
|
||||
// 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({
|
||||
//... Other configurations
|
||||
plugins: [timebar], // Use timebar plugin
|
||||
});
|
||||
```
|
||||
|
||||
## ToolTip
|
||||
|
||||
@ -627,3 +511,412 @@ const graph = new G6.Graph({
|
||||
plugins: [filterLens], // configuring edge filter lens plugin
|
||||
});
|
||||
```
|
||||
## TimeBar
|
||||
|
||||
There are three types of built-in TimeBar in G6:
|
||||
|
||||
- Time bar with a line chart as background;
|
||||
- Simple time bar;
|
||||
- Time bar with descrete ticks.
|
||||
|
||||
All the three types of timebar supports play, fast forward, and fast backward.
|
||||
|
||||
<img src='https://gw.alipayobjects.com/mdn/rms_f8c6a0/afts/img/A*DOo6QpfFfMUAAAAAAAAAAAAAARQnAQ' width='500' />
|
||||
<br />Time bar with a line chart as background<br />
|
||||
|
||||
<img src='https://gw.alipayobjects.com/mdn/rms_f8c6a0/afts/img/A*bzGBQKkewZMAAAAAAAAAAAAAARQnAQ' width='500' />
|
||||
<br />Simple time bar<br />
|
||||
|
||||
<img src='https://gw.alipayobjects.com/mdn/rms_f8c6a0/afts/img/A*kHRkQpnvBmwAAAAAAAAAAAAAARQnAQ' width='500' />
|
||||
<br />Time bar with descrete ticks<br />
|
||||
|
||||
<br />Refer to the demos [HERE](https://g6.antv.vision/en/examples/tool/timebar#timebar)<br />
|
||||
|
||||
### Common Usage
|
||||
|
||||
Same to other plugins of G6, the users can initiate the TimeBar and assign it to the graph as:
|
||||
|
||||
```javascript
|
||||
import G6 from '@antv/g6';
|
||||
|
||||
const timebar = new G6.TimeBar({
|
||||
width: 500,
|
||||
height: 150,
|
||||
padding: 10,
|
||||
type: 'trend',
|
||||
trend: {
|
||||
data: timeBarData,
|
||||
},
|
||||
});
|
||||
|
||||
const graph = new G6.Graph({
|
||||
container: 'container',
|
||||
width,
|
||||
height,
|
||||
plugins: [timebar],
|
||||
});
|
||||
```
|
||||
|
||||
<br />If you want to use the TimeBar with line chart, assign the `type` to be `trend` when instantiating the TimeBar, which results in:
|
||||
|
||||
<img src='https://gw.alipayobjects.com/mdn/rms_f8c6a0/afts/img/A*lfvIQJYbs7oAAAAAAAAAAAAAARQnAQ' width='600' />
|
||||
|
||||
<br />Assigning the `type` to be `simple` results in:
|
||||
|
||||
<img src='https://gw.alipayobjects.com/mdn/rms_f8c6a0/afts/img/A*g2zhQqP6ruYAAAAAAAAAAAAAARQnAQ' width='600' />
|
||||
|
||||
<br />And assigning the `type` to be `tick` results in a TimeBar with descrete ticks. Note that it is different from the above two types of TimeBar, \*\*The TimeBar with decrete ticks is configured with the `tick` object but not the `trend` object.
|
||||
|
||||
```javascript
|
||||
const timebar = new G6.TimeBar({
|
||||
width,
|
||||
height: 150,
|
||||
type: 'tick',
|
||||
tick: {
|
||||
data: timeBarData,
|
||||
width,
|
||||
height: 42,
|
||||
tickLabelFormatter: d => {
|
||||
const dateStr = `${d.date}`;
|
||||
if ((count - 1) % 10 === 0) {
|
||||
return `${dateStr.substr(0, 4)}-${dateStr.substr(4, 2)}-${dateStr.substr(6, 2)}`;
|
||||
}
|
||||
return false;
|
||||
},
|
||||
tooltipFomatter: d => {
|
||||
const dateStr = `${d}`;
|
||||
return `${dateStr.substr(0, 4)}-${dateStr.substr(4, 2)}-${dateStr.substr(6, 2)}`;
|
||||
},
|
||||
},
|
||||
});
|
||||
```
|
||||
|
||||
<img src='https://gw.alipayobjects.com/mdn/rms_f8c6a0/afts/img/A*n6ECQ7Jn5pQAAAAAAAAAAAAAARQnAQ' width='600' />
|
||||
|
||||
|
||||
### Event Listener
|
||||
|
||||
TimeBar Plugin exposes several timing events. They could be listened by `graph.on('eventname', e => {})`.
|
||||
|
||||
| Event Name | Description |
|
||||
| --- | --- |
|
||||
| valuechange | Emitted when the value range of the timebar is chaged. |
|
||||
| timebarstartplay | Emitted when the timeline starts to play. |
|
||||
| timebarendplay | Emitted when the timeline ends playing. |
|
||||
|
||||
### Definition of the Configurations
|
||||
|
||||
#### Definition of the Interfaces
|
||||
|
||||
The complete interfaces for the TimeBar is shown below:
|
||||
|
||||
```javascript
|
||||
interface TimeBarConfig extends IPluginBaseConfig {
|
||||
// position size
|
||||
readonly x?: number;
|
||||
readonly y?: number;
|
||||
readonly width?: number;
|
||||
readonly height?: number;
|
||||
readonly padding?: number;
|
||||
|
||||
readonly type?: 'trend' | 'simple' | 'tick';
|
||||
// the configuration for the TimeBar with line chart and simple TimeBar, takes effect whtn the type is 'trend' or 'simple'
|
||||
readonly trend?: TrendConfig;
|
||||
|
||||
// the configurations for the two sliders
|
||||
readonly slider?: SliderOption;
|
||||
|
||||
// when the type is 'tick', it is the configuration for the TimeBar with descrete ticks
|
||||
// when the type is 'trend' or 'simpe', it is the configuration for the time tick labels under the timeBar
|
||||
readonly tick?: TimeBarSliceOption | TickCfg;
|
||||
|
||||
// the buttons for play, fast forward, and back forward
|
||||
readonly controllerCfg?: ControllerCfg;
|
||||
|
||||
// [Supported from v4.5.1] the CSS style for the DOM container of the timebar
|
||||
readonly containerCSS?: Object;
|
||||
|
||||
// [Supported from v4.5.1] the item types that will be filtered by the timebar. e.g. ['node', 'edge']. The default value is ['node']
|
||||
readonly filterItemTypes?: string[];
|
||||
|
||||
// [Deprecated from v4.5.1, replaced by filterItemTypes] whether to consider the edge filtering. If it is false, only filter the nodes and the edges whose end nodes are filtered out while the selected range of the timeBar is changed. If it is true, there should be `date` properties on the edges data, and the timeBar will filter the edges which is not in the selected range in the same time
|
||||
readonly filterEdge?: boolean;
|
||||
|
||||
// [Supported from v4.5.1] whether filter the nodes and edges on the graph by graph.changeData, which means the data of the graph will be changed by the timebar. If it is false, the graph.hideItem and graph.showItem will be called to hide/show the nodes and edges instead of changeData
|
||||
readonly changeData?: boolean;
|
||||
|
||||
// the callback function after the time range is changed. When it is not assigned, the graph elements will be filtered after the time range is changed
|
||||
rangeChange?: (graph: IGraph, minValue: string, maxValue: string) => void;
|
||||
|
||||
// [Supported from v4.5.1] user returns the date value according to the data of a node or an edge
|
||||
getDate?: (d: any) => number;
|
||||
|
||||
// [Supported from v4.5.1] user returns the value according to the data of a node or an edge. The value is used to draw the trend line for timebar with type 'trend'
|
||||
getValue?: (d: any) => number;
|
||||
|
||||
// [Supported from v4.5.1] user returns true or false to decide whether to ignore the node or the edge while filtering. If it is true, the item with data model will be ignored. Or the item will be filtered according to the min and max date value
|
||||
shouldIgnore?: (itemType: 'node' | 'edge', model: any, dateRage: { min: number, max: number }) => boolean;
|
||||
}
|
||||
```
|
||||
|
||||
#### The Parameters of the Interfaces
|
||||
|
||||
| Name | Type | Default Value | Description |
|
||||
| --- | --- | --- | --- |
|
||||
| container | HTMLDivElement | null | The DOM container of the TimeBar. By default, the plugin will create a container DOM with 'g6-component-timebar' as className |
|
||||
| x | number | 0 | The beginning x position of the TimeBar plugin |
|
||||
| y | number | 0 | The beginning y position of the TimeBar plugin |
|
||||
| width | number | | **Requred**, the width of the TimeBar |
|
||||
| height | number | | **Requred**, the height of the TimeBar |
|
||||
| padding | number/number[] | 10 | The padding of the container of the TimeBar |
|
||||
| type | 'trend' / 'simple' / 'tick' | trend | The type of the TimeBar, 'trend' by default |
|
||||
| trend | TrendConfig | null | The configuration for the TimeBar with line chart and simple TimeBar, takes effect whtn the type is 'trend' or 'simple' |
|
||||
| slider | SliderOption | null | The configurations for the two sliders |
|
||||
| tick | TimeBarSliceOption / TickCfg | null | If the type is 'tick', it is the configuration for the TimeBar with descrete ticks. If it the type is 'trend' or 'simple', it is the configuration for the time tick labels under the timeBar |
|
||||
| controllerCfg | ControllerCfg | null | The buttons for play, fast forward, and back forward |
|
||||
| containerCSS | Object | null | [Supported from v4.5.1] The CSS style for the DOM container of the timebar |
|
||||
| filterItemTypes | string[] | null | [Supported from v4.5.1] The item types that will be filtered by the timebar. e.g. ['node', 'edge']. The default value is ['node'] |
|
||||
| filterEdge | boolean | false | [Deprecated from v4.5.1, replaced by filterItemTypes] Whether to consider the edge filtering. If it is false, only filter the nodes and the edges whose end nodes are filtered out while the selected range of the timeBar is changed. If it is true, there should be `date` properties on the edges data, and the timeBar will filter the edges which is not in the selected range in the same time |
|
||||
| changeData | boolean | null | [Supported from v4.5.1] Whether filter the nodes and edges on the graph by graph.changeData, which means the data of the graph will be changed by the timebar. If it is false, the graph.hideItem and graph.showItem will be called to hide/show the nodes and edges instead of changeData |
|
||||
| rangeChange | Function | null | The callback function after the time range is changed. When it is not assigned, the graph elements will be filtered after the time range is changed |
|
||||
| getDate | (d: any) => number | null | [Supported from v4.5.1] User returns the date value according to the data of a node or an edge |
|
||||
| getValue | (d: any) => number | null | [Supported from v4.5.1] User returns the value according to the data of a node or an edge. The value is used to draw the trend line for timebar with type 'trend' |
|
||||
| shouldIgnore | (itemType: 'node' | 'edge', model: any, dateRage: { min: number, max: number }) => boolean | null | [Supported from v4.5.1] User returns true or false to decide whether to ignore the node or the edge while filtering. If it is true, the item with data model will be ignored. Or the item will be filtered according to the min and max date value |
|
||||
|
||||
#### Interface for TrendConfig
|
||||
|
||||
> Does not support the configurations for the style of the tick labels.
|
||||
|
||||
```javascript
|
||||
interface TrendConfig {
|
||||
// The data
|
||||
readonly data: {
|
||||
date: string;
|
||||
value: string;
|
||||
}[];
|
||||
// The position and size
|
||||
readonly x?: number;
|
||||
readonly y?: number;
|
||||
readonly width?: number;
|
||||
readonly height?: number;
|
||||
// The styles
|
||||
readonly smooth?: boolean;
|
||||
readonly isArea?: boolean;
|
||||
readonly lineStyle?: ShapeStyle;
|
||||
readonly areaStyle?: ShapeStyle;
|
||||
readonly interval?: Interval;
|
||||
}
|
||||
```
|
||||
|
||||
#### Parameters of the TrendConfig
|
||||
|
||||
| Name | Type | Default Value | Description |
|
||||
| --- | --- | --- | --- |
|
||||
| x | number | 0 | The beginning x position of the trend line chart |
|
||||
| y | number | 0 | The beginning y position of the trend line chart |
|
||||
| width | number | The width of the TimeBar | The width of the trend line chart of the TimeBar, we suggest to use the default value. If you wanna custom it, please assign the `width` of the slider in the same time |
|
||||
| height | number | 28 when type='trend'<br />8 when type='simple' | The height of the TimeBar | The width of the trend line chart of the TimeBar, we suggest to use the default value. If you wanna custom it, please assign the `height` of the slider in the same time |
|
||||
| smooth | boolean | false | Whether to show a smooth line on the trend line chart |
|
||||
| isArea | boolean | false | Whether to show a area chart instead |
|
||||
| lineStyle | ShapeStyle | null | The configurations for the style of the line in the line chart |
|
||||
| areaStyle | ShapeStyle | null | The configuration for the style of the area in the chart when `isArea` is `true` |
|
||||
| interval | Interval | null | The configuration for the style of the bars in the chart. When it is assigned, a mixed trend chart will take place. `Interval = { data: number[], style: ShapeStyle }`. Except the configurations in `ShapeStyle` for the style of the shapes in the bar charts, `barWidth` for the width of one bar is also configurable for `style` |
|
||||
|
||||
#### Interfaces of SliderOption
|
||||
|
||||
```javascript
|
||||
export type SliderOption = Partial<{
|
||||
readonly width?: number;
|
||||
readonly height?: number;
|
||||
readonly backgroundStyle?: ShapeStyle;
|
||||
readonly foregroundStyle?: ShapeStyle;
|
||||
// The style of the sliders
|
||||
readonly handlerStyle?: {
|
||||
width?: number;
|
||||
height?: number;
|
||||
style?: ShapeStyle;
|
||||
};
|
||||
readonly textStyle?: ShapeStyle;
|
||||
// The start and end position for the sliders, which indicate the data range for the filtering. Ranges from 0 to 1
|
||||
readonly start: number;
|
||||
readonly end: number;
|
||||
// The labels for the sliders
|
||||
readonly minText: string;
|
||||
readonly maxText: string;
|
||||
}>;
|
||||
```
|
||||
|
||||
#### Parameters for the SliderOption
|
||||
|
||||
| Name | Type | Default Value | Description |
|
||||
| --- | --- | --- | --- |
|
||||
| width | number | The width of the container of the TimeBar - 2 \* padding | The width of the background trend chart. We suggest to use the default value. If you wanna custom it, assign it the the `width` in the `trend` in the same time |
|
||||
| height | number | 28 when type='trend'<br />8 when type='simple' | The height of the background trend chart. We suggest to use the default value. If you wanna custom it, assign it the the `height` in the `trend` in the same time |
|
||||
| backgroundStyle | ShapeStyle | null | The configuration for the style of the background |
|
||||
| foregroundStyle | ShapeStyle | null | The configuration for the style of the forground |
|
||||
| handlerStyle | ShapeStyle | null | The configuration for the style of the two sliders |
|
||||
| textStyle | ShapeStyle | null | The configuration for the style of the labels on the two sliders |
|
||||
| start | number | 0.1 | The start position for the sliders, which indicate the start of the data range for the filtering. Ranges from 0 to `end` |
|
||||
| end | number | 0.9 | The end position for the sliders, which indicate the end of the data range for the filtering. Ranges from `start` to 1 |
|
||||
| minText | string | min | The label for the left slider |
|
||||
| maxText | string | max | The label for the right slider |
|
||||
|
||||
#### TimeBarSliceOption
|
||||
|
||||
```javascript
|
||||
export interface TimeBarSliceOption {
|
||||
// position size
|
||||
readonly x?: number;
|
||||
readonly y?: number;
|
||||
readonly width?: number;
|
||||
readonly height?: number;
|
||||
readonly padding?: number;
|
||||
|
||||
// styles
|
||||
readonly selectedTickStyle?: TickStyle;
|
||||
readonly unselectedTickStyle?: TickStyle
|
||||
readonly tooltipBackgroundColor?: string;
|
||||
|
||||
readonly start?: number;
|
||||
readonly end?: number;
|
||||
|
||||
// data
|
||||
readonly data: {
|
||||
date: string;
|
||||
value: string;
|
||||
}[];
|
||||
|
||||
// custom the formatter function for the tick labels
|
||||
readonly tickLabelFormatter?: (d: any) => string | boolean;
|
||||
// custom the formatter function for the tooltip
|
||||
readonly tooltipFomatter?: (d: any) => string;
|
||||
}
|
||||
```
|
||||
|
||||
#### Parameters for the TimeBarSliceOption
|
||||
|
||||
| Name | Type | Default Value | Description |
|
||||
| --- | --- | --- | --- |
|
||||
| x | number | 0 | The beginning x position for the TimeBar |
|
||||
| y | number | 0 | The beginning y position for the TimeBar |
|
||||
| width | number | | **Requred**, the width of the TimeBar |
|
||||
| height | number | | **Requred**, the height of the TimeBar |
|
||||
| padding | number / number[] | 0 | The padding of the container of the TimeBar |
|
||||
| selectedTickStyle | ShapeStyle | null | The style of the tick(s) which is(are) selected |
|
||||
| unselectedTickStyle | ShapeStyle | null | The style of the tick(s) which is(are) unselected |
|
||||
| tooltipBackgroundColor | ShapeStyle | null | The background style for the tooltip |
|
||||
| start | number | 0.1 | The start position for the sliders, which indicate the start of the data range for the filtering. Ranges from 0 to `end` |
|
||||
| end | number | 0.9 | The end position for the sliders, which indicate the end of the data range for the filtering. Ranges from `start` to 1 |
|
||||
| data | any[] | [] | **Requred**, the data for the ticks |
|
||||
| tickLabelFormatter | Function | null | The formatter function for customing the labels of the ticks |
|
||||
| tooltipFomatter | Function | null | The formatter function for customing the tooltip |
|
||||
|
||||
#### TickCfg
|
||||
|
||||
```javascript
|
||||
export interface TickCfg {
|
||||
// the fomatter for the time tick labels
|
||||
readonly tickLabelFormatter?: (d: any) => string | undefined;
|
||||
// the shape style for the time tick labels. [Supported from v4.5.1] tickLabelStyle.rotate can be configured to controll the rotate of the tick label to avoid overlappings
|
||||
readonly tickLabelStyle?: ShapeStyle;
|
||||
// the shape style for the short vertical lines uppon the time tick labels
|
||||
readonly tickLineStyle?: ShapeStyle;
|
||||
}
|
||||
```
|
||||
|
||||
#### Parameters for TickCfg
|
||||
|
||||
| Name | Type | Default Value | Description |
|
||||
| --- | --- | --- | --- |
|
||||
| tickLabelFormatter | Function | null | The formatter function for customing the labels of the ticks |
|
||||
| tickLabelStyle | ShapeStyle | {} | The shape style for the time tick labels. [Supported from v4.5.1] tickLabelStyle.rotate can be configured to controll the rotate of the tick label to avoid overlappings |
|
||||
| tickLineStyle | ShapeStyle | {} | The shape style for the short vertical lines uppon the time tick labels |
|
||||
|
||||
#### Interface of the ControllerCfg
|
||||
|
||||
> Does not support for now
|
||||
|
||||
> Does not support the style configuration for controller buttons
|
||||
|
||||
> Does not support loop play
|
||||
|
||||
```javascript
|
||||
type ControllerCfg = Partial<{
|
||||
/** the begining position and the size of the controller, the width and height will not scale the sub-controllers but only affects the positions of them. To change the size of the sub-controllers, try ControllerCfg.scale or the scale in the style of sub-controller */
|
||||
readonly x?: number;
|
||||
readonly y?: number;
|
||||
readonly width: number;
|
||||
readonly height: number;
|
||||
/** the scale of the whole controller */
|
||||
readonly scale?: number;
|
||||
/** the fill and stroke color of the background */
|
||||
readonly fill?: string;
|
||||
readonly stroke?: string;
|
||||
/** the font family for the whole controller, whose priority is lower than the fontFamily in the text style of each sub-controller */
|
||||
readonly fontFamily?: string;
|
||||
|
||||
/** the play spped, means the playing time for 1 tick */
|
||||
readonly speed?: number;
|
||||
/** whether play in loop */
|
||||
readonly loop?: boolean;
|
||||
/** whether hide the 'time type controller' on the right-bottom */
|
||||
readonly hideTimeTypeController: boolean;
|
||||
|
||||
/** style of the backward button. scale, offsetX, offsetY are also can be assigned to it to controll the size and position of the backward button */
|
||||
readonly preBtnStyle?: ShapeStyle;
|
||||
|
||||
/** style of the forward button. scale, offsetX, offsetY are also can be assigned to it to controll the size and position of the forward button */
|
||||
readonly nextBtnStyle?: ShapeStyle;
|
||||
|
||||
/** style of the play button. scale, offsetX, offsetY are also can be assigned to it to controll the size and position of the paly button */
|
||||
readonly playBtnStyle?: ShapeStyle;
|
||||
|
||||
/** style of the 'speed controller'. scale, offsetX, offsetY are also can be assigned to it and each sub-styles to controll the size and position of the speed controller and sub-shapes*/
|
||||
readonly speedControllerStyle?: {
|
||||
offsetX?: number,
|
||||
offsetY?: number;
|
||||
scale?: number
|
||||
pointer?: ShapeStyle,
|
||||
scroller?: ShapeStyle,
|
||||
text?: ShapeStyle
|
||||
};
|
||||
|
||||
/** style of the 'time type controller'. scale, offsetX, offsetY are also can be assigned to it and each sub-styles to controll the size and position of the speed controller and sub-shapes */
|
||||
readonly timeTypeControllerStyle?: {
|
||||
offsetX?: number,
|
||||
offsetY?: number;
|
||||
scale?: number
|
||||
check?: ShapeStyle,
|
||||
box?: ShapeStyle,
|
||||
text?: ShapeStyle
|
||||
};
|
||||
/** [Supported from v4.5.1] The style of the background rect of the controller */
|
||||
readonly containerStyle?: ExtendedShapeStyle;
|
||||
/** the text for the right-botton switch controlling play with single time point or time range */
|
||||
readonly timePointControllerText?: string;
|
||||
readonly timeRangeControllerText?: string
|
||||
}>
|
||||
```
|
||||
|
||||
#### Parameters for ControllerCfg
|
||||
|
||||
| Name | Type | Default Value | Description |
|
||||
| --- | --- | --- | --- |
|
||||
| x | number | 0 | The beginning x position for the buttons group of the TimeBar |
|
||||
| y | number | 0 | The beginning y position for the buttons group of the TimeBar |
|
||||
| width | number | The width of the TimeBar | The width of the buttons group of the TimeBar, do not scale the sub-controllers but only affects the positions of them |
|
||||
| height | number | 40 | The width of the buttons group of the TimeBar, do not scale the sub-controllers but only affects the positions of them |
|
||||
| scale | number | 1 | The scale of the whole controller |
|
||||
| speed | number | 1 | The play speed |
|
||||
| loop | boolean | false | _Does not support for now_, whether play in loop |
|
||||
| hideTimeTypeController | boolean | true | Whther hide the time type controller on the right bottom |
|
||||
| fill | string | | The fillling color for the background of the controller |
|
||||
| stroke | string | | The stroke color for the background of the buttons group |
|
||||
| preBtnStyle | ShapeStyle | null | The style of the backward button. `scale`, `offsetX`, `offsetY` are also can be assigned to it to controll the size and position of the backward button |
|
||||
| nextBtnStyle | ShapeStyle | null | The style of the forward button. `scale`, `offsetX`, `offsetY` are also can be assigned to it to controll the size and position of the forward button |
|
||||
| playBtnStyle | ShapeStyle | null | The style of the play button. `scale`, `offsetX`, `offsetY` are also can be assigned to it to controll the size and position of the paly button |
|
||||
| speedControllerStyle | { offsetX?: number, offsetY?: number, scale?: number, pointer?: ShapeStyle, text?: ShapeStyle, scroller?: ShapeStyle} | null | The style of the 'speed controller'. `scale`, `offsetX`, `offsetY` are also can be assigned to it and each sub-styles to controll the size and position of the speed controller and sub-shapes |
|
||||
| timeTypeControllerStyle | { offsetX?: number, offsetY?: number, scale?: number, box?: ShapeStyle, check?: ShapeStyle, text?: ShapeStyle } | null | The style of the 'time type controller'. `scale`, `offsetX`, `offsetY` are also can be assigned to it and each sub-styles to controll the size and position of the speed controller and sub-shapes |
|
||||
| containerStyle | ShapeStyle | {} | [Supported from v4.5.1] The style of the background rect of the controller |
|
||||
| timePointControllerText | string | "单一时间" | The text for the right-botton switch controlling play with single time point or time range |
|
||||
| timeRangeControllerText | string | "时间范围" | The text for the right-botton switch controlling play with single time point or time range |
|
||||
|
@ -662,6 +662,16 @@ const timebar = new G6.TimeBar({
|
||||
|
||||
<img src='https://gw.alipayobjects.com/mdn/rms_f8c6a0/afts/img/A*n6ECQ7Jn5pQAAAAAAAAAAAAAARQnAQ' width='600' />
|
||||
|
||||
### 事件监听
|
||||
|
||||
TimeBar 插件暴露除了几个时机事件,方便用户监听内部状态的变化。以下事件可通过 `graph.on('eventname', e => {})` 进行监听。
|
||||
|
||||
| 事件名称 | 描述 |
|
||||
| --- | --- |
|
||||
| valuechange | 时间轴的时间范围发生变化时触发 |
|
||||
| timebarstartplay | 时间轴开始播放时触发 |
|
||||
| timebarendplay | 时间轴播放结束时触发 |
|
||||
|
||||
### 参数定义
|
||||
|
||||
#### 接口定义
|
||||
@ -683,14 +693,36 @@ interface TimeBarConfig extends IPluginBaseConfig {
|
||||
// 滑块、及前后背景的配置
|
||||
readonly slider?: SliderOption;
|
||||
|
||||
// 刻度时间轴配置项
|
||||
readonly tick?: TimeBarSliceOption;
|
||||
// 当 type 是 tick 时,这是 tick 类型时间轴的配置项
|
||||
// 当 type 是 trend 或 simple 时,这是时间轴下方时间刻度文本的配置项
|
||||
readonly tick?: TimeBarSliceOption | TickCfg;
|
||||
|
||||
// 控制按钮
|
||||
readonly controllerCfg?: ControllerCfg;
|
||||
|
||||
// [v4.5.1 起支持] 容器的 CSS 样式
|
||||
readonly containerCSS?: Object;
|
||||
|
||||
// [v4.5.1 起支持] 过滤的类型, ['node', 'edge'], 默认为 ['node']
|
||||
readonly filterItemTypes?: string[];
|
||||
|
||||
// [v4.5.1 起废弃,由 filterItemTypes 代替] 是否过滤边,若为 true,则需要配合边数据上有 date 字段,过滤节点同时将不满足 date 在选中范围内的边也过滤出去;若为 false,则仅过滤节点以及两端节点都被过滤出去的边
|
||||
readonly filterEdge?: boolean;
|
||||
|
||||
// [v4.5.1 起支持] 是否通过 graph.changeData 改变图上数据从而达到筛选目的。若为 false 则将使用 graph.hideItem 和 graph.showItem 以隐藏/展示图上元素从而达到筛选目的
|
||||
readonly changeData?: boolean;
|
||||
|
||||
// TimeBar 时间范围变化时的回调函数,当不定义该函数时,时间范围变化时默认过滤图上的数据
|
||||
rangeChange?: (graph: IGraph, minValue: string, maxValue: string) => void;
|
||||
valueChange?: (graph: IGraph, value: string) => void;
|
||||
|
||||
// [v4.5.1 起支持] 用户根据节点/边数据返回对应时间值的方法
|
||||
getDate?: (d: any) => number;
|
||||
|
||||
// [v4.5.1 起支持] 用户根据节点/边数据返回对应 value 的方法。value 用于在 type 为 trend 的时间轴上显示趋势线
|
||||
getValue?: (d: any) => number;
|
||||
|
||||
// [v4.5.1 起支持] 在过滤图元素时是否要忽略某些元素。返回 true,则忽略。否则按照正常过滤逻辑处理
|
||||
shouldIgnore?: (itemType: 'node' | 'edge', model: any, dateRage: { min: number, max: number }) => boolean;
|
||||
}
|
||||
```
|
||||
|
||||
@ -701,15 +733,22 @@ interface TimeBarConfig extends IPluginBaseConfig {
|
||||
| container | HTMLDivElement | null | TimeBar 容器,如果不设置,则默认创建 className 为 g6-component-timebar 的 DOM 容器 |
|
||||
| x | number | 0 | TimeBar 开始 x 坐标 |
|
||||
| y | number | 0 | TimeBar 开始 y 坐标 |
|
||||
| width | number | | 必选,TimeBar 容器宽度 |
|
||||
| height | number | | 必选,TimeBar 高度 |
|
||||
| width | number | | **必选**,TimeBar 容器宽度 |
|
||||
| height | number | | **必选**,TimeBar 高度 |
|
||||
| padding | number/number[] | 10 | TimeBar 距离容器的间距值 |
|
||||
| type | 'trend' / 'simple' / 'tick' | trend | 默认的 TimeBar 类型,默认为趋势图样式 |
|
||||
| trend | TrendConfig | null | Timebar 中趋势图的配置项,当 type 为 trend 或 simple 时,该字段必选 |
|
||||
| slider | SliderOption | null | TimeBar 组件背景及控制调节范围的滑块的配置项 |
|
||||
| tick | TimeBarSliceOption | null | 刻度 TimeBar 配置项,当 type 为 tick 时,该字段必选 |
|
||||
| tick | TimeBarSliceOption / TickCfg | null | 当 type 是 tick 时,这是 tick 类型时间轴的配置项,该字段必须按;当 type 是 trend 或 simple 时,这是时间轴下方时间刻度文本的配置项 |
|
||||
| controllerCfg | ControllerCfg | null | 控制按钮组配置项 |
|
||||
| containerCSS | Object | null | [v4.5.1 起支持] 容器的 CSS 样式 |
|
||||
| filterItemTypes | string[] | null | [v4.5.1 起支持] 过滤的类型, ['node', 'edge'], 默认为 ['node'] |
|
||||
| filterEdge | boolean | false | [v4.5.1 起废弃,由 filterItemTypes 代替] 是否过滤边,若为 true,则需要配合边数据上有 date 字段,过滤节点同时将不满足 date 在选中范围内的边也过滤出去;若为 false,则仅过滤节点以及两端节点都被过滤出去的边 |
|
||||
| changeData | boolean | null | [v4.5.1 起支持] 是否通过 graph.changeData 改变图上数据从而达到筛选目的。若为 false 则将使用 graph.hideItem 和 graph.showItem 以隐藏/展示图上元素从而达到筛选目的 |
|
||||
| rangeChange | Function | null | TimeBar 时间范围变化时的回调函数,当不定义该函数时,时间范围变化时默认过滤图上的数据 |
|
||||
| getDate | (d: any) => number | null | [v4.5.1 起支持] 用户根据节点/边数据返回对应时间值的方法 |
|
||||
| getValue | (d: any) => number | null | [v4.5.1 起支持] 用户根据节点/边数据返回对应 value 的方法。value 用于在 type 为 trend 的时间轴上显示趋势线 |
|
||||
| shouldIgnore | (itemType: 'node' | 'edge', model: any, dateRage: { min: number, max: number }) => boolean | null | [v4.5.1 起支持] 在过滤图元素时是否要忽略某些元素。返回 true,则忽略。否则按照正常过滤逻辑处理 |
|
||||
|
||||
#### TrendConfig 接口定义
|
||||
|
||||
@ -748,7 +787,7 @@ interface TrendConfig {
|
||||
| isArea | boolean | false | 是否显示面积图 |
|
||||
| lineStyle | ShapeStyle | null | 折线的样式配置 |
|
||||
| areaStyle | ShapeStyle | null | 面积的样式配置项,只有当 isArea 为 true 时生效 |
|
||||
| interval | Interval | null | 柱状图配置项,当配置了该项后,趋势图上会展现为混合图样式 |
|
||||
| interval | Interval | null | 柱状图配置项,当配置了该项后,趋势图上会展现为混合图样式。`Interval = { data: number[], style: ShapeStyle }`,`style` 除 `ShapeStyle` 类型中图形的样式外,还可配置 `barWidth` 配置柱状图柱子的宽度。 |
|
||||
|
||||
#### SliderOption 接口定义
|
||||
|
||||
@ -839,6 +878,28 @@ export interface TimeBarSliceOption {
|
||||
| tickLabelFormatter | Function | null | 刻度的格式化回调函数 |
|
||||
| tooltipFomatter | Function | null | tooltip 上内容格式化的回调函数 |
|
||||
|
||||
|
||||
#### TickCfg 接口定义
|
||||
|
||||
```javascript
|
||||
export interface TickCfg {
|
||||
// 时间轴下方文本的格式化函数
|
||||
readonly tickLabelFormatter?: (d: any) => string | undefined;
|
||||
// 时间轴下方文本的图形样式。[v4.5.1 起支持] 可配置 tickLabelStyle.rotate 以控制时间轴下方每个文本的旋转角度,可避免文本相互重叠
|
||||
readonly tickLabelStyle?: ShapeStyle;
|
||||
// 时间轴下方文本上的竖线图形样式
|
||||
readonly tickLineStyle?: ShapeStyle;
|
||||
}
|
||||
```
|
||||
|
||||
#### TickCfg 参数说明
|
||||
|
||||
| Name | Type | Default Value | Description |
|
||||
| --- | --- | --- | --- |
|
||||
| tickLabelFormatter | Function | null | 时间轴下方文本的格式化函数 |
|
||||
| tickLabelStyle | ShapeStyle | {} | 时间轴下方文本的图形样式。[v4.5.1 起支持] 可配置 tickLabelStyle.rotate 以控制时间轴下方每个文本的旋转角度,可避免文本相互重叠 |
|
||||
| tickLineStyle | ShapeStyle | {} | 时间轴下方文本上方的竖线的图形样式 |
|
||||
|
||||
#### ControllerCfg 接口定义
|
||||
|
||||
> 暂不支持
|
||||
@ -849,36 +910,84 @@ export interface TimeBarSliceOption {
|
||||
|
||||
```javascript
|
||||
type ControllerCfg = Partial<{
|
||||
|
||||
/** 控制栏的起始位置以及宽高,width height 将不缩放内部子控制器,仅影响它们的位置分布。需要缩放请使用 scale */
|
||||
readonly x?: number;
|
||||
readonly y?: number;
|
||||
readonly width: number;
|
||||
readonly height: number;
|
||||
/** 控制栏缩放比例 */
|
||||
readonly scale?: number;
|
||||
/** 控制器背景的颜色和描边色 */
|
||||
readonly fill?: string;
|
||||
readonly stroke?: string;
|
||||
/** 整个控制栏的字体样式,优先级低于各个子控制器的 text 内的 fontFamily */
|
||||
readonly fontFamily?: string;
|
||||
|
||||
/** 播放速度,1 个 tick 花费时间 */
|
||||
readonly speed?: number;
|
||||
/** 是否循环播放 */
|
||||
readonly loop?: boolean;
|
||||
readonly hiddleToggle: boolean;
|
||||
readonly fill?: string;
|
||||
readonly stroke?: string;
|
||||
/** 是否隐藏右下角的 ’播放时间类型切换器‘ */
|
||||
readonly hideTimeTypeController: boolean;
|
||||
|
||||
/** ‘上一帧’按钮的样式,同时可以为其配置 scale、offsetX、offsetY 单独控制该控制器的缩放以及平移 */
|
||||
readonly preBtnStyle?: ShapeStyle;
|
||||
|
||||
/** ‘下一帧’按钮的样式,同时可以为其配置 scale、offsetX、offsetY 单独控制该控制器的缩放以及平移 */
|
||||
readonly nextBtnStyle?: ShapeStyle;
|
||||
|
||||
/** ‘播放’ 与 ‘暂停’ 按钮的样式,同时可以为其配置 scale、offsetX、offsetY 单独控制该控制器的缩放以及平移 */
|
||||
readonly playBtnStyle?: ShapeStyle;
|
||||
|
||||
/** ‘速度控制器’ 的样式,包括速度的指针、速度指示滚轮(横线)、文本的样式,同时可以为 speedControllerStyle 及其子图形样式配置 scale、offsetX、offsetY 单独控制该控制器及其子图形的缩放以及平移) */
|
||||
readonly speedControllerStyle?: {
|
||||
offsetX?: number,
|
||||
offsetY?: number;
|
||||
scale?: number
|
||||
pointer?: ShapeStyle,
|
||||
scroller?: ShapeStyle,
|
||||
text?: ShapeStyle
|
||||
};
|
||||
|
||||
/** ‘播放时间类型切换器’ 的样式,包括 checkbox 的框、checkbox 的选中勾、文本的样式,同时可以为 timeTypeControllerStyle 及其子图形样式配置 scale、offsetX、offsetY 单独控制该控制器及其子图形的缩放以及平移 */
|
||||
readonly timeTypeControllerStyle?: {
|
||||
offsetX?: number,
|
||||
offsetY?: number;
|
||||
scale?: number
|
||||
check?: ShapeStyle,
|
||||
box?: ShapeStyle,
|
||||
text?: ShapeStyle
|
||||
};
|
||||
/** [v4.5.1 起支持] 控制栏背景方框的样式 */
|
||||
readonly containerStyle?: ExtendedShapeStyle;
|
||||
/** ‘播放时间类型切换器’单一文本时的文本,默认为‘单一时间’ */
|
||||
readonly timePointControllerText?: string;
|
||||
/** ‘播放时间类型切换器’单一文本时的文本,默认为‘时间范围’ */
|
||||
readonly timeRangeControllerText?: string;
|
||||
}>
|
||||
```
|
||||
|
||||
#### ControllerCfg 参数说明
|
||||
|
||||
| 名称 | 类型 | 默认值 | 描述 |
|
||||
| ------------ | ---------- | ------------ | ---------------------- |
|
||||
| x | number | 0 | 按钮控制组开始 x 坐标 |
|
||||
| y | number | 0 | 按钮控制组开始 y 坐标 |
|
||||
| width | number | TimeBar 宽度 | 控制按钮组宽度 |
|
||||
| height | number | 40 | 控制按钮组高度 |
|
||||
| speed | number | 1 | 播放速度 |
|
||||
| loop | boolean | false | 暂不支持,是否循环播放 |
|
||||
| hiddleToggle | boolean | true | 是否隐藏时间类型切换 |
|
||||
| fill | string | | 按钮控制组外层框填充色 |
|
||||
| stroke | string | | 按钮控制组外层框边框色 |
|
||||
| preBtnStyle | ShapeStyle | null | 后退按钮样式配置项 |
|
||||
| nextBtnStyle | ShapeStyle | null | 前进按钮样式配置项 |
|
||||
| playBtnStyle | ShapeStyle | null | 播放按钮样式配置项 |
|
||||
| 名称 | 类型 | 默认值 | 描述 |
|
||||
| --- | --- | --- | --- |
|
||||
| x | number | 0 | 控制栏开始 x 坐标 |
|
||||
| y | number | 0 | 控制栏开始 y 坐标 |
|
||||
| width | number | TimeBar 宽度 | 控制栏宽度,将不缩放内部子控制器,仅影响它们的位置分布 |
|
||||
| height | number | 40 | 控制栏高度,将不缩放内部子控制器,仅影响它们的位置分布 |
|
||||
| scale | number | 1 | 控制栏缩放比例 |
|
||||
| speed | number | 1 | 播放速度 |
|
||||
| loop | boolean | false | 暂不支持,是否循环播放 |
|
||||
| hideTimeTypeController | boolean | true | 是否隐藏时间类型切换 |
|
||||
| fill | string | | 控制栏背景框填充色 |
|
||||
| stroke | string | | 整个控制栏的字体样式,优先级低于各个子控制器的 text 内的 fontFamily |
|
||||
| preBtnStyle | string | null | 控制栏背景框边框色 |
|
||||
| preBtnStyle | ShapeStyle | null | ‘上一帧’按钮的样式,同时可以为其配置 `scale`、`offsetX`、`offsetY` 单独控制该控制器的缩放以及平移 |
|
||||
| nextBtnStyle | ShapeStyle | null | ‘下一帧’按钮的样式,同时可以为其配置 `scale`、`offsetX`、`offsetY` 单独控制该控制器的缩放以及平移 |
|
||||
| playBtnStyle | ShapeStyle | null | ‘播放’ 与 ‘暂停’ 按钮的样式,同时可以为其配置 `scale`、`offsetX`、`offsetY` 单独控制该控制器的缩放以及平移 |
|
||||
| speedControllerStyle | { offsetX?: number, offsetY?: number, scale?: number, pointer?: ShapeStyle, text?: ShapeStyle, scroller?: ShapeStyle} | null | ‘速度控制器’ 的样式,包括速度的指针、速度指示滚轮(横线)、文本的样式,同时可以为 `speedControllerStyle` 及其子图形样式配置 `scale`、`offsetX`、`offsetY` 单独控制该控制器及其子图形的缩放以及平移 |
|
||||
| timeTypeControllerStyle | { offsetX?: number, offsetY?: number, scale?: number, box?: ShapeStyle, check?: ShapeStyle, text?: ShapeStyle } | null | ‘播放时间类型切换器’ 的样式,包括 checkbox 的框、checkbox 的选中勾、文本的样式,同时可以为 `timeTypeControllerStyle` 及其子图形样式配置 `scale`、`offsetX`、`offsetY` 单独控制该控制器及其子图形的缩放以及平移 |
|
||||
| containerStyle | ShapeStyle | {} | 控制栏背景方框的样式 |
|
||||
| timePointControllerText | string | "单一时间" | 右下角“单一时间”文本,默认为”单一时间“ |
|
||||
| timePointControllerText | string | "时间范围" | 右下角“单一时间”文本,默认为”时间范围时间“ |
|
||||
|
@ -1,7 +1,7 @@
|
||||
{
|
||||
"private": true,
|
||||
"name": "@antv/g6-site",
|
||||
"version": "4.4.1",
|
||||
"version": "4.5.1",
|
||||
"description": "G6 sites deployed on gh-pages",
|
||||
"keywords": [
|
||||
"antv",
|
||||
@ -37,7 +37,7 @@
|
||||
"@ant-design/icons": "^4.0.6",
|
||||
"@antv/chart-node-g6": "^0.0.3",
|
||||
"@antv/g6": "4.3.8",
|
||||
"@antv/gatsby-theme-antv": "1.1.7",
|
||||
"@antv/gatsby-theme-antv": "1.1.15",
|
||||
"@antv/util": "^2.0.9",
|
||||
"@antv/vis-predict-engine": "^0.1.1",
|
||||
"@types/react": "^16.9.35",
|
||||
@ -52,4 +52,4 @@
|
||||
"resolutions": {
|
||||
"@types/react": "^16.9.35"
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user