- Go backend (server/)
- Frontend (web/, server/static/)
- Database and deployment files
- Scripts and docs
Co-Authored-By: 狸花猫/Claude-Qwen3.6-Plus 🐾
472 lines
17 KiB
JavaScript
472 lines
17 KiB
JavaScript
"use strict";
|
|
|
|
Object.defineProperty(exports, "__esModule", {
|
|
value: true
|
|
});
|
|
exports.default = void 0;
|
|
var _domUtil = require("@antv/dom-util");
|
|
var _gCanvas = require("@antv/g-canvas");
|
|
var _gSvg = require("@antv/g-svg");
|
|
var _util = require("@antv/util");
|
|
var _base = _interopRequireDefault(require("../base"));
|
|
var _constant = require("./constant");
|
|
var _timeBarSlice = _interopRequireDefault(require("./timeBarSlice"));
|
|
var _trendTimeBar = _interopRequireDefault(require("./trendTimeBar"));
|
|
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
|
|
var __extends = void 0 && (void 0).__extends || function () {
|
|
var _extendStatics = function extendStatics(d, b) {
|
|
_extendStatics = Object.setPrototypeOf || {
|
|
__proto__: []
|
|
} instanceof Array && function (d, b) {
|
|
d.__proto__ = b;
|
|
} || function (d, b) {
|
|
for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p];
|
|
};
|
|
return _extendStatics(d, b);
|
|
};
|
|
return function (d, b) {
|
|
if (typeof b !== "function" && b !== null) throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
|
|
_extendStatics(d, b);
|
|
function __() {
|
|
this.constructor = d;
|
|
}
|
|
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
|
|
};
|
|
}();
|
|
var __assign = void 0 && (void 0).__assign || function () {
|
|
__assign = Object.assign || function (t) {
|
|
for (var s, i = 1, n = arguments.length; i < n; i++) {
|
|
s = arguments[i];
|
|
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];
|
|
}
|
|
return t;
|
|
};
|
|
return __assign.apply(this, arguments);
|
|
};
|
|
var __rest = void 0 && (void 0).__rest || function (s, e) {
|
|
var t = {};
|
|
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0) t[p] = s[p];
|
|
if (s != null && typeof Object.getOwnPropertySymbols === "function") for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
|
|
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i])) t[p[i]] = s[p[i]];
|
|
}
|
|
return t;
|
|
};
|
|
/**
|
|
* 基于 G 的时间轴组件
|
|
*/
|
|
|
|
// simple 版本默认高度
|
|
var DEFAULT_SIMPLE_HEIGHT = 4;
|
|
// trend 版本默认高度
|
|
var DEFAULT_TREND_HEIGHT = 26;
|
|
var TimeBar = /** @class */function (_super) {
|
|
__extends(TimeBar, _super);
|
|
function TimeBar(config) {
|
|
var _this = _super.call(this, config) || this;
|
|
_this.afterrenderListener = function (e) {
|
|
return _this.filterData({});
|
|
};
|
|
_this.valueChangeListener = (0, _util.throttle)(function (e) {
|
|
return _this.filterData(e);
|
|
},
|
|
// 不可简写,否则 filterData 中 this 指针不对
|
|
200, {
|
|
trailing: true,
|
|
leading: true
|
|
});
|
|
_this.changeData = function (e) {
|
|
var graph = _this.get('graph');
|
|
_this.cacheGraphData = graph.get('data');
|
|
_this.filterData({});
|
|
};
|
|
return _this;
|
|
}
|
|
TimeBar.prototype.getDefaultCfgs = function () {
|
|
return {
|
|
container: null,
|
|
className: 'g6-component-timebar',
|
|
padding: 10,
|
|
type: 'trend',
|
|
trend: {
|
|
data: [],
|
|
isArea: false,
|
|
smooth: true
|
|
},
|
|
controllerCfg: {
|
|
speed: 1,
|
|
loop: false
|
|
},
|
|
slider: {
|
|
start: 0.1,
|
|
end: 0.9,
|
|
minText: 'min',
|
|
maxText: 'max'
|
|
},
|
|
tick: {
|
|
start: 0.1,
|
|
end: 0.9,
|
|
data: []
|
|
},
|
|
textStyle: {},
|
|
filterEdge: false,
|
|
filterItemTypes: ['node'],
|
|
containerCSS: {},
|
|
putInGraphContainer: true
|
|
};
|
|
};
|
|
/**
|
|
* 初始化 TimeBar 的容器
|
|
*/
|
|
TimeBar.prototype.initContainer = function () {
|
|
var graph = this.get('graph');
|
|
var _a = this._cfgs,
|
|
width = _a.width,
|
|
height = _a.height,
|
|
putInGraphContainer = _a.putInGraphContainer;
|
|
var className = this.get('className') || 'g6-component-timebar';
|
|
var container = this.get('container');
|
|
var timeBarContainer;
|
|
if (!container) {
|
|
timeBarContainer = (0, _domUtil.createDom)("<div class='".concat(className, "'></div>"));
|
|
(0, _domUtil.modifyCSS)(timeBarContainer, {
|
|
position: 'relative'
|
|
});
|
|
} else {
|
|
if ((0, _util.isString)(container)) {
|
|
container = document.getElementById(container);
|
|
}
|
|
timeBarContainer = container;
|
|
}
|
|
if (putInGraphContainer) {
|
|
var graphContainer = this.get('graph').get('container');
|
|
graphContainer.appendChild(timeBarContainer);
|
|
}
|
|
this.set('timeBarContainer', timeBarContainer);
|
|
var canvas;
|
|
var renderer = graph.get('renderer');
|
|
if (renderer === 'SVG') {
|
|
canvas = new _gSvg.Canvas({
|
|
container: timeBarContainer,
|
|
width: width,
|
|
height: height
|
|
});
|
|
} else {
|
|
canvas = new _gCanvas.Canvas({
|
|
container: timeBarContainer,
|
|
width: width,
|
|
height: height
|
|
});
|
|
}
|
|
// 根据传入的参数修改容器 CSS 样式
|
|
if (this.get('containerCSS')) (0, _domUtil.modifyCSS)(timeBarContainer, this.get('containerCSS'));
|
|
this.set('canvas', canvas);
|
|
};
|
|
TimeBar.prototype.init = function () {
|
|
this.initContainer();
|
|
var canvas = this.get('canvas');
|
|
var timeBarGroup = canvas.addGroup({
|
|
name: 'timebar-group'
|
|
});
|
|
this.set('timeBarGroup', timeBarGroup);
|
|
this.renderTrend();
|
|
this.initEvent();
|
|
var fontFamily = typeof window !== 'undefined' ? window.getComputedStyle(document.body, null).getPropertyValue('font-family') || 'Arial, sans-serif' : 'Arial, sans-serif';
|
|
this.set('fontFamily', fontFamily);
|
|
};
|
|
/**
|
|
* 触发时间轴播放
|
|
*/
|
|
TimeBar.prototype.play = function () {
|
|
this.togglePlay(true);
|
|
};
|
|
/**
|
|
* 触发时间轴暂停
|
|
*/
|
|
TimeBar.prototype.pause = function () {
|
|
this.togglePlay(false);
|
|
};
|
|
/**
|
|
* 时间轴播放状态(播放/暂停)的切换
|
|
*/
|
|
TimeBar.prototype.togglePlay = function (play) {
|
|
var timebar = this.get('timebar');
|
|
if (!timebar) return;
|
|
timebar.isPlay = !!play;
|
|
timebar.changePlayStatus();
|
|
};
|
|
TimeBar.prototype.renderTrend = function () {
|
|
var _this = this;
|
|
var _a = this._cfgs,
|
|
width = _a.width,
|
|
x = _a.x,
|
|
y = _a.y,
|
|
padding = _a.padding,
|
|
type = _a.type,
|
|
trend = _a.trend,
|
|
slider = _a.slider,
|
|
controllerCfg = _a.controllerCfg,
|
|
textStyle = _a.textStyle,
|
|
tick = _a.tick,
|
|
backgroundStyle = _a.backgroundStyle,
|
|
foregroundStyle = _a.foregroundStyle;
|
|
var data = trend.data,
|
|
other = __rest(trend, ["data"]);
|
|
var realWidth = width - 2 * padding;
|
|
var defaultHeight = type === 'trend' ? DEFAULT_TREND_HEIGHT : DEFAULT_SIMPLE_HEIGHT;
|
|
var graph = this.get('graph');
|
|
var group = this.get('timeBarGroup');
|
|
var canvas = this.get('canvas');
|
|
var timebar = null;
|
|
if (type === 'trend' || type === 'simple') {
|
|
var getValue_1 = this.get('getValue');
|
|
timebar = new _trendTimeBar.default(__assign(__assign({
|
|
graph: graph,
|
|
canvas: canvas,
|
|
group: group,
|
|
type: type,
|
|
x: x + padding,
|
|
y: type === 'trend' ? y + padding : y + padding + 15,
|
|
width: realWidth,
|
|
height: defaultHeight,
|
|
padding: padding,
|
|
backgroundStyle: backgroundStyle,
|
|
foregroundStyle: foregroundStyle,
|
|
trendCfg: __assign(__assign({}, other), {
|
|
data: data.map(function (d) {
|
|
return (getValue_1 === null || getValue_1 === void 0 ? void 0 : getValue_1(d)) || d.value;
|
|
})
|
|
})
|
|
}, slider), {
|
|
tick: {
|
|
ticks: data,
|
|
tickLabelFormatter: tick.tickLabelFormatter,
|
|
tickLabelStyle: tick.tickLabelStyle,
|
|
tickLineStyle: tick.tickLineStyle
|
|
},
|
|
handlerStyle: __assign(__assign({}, slider.handlerStyle), {
|
|
height: slider.height || defaultHeight
|
|
}),
|
|
controllerCfg: controllerCfg,
|
|
textStyle: textStyle
|
|
}));
|
|
} else if (type === 'tick') {
|
|
// 刻度时间轴
|
|
timebar = new _timeBarSlice.default(__assign({
|
|
graph: graph,
|
|
canvas: canvas,
|
|
group: group,
|
|
x: x + padding,
|
|
y: y + padding,
|
|
width: width,
|
|
height: 42,
|
|
padding: 2,
|
|
controllerCfg: controllerCfg
|
|
}, tick));
|
|
}
|
|
// 鼠标按下左/右滑块或范围条后在任意地方释放,都触发暂停播放
|
|
var _handleMouseUp = function handleMouseUp() {
|
|
var 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', function (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);
|
|
};
|
|
TimeBar.prototype.filterData = function (evt) {
|
|
var _a;
|
|
var value = evt.value;
|
|
if (!value) {
|
|
value = [];
|
|
var type_1 = this._cfgs.type;
|
|
if (!type_1 || type_1 === 'trend' || type_1 === 'simple') {
|
|
value[0] = this._cfgs.slider.start;
|
|
value[1] = this._cfgs.slider.end;
|
|
} else if (type_1 === 'tick') {
|
|
value[0] = this._cfgs.tick.start;
|
|
value[1] = this._cfgs.tick.end;
|
|
}
|
|
}
|
|
var trendData = null;
|
|
var type = this._cfgs.type;
|
|
if (type === 'trend' || type === 'simple') {
|
|
trendData = this._cfgs.trend.data;
|
|
} else if (type === 'tick') {
|
|
trendData = this._cfgs.tick.data;
|
|
}
|
|
if (!trendData || trendData.length === 0) {
|
|
console.warn('请配置 TimeBar 组件的数据');
|
|
return;
|
|
}
|
|
var rangeChange = this.get('rangeChange');
|
|
var graph = this.get('graph');
|
|
var min = Math.round(trendData.length * value[0]);
|
|
var max = Math.round(trendData.length * value[1]);
|
|
max = max >= trendData.length ? trendData.length - 1 : max;
|
|
min = min >= trendData.length ? trendData.length - 1 : min;
|
|
var tickLabelFormatter = (_a = this._cfgs.tick) === null || _a === void 0 ? void 0 : _a.tickLabelFormatter;
|
|
var minText = tickLabelFormatter ? tickLabelFormatter(trendData[min]) : trendData[min].date;
|
|
var maxText = tickLabelFormatter ? tickLabelFormatter(trendData[max]) : trendData[max].date;
|
|
if (type !== 'tick') {
|
|
var timebar = this.get('timebar');
|
|
timebar.setText(minText, maxText);
|
|
}
|
|
if (rangeChange) {
|
|
rangeChange(graph, minText, maxText);
|
|
} else {
|
|
// 自动过滤数据,并渲染 graph
|
|
if (!this.cacheGraphData || this.cacheGraphData.nodes && this.cacheGraphData.nodes.length === 0) {
|
|
this.cacheGraphData = graph.get('data'); // graph.save() as GraphData;
|
|
}
|
|
var filterItemTypes = this.get('filterItemTypes');
|
|
var changeData = this.get('changeData');
|
|
// 过滤不在 min 和 max 范围内的节点
|
|
var getDate_1 = this.get('getDate');
|
|
var shouldIgnore_1 = this.get('shouldIgnore');
|
|
var minDate_1 = trendData[min].date,
|
|
maxDate_1 = trendData[max].date;
|
|
if (changeData || changeData === undefined) {
|
|
var originNodes = this.cacheGraphData.nodes;
|
|
var originEdges = this.cacheGraphData.edges;
|
|
var currentNodeExistMap_1 = {};
|
|
var currentEdgeExistMap_1 = {};
|
|
graph.getNodes().forEach(function (node) {
|
|
return currentNodeExistMap_1[node.getID()] = true;
|
|
});
|
|
graph.getEdges().forEach(function (edge) {
|
|
return currentEdgeExistMap_1[edge.getID()] = true;
|
|
});
|
|
if (filterItemTypes.includes('node')) {
|
|
originNodes === null || originNodes === void 0 ? void 0 : originNodes.forEach(function (node) {
|
|
var date = +((getDate_1 === null || getDate_1 === void 0 ? void 0 : getDate_1(node)) || node.date);
|
|
var hitRange = date >= minDate_1 && date <= maxDate_1 || (shouldIgnore_1 === null || shouldIgnore_1 === void 0 ? void 0 : shouldIgnore_1('node', node, {
|
|
min: minDate_1,
|
|
max: maxDate_1
|
|
}));
|
|
var exist = currentNodeExistMap_1[node.id];
|
|
if (exist && !hitRange) {
|
|
graph.removeItem(node.id);
|
|
currentNodeExistMap_1[node.id] = false;
|
|
} else if (!exist && hitRange) {
|
|
graph.addItem('node', node);
|
|
currentNodeExistMap_1[node.id] = true;
|
|
}
|
|
});
|
|
// 过滤 source 或 target 不在 min 和 max 范围内的边
|
|
originEdges === null || originEdges === void 0 ? void 0 : originEdges.forEach(function (edge) {
|
|
var shouldShow = currentNodeExistMap_1[edge.source] && currentNodeExistMap_1[edge.target] || (shouldIgnore_1 === null || shouldIgnore_1 === void 0 ? void 0 : shouldIgnore_1('edge', edge, {
|
|
min: minDate_1,
|
|
max: maxDate_1
|
|
}));
|
|
var exist = !!graph.findById(edge.id);
|
|
if (exist && !shouldShow) {
|
|
graph.removeItem(edge.id);
|
|
currentEdgeExistMap_1[edge.id] = false;
|
|
} else if (!exist && shouldShow) {
|
|
graph.addItem('edge', edge);
|
|
currentEdgeExistMap_1[edge.id] = true;
|
|
} else if (!exist) {
|
|
currentEdgeExistMap_1[edge.id] = false;
|
|
}
|
|
});
|
|
}
|
|
if (this.get('filterEdge') || filterItemTypes.includes('edge')) {
|
|
originEdges === null || originEdges === void 0 ? void 0 : originEdges.filter(function (edge) {
|
|
var date = +((getDate_1 === null || getDate_1 === void 0 ? void 0 : getDate_1(edge)) || edge.date);
|
|
var hitRange = date >= minDate_1 && date <= maxDate_1 || (shouldIgnore_1 === null || shouldIgnore_1 === void 0 ? void 0 : shouldIgnore_1('edge', edge, {
|
|
min: minDate_1,
|
|
max: maxDate_1
|
|
}));
|
|
var endsExist = currentNodeExistMap_1[edge.source] && currentNodeExistMap_1[edge.target];
|
|
var shouldShow = hitRange && endsExist;
|
|
var exist = currentEdgeExistMap_1[edge.id];
|
|
if (exist && !shouldShow) {
|
|
currentEdgeExistMap_1[edge.id] = false;
|
|
graph.removeItem(edge.id);
|
|
} else if (!exist && shouldShow) {
|
|
currentEdgeExistMap_1[edge.id] = true;
|
|
graph.addItem('edge', edge);
|
|
}
|
|
});
|
|
}
|
|
} else {
|
|
if (filterItemTypes.includes('node')) {
|
|
graph.getNodes().forEach(function (node) {
|
|
var model = node.getModel();
|
|
if (shouldIgnore_1 === null || shouldIgnore_1 === void 0 ? void 0 : shouldIgnore_1('node', model, {
|
|
min: minDate_1,
|
|
max: maxDate_1
|
|
})) return;
|
|
var date = +((getDate_1 === null || getDate_1 === void 0 ? void 0 : getDate_1(model)) || model.date);
|
|
if (date < minDate_1 || date > maxDate_1) {
|
|
graph.hideItem(node);
|
|
} else {
|
|
graph.showItem(node);
|
|
}
|
|
});
|
|
}
|
|
if (this.get('filterEdge') || filterItemTypes.includes('edge')) {
|
|
graph.getEdges().forEach(function (edge) {
|
|
var model = edge.getModel();
|
|
if (shouldIgnore_1 === null || shouldIgnore_1 === void 0 ? void 0 : shouldIgnore_1('edge', model, {
|
|
min: trendData[min].date,
|
|
max: trendData[max].date
|
|
})) return;
|
|
var date = +((getDate_1 === null || getDate_1 === void 0 ? void 0 : getDate_1(model)) || model.date);
|
|
if (date < trendData[min].date || date > trendData[max].date) {
|
|
graph.hideItem(edge);
|
|
} else {
|
|
var sourceVisible = edge.getSource().isVisible();
|
|
var targetVisible = edge.getTarget().isVisible();
|
|
if (sourceVisible && targetVisible) graph.showItem(edge);
|
|
}
|
|
});
|
|
}
|
|
}
|
|
}
|
|
};
|
|
TimeBar.prototype.initEvent = function () {
|
|
var graph = this.get('graph');
|
|
// 图数据变化,更新时间轴的原始数据
|
|
graph.on('afterchangedata', this.changeData);
|
|
// 图渲染,触发时间轴筛选
|
|
graph.on('afterrender', this.afterrenderListener);
|
|
// 时间轴的值发生改变的事件,触发筛选
|
|
graph.on(_constant.VALUE_CHANGE, this.valueChangeListener);
|
|
};
|
|
TimeBar.prototype.destroy = function () {
|
|
var graph = this.get('graph');
|
|
graph.off('afterchangedata', this.changeData);
|
|
graph.off('afterrender', this.afterrenderListener);
|
|
graph.off(_constant.VALUE_CHANGE, this.valueChangeListener);
|
|
var timebar = this.get('timebar');
|
|
if (timebar && timebar.destory) {
|
|
timebar.destory();
|
|
}
|
|
_super.prototype.destroy.call(this);
|
|
var timeBarContainer = this.get('timeBarContainer');
|
|
if (timeBarContainer) {
|
|
var container = this.get('container');
|
|
if (!container) {
|
|
container = this.get('graph').get('container');
|
|
}
|
|
if ((0, _util.isString)(container)) {
|
|
container = document.getElementById(container);
|
|
}
|
|
if (container === timeBarContainer) {
|
|
container = container.parentElement;
|
|
}
|
|
container.removeChild(timeBarContainer);
|
|
}
|
|
};
|
|
return TimeBar;
|
|
}(_base.default);
|
|
var _default = exports.default = TimeBar; |