Merge branch 'dev-v2' into pr@dev-v2_dzz
This commit is contained in:
commit
d1799baaf3
2
.gitignore
vendored
2
.gitignore
vendored
@ -48,3 +48,5 @@ core/core-frontend/src/assets/fsSvg.html
|
||||
/sdk/dataease-plugin-filter/
|
||||
/sdk/dataease-plugin-interface/
|
||||
/sdk/dataease-plugin-view/
|
||||
/extensions/
|
||||
.vite/
|
||||
|
||||
@ -53,3 +53,4 @@ i18n_schema_is_empty=schema \u4E3A\u7A7A\uFF01
|
||||
i18n_table_name_repeat=\u540D\u79F0\u91CD\u590D:
|
||||
i18n_sql_not_empty=sql \u4E0D\u80FD\u4E3A\u7A7A
|
||||
i18n_menu.parameter=\u7CFB\u7EDF\u53C2\u6570
|
||||
i18n_user_old_pwd_error=\u539F\u59CB\u5BC6\u7801\u9519\u8BEF
|
||||
|
||||
5
core/core-frontend/src/assets/svg/top-doc-default.svg
Normal file
5
core/core-frontend/src/assets/svg/top-doc-default.svg
Normal file
@ -0,0 +1,5 @@
|
||||
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M4 2.5C4 1.94772 4.44772 1.5 5 1.5H14.8608C14.9949 1.5 15.1234 1.55387 15.2174 1.64951L19.8566 6.36941C19.9485 6.46292 20 6.58879 20 6.7199V21.5C20 22.0523 19.5523 22.5 19 22.5H5C4.44772 22.5 4 22.0523 4 21.5V2.5Z" fill="#3370FF"/>
|
||||
<path d="M15 1.51978C15.0817 1.54345 15.1567 1.58778 15.2174 1.64952L19.8566 6.36942C19.8946 6.40806 19.9256 6.45223 19.949 6.50001H16.1351C15.5082 6.50001 15 5.99179 15 5.36488V1.51978Z" fill="#245BDB"/>
|
||||
<path d="M8.07282 10.1819H15.6546C15.745 10.1819 15.8183 10.2551 15.8183 10.3455V11.1092C15.8183 11.1995 15.745 11.2728 15.6546 11.2728H8.07282C7.98244 11.2728 7.90918 11.1995 7.90918 11.1092V10.3455C7.90918 10.2551 7.98244 10.1819 8.07282 10.1819ZM8.07282 13.4546H15.6546C15.745 13.4546 15.8183 13.5279 15.8183 13.6182V14.3819C15.8183 14.4723 15.745 14.5455 15.6546 14.5455H8.07282C7.98244 14.5455 7.90918 14.4723 7.90918 14.3819V13.6182C7.90918 13.5279 7.98244 13.4546 8.07282 13.4546ZM8.07282 16.7273H12.1092C12.1996 16.7273 12.2728 16.8006 12.2728 16.891V17.6546C12.2728 17.745 12.1996 17.8182 12.1092 17.8182H8.07282C7.98244 17.8182 7.90918 17.745 7.90918 17.6546V16.891C7.90918 16.8006 7.98244 16.7273 8.07282 16.7273Z" fill="white"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.3 KiB |
@ -0,0 +1,5 @@
|
||||
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M4 2.63514C4 2.00822 4.49403 1.5 5.10345 1.5L15.0674 1.5C15.2129 1.5 15.3526 1.55913 15.4559 1.66452L19.8367 6.13257C19.9412 6.23915 20 6.38425 20 6.53562V21.3649C20 21.9918 19.506 22.5 18.8966 22.5H5.10345C4.49403 22.5 4 21.9918 4 21.3649L4 2.63514Z" fill="#14C0FF"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M15.2947 1.55029C15.3541 1.5779 15.4088 1.61637 15.456 1.66447L19.8368 6.13253C19.8908 6.18764 19.9327 6.25304 19.9604 6.32428H16.3981C15.7887 6.32428 15.2947 5.81607 15.2947 5.18915V1.55029Z" fill="#72D9FF"/>
|
||||
<path d="M12 10C11.7239 10 11.5 10.2239 11.5 10.5V13.5H8.5C8.22386 13.5 8 13.7239 8 14C8 14.2761 8.22386 14.5 8.5 14.5H11.5V17.5C11.5 17.7761 11.7239 18 12 18C12.2761 18 12.5 17.7761 12.5 17.5V14.5H15.5C15.7761 14.5 16 14.2761 16 14C16 13.7239 15.7761 13.5 15.5 13.5H12.5V10.5C12.5 10.2239 12.2761 10 12 10Z" fill="white"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 964 B |
5
core/core-frontend/src/assets/svg/top-help-doc.svg
Normal file
5
core/core-frontend/src/assets/svg/top-help-doc.svg
Normal file
@ -0,0 +1,5 @@
|
||||
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M4 2.5C4 1.94772 4.44772 1.5 5 1.5H14.8608C14.9949 1.5 15.1234 1.55387 15.2174 1.64951L19.8566 6.36941C19.9485 6.46292 20 6.58879 20 6.7199V21.5C20 22.0523 19.5523 22.5 19 22.5H5C4.44772 22.5 4 22.0523 4 21.5V2.5Z" fill="#3370FF"/>
|
||||
<path d="M15 1.51978C15.0817 1.54345 15.1567 1.58778 15.2174 1.64952L19.8566 6.36942C19.8946 6.40806 19.9256 6.45223 19.949 6.50001H16.1351C15.5082 6.50001 15 5.99179 15 5.36488V1.51978Z" fill="#85A9FF"/>
|
||||
<path d="M8.07282 10.1819H15.6546C15.745 10.1819 15.8183 10.2551 15.8183 10.3455V11.1092C15.8183 11.1995 15.745 11.2728 15.6546 11.2728H8.07282C7.98244 11.2728 7.90918 11.1995 7.90918 11.1092V10.3455C7.90918 10.2551 7.98244 10.1819 8.07282 10.1819ZM8.07282 13.4546H15.6546C15.745 13.4546 15.8183 13.5279 15.8183 13.6182V14.3819C15.8183 14.4723 15.745 14.5455 15.6546 14.5455H8.07282C7.98244 14.5455 7.90918 14.4723 7.90918 14.3819V13.6182C7.90918 13.5279 7.98244 13.4546 8.07282 13.4546ZM8.07282 16.7273H12.1092C12.1996 16.7273 12.2728 16.8006 12.2728 16.891V17.6546C12.2728 17.745 12.1996 17.8182 12.1092 17.8182H8.07282C7.98244 17.8182 7.90918 17.745 7.90918 17.6546V16.891C7.90918 16.8006 7.98244 16.7273 8.07282 16.7273Z" fill="white"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.3 KiB |
4
core/core-frontend/src/assets/svg/top-product-bbs.svg
Normal file
4
core/core-frontend/src/assets/svg/top-product-bbs.svg
Normal file
@ -0,0 +1,4 @@
|
||||
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M17 11C17 10.4477 17.4477 10 18 10H22C22.5523 10 23 10.4477 23 11V19C23 19.5523 22.5523 20 22 20H19.9142L18.7071 21.2071C18.3166 21.5976 17.6834 21.5976 17.2929 21.2071L16.0858 20H11C10.4477 20 10 19.5523 10 19V15C10 14.4477 10.4477 14 11 14H17V11ZM19 12V15C19 15.5523 18.5523 16 18 16H12V18H16.5C16.7652 18 17.0196 18.1054 17.2071 18.2929L18 19.0858L18.7929 18.2929C18.9804 18.1054 19.2348 18 19.5 18H21V12H19Z" fill="#FFB866"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M2 2C1.44772 2 1 2.44772 1 3V15C1 15.5523 1.44772 16 2 16H4.08579L5.79289 17.7071C6.18342 18.0976 6.81658 18.0976 7.20711 17.7071L8.91421 16H18C18.5523 16 19 15.5523 19 15V3C19 2.44772 18.5523 2 18 2H2ZM7 9C7 9.55228 6.55228 10 6 10C5.44772 10 5 9.55228 5 9C5 8.44772 5.44772 8 6 8C6.55228 8 7 8.44772 7 9ZM11 9C11 9.55228 10.5523 10 10 10C9.44772 10 9 9.55228 9 9C9 8.44772 9.44772 8 10 8C10.5523 8 11 8.44772 11 9ZM15 9C15 9.55228 14.5523 10 14 10C13.4477 10 13 9.55228 13 9C13 8.44772 13.4477 8 14 8C14.5523 8 15 8.44772 15 9Z" fill="#FF8800"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.2 KiB |
3
core/core-frontend/src/assets/svg/top-tech-video.svg
Normal file
3
core/core-frontend/src/assets/svg/top-tech-video.svg
Normal file
@ -0,0 +1,3 @@
|
||||
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M12 1C18.075 1 23 5.925 23 12C23 18.075 18.075 23 12 23C5.925 23 1 18.075 1 12C1 5.925 5.925 1 12 1ZM9.869 7C9.63898 7.00035 9.41817 7.0904 9.2535 7.251C9.0905 7.411 8.999 7.6275 9 7.853V16.148C9 16.3075 9.046 16.4635 9.132 16.5995C9.2552 16.7922 9.44972 16.9283 9.673 16.978C9.898 17.029 10.134 16.9905 10.3295 16.8705L17.092 12.7235C17.346 12.5665 17.5 12.2935 17.5 12C17.5 11.7065 17.346 11.434 17.092 11.2765L10.33 7.13C10.1912 7.0451 10.0317 6.99978 9.869 7Z" fill="#FFC60A"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 594 B |
4
core/core-frontend/src/assets/svg/top-technology.svg
Normal file
4
core/core-frontend/src/assets/svg/top-technology.svg
Normal file
@ -0,0 +1,4 @@
|
||||
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M4.04762 2.04768H7V6.00024C7 6.55253 7.44772 7.00024 8 7.00024H16C16.5523 7.00024 17 6.55253 17 6.00025V2.04768L19.9524 2.04761C20.671 2.04761 21 2.45202 21 3.09526V21.9523C21 22.5949 20.671 23 19.9524 23L4.04762 23C3.32895 23 3 22.5956 3 21.9524V3.09529C3 2.45275 3.32895 2.04768 4.04762 2.04768ZM7.52376 11.0002C7.23447 11.0002 6.99995 11.2347 6.99995 11.524V12.5716C6.99995 12.8609 7.23447 13.0954 7.52376 13.0954H16.4761C16.7654 13.0954 16.9999 12.8609 16.9999 12.5716V11.524C16.9999 11.2347 16.7654 11.0002 16.4761 11.0002H7.52376ZM7.52376 15.9999C7.23447 15.9999 6.99995 16.2344 6.99995 16.5237V17.5713C6.99995 17.8606 7.23447 18.0951 7.52376 18.0951H16.7618C17.0511 18.0951 17.2856 17.8606 17.2856 17.5713V16.5237C17.2856 16.2344 17.0511 15.9999 16.7618 15.9999H7.52376Z" fill="#00D6B9"/>
|
||||
<path d="M9.5 1C9.22386 1 9 1.22386 9 1.5V4.5C9 4.77614 9.22386 5 9.5 5H14.5C14.7761 5 15 4.77614 15 4.5V1.5C15 1.22386 14.7761 1 14.5 1H9.5Z" fill="#66E6D5"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.0 KiB |
@ -158,7 +158,6 @@ const { t } = useI18n()
|
||||
const dvMainStore = dvMainStoreWithOut()
|
||||
const snapshotStore = snapshotStoreWithOut()
|
||||
const filterStyle = computed<any>(() => {
|
||||
console.log('filterStyle==' + JSON.stringify(dvMainStore.canvasStyleData.component.filterStyle))
|
||||
return dvMainStore.canvasStyleData.component.filterStyle
|
||||
})
|
||||
|
||||
|
||||
@ -1,20 +1,48 @@
|
||||
<script lang="ts" setup>
|
||||
import { ref } from 'vue'
|
||||
import { Icon } from '@/components/icon-custom'
|
||||
import TopDocCard from '@/layout/components/TopDocCard.vue'
|
||||
const helpLink = ref('https://dataease.io/docs/')
|
||||
const openBlank = () => {
|
||||
window.open(helpLink.value)
|
||||
}
|
||||
|
||||
const cardInfoList = [
|
||||
{ name: '帮助文档', url: 'https://dataease.io/docs/index.html', icon: 'top-help-doc' },
|
||||
{ name: '产品论坛', url: 'https://bbs.fit2cloud.com/c/de/6', icon: 'top-product-bbs' },
|
||||
{
|
||||
name: '技术博客',
|
||||
url: 'https://blog.fit2cloud.com/categories/dataease',
|
||||
icon: 'top-technology'
|
||||
},
|
||||
{ name: '企业版试用', url: 'https://jinshuju.net/f/TK5TTd', icon: 'top-enterprise-trial' }
|
||||
]
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<el-tooltip class="box-item" effect="dark" content="帮助文档" placement="top">
|
||||
<div class="sys-setting">
|
||||
<el-icon @click="openBlank">
|
||||
<Icon name="docs" />
|
||||
</el-icon>
|
||||
</div>
|
||||
</el-tooltip>
|
||||
<el-popover
|
||||
:show-arrow="false"
|
||||
popper-class="top-popover"
|
||||
placement="bottom-end"
|
||||
width="208"
|
||||
trigger="click"
|
||||
>
|
||||
<el-row>
|
||||
<top-doc-card
|
||||
:span="12"
|
||||
v-for="(item, index) in cardInfoList"
|
||||
:key="index"
|
||||
:card-info="item"
|
||||
></top-doc-card>
|
||||
</el-row>
|
||||
<template #reference>
|
||||
<div class="sys-setting">
|
||||
<el-icon>
|
||||
<Icon name="docs" />
|
||||
</el-icon>
|
||||
</div>
|
||||
</template>
|
||||
</el-popover>
|
||||
</template>
|
||||
|
||||
<style lang="less" scoped>
|
||||
@ -31,3 +59,9 @@ const openBlank = () => {
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
<style lang="less">
|
||||
.top-popover {
|
||||
padding: 0 0 16px 0 !important;
|
||||
}
|
||||
</style>
|
||||
|
||||
63
core/core-frontend/src/layout/components/TopDocCard.vue
Normal file
63
core/core-frontend/src/layout/components/TopDocCard.vue
Normal file
@ -0,0 +1,63 @@
|
||||
<script lang="ts" setup>
|
||||
import { toRefs } from 'vue'
|
||||
|
||||
const props = defineProps({
|
||||
cardInfo: {
|
||||
type: Object,
|
||||
default() {
|
||||
return {
|
||||
name: '',
|
||||
url: '',
|
||||
icon: ''
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
const { cardInfo } = toRefs(props)
|
||||
|
||||
const openBlank = () => {
|
||||
window.open(cardInfo.value.url)
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="doc-card" @click="openBlank">
|
||||
<el-row class="base-show">
|
||||
<Icon class-name="item-top-icon" :name="cardInfo.icon" />
|
||||
</el-row>
|
||||
<el-row class="base-show show-content"> {{ cardInfo.name }}</el-row>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style lang="less" scoped>
|
||||
.doc-card {
|
||||
padding-top: 2px;
|
||||
margin-top: 16px;
|
||||
margin-left: 16px;
|
||||
width: 80px;
|
||||
height: 50px;
|
||||
cursor: pointer;
|
||||
&:hover {
|
||||
background-color: rgba(30, 39, 56, 0.05);
|
||||
}
|
||||
&:active {
|
||||
background-color: rgba(30, 39, 56, 0.1);
|
||||
}
|
||||
}
|
||||
.base-show {
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.show-content {
|
||||
font-size: 14px;
|
||||
color: #1f2329;
|
||||
line-height: 22px;
|
||||
font-weight: 400;
|
||||
margin-top: 4px;
|
||||
}
|
||||
|
||||
.item-top-icon {
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
}
|
||||
</style>
|
||||
@ -230,6 +230,7 @@ export default {
|
||||
manage: '管理',
|
||||
auth: '授权',
|
||||
resource_name: '资源名称',
|
||||
menu_name: '菜单名称',
|
||||
from_role: '继承自以下角色:',
|
||||
auth_alone: '单独授权',
|
||||
org_role_empty: '组织管理员已拥有所有资源的权限,无需再授权',
|
||||
|
||||
21
core/core-frontend/src/models/chart/editor.d.ts
vendored
21
core/core-frontend/src/models/chart/editor.d.ts
vendored
@ -86,4 +86,25 @@ declare interface ChartEditorForm<T> {
|
||||
* 是否渲染图表
|
||||
*/
|
||||
render: boolean
|
||||
/**
|
||||
* 子属性
|
||||
*/
|
||||
prop?: string
|
||||
}
|
||||
/**
|
||||
* 轴编辑表单
|
||||
*/
|
||||
declare interface AxisEditForm {
|
||||
/**
|
||||
* 轴类型
|
||||
*/
|
||||
axisType: AxisType
|
||||
/**
|
||||
* 变更内容
|
||||
*/
|
||||
axis: Axis[]
|
||||
/**
|
||||
* 变更类型
|
||||
*/
|
||||
editType: 'add' | 'remove' | 'update'
|
||||
}
|
||||
|
||||
@ -95,6 +95,9 @@ export const pathValid = path => {
|
||||
* @returns
|
||||
*/
|
||||
const hasCurrentRouter = (locations, routers, index) => {
|
||||
if (!routers?.length) {
|
||||
return false
|
||||
}
|
||||
const location = locations[index]
|
||||
let kids = []
|
||||
const isvalid = routers.some(router => {
|
||||
|
||||
@ -7,10 +7,11 @@ import cloneDeep from 'lodash-es/cloneDeep'
|
||||
import defaultsDeep from 'lodash-es/defaultsDeep'
|
||||
import { formatterType, unitType } from '../../../js/formatter'
|
||||
import { fieldType } from '@/utils/attr'
|
||||
import { differenceBy, partition } from 'lodash-es'
|
||||
import { partition } from 'lodash-es'
|
||||
import chartViewManager from '../../../js/panel'
|
||||
import { dvMainStoreWithOut } from '@/store/modules/data-visualization/dvMain'
|
||||
import { storeToRefs } from 'pinia'
|
||||
import { useEmitt } from '@/hooks/web/useEmitt'
|
||||
|
||||
const { t } = useI18n()
|
||||
|
||||
@ -34,11 +35,10 @@ const toolTip = computed(() => {
|
||||
return props.themes === 'dark' ? 'ndark' : 'dark'
|
||||
})
|
||||
const emit = defineEmits(['onTooltipChange', 'onExtTooltipChange'])
|
||||
|
||||
const curSeriesFormatter = ref<DeepPartial<SeriesFormatter>>({})
|
||||
const quotaData = ref<Axis[]>(inject('quotaData'))
|
||||
const showSeriesTooltipFormatter = computed(() => {
|
||||
return showProperty('seriesTooltipFormatter') && !batchOptStatus.value
|
||||
return showProperty('seriesTooltipFormatter') && !batchOptStatus.value && props.chart.id
|
||||
})
|
||||
// 初始化系列提示
|
||||
const initSeriesTooltip = () => {
|
||||
@ -90,84 +90,15 @@ const initSeriesTooltip = () => {
|
||||
}
|
||||
curSeriesFormatter.value = axisMap[curSeriesFormatter.value.seriesId]
|
||||
}
|
||||
// 更新系列提示
|
||||
const updateSeriesTooltip = (newAxis?: SeriesFormatter[], oldAxis?: SeriesFormatter[]) => {
|
||||
if (
|
||||
!showSeriesTooltipFormatter.value ||
|
||||
!state.tooltipForm.seriesTooltipFormatter.length ||
|
||||
!quotaData.value?.length
|
||||
) {
|
||||
return
|
||||
}
|
||||
const axisMap: Record<string, Axis> = newAxis?.reduce((pre, next) => {
|
||||
pre[next.seriesId] = next
|
||||
return pre
|
||||
}, {})
|
||||
// 新增
|
||||
const addedAxisMap = differenceBy(newAxis, oldAxis, 'seriesId').reduce((pre, next) => {
|
||||
pre[next.id] = next
|
||||
return pre
|
||||
}, {}) as Record<string, SeriesFormatter>
|
||||
// 删除
|
||||
const removedAxisMap = differenceBy(oldAxis, newAxis, 'seriesId').reduce((pre, next) => {
|
||||
pre[next.seriesId] = next
|
||||
return pre
|
||||
}, {}) as Record<string, SeriesFormatter>
|
||||
const quotaIds = quotaData.value?.map(i => i.id)
|
||||
state.tooltipForm.seriesTooltipFormatter = state.tooltipForm.seriesTooltipFormatter?.filter(i =>
|
||||
quotaIds?.includes(i.id)
|
||||
)
|
||||
const dupAxis: SeriesFormatter[] = []
|
||||
state.tooltipForm.seriesTooltipFormatter?.forEach(ele => {
|
||||
if (addedAxisMap[ele.id]) {
|
||||
// 数据集中的字段
|
||||
ele.show = true
|
||||
if (ele.seriesId === ele.id) {
|
||||
ele.seriesId = addedAxisMap[ele.id].seriesId
|
||||
ele.axisType = addedAxisMap[ele.id].axisType
|
||||
} else {
|
||||
// 其他轴已有的字段
|
||||
const tmp = cloneDeep(addedAxisMap[ele.id])
|
||||
tmp.show = true
|
||||
dupAxis.push(tmp)
|
||||
}
|
||||
}
|
||||
if (removedAxisMap[ele.seriesId]) {
|
||||
ele.show = false
|
||||
ele.seriesId = ele.id
|
||||
}
|
||||
ele.chartShowName = axisMap[ele.seriesId]?.chartShowName
|
||||
ele.summary = axisMap[ele.seriesId]?.summary ?? ele.summary
|
||||
})
|
||||
// 重新排序
|
||||
state.tooltipForm.seriesTooltipFormatter =
|
||||
state.tooltipForm.seriesTooltipFormatter.concat(dupAxis)
|
||||
state.tooltipForm.seriesTooltipFormatter = partition(
|
||||
state.tooltipForm.seriesTooltipFormatter,
|
||||
ele => axisMap[ele.seriesId]
|
||||
).flat()
|
||||
if (removedAxisMap[curSeriesFormatter.value?.seriesId]) {
|
||||
curSeriesFormatter.value = state.tooltipForm.seriesTooltipFormatter?.[0]
|
||||
}
|
||||
if (!newAxis.length) {
|
||||
curSeriesFormatter.value = {}
|
||||
}
|
||||
emit('onTooltipChange', { data: state.tooltipForm, render: false })
|
||||
emit('onExtTooltipChange', extTooltip.value)
|
||||
}
|
||||
const AXIS_PROP: AxisType[] = ['yAxis', 'yAxisExt', 'extBubble']
|
||||
const quotaAxis = computed(() => {
|
||||
let result = []
|
||||
const axisProp: AxisType[] = ['yAxis', 'yAxisExt', 'extBubble']
|
||||
axisProp.forEach(prop => {
|
||||
AXIS_PROP.forEach(prop => {
|
||||
if (!chartViewInstance.value?.axis?.includes(prop)) {
|
||||
return
|
||||
}
|
||||
const axis = props.chart[prop]
|
||||
axis?.forEach(item => {
|
||||
item.axisType = prop
|
||||
item.seriesId = `${item.id}-${prop}`
|
||||
result.push(item)
|
||||
})
|
||||
axis?.forEach(item => result.push(item))
|
||||
})
|
||||
return result
|
||||
})
|
||||
@ -205,13 +136,6 @@ const AGGREGATION_TYPE = [
|
||||
{ name: t('chart.count'), value: 'count' },
|
||||
{ name: t('chart.count_distinct'), value: 'count_distinct' }
|
||||
]
|
||||
watch(
|
||||
() => cloneDeep(quotaAxis.value),
|
||||
(newVal, oldVal) => {
|
||||
updateSeriesTooltip(newVal, oldVal)
|
||||
},
|
||||
{ deep: true }
|
||||
)
|
||||
watch(
|
||||
[() => props.chart.customAttr.tooltip, () => props.chart.customAttr.tooltip.show],
|
||||
() => {
|
||||
@ -262,7 +186,15 @@ const init = () => {
|
||||
if (customAttr.tooltip) {
|
||||
state.tooltipForm = defaultsDeep(customAttr.tooltip, cloneDeep(DEFAULT_TOOLTIP))
|
||||
formatterSelector.value?.blur()
|
||||
// 新增视图
|
||||
const formatter = state.tooltipForm.seriesTooltipFormatter
|
||||
if (!quotaAxis.value?.length) {
|
||||
if (!formatter.length) {
|
||||
quotaData.value?.forEach(i => formatter.push({ ...i, seriesId: i.id, show: false }))
|
||||
}
|
||||
curSeriesFormatter.value = {}
|
||||
return
|
||||
}
|
||||
const seriesAxisMap = formatter.reduce((pre, next) => {
|
||||
next.seriesId = next.seriesId ?? next.id
|
||||
pre[next.seriesId] = next
|
||||
@ -278,9 +210,131 @@ const init = () => {
|
||||
}
|
||||
|
||||
const showProperty = prop => props.propertyInner?.includes(prop)
|
||||
|
||||
const updateSeriesTooltipFormatter = (form: AxisEditForm) => {
|
||||
const { axisType, editType } = form
|
||||
if (
|
||||
!showSeriesTooltipFormatter.value ||
|
||||
!state.tooltipForm.seriesTooltipFormatter.length ||
|
||||
!quotaData.value?.length ||
|
||||
!AXIS_PROP.includes(axisType)
|
||||
) {
|
||||
return
|
||||
}
|
||||
switch (editType) {
|
||||
case 'add':
|
||||
addAxis(form)
|
||||
break
|
||||
case 'remove':
|
||||
removeAxis(form)
|
||||
break
|
||||
case 'update':
|
||||
updateAxis(form)
|
||||
break
|
||||
default:
|
||||
break
|
||||
}
|
||||
emit('onTooltipChange', { data: state.tooltipForm, render: false }, 'seriesTooltipFormatter')
|
||||
emit('onExtTooltipChange', extTooltip.value)
|
||||
}
|
||||
const addAxis = (form: AxisEditForm) => {
|
||||
const { axis, axisType } = form
|
||||
const axisMap = axis.reduce((pre, next) => {
|
||||
next.axisType = axisType
|
||||
next.seriesId = `${next.id}-${axisType}`
|
||||
pre[next.id] = next
|
||||
return pre
|
||||
}, {})
|
||||
const dupAxis = []
|
||||
state.tooltipForm.seriesTooltipFormatter.forEach(ele => {
|
||||
if (axisMap[ele.id]) {
|
||||
// 数据集中的字段
|
||||
ele.show = true
|
||||
if (ele.seriesId === ele.id) {
|
||||
ele.seriesId = axisMap[ele.id].seriesId
|
||||
ele.axisType = axisMap[ele.id].axisType
|
||||
ele.summary = axisMap[ele.id].summary
|
||||
ele.chartShowName = axisMap[ele.id].chartShowName
|
||||
} else {
|
||||
// 其他轴已有的字段
|
||||
const tmp = cloneDeep(axisMap[ele.id])
|
||||
tmp.show = true
|
||||
dupAxis.push(tmp)
|
||||
}
|
||||
}
|
||||
})
|
||||
state.tooltipForm.seriesTooltipFormatter =
|
||||
state.tooltipForm.seriesTooltipFormatter.concat(dupAxis)
|
||||
state.tooltipForm.seriesTooltipFormatter = partition(
|
||||
state.tooltipForm.seriesTooltipFormatter,
|
||||
ele => quotaAxis.value.findIndex(item => item.id === ele.id) !== -1
|
||||
).flat()
|
||||
}
|
||||
const removeAxis = (form: AxisEditForm) => {
|
||||
const { axis, axisType } = form
|
||||
const axisMap = axis.reduce((pre, next) => {
|
||||
if (!next) {
|
||||
return pre
|
||||
}
|
||||
next.axisType = axisType
|
||||
next.seriesId = `${next.id}-${axisType}`
|
||||
pre[next.seriesId] = next
|
||||
return pre
|
||||
}, {})
|
||||
const quotaIds = quotaData.value?.map(i => i.id)
|
||||
const formatterDupMap = state.tooltipForm.seriesTooltipFormatter.reduce((pre, next) => {
|
||||
if (pre[next.id] !== undefined) {
|
||||
pre[`${next.id}-${axisType}`] = true
|
||||
} else {
|
||||
pre[next.id] = false
|
||||
}
|
||||
return pre
|
||||
}, {})
|
||||
state.tooltipForm.seriesTooltipFormatter = state.tooltipForm.seriesTooltipFormatter?.filter(
|
||||
i => quotaIds?.includes(i.id) && !formatterDupMap[i.seriesId]
|
||||
)
|
||||
state.tooltipForm.seriesTooltipFormatter.forEach(ele => {
|
||||
if (axisMap[ele.seriesId]) {
|
||||
// 数据集中的字段
|
||||
ele.show = false
|
||||
ele.seriesId = ele.id
|
||||
ele.summary = 'sum'
|
||||
}
|
||||
})
|
||||
state.tooltipForm.seriesTooltipFormatter = partition(
|
||||
state.tooltipForm.seriesTooltipFormatter,
|
||||
ele => quotaAxis.value.findIndex(item => item.id === ele.id) !== -1
|
||||
).flat()
|
||||
if (!quotaAxis.value?.length) {
|
||||
curSeriesFormatter.value = {}
|
||||
return
|
||||
}
|
||||
if (axisMap[curSeriesFormatter.value?.seriesId]) {
|
||||
curSeriesFormatter.value = state.tooltipForm.seriesTooltipFormatter?.[0]
|
||||
}
|
||||
}
|
||||
const updateAxis = (form: AxisEditForm) => {
|
||||
const { axis, axisType } = form
|
||||
const axisMap = axis.reduce((pre, next) => {
|
||||
if (!next) {
|
||||
return pre
|
||||
}
|
||||
next.axisType = axisType
|
||||
next.seriesId = `${next.id}-${axisType}`
|
||||
pre[next.seriesId] = next
|
||||
return pre
|
||||
}, {})
|
||||
state.tooltipForm.seriesTooltipFormatter.forEach(ele => {
|
||||
if (axisMap[ele.seriesId]) {
|
||||
ele.chartShowName = axisMap[ele.seriesId]?.chartShowName
|
||||
ele.summary = axisMap[ele.seriesId]?.summary ?? ele.summary
|
||||
}
|
||||
})
|
||||
}
|
||||
onMounted(() => {
|
||||
init()
|
||||
useEmitt({ name: 'addAxis', callback: updateSeriesTooltipFormatter })
|
||||
useEmitt({ name: 'removeAxis', callback: updateSeriesTooltipFormatter })
|
||||
useEmitt({ name: 'updateAxis', callback: updateSeriesTooltipFormatter })
|
||||
})
|
||||
</script>
|
||||
|
||||
@ -482,10 +536,11 @@ onMounted(() => {
|
||||
<template v-if="curSeriesFormatter?.seriesId">
|
||||
<el-form-item class="form-item form-item-checkbox" :class="'form-item-' + themes">
|
||||
<el-checkbox
|
||||
size="small"
|
||||
@change="changeTooltipAttr('seriesTooltipFormatter', true)"
|
||||
:disabled="!formatterEditable"
|
||||
v-model="curSeriesFormatter.show"
|
||||
size="small"
|
||||
label="quota"
|
||||
@change="changeTooltipAttr('seriesTooltipFormatter', true)"
|
||||
>
|
||||
{{ t('chart.show') }}
|
||||
</el-checkbox>
|
||||
|
||||
@ -15,7 +15,6 @@ import {
|
||||
import Icon from '@/components/icon-custom/src/Icon.vue'
|
||||
import type { FormInstance, FormRules } from 'element-plus-secondary'
|
||||
import { useI18n } from '@/hooks/web/useI18n'
|
||||
import { Field, getFieldByDQ } from '@/api/chart'
|
||||
import { Tree } from '../../../visualized/data/dataset/form/CreatDsGroup.vue'
|
||||
import { useEmitt } from '@/hooks/web/useEmitt'
|
||||
import { ElMessage, ElTreeSelect } from 'element-plus-secondary'
|
||||
@ -43,13 +42,13 @@ import CustomSortEdit from '@/views/chart/components/editor/drag-item/components
|
||||
import { snapshotStoreWithOut } from '@/store/modules/data-visualization/snapshot'
|
||||
import CalcFieldEdit from '@/views/visualized/data/dataset/form/CalcFieldEdit.vue'
|
||||
import { getFieldName, guid } from '@/views/visualized/data/dataset/form/util'
|
||||
import { cloneDeep } from 'lodash-es'
|
||||
import { cloneDeep, get } from 'lodash-es'
|
||||
import { deleteField, saveField } from '@/api/dataset'
|
||||
import { getWorldTree } from '@/api/map'
|
||||
import chartViewManager from '@/views/chart/components/js/panel'
|
||||
import DatasetSelect from '@/views/chart/components/editor/dataset-select/DatasetSelect.vue'
|
||||
import { useDraggable } from '@vueuse/core'
|
||||
import _ from 'lodash'
|
||||
import { set, concat, keys } from 'lodash-es'
|
||||
|
||||
const snapshotStore = snapshotStoreWithOut()
|
||||
const dvMainStore = dvMainStoreWithOut()
|
||||
@ -63,7 +62,7 @@ const tabActiveVQuery = ref('style')
|
||||
const datasetSelector = ref(null)
|
||||
const curDatasetWeight = ref(0)
|
||||
const renameForm = ref<FormInstance>()
|
||||
|
||||
const { emitter } = useEmitt()
|
||||
const props = defineProps({
|
||||
view: {
|
||||
type: Object as PropType<ChartObj>,
|
||||
@ -144,14 +143,6 @@ const state = reactive({
|
||||
useless: null
|
||||
})
|
||||
|
||||
watch(
|
||||
[() => props.view.tableId],
|
||||
() => {
|
||||
getFields(props.view.tableId, props.view.id)
|
||||
},
|
||||
{ deep: true }
|
||||
)
|
||||
|
||||
watch(
|
||||
[() => view.value['tableId']],
|
||||
() => {
|
||||
@ -222,31 +213,8 @@ const filterNode = (value, data) => {
|
||||
return data.name?.includes(value)
|
||||
}
|
||||
|
||||
const getFields = (id, chartId) => {
|
||||
if (id && chartId) {
|
||||
getFieldByDQ(id, chartId)
|
||||
.then(res => {
|
||||
state.dimension = (res.dimensionList as unknown as Field[]) || []
|
||||
state.quota = (res.quotaList as unknown as Field[]) || []
|
||||
state.dimensionData = JSON.parse(JSON.stringify(state.dimension))
|
||||
state.quotaData = JSON.parse(JSON.stringify(state.quota))
|
||||
})
|
||||
.catch(() => {
|
||||
state.dimension = []
|
||||
state.quota = []
|
||||
state.dimensionData = []
|
||||
state.quotaData = []
|
||||
})
|
||||
} else {
|
||||
state.dimension = []
|
||||
state.quota = []
|
||||
state.dimensionData = []
|
||||
state.quotaData = []
|
||||
}
|
||||
}
|
||||
|
||||
const allFields = computed(() => {
|
||||
return _.concat(state.quotaData, state.dimensionData)
|
||||
return concat(state.quotaData, state.dimensionData)
|
||||
})
|
||||
|
||||
const queryList = computed(() => {
|
||||
@ -266,9 +234,9 @@ const queryList = computed(() => {
|
||||
|
||||
const quotaData = computed(() => {
|
||||
if (view.value?.type === 'table-info') {
|
||||
return state.quotaData?.filter(item => item.id !== '-1')
|
||||
return state.quota?.filter(item => item.id !== '-1')
|
||||
}
|
||||
return state.quotaData
|
||||
return state.quota
|
||||
})
|
||||
provide('quotaData', quotaData)
|
||||
|
||||
@ -313,23 +281,29 @@ const dimensionItemRemove = item => {
|
||||
}
|
||||
}
|
||||
|
||||
const quotaItemChange = () => {
|
||||
const quotaItemChange = (axis: Axis, axisType: AxisType) => {
|
||||
recordSnapshotInfo('calcData')
|
||||
// do quotaItemChange
|
||||
emitter.emit('updateAxis', { axisType, axis: [axis], editType: 'update' })
|
||||
}
|
||||
const quotaItemRemove = item => {
|
||||
recordSnapshotInfo('calcData')
|
||||
let axisType: AxisType = item.removeType
|
||||
let axis
|
||||
if (item.removeType === 'quota') {
|
||||
view.value.yAxis.splice(item.index, 1)
|
||||
axisType = 'yAxis'
|
||||
axis = view.value.yAxis.splice(item.index, 1)
|
||||
} else if (item.removeType === 'quotaExt') {
|
||||
view.value.yAxisExt.splice(item.index, 1)
|
||||
axisType = 'yAxisExt'
|
||||
axis = view.value.yAxisExt.splice(item.index, 1)
|
||||
} else if (item.removeType === 'extLabel') {
|
||||
view.value.extLabel.splice(item.index, 1)
|
||||
axis = view.value.extLabel.splice(item.index, 1)
|
||||
} else if (item.removeType === 'extTooltip') {
|
||||
view.value.extTooltip.splice(item.index, 1)
|
||||
axis = view.value.extTooltip.splice(item.index, 1)
|
||||
} else if (item.removeType === 'extBubble') {
|
||||
view.value.extBubble.splice(item.index, 1)
|
||||
axis = view.value.extBubble.splice(item.index, 1)
|
||||
}
|
||||
useEmitt().emitter.emit('removeAxis', { axisType, axis, editType: 'remove' })
|
||||
}
|
||||
const arrowIcon = () => {
|
||||
return h(Icon, { name: 'icon_down_outlined-1' })
|
||||
@ -394,7 +368,7 @@ const onMove = e => {
|
||||
// drag
|
||||
const dragCheckType = (list, type) => {
|
||||
if (list && list.length > 0) {
|
||||
var valid = true
|
||||
let valid = true
|
||||
for (let i = 0; i < list.length; i++) {
|
||||
if (list[i].groupType !== type) {
|
||||
list.splice(i, 1)
|
||||
@ -407,6 +381,7 @@ const dragCheckType = (list, type) => {
|
||||
type: 'warning'
|
||||
})
|
||||
}
|
||||
return valid
|
||||
}
|
||||
}
|
||||
const dragMoveDuplicate = (list, e, mode) => {
|
||||
@ -418,6 +393,7 @@ const dragMoveDuplicate = (list, e, mode) => {
|
||||
})
|
||||
if (dup && dup.length > 1) {
|
||||
list.splice(e.newDraggableIndex, 1)
|
||||
return dup
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -439,14 +415,37 @@ const addAxis = (e, axis: AxisType) => {
|
||||
return
|
||||
}
|
||||
const { type, limit, duplicate } = axisSpec
|
||||
let typeValid, dup
|
||||
if (type) {
|
||||
dragCheckType(view.value[axis], type)
|
||||
typeValid = dragCheckType(view.value[axis], type)
|
||||
}
|
||||
if (!duplicate) {
|
||||
dragMoveDuplicate(view.value[axis], e, 'chart')
|
||||
dup = dragMoveDuplicate(view.value[axis], e, 'chart')
|
||||
}
|
||||
if (limit) {
|
||||
view.value[axis] = view.value[axis].splice(0, limit)
|
||||
if (view.value[axis].length > limit) {
|
||||
const removedAxis = view.value[axis].splice(limit)
|
||||
if (e.newDraggableIndex + 1 <= limit) {
|
||||
emitter.emit('removeAxis', { axisType: axis, axis: removedAxis, editType: 'remove' })
|
||||
emitter.emit('addAxis', {
|
||||
axisType: axis,
|
||||
axis: [view.value[axis][e.newDraggableIndex]],
|
||||
editType: 'add'
|
||||
})
|
||||
}
|
||||
} else {
|
||||
if (!dup && typeValid) {
|
||||
emitter.emit('addAxis', {
|
||||
axisType: axis,
|
||||
axis: [view.value[axis][e.newDraggableIndex]],
|
||||
editType: 'add'
|
||||
})
|
||||
}
|
||||
}
|
||||
if (view.value.type === 'line') {
|
||||
if (view.value?.xAxisExt?.length && view.value?.yAxis?.length > 1) {
|
||||
const axis = view.value.yAxis.splice(1)
|
||||
emitter.emit('removeAxis', { axisType: 'yAxis', axis, editType: 'remove' })
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -505,6 +504,13 @@ const moveToQuota = e => {
|
||||
dragMoveDuplicate(state.quotaData, e, 'ds')
|
||||
}
|
||||
|
||||
const onAxisChange = (e, axis: AxisType) => {
|
||||
if (e.removed) {
|
||||
const { element } = e.removed
|
||||
emitter.emit('removeAxis', { axisType: axis, axis: [element], editType: 'remove' })
|
||||
}
|
||||
}
|
||||
|
||||
const calcData = (view, resetDrill = false, updateQuery = '') => {
|
||||
if (
|
||||
view.refreshTime === '' ||
|
||||
@ -551,26 +557,36 @@ const onTypeChange = (render, type) => {
|
||||
view.value = chartViewInstance.setupDefaultOptions(view.value) as unknown as ChartObj
|
||||
// 处理轴
|
||||
const axisConfig = chartViewInstance.axisConfig
|
||||
_.keys(axisConfig).forEach((axis: AxisType) => {
|
||||
keys(axisConfig).forEach((axis: AxisType) => {
|
||||
const axisArr = view.value[axis] as Axis[]
|
||||
if (!axisArr?.length) {
|
||||
return
|
||||
}
|
||||
const axisSpec = axisConfig[axis]
|
||||
const { type, limit } = axisSpec
|
||||
const removedAxis = []
|
||||
// check type
|
||||
if (type) {
|
||||
for (let i = axisArr.length - 1; i >= 0; i--) {
|
||||
if (axisArr[i].groupType !== type) {
|
||||
axisArr.splice(i, 1)
|
||||
const [axis] = axisArr.splice(i, 1)
|
||||
removedAxis.push(axis)
|
||||
}
|
||||
}
|
||||
}
|
||||
// check limit
|
||||
if (limit && axisArr.length) {
|
||||
axisArr.splice(0, axisArr.length - limit)
|
||||
if (limit && limit < axisArr.length) {
|
||||
axisArr.splice(limit).forEach(i => removedAxis.push(i))
|
||||
}
|
||||
removedAxis.length &&
|
||||
emitter.emit('removeAxis', { axisType: axis, axis: removedAxis, editType: 'remove' })
|
||||
})
|
||||
if (view.value.type === 'line') {
|
||||
if (view.value?.xAxisExt?.length && view.value?.yAxis?.length > 1) {
|
||||
const axis = view.value.yAxis.splice(1)
|
||||
emitter.emit('removeAxis', { axisType: 'yAxis', axis, editType: 'remove' })
|
||||
}
|
||||
}
|
||||
}
|
||||
curComponent.value.innerType = type
|
||||
calcData(view.value, true)
|
||||
@ -617,23 +633,22 @@ const onLabelChange = val => {
|
||||
view.value.customAttr.label = val
|
||||
renderChart(view.value)
|
||||
}
|
||||
watch([() => view.value.xAxisExt?.length, () => view.value.yAxis?.length], () => {
|
||||
if (view.value.type === 'line') {
|
||||
if (view.value?.xAxisExt?.length && view.value?.yAxis?.length > 1) {
|
||||
view.value.yAxis.splice(1)
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
const onTooltipChange = (chartForm: ChartEditorForm<ChartTooltipAttr>) => {
|
||||
const onTooltipChange = (chartForm: ChartEditorForm<ChartTooltipAttr>, prop: string) => {
|
||||
const { data, requestData, render } = chartForm
|
||||
let tooltipObj = data
|
||||
if (!data) {
|
||||
view.value.customAttr.tooltip = chartForm as unknown as ChartTooltipAttr
|
||||
tooltipObj = chartForm as unknown as ChartTooltipAttr
|
||||
}
|
||||
if (prop) {
|
||||
const val = get(tooltipObj, prop)
|
||||
set(view.value.customAttr.tooltip, prop, val)
|
||||
} else {
|
||||
view.value.customAttr.tooltip = data
|
||||
view.value.customAttr.tooltip = tooltipObj
|
||||
}
|
||||
if (requestData) {
|
||||
calcData(view.value)
|
||||
return
|
||||
}
|
||||
// for compatibility
|
||||
if (render !== false) {
|
||||
@ -716,29 +731,31 @@ const removeItems = (
|
||||
_type: 'xAxis' | 'xAxisExt' | 'extStack' | 'yAxis' | 'extBubble' | 'customFilter' | 'drillFields'
|
||||
) => {
|
||||
recordSnapshotInfo('calcData')
|
||||
let axis = []
|
||||
switch (_type) {
|
||||
case 'xAxis':
|
||||
view.value.xAxis = []
|
||||
axis = view.value.xAxis?.splice(0)
|
||||
break
|
||||
case 'xAxisExt':
|
||||
view.value.xAxisExt = []
|
||||
axis = view.value.xAxisExt?.splice(0)
|
||||
break
|
||||
case 'extStack':
|
||||
view.value.extStack = []
|
||||
axis = view.value.extStack?.splice(0)
|
||||
break
|
||||
case 'yAxis':
|
||||
view.value.yAxis = []
|
||||
axis = view.value.yAxis?.splice(0)
|
||||
break
|
||||
case 'extBubble':
|
||||
view.value.extBubble = []
|
||||
axis = view.value.extBubble?.splice(0)
|
||||
break
|
||||
case 'customFilter':
|
||||
view.value.customFilter = []
|
||||
axis = view.value.customFilter?.splice(0)
|
||||
break
|
||||
case 'drillFields':
|
||||
view.value.drillFields = []
|
||||
axis = view.value.drillFields?.splice(0)
|
||||
break
|
||||
}
|
||||
axis?.length && emitter.emit('removeAxis', { axisType: _type, axis, editType: 'remove' })
|
||||
}
|
||||
|
||||
const saveRename = ref => {
|
||||
@ -746,14 +763,19 @@ const saveRename = ref => {
|
||||
ref.validate(valid => {
|
||||
if (valid) {
|
||||
const { renameType, index, chartShowName } = state.itemForm
|
||||
let axisType, axis
|
||||
switch (renameType) {
|
||||
case 'quota':
|
||||
axisType = 'yAxis'
|
||||
axis = view.value.yAxis[index]
|
||||
view.value.yAxis[index].chartShowName = chartShowName
|
||||
break
|
||||
case 'dimension':
|
||||
view.value.xAxis[index].chartShowName = chartShowName
|
||||
break
|
||||
case 'quotaExt':
|
||||
axisType = 'yAxisExt'
|
||||
axis = view.value.yAxisExt[index]
|
||||
view.value.yAxisExt[index].chartShowName = chartShowName
|
||||
break
|
||||
case 'dimensionExt':
|
||||
@ -763,6 +785,8 @@ const saveRename = ref => {
|
||||
view.value.extStack[index].chartShowName = chartShowName
|
||||
break
|
||||
case 'extBubble':
|
||||
axisType = 'extBubble'
|
||||
axis = view.value.extBubble[index]
|
||||
view.value.extBubble[index].chartShowName = chartShowName
|
||||
break
|
||||
case 'extLabel':
|
||||
@ -774,6 +798,7 @@ const saveRename = ref => {
|
||||
default:
|
||||
break
|
||||
}
|
||||
axisType && emitter.emit('updateAxis', { axisType, axis: [axis], editType: 'update' })
|
||||
closeRename()
|
||||
} else {
|
||||
return false
|
||||
@ -1356,6 +1381,7 @@ const onRefreshChange = val => {
|
||||
class="drag-block-style"
|
||||
:class="{ dark: themes === 'dark' }"
|
||||
@add="addYaxis"
|
||||
@change="e => onAxisChange(e, 'yAxis')"
|
||||
>
|
||||
<template #item="{ element, index }">
|
||||
<quota-item
|
||||
@ -1366,7 +1392,7 @@ const onRefreshChange = val => {
|
||||
:index="index"
|
||||
type="quota"
|
||||
:themes="props.themes"
|
||||
@onQuotaItemChange="quotaItemChange"
|
||||
@onQuotaItemChange="item => quotaItemChange(item, 'yAxis')"
|
||||
@onQuotaItemRemove="quotaItemRemove"
|
||||
@onNameEdit="showRename"
|
||||
@editItemFilter="showQuotaEditFilter"
|
||||
@ -1403,6 +1429,7 @@ const onRefreshChange = val => {
|
||||
class="drag-block-style"
|
||||
:class="{ dark: themes === 'dark' }"
|
||||
@add="addExtBubble"
|
||||
@change="e => onAxisChange(e, 'extBubble')"
|
||||
>
|
||||
<template #item="{ element, index }">
|
||||
<quota-item
|
||||
@ -1413,7 +1440,7 @@ const onRefreshChange = val => {
|
||||
:index="index"
|
||||
type="extBubble"
|
||||
:themes="props.themes"
|
||||
@onQuotaItemChange="quotaItemChange"
|
||||
@onQuotaItemChange="item => quotaItemChange(item, 'extBubble')"
|
||||
@onQuotaItemRemove="quotaItemRemove"
|
||||
@onNameEdit="showRename"
|
||||
@editItemFilter="showQuotaEditFilter"
|
||||
|
||||
@ -253,9 +253,8 @@ export function handleEmptyDataStrategy<O extends PickOptions>(chart: Chart, opt
|
||||
handleIgnoreData(data)
|
||||
return options
|
||||
}
|
||||
const yAxis = JSON.parse(JSON.stringify(chart.yAxis))
|
||||
const extAxis = JSON.parse(JSON.stringify(chart.xAxisExt))
|
||||
const multiDimension = yAxis?.length >= 2 || extAxis?.length > 0
|
||||
const { yAxis, xAxisExt, extStack } = chart
|
||||
const multiDimension = yAxis?.length >= 2 || xAxisExt?.length > 0 || extStack?.length > 0
|
||||
switch (strategy) {
|
||||
case 'breakLine': {
|
||||
if (multiDimension) {
|
||||
|
||||
@ -434,7 +434,7 @@ onMounted(() => {
|
||||
}
|
||||
})
|
||||
useEmitt({
|
||||
name: 'calc-data-' + view.value.id,
|
||||
name: 'calcData-' + view.value.id,
|
||||
callback: function (val) {
|
||||
if (!state.initReady) {
|
||||
return
|
||||
|
||||
@ -40,7 +40,7 @@ const handleClick = (tab, event: Event) => {
|
||||
.sys-setting-p {
|
||||
width: 100%;
|
||||
background: var(--ContentBG, #ffffff);
|
||||
height: calc(100% - 95px);
|
||||
height: calc(100vh - 176px);
|
||||
box-sizing: border-box;
|
||||
margin-top: 12px;
|
||||
}
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
<template>
|
||||
<el-container class="geometry-container">
|
||||
<el-aside width="200px" class="geonetry-aside">
|
||||
<el-aside class="geonetry-aside">
|
||||
<div class="geo-title">
|
||||
<span>{{ t('online_map.geometry') }}</span>
|
||||
<span class="add-icon-span">
|
||||
@ -10,7 +10,13 @@
|
||||
</span>
|
||||
</div>
|
||||
<div class="geo-search">
|
||||
<el-input class="m16 w100" v-model="keyword" clearable :placeholder="t('commons.search')">
|
||||
<el-input
|
||||
class="m16 w100"
|
||||
v-model="keyword"
|
||||
clearable
|
||||
:placeholder="t('commons.search')"
|
||||
@change="filterResource"
|
||||
>
|
||||
<template #prefix>
|
||||
<el-icon>
|
||||
<Icon name="icon_search-outline_outlined"></Icon>
|
||||
@ -19,90 +25,118 @@
|
||||
</el-input>
|
||||
</div>
|
||||
<div class="map-tree-container">
|
||||
<el-tree :data="data" :props="defaultProps" @node-click="handleNodeClick" />
|
||||
<el-scrollbar class="menu-tree">
|
||||
<el-tree
|
||||
menu
|
||||
ref="areaTreeRef"
|
||||
node-key="id"
|
||||
:data="treeData"
|
||||
@node-click="handleNodeClick"
|
||||
:highlight-current="true"
|
||||
:expand-on-click-node="false"
|
||||
:default-expand-all="false"
|
||||
:filter-node-method="filterResourceNode"
|
||||
>
|
||||
<template #default="{ node, data }">
|
||||
<span class="custom-tree-node" :class="{ 'is-disabled': node.disabled || data.root }">
|
||||
<span
|
||||
:title="data.name"
|
||||
v-html="data.colorName && keyword ? data.colorName : data.name"
|
||||
/>
|
||||
</span>
|
||||
</template>
|
||||
</el-tree>
|
||||
</el-scrollbar>
|
||||
</div>
|
||||
</el-aside>
|
||||
<el-main>地理信息内容区域</el-main>
|
||||
<el-main class="geometry-main">
|
||||
<div class="geo-content-container" v-if="!selectedData">
|
||||
<EmptyBackground img-type="noneWhite" description="请在左侧选择区域" />
|
||||
</div>
|
||||
<div v-else class="geo-content-container">
|
||||
<div class="geo-content-top">
|
||||
<span>{{ selectedData.name }}</span>
|
||||
</div>
|
||||
<div class="geo-content-middle">
|
||||
<div class="geo-area">
|
||||
<div class="area-label"><span>区域代码</span></div>
|
||||
<div class="area-content">
|
||||
<span>{{ selectedData.id }}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="geo-area">
|
||||
<div class="area-label"><span>上级区域</span></div>
|
||||
<div class="area-content">
|
||||
<span>{{ selectedData.parentName }}</span>
|
||||
<span v-if="selectedData.pid" class="area-secondary">{{
|
||||
'(' + selectedData.pid + ')'
|
||||
}}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="geo-content-bottom">
|
||||
<div class="area-label"><span>坐标文件</span></div>
|
||||
<el-scrollbar class="area-content-geo">
|
||||
<span>{{ selectedData.geoJson }}</span>
|
||||
</el-scrollbar>
|
||||
</div>
|
||||
</div>
|
||||
</el-main>
|
||||
</el-container>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { ref } from 'vue'
|
||||
import { useI18n } from '@/hooks/web/useI18n'
|
||||
import { getWorldTree } from '@/api/map'
|
||||
import EmptyBackground from '@/components/empty-background/src/EmptyBackground.vue'
|
||||
import { getGeoJsonFile } from '@/views/chart/components/js/util'
|
||||
import { cloneDeep } from 'lodash-es'
|
||||
import { setColorName } from '@/utils/utils'
|
||||
const { t } = useI18n()
|
||||
const keyword = ref('')
|
||||
|
||||
const treeData = ref([])
|
||||
interface Tree {
|
||||
label: string
|
||||
children?: Tree[]
|
||||
}
|
||||
const areaTreeRef = ref(null)
|
||||
|
||||
const handleNodeClick = (data: Tree) => {
|
||||
console.log(data)
|
||||
}
|
||||
const selectedData = ref(null)
|
||||
|
||||
const data: Tree[] = [
|
||||
{
|
||||
label: 'Level one 1',
|
||||
children: [
|
||||
{
|
||||
label: 'Level two 1-1',
|
||||
children: [
|
||||
{
|
||||
label: 'Level three 1-1-1'
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
label: 'Level one 2',
|
||||
children: [
|
||||
{
|
||||
label: 'Level two 2-1',
|
||||
children: [
|
||||
{
|
||||
label: 'Level three 2-1-1'
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
label: 'Level two 2-2',
|
||||
children: [
|
||||
{
|
||||
label: 'Level three 2-2-1'
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
label: 'Level one 3',
|
||||
children: [
|
||||
{
|
||||
label: 'Level two 3-1',
|
||||
children: [
|
||||
{
|
||||
label: 'Level three 3-1-1'
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
label: 'Level two 3-2',
|
||||
children: [
|
||||
{
|
||||
label: 'Level three 3-2-1'
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
const handleNodeClick = async (data: Tree) => {
|
||||
selectedData.value = data
|
||||
const geoJson = cloneDeep(await getGeoJsonFile(data['id']))
|
||||
selectedData.value['geoJson'] = geoJson
|
||||
const pid = data['pid']
|
||||
if (pid) {
|
||||
const parent = areaTreeRef.value.getNode(pid)
|
||||
if (parent) {
|
||||
selectedData.value.parentName = parent.data.name
|
||||
}
|
||||
}
|
||||
]
|
||||
|
||||
const defaultProps = {
|
||||
children: 'children',
|
||||
label: 'label'
|
||||
}
|
||||
const filterResource = val => {
|
||||
areaTreeRef.value?.filter(val)
|
||||
}
|
||||
const filterResourceNode = (value: string, data) => {
|
||||
setColorName(data, value)
|
||||
if (!value) return true
|
||||
return data.name.toLocaleLowerCase().includes(value.toLocaleLowerCase())
|
||||
}
|
||||
|
||||
const loadTreeData = () => {
|
||||
getWorldTree()
|
||||
.then(res => {
|
||||
const root = res.data
|
||||
treeData.value = [root]
|
||||
})
|
||||
.catch(e => {
|
||||
console.error(e)
|
||||
})
|
||||
}
|
||||
|
||||
loadTreeData()
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
@ -112,6 +146,7 @@ const defaultProps = {
|
||||
width: 280px !important;
|
||||
border-right: 1px solid #1f232926;
|
||||
padding: 16px;
|
||||
height: 100%;
|
||||
.geo-title {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
@ -123,6 +158,7 @@ const defaultProps = {
|
||||
line-height: 24px;
|
||||
}
|
||||
.add-icon-span {
|
||||
display: none;
|
||||
color: #3370ff;
|
||||
height: 20px;
|
||||
width: 20px;
|
||||
@ -140,6 +176,79 @@ const defaultProps = {
|
||||
.geo-search {
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
.map-tree-container {
|
||||
height: calc(100% - 96px);
|
||||
overflow-y: auto;
|
||||
}
|
||||
}
|
||||
.geometry-main {
|
||||
padding: 16px !important;
|
||||
}
|
||||
}
|
||||
.geo-content-container {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
.geo-content-top {
|
||||
height: 24px;
|
||||
line-height: 24px;
|
||||
margin-bottom: 16px;
|
||||
span {
|
||||
font-weight: 500;
|
||||
font-size: 16px;
|
||||
color: #1f2329;
|
||||
}
|
||||
}
|
||||
.geo-content-middle {
|
||||
display: flex;
|
||||
.geo-area {
|
||||
height: 48px;
|
||||
width: 50%;
|
||||
}
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
:deep(.area-label) {
|
||||
height: 22px;
|
||||
line-height: 22px;
|
||||
span {
|
||||
font-size: 14px;
|
||||
color: #646a73;
|
||||
font-weight: 400;
|
||||
}
|
||||
}
|
||||
:deep(.area-content) {
|
||||
line-height: 22px;
|
||||
height: 22px;
|
||||
span {
|
||||
font-size: 14px;
|
||||
color: #1f2329;
|
||||
font-weight: 400;
|
||||
}
|
||||
.area-secondary {
|
||||
color: #646a73;
|
||||
}
|
||||
}
|
||||
.geo-content-bottom {
|
||||
width: 100%;
|
||||
height: calc(100% - 110px);
|
||||
.area-content-geo {
|
||||
line-height: 22px;
|
||||
overflow-x: hidden;
|
||||
overflow-y: auto;
|
||||
height: calc(100% - 30px);
|
||||
span {
|
||||
font-size: 14px;
|
||||
color: #1f2329;
|
||||
font-weight: 400;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.custom-tree-node {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
box-sizing: content-box;
|
||||
padding-right: 4px;
|
||||
overflow: hidden;
|
||||
}
|
||||
</style>
|
||||
|
||||
2
de-xpack
2
de-xpack
@ -1 +1 @@
|
||||
Subproject commit 1ca8187376d058b65d163dbad52ff6159ca024f3
|
||||
Subproject commit c2c4436bac4d300e5297ff1854fd6d45e01435ad
|
||||
Loading…
Reference in New Issue
Block a user