) => {
}
return result
}
+
+export function drawImage() {
+ const img = new Image()
+ const { x, y, width, height, fieldValue } = this.meta
+ img.src = fieldValue as string
+ img.setAttribute('crossOrigin', 'anonymous')
+ img.onload = () => {
+ !this.cfg.children && (this.cfg.children = [])
+ const { width: imgWidth, height: imgHeight } = img
+ const ratio = Math.max(imgWidth / width, imgHeight / height)
+ // 不铺满,部分留白
+ const imgShowWidth = (imgWidth / ratio) * 0.8
+ const imgShowHeight = (imgHeight / ratio) * 0.8
+ this.textShape = this.addShape('image', {
+ attrs: {
+ x: x + (imgShowWidth < width ? (width - imgShowWidth) / 2 : 0),
+ y: y + (imgShowHeight < height ? (height - imgShowHeight) / 2 : 0),
+ width: imgShowWidth,
+ height: imgShowHeight,
+ img
+ }
+ })
+ }
+}
diff --git a/frontend/src/data-visualization/chart/components/js/panel/types/impl/g2plot.ts b/frontend/src/data-visualization/chart/components/js/panel/types/impl/g2plot.ts
index c8269b5..dd32468 100644
--- a/frontend/src/data-visualization/chart/components/js/panel/types/impl/g2plot.ts
+++ b/frontend/src/data-visualization/chart/components/js/panel/types/impl/g2plot.ts
@@ -170,7 +170,7 @@ export abstract class G2PlotChartView<
public setupSeriesColor(chart: ChartObj, data?: any[]): ChartBasicStyle['seriesColor'] {
return setupSeriesColor(chart, data)
}
-
+ // eslint-disable-next-line
public setupSubSeriesColor(chart: ChartObj, data?: any[]): ChartBasicStyle['seriesColor'] {
return undefined
}
@@ -191,8 +191,8 @@ export abstract class G2PlotChartView<
return addConditionsStyleColorToData(chart, data)
}
- protected configEmptyDataStyle(newChart, newData: any[], container: string) {
- configEmptyDataStyle(newChart, newData, container)
+ protected configEmptyDataStyle(newData, container, newChart?, content?) {
+ configEmptyDataStyle(newData, container, newChart, content)
}
/**
diff --git a/frontend/src/data-visualization/chart/components/js/panel/types/impl/l7.ts b/frontend/src/data-visualization/chart/components/js/panel/types/impl/l7.ts
index 24bd6aa..093ffd1 100644
--- a/frontend/src/data-visualization/chart/components/js/panel/types/impl/l7.ts
+++ b/frontend/src/data-visualization/chart/components/js/panel/types/impl/l7.ts
@@ -107,8 +107,8 @@ export abstract class L7ChartView<
return options
}
- protected configZoomButton(chart: Chart, plot: S) {
- configL7Zoom(chart, plot)
+ protected configZoomButton(chart: Chart, plot: S, mapKey?: any) {
+ configL7Zoom(chart, plot, mapKey)
}
protected configLabel(chart: Chart, options: O): O {
diff --git a/frontend/src/data-visualization/chart/components/js/panel/types/impl/s2.ts b/frontend/src/data-visualization/chart/components/js/panel/types/impl/s2.ts
index 3bcc669..2ec21e4 100644
--- a/frontend/src/data-visualization/chart/components/js/panel/types/impl/s2.ts
+++ b/frontend/src/data-visualization/chart/components/js/panel/types/impl/s2.ts
@@ -136,18 +136,18 @@ export abstract class S2ChartView extends AntVAbstractCha
if (duration > 300) {
return
}
+ const canvasPosition = canvas.getBoundingClientRect()
+ const touchPosition = [e.changedTouches[0].pageX, e.changedTouches[0].pageY]
+ const relativePosition = [
+ touchPosition[0] - canvasPosition.x,
+ touchPosition[1] - canvasPosition.y
+ ]
+ const shape = s2Instance.container.getShape(relativePosition[0], relativePosition[1])
+ // 图片单元格,表头排序图标点击放大图片
+ if (shape.cfg?.type === 'image') {
+ return
+ }
const callback = () => {
- const canvasPosition = canvas.getBoundingClientRect()
- const touchPosition = [e.changedTouches[0].pageX, e.changedTouches[0].pageY]
- const relativePosition = [
- touchPosition[0] - canvasPosition.x,
- touchPosition[1] - canvasPosition.y
- ]
- const shape = s2Instance.container.getShape(relativePosition[0], relativePosition[1])
- // 图片单元格点击放大图片
- if (shape.cfg?.parent.constructor.name === 'ImageCell') {
- return
- }
e.preventDefault()
e.stopPropagation()
if (shape) {
diff --git a/frontend/src/data-visualization/chart/components/js/util.ts b/frontend/src/data-visualization/chart/components/js/util.ts
index 33984be..1e7af19 100644
--- a/frontend/src/data-visualization/chart/components/js/util.ts
+++ b/frontend/src/data-visualization/chart/components/js/util.ts
@@ -1,4 +1,4 @@
-import { isEmpty, isNumber } from 'lodash-es'
+import { isNumber } from 'lodash-es'
import { DEFAULT_TITLE_STYLE } from '../editor/util/chart'
import { equalsAny, includesAny } from '../editor/util/StringUtils'
import { FeatureCollection } from '@antv/l7plot/dist/esm/plots/choropleth/types'
@@ -12,6 +12,8 @@ import { ElMessage } from 'element-plus-secondary'
import { useI18n } from '@/data-visualization/hooks/web/useI18n'
import { useLinkStoreWithOut } from '@/data-visualization/store/modules/link'
import { useAppStoreWithOut } from '@/data-visualization/store/modules/app'
+import { Decimal } from 'decimal.js'
+
const appStore = useAppStoreWithOut()
const isDataEaseBi = computed(() => appStore.getIsDataEaseBi)
@@ -283,17 +285,23 @@ export function handleEmptyDataStrategy(chart: Chart, opt
}
return options
}
- const { yAxis, xAxisExt, extStack } = chart
+ const { yAxis, xAxisExt, extStack, extBubble } = chart
const multiDimension = yAxis?.length >= 2 || xAxisExt?.length > 0 || extStack?.length > 0
switch (strategy) {
case 'breakLine': {
- if (multiDimension) {
- // 多维度保持空
- if (isChartMix) {
- for (let i = 0; i < data.length; i++) {
- handleBreakLineMultiDimension(data[i] as Record[])
+ if (isChartMix) {
+ if (data[0]) {
+ if (xAxisExt?.length > 0 || extStack?.length > 0) {
+ handleBreakLineMultiDimension(data[0] as Record[])
}
- } else {
+ }
+ if (data[1]) {
+ if (extBubble?.length > 0) {
+ handleBreakLineMultiDimension(data[1] as Record[])
+ }
+ }
+ } else {
+ if (multiDimension) {
handleBreakLineMultiDimension(data)
}
}
@@ -303,22 +311,27 @@ export function handleEmptyDataStrategy(chart: Chart, opt
}
}
case 'setZero': {
- if (multiDimension) {
- // 多维度置0
- if (isChartMix) {
- for (let i = 0; i < data.length; i++) {
- handleSetZeroMultiDimension(data[i] as Record[])
+ if (isChartMix) {
+ if (data[0]) {
+ if (xAxisExt?.length > 0 || extStack?.length > 0) {
+ handleSetZeroMultiDimension(data[0] as Record[])
+ } else {
+ handleSetZeroSingleDimension(data[0] as Record[])
+ }
+ }
+ if (data[1]) {
+ if (extBubble?.length > 0) {
+ handleSetZeroMultiDimension(data[1] as Record[], true)
+ } else {
+ handleSetZeroSingleDimension(data[1] as Record[], true)
}
- } else {
- handleSetZeroMultiDimension(data)
}
} else {
- // 单维度置0
- if (isChartMix) {
- for (let i = 0; i < data.length; i++) {
- handleSetZeroSingleDimension(data[i] as Record[])
- }
+ if (multiDimension) {
+ // 多维度置0
+ handleSetZeroMultiDimension(data)
} else {
+ // 单维度置0
handleSetZeroSingleDimension(data)
}
}
@@ -364,7 +377,7 @@ function handleBreakLineMultiDimension(data) {
})
}
-function handleSetZeroMultiDimension(data: Record[]) {
+function handleSetZeroMultiDimension(data: Record[], isExt = false) {
const dimensionInfoMap = new Map()
const subDimensionSet = new Set()
const quotaMap = new Map()
@@ -372,6 +385,9 @@ function handleSetZeroMultiDimension(data: Record[]) {
const item = data[i]
if (item.value === null) {
item.value = 0
+ if (isExt) {
+ item.valueExt = 0
+ }
}
const dimensionInfo = dimensionInfoMap.get(item.field)
if (dimensionInfo) {
@@ -388,12 +404,17 @@ function handleSetZeroMultiDimension(data: Record[]) {
let subInsertIndex = 0
subDimensionSet.forEach(dimension => {
if (!dimensionInfo.set.has(dimension)) {
- data.splice(dimensionInfo.index + insertCount + subInsertIndex, 0, {
+ const _temp = {
field,
value: 0,
category: dimension,
quotaList: quotaMap.get(dimension as string)
- })
+ } as any
+ if (isExt) {
+ _temp.valueExt = 0
+ }
+
+ data.splice(dimensionInfo.index + insertCount + subInsertIndex, 0, _temp)
}
subInsertIndex++
})
@@ -402,10 +423,14 @@ function handleSetZeroMultiDimension(data: Record[]) {
})
}
-function handleSetZeroSingleDimension(data: Record[]) {
+function handleSetZeroSingleDimension(data: Record[], isExt = false) {
data.forEach(item => {
if (item.value === null) {
- item.value = 0
+ if (!isExt) {
+ item.value = 0
+ } else {
+ item.valueExt = 0
+ }
}
})
}
@@ -489,7 +514,7 @@ const getExcelDownloadRequest = (data, type?) => {
const tableRow = JSON.parse(JSON.stringify(data.tableRow))
const excelHeader = fields.map(item => item.chartShowName ?? item.name)
const excelTypes = fields.map(item => item.deType)
- const excelHeaderKeys = fields.map(item => item.dataeaseName)
+ const excelHeaderKeys = fields.map(item => item.gisbiName)
let excelData = tableRow.map(item => excelHeaderKeys.map(i => item[i]))
let detailFields = []
if (data.detailFields?.length) {
@@ -497,7 +522,7 @@ const getExcelDownloadRequest = (data, type?) => {
return {
name: item.name,
deType: item.deType,
- dataeaseName: item.dataeaseName
+ gisbiName: item.gisbiName
}
})
excelData = tableRow.map(item => {
@@ -505,7 +530,7 @@ const getExcelDownloadRequest = (data, type?) => {
if (i === 'detail' && !item[i] && Array.isArray(item['details'])) {
const arr = item['details']
if (arr?.length) {
- return arr.map(ele => detailFields.map(field => ele[field.dataeaseName]))
+ return arr.map(ele => detailFields.map(field => ele[field.gisbiName]))
}
return null
}
@@ -522,8 +547,20 @@ const getExcelDownloadRequest = (data, type?) => {
}
}
-export const exportExcelDownload = (chart, callBack?) => {
- const excelName = chart.title
+function getChartExcelTitle(preFix, viewTitle) {
+ const now = new Date()
+ const pad = n => n.toString().padStart(2, '0')
+ const year = now.getFullYear()
+ const month = pad(now.getMonth() + 1) // 月份从 0 开始
+ const day = pad(now.getDate())
+ const hour = pad(now.getHours())
+ const minute = pad(now.getMinutes())
+ const second = pad(now.getSeconds())
+ return `${preFix}_${viewTitle}_${year}${month}${day}_${hour}${minute}${second}`
+}
+
+export const exportExcelDownload = (chart, preFix, callBack?) => {
+ const excelName = getChartExcelTitle(preFix, chart.title)
let request: any = {
proxy: null,
dvId: chart.sceneId,
@@ -586,18 +623,21 @@ export const exportExcelDownload = (chart, callBack?) => {
}
export const copyString = (content: string, notify = false) => {
- const clipboard = navigator.clipboard || {
- writeText: data => {
- return new Promise(resolve => {
- const textareaDom = document.createElement('textarea')
- textareaDom.setAttribute('style', 'z-index: -1;position: fixed;opacity: 0;')
- textareaDom.value = data
- document.body.appendChild(textareaDom)
- textareaDom.select()
- document.execCommand('copy')
- textareaDom.remove()
- resolve()
- })
+ let clipboard = navigator.clipboard as Pick
+ if (!clipboard || window.top !== window.self) {
+ clipboard = {
+ writeText: data => {
+ return new Promise(resolve => {
+ const textareaDom = document.createElement('textarea')
+ textareaDom.setAttribute('style', 'z-index: -1;position: fixed;opacity: 0;')
+ textareaDom.value = data
+ document.body.appendChild(textareaDom)
+ textareaDom.select()
+ document.execCommand('copy')
+ textareaDom.remove()
+ resolve()
+ })
+ }
}
}
clipboard.writeText(content).then(() => {
@@ -779,7 +819,7 @@ export function getColor(chart: Chart) {
}
}
-export function setupSeriesColor(chart: ChartObj, data?: any[]): ChartBasicStyle['seriesColor'] {
+export function setupSeriesColor(chart: ChartObj): ChartBasicStyle['seriesColor'] {
const result: ChartBasicStyle['seriesColor'] = []
const seriesSet = new Set()
const colors = chart.customAttr.basicStyle.colors
@@ -1152,8 +1192,10 @@ export function getLineLabelColorByCondition(conditions, value, fieldId) {
if (fieldConditions.length) {
fieldConditions.some(item => {
if (
- (item.term === 'lt' && value <= item.value) ||
- (item.term === 'gt' && value >= item.value) ||
+ (item.term === 'lt' && value < item.value) ||
+ (item.term === 'le' && value <= item.value) ||
+ (item.term === 'gt' && value > item.value) ||
+ (item.term === 'ge' && value >= item.value) ||
(item.term === 'between' && value >= item.min && value <= item.max)
) {
color = item.color
@@ -1207,3 +1249,27 @@ export const hexToRgba = (hex, alpha = 1) => {
// 返回 RGBA 格式
return `rgba(${r}, ${g}, ${b}, ${a})`
}
+
+// 安全计算数值字段的总和,使用 Decimal 避免浮点数精度问题
+export function safeDecimalSum(data, field) {
+ // 使用 reduce 累加所有行的指定字段值
+ return data
+ .reduce((acc, row) => {
+ // 将字段值转换为 Decimal 类型并累加到累加器
+ return acc.plus(new Decimal(row[field] ?? 0))
+ }, new Decimal(0))
+ .toNumber() // 最终结果转换为普通数字返回
+}
+
+// 安全计算数值字段的平均值,使用 Decimal 避免浮点数精度问题
+export function safeDecimalMean(data, field) {
+ // 如果数据为空,直接返回 0
+ if (!data.length) return 0
+ // 计算所有行的指定字段值的总和
+ const sum = data.reduce((acc, row) => {
+ // 将字段值转换为 Decimal 类型并累加到累加器
+ return acc.plus(new Decimal(row[field] ?? 0))
+ }, new Decimal(0))
+ // 将总和除以数据行数,得到平均值,并转换为普通数字返回
+ return sum.dividedBy(data.length).toNumber()
+}
diff --git a/frontend/src/data-visualization/chart/components/views/components/ChartComponentG2Plot.vue b/frontend/src/data-visualization/chart/components/views/components/ChartComponentG2Plot.vue
index 850343f..df0eef1 100644
--- a/frontend/src/data-visualization/chart/components/views/components/ChartComponentG2Plot.vue
+++ b/frontend/src/data-visualization/chart/components/views/components/ChartComponentG2Plot.vue
@@ -28,7 +28,8 @@ import { isDashboard, trackBarStyleCheck } from '@/data-visualization/utils/canv
import { useEmitt } from '@/data-visualization/hooks/web/useEmitt'
import { L7ChartView } from '@/data-visualization/chart/components/js/panel/types/impl/l7'
import { useI18n } from '@/data-visualization/hooks/web/useI18n'
-import { ExportImage,Scale } from '@antv/l7'
+import { ExportImage, Scale, Fullscreen, Control, Scene, TileLayer } from '@antv/l7'
+import { GaodeMap } from '@antv/l7-maps';
const { t } = useI18n()
const dvMainStore = dvMainStoreWithOut()
const { nowPanelTrackInfo, nowPanelJumpInfo, mobileInPc, embeddedCallBack, inMobile } =
@@ -111,7 +112,8 @@ const state = reactive({
},
linkageActiveParam: null,
pointParam: null,
- data: { fields: [] } // 图表数据
+ data: { fields: [] }, // 图表数据
+ satelliteVisible: false, // 新增卫星图层状态
})
let chartData = shallowRef>({
fields: []
@@ -333,35 +335,100 @@ const renderL7Plot = async (chart: ChartObj, chartView: L7PlotChartView, callback) => {
- mapL7Timer && clearTimeout(mapL7Timer)
+ mapL7Timer && clearTimeout(mapL7Timer);
mapL7Timer = setTimeout(async () => {
myChart = await chartView.drawChart({
chartObj: myChart,
container: containerId,
chart: chart,
action
- })
-
- // 清除已有比例尺
- if (scaleControl) {
- myChart.getScene()?.removeControl(scaleControl)
- scaleControl = null
+ });
+
+ // 清除已有比例尺
+ if (!scaleControl) {
+ scaleControl = new Scale({
+ position: 'bottomleft',
+ imperial: false
+ });
+ myChart.getScene()?.addControl(scaleControl);
}
// 创建并添加新比例尺
- scaleControl = new Scale({
- position: 'bottomleft',
- imperial: false
- })
- myChart.getScene()?.addControl(scaleControl)
- myChart?.render()
- callback?.()
- emit('resetLoading')
- }, 500)
-}
+
+ // 添加全屏控件
+ if (fullscreenControl) {
+
+ } else {
+ fullscreenControl = new Fullscreen({
+ position: 'bottomright',
+ });
+ myChart.getScene()?.addControl(fullscreenControl, 'bottomright');
+ }
+
+
+ // ====== 使用高德地图原生API实现卫星图层切换 ======
+ let satelliteLayer: any = null;
+ let isSatelliteVisible = false;
+
+ class SatelliteControl extends Control {
+ protected onAdd() {
+ const btn = document.createElement('button');
+ btn.className = 'l7-control-button l7-satellite-control';
+ btn.innerHTML = '卫星';
+ // btn.title = '切换到卫星视图';
+ btn.style.backgroundColor = '#000';
+ btn.style.color = '#fff';
+ btn.style.padding = '2px';
+ btn.style.borderRadius = '4px';
+ btn.style.cursor = 'pointer'
+ btn.style.fontSize = '11px';
+ const scene = myChart.getScene()
+ // 确保地图加载完成
+ scene.on('loaded', () => {
+ // 创建高德卫星图层
+ satelliteLayer = new window.AMap.TileLayer.Satellite();
+ btn.onclick = () => {
+ isSatelliteVisible = !isSatelliteVisible;
+
+ if (isSatelliteVisible) {
+ // 使用 scene.addLayer 方法添加卫星图层
+ btn.style.backgroundColor = '#409eff';
+ scene.map.add(satelliteLayer)
+ } else {
+ // 使用 scene.removeLayer 方法移除卫星图层
+ btn.style.backgroundColor = '#000';
+ scene.map.remove(satelliteLayer)
+
+ }
+ };
+ });
+
+ return btn;
+ }
+ }
+
+ // 添加控件到地图
+ // 移除之前的卫星控件(如果存在)
+ if (satelliteControlInstance) {
+
+ } else {
+ // 添加新的卫星控件到地图
+ satelliteControlInstance = new SatelliteControl({ position: 'bottomright' });
+ myChart.getScene()?.addControl(satelliteControlInstance);
+ }
+
+
+ // ====== 修复完成 ======
+
+ myChart?.render();
+ callback?.();
+ emit('resetLoading');
+ }, 500);
+};
const pointClickTrans = () => {
if (embeddedCallBack.value === 'yes') {
trackClick('pointClick')
@@ -706,15 +773,8 @@ onBeforeUnmount(() => {
@@ -726,12 +786,32 @@ onBeforeUnmount(() => {
width: 100%;
height: 100%;
z-index: 0;
+
.canvas-content {
width: 100% !important;
height: 100% !important;
+
:deep(.g2-tooltip) {
position: fixed !important;
}
}
}
-
+
+:deep(.l7-button-control) {
+ background-color: #000000 !important;
+}
+
+:deep(.l7-button-control:not(:disabled):hover) {
+ background-color: #000000d5 !important;
+}
+
+:deep(.l7-button-control .l7-iconfont) {
+ fill: #fff !important;
+ color: #fff !important;
+}
+
+// :deep(.l7-control-container .l7-top) {
+// top: auto !important;
+// bottom: 133px !important;
+
+// }
diff --git a/frontend/src/data-visualization/chart/components/views/components/ChartComponentS2.vue b/frontend/src/data-visualization/chart/components/views/components/ChartComponentS2.vue
index b7fb246..9d3fced 100644
--- a/frontend/src/data-visualization/chart/components/views/components/ChartComponentS2.vue
+++ b/frontend/src/data-visualization/chart/components/views/components/ChartComponentS2.vue
@@ -16,7 +16,6 @@ import {
} from 'vue'
import { getData } from '@/api/data-visualization/chart'
import chartViewManager from '@/data-visualization/chart/components/js/panel'
-import { useAppStoreWithOut } from '@/data-visualization/store/modules/app'
import { dvMainStoreWithOut } from '@/data-visualization/store/modules/data-visualization/dvMain'
import ViewTrackBar from '@/data-visualization/components/visualization/ViewTrackBar.vue'
import { storeToRefs } from 'pinia'
@@ -125,6 +124,7 @@ const state = reactive({
imgEnlarge: false,
imgSrc: ''
})
+const PAGE_CHARTS = ['table-info', 'table-normal']
// 图表数据不用全响应式
let chartData = shallowRef>({
fields: []
@@ -133,19 +133,20 @@ let chartData = shallowRef>({
const containerId = 'container-' + showPosition.value + '-' + view.value.id + '-' + suffixId.value
const viewTrack = ref(null)
-const calcData = (view: Chart, callback, resetPageInfo = true) => {
- if (view.customAttr.basicStyle.tablePageStyle === 'general') {
+const calcData = (viewInfo: Chart, callback, resetPageInfo = true) => {
+ if (viewInfo.customAttr.basicStyle.tablePageStyle === 'general') {
if (state.currentPageSize !== 0) {
- view.chartExtRequest.pageSize = state.currentPageSize
+ viewInfo.chartExtRequest.pageSize = state.currentPageSize
+ state.pageInfo.pageSize = state.currentPageSize
+ } else {
+ viewInfo.chartExtRequest.pageSize = state.pageInfo.pageSize
}
} else {
- if(view.chartExtRequest != undefined){
- delete view.chartExtRequest.pageSize
- }
+ delete viewInfo.chartExtRequest?.pageSize
}
- if (view.tableId || view['dataFrom'] === 'template') {
+ if (viewInfo.tableId || viewInfo['dataFrom'] === 'template') {
isError.value = false
- const v = JSON.parse(JSON.stringify(view))
+ const v = JSON.parse(JSON.stringify(viewInfo))
getData(v)
.then(res => {
if (res.code && res.code !== 0) {
@@ -154,7 +155,7 @@ const calcData = (view: Chart, callback, resetPageInfo = true) => {
} else {
chartData.value = res?.data as Partial
state.totalItems = res?.totalItems
- dvMainStore.setViewDataDetails(view.id, res)
+ dvMainStore.setViewDataDetails(viewInfo.id, res)
emit('onDrillFilters', res?.drillFilters)
renderChart(res as unknown as Chart, resetPageInfo)
}
@@ -225,7 +226,7 @@ const renderChart = (viewInfo: Chart, resetPageInfo: boolean) => {
nextTick(() => debounceRender(resetPageInfo))
}
-const debounceRender = debounce(resetPageInfo => {
+const debounceRender = debounce(() => {
myChart?.facet?.timer?.stop()
myChart?.facet?.cancelScrollFrame()
myChart?.destroy()
@@ -250,19 +251,13 @@ const debounceRender = debounce(resetPageInfo => {
const setupPage = (chart: ChartObj, resetPageInfo?: boolean) => {
const customAttr = chart.customAttr
- if (chart.type !== 'table-info' || customAttr.basicStyle.tablePageMode !== 'page') {
+ if (!PAGE_CHARTS.includes(chart.type) || customAttr.basicStyle.tablePageMode !== 'page') {
state.showPage = false
return
}
const pageInfo = state.pageInfo
state.pageStyle = customAttr.basicStyle.tablePageStyle
- if (state.pageStyle === 'general') {
- if (state.currentPageSize === 0) {
- state.currentPageSize = pageInfo.pageSize
- } else {
- pageInfo.pageSize = state.currentPageSize
- }
- } else {
+ if (state.pageStyle !== 'general') {
pageInfo.pageSize = customAttr.basicStyle.tablePageSize ?? 20
}
if (state.totalItems > state.pageInfo.pageSize || state.pageStyle === 'general') {
@@ -274,6 +269,7 @@ const setupPage = (chart: ChartObj, resetPageInfo?: boolean) => {
if (resetPageInfo) {
state.pageInfo.currentPage = 1
}
+ dvMainStore.setViewPageInfo(chart.id, state.pageInfo)
}
const mouseMove = () => {
@@ -295,7 +291,8 @@ const initScroll = () => {
myChart &&
senior?.scrollCfg?.open &&
chartData.value.tableRow?.length &&
- (view.value.type === 'table-normal' || (view.value.type === 'table-info' && !state.showPage))
+ PAGE_CHARTS.includes(props.view.type) &&
+ !state.showPage
) {
// 防止多次渲染
myChart.facet.timer?.stop()
@@ -339,7 +336,7 @@ const initScroll = () => {
}
const showPage = computed(() => {
- if (view.value.type !== 'table-info') {
+ if (!PAGE_CHARTS.includes(view.value.type)) {
return false
}
return state.showPage
@@ -357,6 +354,7 @@ const handleCurrentChange = pageNum => {
const handlePageSizeChange = pageSize => {
if (state.pageStyle === 'general') {
state.currentPageSize = pageSize
+ emitter.emit('set-page-size', pageSize)
}
let extReq = { pageSize: pageSize }
if (chartExtRequest.value) {
@@ -403,10 +401,9 @@ const action = param => {
state.trackBarStyle.top = barStyleTemp.top + 'px'
}
- viewTrack.value.trackButtonClick()
+ viewTrack.value.trackButtonClick(view.value.id)
}
}
-const appStore = useAppStoreWithOut()
const trackClick = trackAction => {
const param = state.pointParam
@@ -683,12 +680,6 @@ const autoStyle = computed(() => {
}
})
-const autoHeightStyle = computed(() => {
- return {
- height: 20 * scale.value + 8 + 'px'
- }
-})
-
const tabStyle = computed(() => [
{ '--de-pager-color': canvasStyleData.value.component.seniorStyleSetting?.pagerColor }
])
@@ -745,7 +736,7 @@ const tablePageClass = computed(() => {
v-else
class="table-page-content"
layout="prev, pager, next, sizes, jumper"
- v-model:page-size="state.currentPageSize"
+ v-model:page-size="state.pageInfo.pageSize"
v-model:current-page="state.pageInfo.currentPage"
:pager-count="5"
:total="state.pageInfo.total"
diff --git a/frontend/src/data-visualization/chart/components/views/components/ChartError.vue b/frontend/src/data-visualization/chart/components/views/components/ChartError.vue
index ac3325a..39252c9 100644
--- a/frontend/src/data-visualization/chart/components/views/components/ChartError.vue
+++ b/frontend/src/data-visualization/chart/components/views/components/ChartError.vue
@@ -4,7 +4,7 @@ import { ref } from 'vue'
const { t } = useI18n()
-const props = defineProps({
+defineProps({
errMsg: {
type: String,
required: true,
diff --git a/frontend/src/data-visualization/chart/components/views/components/DrillPath.vue b/frontend/src/data-visualization/chart/components/views/components/DrillPath.vue
index b40a787..3f22f80 100644
--- a/frontend/src/data-visualization/chart/components/views/components/DrillPath.vue
+++ b/frontend/src/data-visualization/chart/components/views/components/DrillPath.vue
@@ -1,7 +1,6 @@
diff --git a/frontend/src/data-visualization/chart/components/views/components/ScrollShadow.vue b/frontend/src/data-visualization/chart/components/views/components/ScrollShadow.vue
new file mode 100644
index 0000000..9f96d4c
--- /dev/null
+++ b/frontend/src/data-visualization/chart/components/views/components/ScrollShadow.vue
@@ -0,0 +1,16 @@
+
+
+
+ tet
+
+
+
diff --git a/frontend/src/data-visualization/chart/components/views/index.vue b/frontend/src/data-visualization/chart/components/views/index.vue
index add19a2..893dbd5 100644
--- a/frontend/src/data-visualization/chart/components/views/index.vue
+++ b/frontend/src/data-visualization/chart/components/views/index.vue
@@ -33,7 +33,7 @@ import {
} from '@/data-visualization/chart/components/editor/util/chart'
import DrillPath from '@/data-visualization/chart/components/views/components/DrillPath.vue'
import { ElIcon, ElInput, ElMessage } from 'element-plus-secondary'
-// import { useFilter } from '@/data-visualization/hooks/web/useFilter'
+import { useFilter } from '@/data-visualization/hooks/web/useFilter'
import { useCache } from '@/data-visualization/hooks/web/useCache'
import { dvMainStoreWithOut } from '@/data-visualization/store/modules/data-visualization/dvMain'
@@ -54,6 +54,8 @@ import request from '@/data-visualization/config/axios'
import { store } from '@/data-visualization/store'
import { clearExtremum } from '@/data-visualization/chart/components/js/extremumUitl'
import DePreviewPopDialog from '@/data-visualization/components/visualization/DePreviewPopDialog.vue'
+import { useRoute } from 'vue-router'
+const route = useRoute()
const { wsCache } = useCache()
const chartComponent = ref()
const { t } = useI18n()
@@ -61,12 +63,13 @@ const dvMainStore = dvMainStoreWithOut()
const { emitter } = useEmitt()
const dePreviewPopDialogRef = ref(null)
let innerRefreshTimer = null
+let innerSearchCount = 0
const appStore = useAppStoreWithOut()
const appearanceStore = useAppearanceStoreWithOut()
const isDataEaseBi = computed(() => appStore.getIsDataEaseBi)
const isIframe = computed(() => appStore.getIsIframe)
-const emit = defineEmits(['onPointClick'])
+const emit = defineEmits(['onPointClick', 'onComponentEvent'])
const {
nowPanelJumpInfo,
@@ -76,11 +79,15 @@ const {
canvasStyleData,
mobileInPc,
inMobile,
- editMode,
- hiddenListStatus
+ editMode
} = storeToRefs(dvMainStore)
const props = defineProps({
+ // 公共参数集
+ commonParams: {
+ type: Object,
+ required: false
+ },
active: {
type: Boolean,
default: false
@@ -234,6 +241,7 @@ const buildInnerRefreshTimer = (
innerRefreshTimer = setInterval(() => {
clearViewLinkage()
queryData()
+ innerSearchCount++
}, timerRefreshTime)
}
}
@@ -244,14 +252,6 @@ const clearViewLinkage = () => {
useEmitt().emitter.emit('clearPanelLinkage', { viewId: element.value.id })
}
-watch(
- [() => view.value],
- () => {
- initTitle()
- },
- { deep: true }
-)
-
watch([() => scale.value], () => {
initTitle()
})
@@ -374,17 +374,29 @@ const chartClick = param => {
// 仪表板和大屏所有额外过滤参数都在此处
const filter = (firstLoad?: boolean) => {
- // const { filter } = useFilter(view.value.id, firstLoad)
- // return {
- // user: wsCache.get('user.uid'),
- // filter,
- // linkageFilters: element.value.linkageFilters,
- // outerParamsFilters: element.value.outerParamsFilters,
- // webParamsFilters: element.value.webParamsFilters,
- // drill: state.drillClickDimensionList,
- // resultCount: resultCount.value,
- // resultMode: resultMode.value
- // }
+ const { filter } = useFilter(view.value.id, firstLoad)
+ const result = {
+ user: wsCache.get('user.uid'),
+ filter,
+ linkageFilters: element.value.linkageFilters,
+ outerParamsFilters: element.value.outerParamsFilters,
+ webParamsFilters: element.value.webParamsFilters,
+ drill: state.drillClickDimensionList,
+ resultCount: resultCount.value,
+ resultMode: resultMode.value
+ }
+ // 定时报告相关勿动
+ if (route.path === '/preview' && route.query.taskId) {
+ const sceneId = view.value['sceneId']
+ const filterJson = window[`de-report-filter-${sceneId}`]
+ let filterObj = {}
+ if (filterJson) {
+ filterObj = JSON.parse(filterJson)
+ }
+ filterObj[view.value.id] = result
+ window[`de-report-filter-${sceneId}`] = JSON.stringify(filterObj)
+ }
+ return result
}
const onDrillFilters = param => {
@@ -457,9 +469,16 @@ const jumpClick = param => {
if (isDataEaseBi.value) {
embeddedBaseUrl = embeddedStore.baseUrl
}
+ const jumpInfoParam = `&jumpInfoParam=${encodeURIComponent(
+ Base64.encode(JSON.stringify(param))
+ )}`
+
// 内部仪表板跳转
if (jumpInfo.linkType === 'inner') {
if (jumpInfo.targetDvId) {
+ const editPreviewParams = ['canvas', 'edit-preview'].includes(showPosition.value)
+ ? '&editPreview=true'
+ : ''
const filterOuterParams = {}
const curFilter = dvMainStore.getLastViewRequestInfo(param.viewId)
const targetViewInfoList = jumpInfo.targetViewInfoList
@@ -492,13 +511,11 @@ const jumpClick = param => {
if (publicLinkStatus.value) {
// 判断是否有公共链接ID
if (jumpInfo.publicJumpId) {
- let url = `${embeddedBaseUrl}#/de-link/${
- jumpInfo.publicJumpId
- }?fromLink=true&jumpInfoParam=${encodeURIComponent(
- Base64.encode(JSON.stringify(param))
- )}`
+ let url = `${embeddedBaseUrl}#/de-link/${jumpInfo.publicJumpId}?fromLink=true&dvType=${jumpInfo.targetDvType}`
if (attachParamsInfo) {
- url = url + attachParamsInfo
+ url = url + attachParamsInfo + jumpInfoParam + editPreviewParams
+ } else {
+ url = url + '&ignoreParams=true' + jumpInfoParam + editPreviewParams
}
const currentUrl = window.location.href
localStorage.setItem('beforeJumpUrl', currentUrl)
@@ -507,11 +524,11 @@ const jumpClick = param => {
ElMessage.warning(t('visualization.public_link_tips'))
}
} else {
- let url = `${embeddedBaseUrl}#/preview?dvId=${
- jumpInfo.targetDvId
- }&fromLink=true&jumpInfoParam=${encodeURIComponent(Base64.encode(JSON.stringify(param)))}`
+ let url = `${embeddedBaseUrl}#/preview?dvId=${jumpInfo.targetDvId}&fromLink=true&dvType=${jumpInfo.targetDvType}`
if (attachParamsInfo) {
- url = url + attachParamsInfo
+ url = url + attachParamsInfo + jumpInfoParam + editPreviewParams
+ } else {
+ url = url + '&ignoreParams=true' + jumpInfoParam + editPreviewParams
}
const currentUrl = window.location.href
localStorage.setItem('beforeJumpUrl', currentUrl)
@@ -567,13 +584,13 @@ const calcData = params => {
methodName: 'calcData',
args: [
params,
- res => {
+ () => {
loading.value = false
}
]
})
} else {
- chartComponent?.value?.calcData?.(params, res => {
+ chartComponent?.value?.calcData?.(params, () => {
loading.value = false
})
}
@@ -691,10 +708,19 @@ const changeChartType = () => {
const changeDataset = () => {
checkFieldIsAllowEmpty()
}
+
+const loadPlugin = ref(false)
+
onMounted(() => {
if (!view.value.isPlugin) {
state.drillClickDimensionList = view.value?.chartExtRequest?.drill ?? []
queryData(!showPosition.value.includes('viewDialog'))
+ } else {
+ const searched = dvMainStore.firstLoadMap.includes(element.value.id)
+ const queryFilter = filter(!searched)
+ view.value['chartExtRequest'] = queryFilter
+ chartExtRequest.value = queryFilter
+ loadPlugin.value = true
}
if (!listenerEnable.value) {
return
@@ -829,7 +855,11 @@ onMounted(() => {
// 1.开启仪表板刷新 2.首次加载(searchCount =0 )3.正在请求数据 则显示加载状态
const loadingFlag = computed(() => {
- return (canvasStyleData.value.refreshViewLoading || searchCount.value === 0) && loading.value
+ return (
+ (canvasStyleData.value.refreshViewLoading ||
+ (searchCount.value === 0 && innerSearchCount === 0)) &&
+ loading.value
+ )
})
const chartAreaShow = computed(() => {
@@ -903,7 +933,7 @@ function onTitleChange() {
}
const toolTip = computed(() => {
- return props.themes === 'dark' ? 'ndark' : 'dark'
+ return props.themes === 'dark' ? 'light' : 'dark'
})
const marginBottom = computed(() => {
@@ -1033,6 +1063,14 @@ const titleTooltipWidth = computed(() => {
}
return '500px'
})
+const clearG2Tooltip = () => {
+ const g2TooltipWrapper = document.getElementById('g2-tooltip-wrapper')
+ if (g2TooltipWrapper) {
+ for (const ele of g2TooltipWrapper.children) {
+ ele.style.display = 'none'
+ }
+ }
+}
@@ -1123,7 +1161,7 @@ const titleTooltipWidth = computed(() => {
{
:themes="canvasStyleData.dashboard.themeColor"
ref="chartComponent"
:view="view"
+ :element="element"
:show-position="showPosition"
:suffixId="suffixId"
:font-family="fontFamily"
+ :common-params="commonParams"
+ @touchstart="clearG2Tooltip"
+ @onChartClick="chartClick"
+ @onPointClick="onPointClick"
+ @onDrillFilters="onDrillFilters"
+ @onJumpClick="jumpClick"
+ @onComponentEvent="() => emit('onComponentEvent')"
/>
{
:element="element"
:suffixId="suffixId"
:font-family="fontFamily"
+ :active="active"
v-else-if="
showChartView(ChartLibraryType.G2_PLOT, ChartLibraryType.L7_PLOT, ChartLibraryType.L7)
"
@@ -1212,6 +1259,7 @@ const titleTooltipWidth = computed(() => {
v-if="(!chartAreaShow || showEmpty) && !allEmptyCheck"
:themes="canvasStyleData.dashboard.themeColor"
:view-icon="view.type"
+ @touchstart="clearG2Tooltip"
>
{
overflow: hidden;
}
.title-container {
+ position: relative;
margin: 0;
width: 100%;
diff --git a/frontend/src/data-visualization/components/data-visualization/canvas/CanvasCore.vue b/frontend/src/data-visualization/components/data-visualization/canvas/CanvasCore.vue
index 1865f98..22faba3 100644
--- a/frontend/src/data-visualization/components/data-visualization/canvas/CanvasCore.vue
+++ b/frontend/src/data-visualization/components/data-visualization/canvas/CanvasCore.vue
@@ -59,7 +59,6 @@ const contextmenuStore = contextmenuStoreWithOut()
const { curComponent, dvInfo, editMode, tabMoveOutComponentId, canvasState, mainScrollTop } =
storeToRefs(dvMainStore)
const { editorMap, areaData, isCtrlOrCmdDown } = storeToRefs(composeStore)
-const emits = defineEmits(['scrollCanvasAdjust'])
const props = defineProps({
themes: {
type: String,
@@ -265,7 +264,7 @@ watch(
watch(
() => areaData.value.components.length,
- (val, oldVal) => {
+ () => {
groupAreaClickChange()
}
)
@@ -280,7 +279,7 @@ const initWatermark = (waterDomId = 'editor-canvas-main') => {
try {
if (
dvInfo.value.watermarkInfo &&
- dvInfo.value.watermarkInfo.settingContent &&
+ dvInfo.value.watermarkInfo?.settingContent &&
isMainCanvas(canvasId.value)
) {
activeWatermarkCheckUser(waterDomId, canvasId.value, curScale.value)
@@ -938,7 +937,7 @@ function removeItem(index) {
dvMainStore.removeLinkageInfo(item['id'])
if (isMainCanvas(canvasId.value)) {
// 主画布中存在隐藏组件 直接从原始componentData中进行删除
- dvMainStore.deleteComponentById(item.id)
+ dvMainStore.deleteComponentById(item.id, undefined, false)
} else {
componentData.value.splice(index, 1)
}
diff --git a/frontend/src/data-visualization/components/data-visualization/canvas/ComponentWrapper.vue b/frontend/src/data-visualization/components/data-visualization/canvas/ComponentWrapper.vue
index 0f999e7..a453c74 100644
--- a/frontend/src/data-visualization/components/data-visualization/canvas/ComponentWrapper.vue
+++ b/frontend/src/data-visualization/components/data-visualization/canvas/ComponentWrapper.vue
@@ -1,19 +1,27 @@
props.popActive || (dvMainStore.mobileInPc &&
element-loading-text="导出中..."
element-loading-background="rgba(255, 255, 255, 1)"
>
+
+
+