UNPKG

@visactor/vtable

Version:

canvas table width high performance

255 lines (248 loc) 23.1 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: !0 }), exports.Chart = exports.CHART_NUMBER_TYPE = void 0; const vrender_1 = require("./../../vrender"), vutils_1 = require("@visactor/vutils"), is_cell_hover_1 = require("../../state/hover/is-cell-hover"), active_cell_chart_list_1 = require("./active-cell-chart-list"), get_axis_config_1 = require("../../layout/chart-helper/get-axis-config"), util_1 = require("../../tools/util"); exports.CHART_NUMBER_TYPE = (0, vrender_1.genNumberType)(); class Chart extends vrender_1.Rect { constructor(isShareChartSpec, params) { if (super(params), this.type = "chart", this.activeChartInstanceLastViewBox = null, this.activeChartInstanceHoverOnMark = null, this.justShowMarkTooltip = void 0, this.justShowMarkTooltipTimer = Date.now(), this.delayRunDimensionHoverTimer = void 0, this.numberType = exports.CHART_NUMBER_TYPE, this.isShareChartSpec = isShareChartSpec, params.chartInstance) this.chartInstance = params.chartInstance; else { const chartInstance = this.chartInstance = new params.ClassType(params.spec, (0, vutils_1.merge)({}, this.attribute.tableChartOption, { renderCanvas: params.canvas, mode: "node" === this.attribute.mode ? "node" : "desktop-browser", modeParams: this.attribute.modeParams, canvasControled: !1, viewBox: { x1: 0, x2: 0, y1: 0, y2: 0 }, dpr: params.dpr, interactive: !1, animation: !1, autoFit: !1 })); chartInstance.renderSync(), chartInstance.getStage().enableDirtyBounds(), params.chartInstance = this.chartInstance = chartInstance; } } activate(table) { var _a, _b, _c, _d, _e, _f, _g, _h, _j; if (this.activeChartInstance) return; const {col: col, row: row} = this.parent, hoverColor = (0, is_cell_hover_1.getCellHoverColor)(this.parent, table), {x1: x1, y1: y1, x2: x2, y2: y2} = this.getViewBox(), clipBound = getTableBounds(col, row, table).intersect({ x1: x1 - table.scrollLeft, x2: x2 - table.scrollLeft, y1: y1 - table.scrollTop, y2: y2 - table.scrollTop }); this.attribute.ClassType.globalConfig.uniqueTooltip = !1, this.activeChartInstance = new this.attribute.ClassType(this.attribute.spec, (0, vutils_1.merge)({}, this.attribute.tableChartOption, { renderCanvas: this.attribute.canvas, mode: "desktop-browser", canvasControled: !1, viewBox: { x1: 0, x2: x2 - x1, y1: 0, y2: y2 - y1 }, dpr: table.internalProps.pixelRatio, animation: !1, interactive: !0, autoFit: !1, beforeRender: chartStage => { const stage = this.stage, ctx = chartStage.window.getContext(), stageMatrix = stage.window.getViewBoxTransform(), viewBox = stage.window.getViewBox(); ctx.inuse = !0, ctx.clearMatrix(), ctx.setTransform(stageMatrix.a, stageMatrix.b, stageMatrix.c, stageMatrix.d, stageMatrix.e, stageMatrix.f, !0), ctx.translate(viewBox.x1, viewBox.y1), ctx.setTransformForCurrent(!0), ctx.beginPath(), ctx.rect(clipBound.x1, clipBound.y1, clipBound.x2 - clipBound.x1, clipBound.y2 - clipBound.y1), ctx.clip(), ctx.clearMatrix(), table.options.canvas && !chartStage.needRender && (chartStage.pauseRender(), table.scenegraph.stage.dirtyBounds.union(this.globalAABBBounds), table.scenegraph.updateNextFrame()); }, afterRender(stage) { stage.window.getContext().inuse = !1, stage.needRender = !1, chartStage.resumeRender(); }, renderHooks: { afterClearRect(drawParams) { const {context: context, layer: layer, viewBox: viewBox} = drawParams; layer.main && drawParams.clear && hoverColor && (context.beginPath(), context.fillStyle = hoverColor, context.rect(viewBox.x1, viewBox.y1, viewBox.x2 - viewBox.x1, viewBox.y2 - viewBox.y1), context.fill()); } }, componentShowContent: (null === (_a = table.options.chartDimensionLinkage) || void 0 === _a ? void 0 : _a.showTooltip) && "scatter" !== this.attribute.spec.type ? { tooltip: { dimension: !1, mark: !0 }, crosshair: !1 } : void 0 })); const chartStage = this.activeChartInstance.getStage(), matrix = this.globalTransMatrix.clone(), stageMatrix = this.stage.window.getViewBoxTransform(); let brushChangeThrottle; matrix.multiply(stageMatrix.a, stageMatrix.b, stageMatrix.c, stageMatrix.d, stageMatrix.e, stageMatrix.f), chartStage.window.setViewBoxTransform && chartStage.window.setViewBoxTransform(matrix.a, matrix.b, matrix.c, matrix.d, matrix.e, matrix.f), this.activeChartInstance.renderSync(), null === (_c = null === (_b = table.internalProps.layoutMap) || void 0 === _b ? void 0 : _b.updateDataStateToActiveChartInstance) || void 0 === _c || _c.call(_b, this.activeChartInstance), this.activeChartInstance.on("click", (params => { var _a, _b, _c, _d; Chart.temp && (!1 === (null === (_a = this.attribute.spec.select) || void 0 === _a ? void 0 : _a.enable) ? (null === (_b = this.attribute.spec.interactions) || void 0 === _b ? void 0 : _b.find((interaction => "element-select" === interaction.type && interaction.isMultiple))) ? table.scenegraph.updateChartState(null == params ? void 0 : params.datum, "multiple-select") : table.scenegraph.updateChartState(null, void 0) : !0 === (null === (_c = this.attribute.spec.select) || void 0 === _c ? void 0 : _c.enable) && "multiple" === (null === (_d = this.attribute.spec.select) || void 0 === _d ? void 0 : _d.mode) ? table.scenegraph.updateChartState(null == params ? void 0 : params.datum, "multiple-select") : (table.scenegraph.updateChartState(null, "brush"), table.scenegraph.updateChartState(null == params ? void 0 : params.datum, "click")), (0, active_cell_chart_list_1.clearBrushingChartInstance)(table.scenegraph)); })), (null === (_d = table.options.chartDimensionLinkage) || void 0 === _d ? void 0 : _d.listenBrushChange) && (brushChangeThrottle = (0, util_1.cancellableThrottle)(table.scenegraph.updateChartState.bind(table.scenegraph), null !== (_f = null === (_e = table.options.chartDimensionLinkage) || void 0 === _e ? void 0 : _e.brushChangeDelay) && void 0 !== _f ? _f : 100), this.activeChartInstance.on("brushChange", (params => { var _a; brushChangeThrottle.throttled(null === (_a = null == params ? void 0 : params.value) || void 0 === _a ? void 0 : _a.inBrushData, "brush"); }))), this.activeChartInstance.on("brushStart", (params => { const brushingChartInstance = (0, active_cell_chart_list_1.getBrushingChartInstance)(table.scenegraph); brushingChartInstance !== this.activeChartInstance && (brushingChartInstance && (0, active_cell_chart_list_1.clearAndReleaseBrushingChartInstance)(table.scenegraph), (0, active_cell_chart_list_1.setBrushingChartInstance)(this.activeChartInstance, col, row, table.scenegraph)); })), this.activeChartInstance.on("brushEnd", (params => { var _a; null == brushChangeThrottle || brushChangeThrottle.cancel(), table.scenegraph.updateChartState(null === (_a = null == params ? void 0 : params.value) || void 0 === _a ? void 0 : _a.inBrushData, "brush"), Chart.temp = 0, setTimeout((() => { Chart.temp = 1; }), 0); })), (null === (_g = table.options.chartDimensionLinkage) || void 0 === _g ? void 0 : _g.showTooltip) && ("pie" === this.attribute.spec.type && (this.activeChartInstance.on("pointerover", { markName: "pie" }, (params => { var _a; const categoryField = this.attribute.spec.categoryField, datum = { [categoryField]: null === (_a = null == params ? void 0 : params.datum) || void 0 === _a ? void 0 : _a[categoryField] }; (0, active_cell_chart_list_1.generateChartInstanceListByViewRange)(datum, table, !1); })), this.activeChartInstance.on("pointerout", { markName: "pie" }, (params => { var _a; const categoryField = this.attribute.spec.categoryField, datum = { [categoryField]: null === (_a = null == params ? void 0 : params.datum) || void 0 === _a ? void 0 : _a[categoryField] }; (0, active_cell_chart_list_1.generateChartInstanceListByViewRange)(datum, table, !0); }))), this.activeChartInstance.on("dimensionHover", (params => { var _a, _b; if ((0, active_cell_chart_list_1.isDisabledTooltipToAllChartInstances)(table.scenegraph)) return; this.activeChartInstance.disableTooltip(!1); const dimensionInfo = null == params ? void 0 : params.dimensionInfo[0], canvasXY = null === (_a = null == params ? void 0 : params.event) || void 0 === _a ? void 0 : _a.canvas, viewport = null === (_b = null == params ? void 0 : params.event) || void 0 === _b ? void 0 : _b.viewport; if (viewport) { const xValue = dimensionInfo.data[0].series.positionToDataX(viewport.x), yValue = dimensionInfo.data[0].series.positionToDataY(viewport.y); if ("scatter" === this.attribute.spec.type) { (0, active_cell_chart_list_1.generateChartInstanceListByColumnDirection)(col, xValue, void 0, canvasXY, table, !1, !0), (0, active_cell_chart_list_1.generateChartInstanceListByRowDirection)(row, void 0, yValue, canvasXY, table, !1, !0); (0, get_axis_config_1.getAxisConfigInPivotChart)(table.rowHeaderLevelCount - 1, row, table.internalProps.layoutMap).labelHoverOnAxis && table.scenegraph.getCell(table.rowHeaderLevelCount - 1, row).firstChild.showLabelHoverOnAxis(canvasXY.y - table.getCellRelativeRect(col, row).top, yValue); (0, get_axis_config_1.getAxisConfigInPivotChart)(col, table.rowCount - table.bottomFrozenRowCount, table.internalProps.layoutMap).labelHoverOnAxis && table.scenegraph.getCell(col, table.rowCount - table.bottomFrozenRowCount).firstChild.showLabelHoverOnAxis(canvasXY.x - table.getCellRelativeRect(col, row).left, xValue); } else { let justShowMarkTooltip = !0; const preMark = this.activeChartInstanceHoverOnMark, prev_justShowMarkTooltip = this.justShowMarkTooltip; params.mark && params.datum && !Array.isArray(params.datum) ? (this.activeChartInstanceHoverOnMark = params.mark, justShowMarkTooltip = !0) : (this.activeChartInstanceHoverOnMark = null, justShowMarkTooltip = !1), this.justShowMarkTooltip = justShowMarkTooltip; let delayRunDimensionHover = !1; if (!1 !== prev_justShowMarkTooltip && !1 === justShowMarkTooltip ? (this.justShowMarkTooltipTimer = Date.now(), delayRunDimensionHover = !0) : !1 === prev_justShowMarkTooltip && !1 === justShowMarkTooltip ? delayRunDimensionHover = Date.now() - this.justShowMarkTooltipTimer < 100 : (!1 === prev_justShowMarkTooltip && !0 === justShowMarkTooltip || !0 === prev_justShowMarkTooltip && !0 === justShowMarkTooltip) && (delayRunDimensionHover = !1, this.clearDelayRunDimensionHoverTimer()), "enter" === params.action || "move" === params.action || preMark !== this.activeChartInstanceHoverOnMark) { const dimensionValue = dimensionInfo.value, indicatorsAsCol = table.options.indicatorsAsCol; if (delayRunDimensionHover ? (this.clearDelayRunDimensionHoverTimer(), this.delayRunDimensionHoverTimer = setTimeout((() => { (0, active_cell_chart_list_1.isDisabledTooltipToAllChartInstances)(table.scenegraph) || (indicatorsAsCol ? (0, active_cell_chart_list_1.generateChartInstanceListByRowDirection)(row, dimensionValue, null, canvasXY, table, justShowMarkTooltip, !1) : (0, active_cell_chart_list_1.generateChartInstanceListByColumnDirection)(col, dimensionValue, null, canvasXY, table, justShowMarkTooltip, !1)); }), 100)) : indicatorsAsCol ? (0, active_cell_chart_list_1.generateChartInstanceListByRowDirection)(row, dimensionValue, null, canvasXY, table, justShowMarkTooltip, !1) : (0, active_cell_chart_list_1.generateChartInstanceListByColumnDirection)(col, dimensionValue, null, canvasXY, table, justShowMarkTooltip, !1), indicatorsAsCol) { const series = dimensionInfo.data[0].series, width = "histogram" === this.attribute.spec.type || "line" === series.type || "area" === series.type ? 0 : series.getYAxisHelper().getBandwidth(0); let y = series.valueToPositionY(dimensionValue); const axisConfig = (0, get_axis_config_1.getAxisConfigInPivotChart)(table.rowHeaderLevelCount - 1, row, table.internalProps.layoutMap); let hoverOnLabelValue = yValue; if ("histogram" === this.attribute.spec.type) { const {series: series, datum: datum} = dimensionInfo.data[0]; if (datum.length > 0) { const rangeStartValue = datum[0][series.fieldY[0]], rangeEndValue = datum[0][series.fieldY2]; hoverOnLabelValue = rangeStartValue + " ~ " + rangeEndValue, y = (series.valueToPositionY(rangeStartValue) + series.valueToPositionY(rangeEndValue)) / 2; } } axisConfig.labelHoverOnAxis && table.scenegraph.getCell(table.rowHeaderLevelCount - 1, row).firstChild.showLabelHoverOnAxis(y + ("line" === series.type || "area" === series.type ? 0 : width / 2), hoverOnLabelValue); } else { const series = dimensionInfo.data[0].series, width = "histogram" === this.attribute.spec.type || "line" === series.type || "area" === series.type ? 0 : series.getXAxisHelper().getBandwidth(0); let x = series.valueToPositionX(dimensionValue); const axisConfig = (0, get_axis_config_1.getAxisConfigInPivotChart)(col, table.rowCount - table.bottomFrozenRowCount, table.internalProps.layoutMap); let hoverOnLabelValue = dimensionValue; if ("histogram" === this.attribute.spec.type) { const {series: series, datum: datum} = dimensionInfo.data[0]; if (datum.length > 0) { const rangeStartValue = datum[0][series.fieldX[0]], rangeEndValue = datum[0][series.fieldX2]; hoverOnLabelValue = rangeStartValue + " ~ " + rangeEndValue, x = (series.valueToPositionX(rangeStartValue) + series.valueToPositionX(rangeEndValue)) / 2; } } axisConfig.labelHoverOnAxis && table.scenegraph.getCell(col, table.rowCount - table.bottomFrozenRowCount).firstChild.showLabelHoverOnAxis(x + width / 2, hoverOnLabelValue); } } } } }))), null === (_j = (_h = table)._bindChartEvent) || void 0 === _j || _j.call(_h, this.activeChartInstance), (0, active_cell_chart_list_1.isDisabledTooltipToAllChartInstances)(table.scenegraph) && this.activeChartInstance.disableTooltip(!0); } clearDelayRunDimensionHoverTimer() { clearTimeout(this.delayRunDimensionHoverTimer), this.delayRunDimensionHoverTimer = void 0; } deactivate(table, {forceRelease: forceRelease = !1, releaseChartInstance: releaseChartInstance = !0, releaseColumnChartInstance: releaseColumnChartInstance = !0, releaseRowChartInstance: releaseRowChartInstance = !0, releaseAllChartInstance: releaseAllChartInstance = !1} = {}) { var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k; if (this.activeChartInstanceHoverOnMark = null, this.justShowMarkTooltip = void 0, this.justShowMarkTooltipTimer = Date.now(), this.clearDelayRunDimensionHoverTimer(), releaseChartInstance) { !this.activeChartInstance || !forceRelease && (0, active_cell_chart_list_1.getBrushingChartInstance)(table.scenegraph) && (0, active_cell_chart_list_1.getBrushingChartInstance)(table.scenegraph) === this.activeChartInstance || (null === (_a = this.activeChartInstance) || void 0 === _a || _a.updateViewBox({ x1: -1e3, x2: -800, y1: -1e3, y2: -800 }, !1, !1), null === (_b = this.activeChartInstance) || void 0 === _b || _b.release(), this.activeChartInstance = null); const {col: col, row: row} = this.parent; table.internalProps.layoutMap.isAxisCell(table.rowHeaderLevelCount - 1, row) && (null === (_d = null === (_c = table.scenegraph.getCell(table.rowHeaderLevelCount - 1, row).firstChild) || void 0 === _c ? void 0 : _c.hideLabelHoverOnAxis) || void 0 === _d || _d.call(_c)), table.internalProps.layoutMap.isAxisCell(col, table.rowCount - table.bottomFrozenRowCount) && (null === (_f = null === (_e = table.scenegraph.getCell(col, table.rowCount - table.bottomFrozenRowCount).firstChild) || void 0 === _e ? void 0 : _e.hideLabelHoverOnAxis) || void 0 === _f || _f.call(_e)); } else { const {col: col, row: row} = this.parent; releaseColumnChartInstance && table.internalProps.layoutMap.isAxisCell(col, table.rowCount - table.bottomFrozenRowCount) && (null === (_h = null === (_g = table.scenegraph.getCell(col, table.rowCount - table.bottomFrozenRowCount).firstChild) || void 0 === _g ? void 0 : _g.hideLabelHoverOnAxis) || void 0 === _h || _h.call(_g)), releaseRowChartInstance && table.internalProps.layoutMap.isAxisCell(table.rowHeaderLevelCount - 1, row) && (null === (_k = null === (_j = table.scenegraph.getCell(table.rowHeaderLevelCount - 1, row).firstChild) || void 0 === _j ? void 0 : _j.hideLabelHoverOnAxis) || void 0 === _k || _k.call(_j)); } releaseAllChartInstance ? (0, active_cell_chart_list_1.clearAllChartInstanceList)(table, forceRelease) : (releaseColumnChartInstance && (0, active_cell_chart_list_1.clearChartInstanceListByColumnDirection)(this.parent.col, "scatter" === this.attribute.spec.type ? this.parent.row : void 0, table, forceRelease), releaseRowChartInstance && (0, active_cell_chart_list_1.clearChartInstanceListByRowDirection)(this.parent.row, "scatter" === this.attribute.spec.type ? this.parent.col : void 0, table, forceRelease)); } updateData(data) { this.attribute.data = data; } getViewBox() { var _a, _b, _c, _d, _e, _f, _g, _h; const cellGroup = this.parent, padding = this.attribute.cellPadding, table = this.stage.table, {x1: x1, y1: y1, x2: x2, y2: y2} = cellGroup.globalAABBBounds, viewBox = { x1: Math.ceil(x1 + padding[3] + table.scrollLeft + (null !== (_b = null === (_a = table.options.viewBox) || void 0 === _a ? void 0 : _a.x1) && void 0 !== _b ? _b : 0)), x2: Math.ceil(x1 + cellGroup.attribute.width - padding[1] + table.scrollLeft + (null !== (_d = null === (_c = table.options.viewBox) || void 0 === _c ? void 0 : _c.x1) && void 0 !== _d ? _d : 0)), y1: Math.ceil(y1 + padding[0] + table.scrollTop + (null !== (_f = null === (_e = table.options.viewBox) || void 0 === _e ? void 0 : _e.y1) && void 0 !== _f ? _f : 0)), y2: Math.ceil(y1 + cellGroup.attribute.height - padding[2] + table.scrollTop + (null !== (_h = null === (_g = table.options.viewBox) || void 0 === _g ? void 0 : _g.y1) && void 0 !== _h ? _h : 0)) }; return this.activeChartInstance ? this.activeChartInstanceLastViewBox = viewBox : this.activeChartInstanceLastViewBox = null, viewBox; } } function getTableBounds(col, row, table) { var _a, _b, _c, _d, _e, _f, _g, _h; const {layoutMap: layoutMap} = table.internalProps, bodyBound = new vutils_1.Bounds, tableBound = table.scenegraph.tableGroup.globalAABBBounds; return bodyBound.x1 = tableBound.x1, bodyBound.x2 = tableBound.x2, bodyBound.y1 = tableBound.y1, bodyBound.y2 = tableBound.y2, layoutMap.isLeftBottomCorner(col, row) || layoutMap.isRightTopCorner(col, row) || layoutMap.isLeftTopCorner(col, row) || layoutMap.isRightBottomCorner(col, row) || (layoutMap.isFrozenColumn(col, row) ? (bodyBound.y1 = tableBound.y1 + table.getFrozenRowsHeight(), bodyBound.y2 = tableBound.y2 - table.getBottomFrozenRowsHeight()) : layoutMap.isFrozenRow(col, row) ? (bodyBound.x1 = tableBound.x1 + table.getFrozenColsWidth(), bodyBound.x2 = tableBound.x2 - table.getRightFrozenColsWidth()) : layoutMap.isRightFrozenColumn(col, row) ? (bodyBound.y1 = tableBound.y1 + table.getFrozenRowsHeight(), bodyBound.y2 = tableBound.y2 - table.getBottomFrozenRowsHeight()) : layoutMap.isBottomFrozenRow(col, row) ? (bodyBound.x1 = tableBound.x1 + table.getFrozenColsWidth(), bodyBound.x2 = tableBound.x2 - table.getRightFrozenColsWidth()) : layoutMap.isFrozenColumn(col, row) || layoutMap.isRightFrozenColumn(col, row) || (bodyBound.x1 = tableBound.x1 + table.getFrozenColsWidth(), bodyBound.x2 = tableBound.x2 - table.getRightFrozenColsWidth(), bodyBound.y1 = tableBound.y1 + table.getFrozenRowsHeight(), bodyBound.y2 = tableBound.y2 - table.getBottomFrozenRowsHeight())), bodyBound.x1 = bodyBound.x1 + (null !== (_b = null === (_a = table.options.viewBox) || void 0 === _a ? void 0 : _a.x1) && void 0 !== _b ? _b : 0), bodyBound.x2 = bodyBound.x2 + (null !== (_d = null === (_c = table.options.viewBox) || void 0 === _c ? void 0 : _c.x1) && void 0 !== _d ? _d : 0), bodyBound.y1 = bodyBound.y1 + (null !== (_f = null === (_e = table.options.viewBox) || void 0 === _e ? void 0 : _e.y1) && void 0 !== _f ? _f : 0), bodyBound.y2 = bodyBound.y2 + (null !== (_h = null === (_g = table.options.viewBox) || void 0 === _g ? void 0 : _g.y1) && void 0 !== _h ? _h : 0), bodyBound; } exports.Chart = Chart, Chart.temp = 1; //# sourceMappingURL=chart.js.map