feat(图表): 指标卡支持联动并支持在嵌入时将过滤参数向外传递

This commit is contained in:
wangjiahao
2025-03-21 16:18:05 +08:00
committed by 王嘉豪
parent 7c814454fe
commit bc169bc375
4 changed files with 102 additions and 46 deletions

View File

@@ -44,6 +44,7 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.*;
import java.util.concurrent.atomic.AtomicReference;
import java.util.stream.Collectors;
/**
@@ -223,11 +224,17 @@ public class ChartDataManage {
}
List<ChartExtFilterDTO> filters = new ArrayList<>();
FilterTreeObj customLinkageFilter = null;
// 联动条件
if (ObjectUtils.isNotEmpty(chartExtRequest.getLinkageFilters())) {
filters.addAll(chartExtRequest.getLinkageFilters());
for(ChartExtFilterDTO linkageFilter: chartExtRequest.getLinkageFilters()) {
if (3 == linkageFilter.getFilterType()) {
customLinkageFilter = linkageFilter.getCustomFilter();
} else {
filters.add(linkageFilter);
}
}
}
// 外部参数条件
if (ObjectUtils.isNotEmpty(chartExtRequest.getOuterParamsFilters())) {
filters.addAll(chartExtRequest.getOuterParamsFilters());
@@ -355,6 +362,10 @@ public class ChartDataManage {
}
// 字段过滤器
FilterTreeObj fieldCustomFilter = view.getCustomFilter();
// 指标表联动时 使用的CustomFilter
if (customLinkageFilter != null) {
fieldCustomFilter = customLinkageFilter;
}
chartFilterTreeService.searchFieldAndSet(fieldCustomFilter);
fieldCustomFilter = chartFilterTreeService.charReplace(fieldCustomFilter);
// 获取dsMap,union sql

View File

@@ -392,18 +392,21 @@ const calcData = (view, callback) => {
const trackClick = trackAction => {
const param = state.pointParam
if (!param?.data?.dimensionList) {
if (!param?.data?.dimensionList && !param?.data?.quotaList) {
return
}
const linkageParam = {
option: 'linkage',
innerType: 'indicator',
name: state.pointParam.data.name,
viewId: view.value.id,
dimensionList: state.pointParam.data.dimensionList,
quotaList: state.pointParam.data.quotaList
quotaList: state.pointParam.data.quotaList,
customFilter: state.pointParam.data.customFilter
}
const jumpParam = {
option: 'jump',
innerType: 'indicator',
name: state.pointParam.data.name,
viewId: view.value.id,
dimensionList: state.pointParam.data.dimensionList,
@@ -413,10 +416,12 @@ const trackClick = trackAction => {
const clickParams = {
option: 'pointClick',
innerType: 'indicator',
name: state.pointParam.data.name,
viewId: view.value.id,
dimensionList: state.pointParam.data.dimensionList,
quotaList: state.pointParam.data.quotaList
quotaList: state.pointParam.data.quotaList,
customFilter: state.pointParam.data.customFilter
}
switch (trackAction) {
@@ -477,6 +482,10 @@ const trackMenu = computed(() => {
return trackMenuInfo
})
const showCursor = computed(() => {
return trackMenu.value.length || embeddedCallBack.value === 'yes'
})
const pointClickTrans = () => {
if (embeddedCallBack.value === 'yes') {
trackClick('pointClick')
@@ -516,11 +525,10 @@ const onPointClick = () => {
// 模拟点击
const params = {
data: {
data: {
name: axis.name,
dimensionList: [],
quotaList: view.value.yAxis
}
name: axis.name,
dimensionList: view.value.xAxis,
quotaList: view.value.yAxis,
customFilter: view.value.customFilter
}
}
action(params)
@@ -534,7 +542,7 @@ defineExpose({
</script>
<template>
<div :style="contentStyle" @click="onPointClick">
<div :class="{ 'menu-point': showCursor }" :style="contentStyle" @click="onPointClick">
<view-track-bar
ref="viewTrack"
:track-menu="trackMenu"
@@ -554,4 +562,8 @@ defineExpose({
</div>
</template>
<style scoped lang="less"></style>
<style scoped lang="less">
.menu-point {
cursor: pointer;
}
</style>

View File

@@ -1005,11 +1005,19 @@ export const dvMainStore = defineStore('dataVisualization', {
}
const preActiveComponentIds = []
const checkQDList = [...data.dimensionList, ...data.quotaList]
const customFilterInfo = data.customFilter
for (let indexOuter = 0; indexOuter < this.componentData.length; indexOuter++) {
const element = this.componentData[indexOuter]
if (element.id !== viewId) {
if (['UserView', 'VQuery'].includes(element.component)) {
this.trackFilterCursor(element, checkQDList, trackInfo, preActiveComponentIds, viewId)
this.trackFilterCursor(
element,
checkQDList,
trackInfo,
preActiveComponentIds,
viewId,
customFilterInfo
)
this.componentData[indexOuter] = element
} else if (element.component === 'Group') {
element.propValue?.forEach((groupItem, index) => {
@@ -1018,7 +1026,8 @@ export const dvMainStore = defineStore('dataVisualization', {
checkQDList,
trackInfo,
preActiveComponentIds,
viewId
viewId,
customFilterInfo
)
element.propValue[index] = groupItem
})
@@ -1030,7 +1039,8 @@ export const dvMainStore = defineStore('dataVisualization', {
checkQDList,
trackInfo,
preActiveComponentIds,
viewId
viewId,
customFilterInfo
)
tabItem.componentData[index] = tabComponent
})
@@ -1314,11 +1324,25 @@ export const dvMainStore = defineStore('dataVisualization', {
})
}
},
trackFilterCursor(element, checkQDList, trackInfo, preActiveComponentIds, viewId) {
trackFilterCursor(
element,
checkQDList,
trackInfo,
preActiveComponentIds,
viewId,
customFilter?
) {
let currentFilters = element.linkageFilters || [] // 当前联动filter
if (['table-info', 'table-normal'].includes(element.innerType)) {
currentFilters = []
}
if (currentFilters.length) {
for (let i = currentFilters.length - 1; i >= 0; i--) {
if (currentFilters[i].filterType === 3) {
currentFilters.splice(i, 1)
}
}
}
// 联动的图表情况历史条件
// const currentFilters = []
checkQDList.forEach(QDItem => {
@@ -1330,38 +1354,46 @@ export const dvMainStore = defineStore('dataVisualization', {
const targetInfoArray = targetInfo.split('#')
const targetViewId = targetInfoArray[0] // 目标图表
if (element.component === 'UserView' && element.id === targetViewId) {
// 如果目标图表 和 当前循环组件id相等 则进行条件增减
const targetFieldId = targetInfoArray[1] // 目标图表列ID
let condition
if (QDItem.timeValue && Array.isArray(QDItem.timeValue)) {
// 如果dimension.timeValue存在值且是数组 目前判断为是时间组件
condition = {
fieldId: targetFieldId,
operator: 'between',
value: QDItem.timeValue,
viewIds: [targetViewId],
sourceViewId: viewId
}
// 如果含有customFilter 仅加入customFilter
if (customFilter) {
currentFilters.push({
filterType: 3,
customFilter: customFilter
})
} else {
condition = {
fieldId: targetFieldId,
operator: 'eq',
value: [QDItem.value],
viewIds: [targetViewId],
sourceViewId: viewId
// 如果目标图表 和 当前循环组件id相等 则进行条件增减
const targetFieldId = targetInfoArray[1] // 目标图表列ID
let condition
if (QDItem.timeValue && Array.isArray(QDItem.timeValue)) {
// 如果dimension.timeValue存在值且是数组 目前判断为是时间组件
condition = {
fieldId: targetFieldId,
operator: 'between',
value: QDItem.timeValue,
viewIds: [targetViewId],
sourceViewId: viewId
}
} else {
condition = {
fieldId: targetFieldId,
operator: 'eq',
value: [QDItem.value],
viewIds: [targetViewId],
sourceViewId: viewId
}
}
}
let j = currentFilters.length
while (j--) {
const filter = currentFilters[j]
// 兼容性准备 viewIds 只会存放一个值
if (targetFieldId === filter.fieldId && filter.viewIds.includes(targetViewId)) {
currentFilters.splice(j, 1)
let j = currentFilters.length
while (j--) {
const filter = currentFilters[j]
// 兼容性准备 viewIds 只会存放一个值
if (targetFieldId === filter.fieldId && filter.viewIds.includes(targetViewId)) {
currentFilters.splice(j, 1)
}
}
// 不存在该条件 且 条件有效 直接保存该条件
// !filterExist && vValid && currentFilters.push(condition)
currentFilters.push(condition)
}
// 不存在该条件 且 条件有效 直接保存该条件
// !filterExist && vValid && currentFilters.push(condition)
currentFilters.push(condition)
preActiveComponentIds.includes(element.id) || preActiveComponentIds.push(element.id)
}
if (element.component === 'VQuery') {

View File

@@ -4,6 +4,7 @@ package io.dataease.extensions.view.dto;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.fasterxml.jackson.annotation.JsonIgnore;
import io.dataease.extensions.datasource.dto.DatasetTableFieldDTO;
import io.dataease.extensions.view.filter.FilterTreeObj;
import lombok.Data;
@@ -25,6 +26,6 @@ public class ChartExtFilterDTO {
private String datePattern;
@JsonIgnore
private List<String> originValue;
private int filterType;// 0-过滤组件1-下钻2-联动,外部参数
private int filterType;// 0-过滤组件1-下钻2-联动,外部参数 3-联动 自定义参数
private FilterTreeObj customFilter;
}