更新前端src/components目录文件

This commit is contained in:
limengnan 2025-06-23 18:21:36 +08:00
parent 06ce725f8d
commit 3269955233
55 changed files with 923 additions and 701 deletions

View File

@ -64,21 +64,23 @@ const handleCheckAllChange = (val: CheckboxValueType) => {
</el-button> </el-button>
<template #dropdown> <template #dropdown>
<el-dropdown-menu class="list-columns-select"> <el-dropdown-menu class="list-columns-select">
<p class="title">{{ $t('component.selectInfo') }}</p> <el-main class="main-div-select">
<el-checkbox <p class="title">{{ $t('component.selectInfo') }}</p>
v-model="checkAll" <el-checkbox
:indeterminate="isIndeterminate" v-model="checkAll"
@change="handleCheckAllChange" :indeterminate="isIndeterminate"
>{{ $t('component.allSelect') }}</el-checkbox @change="handleCheckAllChange"
> >{{ $t('component.allSelect') }}</el-checkbox
<el-checkbox-group >
v-model="state.checkedColumnNames" <el-checkbox-group
@change="handleCheckedColumnNamesChange" v-model="state.checkedColumnNames"
> @change="handleCheckedColumnNamesChange"
<el-checkbox v-for="column in columnNames" :key="column.props" :label="column.props">{{ >
$t(column.label) <el-checkbox v-for="column in columnNames" :key="column.props" :label="column.props">{{
}}</el-checkbox> $t(column.label)
</el-checkbox-group> }}</el-checkbox>
</el-checkbox-group>
</el-main>
</el-dropdown-menu> </el-dropdown-menu>
</template> </template>
</el-dropdown> </el-dropdown>
@ -102,5 +104,9 @@ const handleCheckAllChange = (val: CheckboxValueType) => {
.ed-checkbox { .ed-checkbox {
width: 100%; width: 100%;
} }
.main-div-select {
max-height: 320px;
padding: 0;
}
} }
</style> </style>

View File

@ -120,13 +120,7 @@ const emits = defineEmits(['update:modelValue'])
</el-tab-pane> </el-tab-pane>
</el-tabs> </el-tabs>
<!-- table --> <!-- table -->
<el-table <el-table :data="tableData" size="mini" border style="width: 100%">
header-cell-class-name="header-cell"
:data="tableData"
size="mini"
border
style="width: 100%"
>
<el-table-column prop="sVal" :label="t('cron.second')" width="70" /> <el-table-column prop="sVal" :label="t('cron.second')" width="70" />
<el-table-column prop="mVal" :label="t('cron.minute')" width="70" /> <el-table-column prop="mVal" :label="t('cron.minute')" width="70" />
<el-table-column prop="hVal" :label="t('cron.hour')" width="70" /> <el-table-column prop="hVal" :label="t('cron.hour')" width="70" />

View File

@ -185,7 +185,6 @@ const saveSelfSubject = () => {
top: 4px; top: 4px;
right: 4px; right: 4px;
font-size: 12px; font-size: 12px;
color: #0089ff;
} }
} }

View File

@ -1,6 +1,6 @@
<script setup lang="ts"> <script setup lang="ts">
import dvBatch from '@/assets/svg/dv-batch_white.svg' import dvBatch from '@/assets/svg/dv-batch.svg'
import dvDashboard from '@/assets/svg/dv-dashboard_white.svg' import dvDashboard from '@/assets/svg/dv-dashboard.svg'
import dvHidden from '@/assets/svg/dv-hidden.svg' import dvHidden from '@/assets/svg/dv-hidden.svg'
import dvFilter from '@/assets/svg/dv-filter.svg' import dvFilter from '@/assets/svg/dv-filter.svg'
import dvMedia from '@/assets/svg/dv-media.svg' import dvMedia from '@/assets/svg/dv-media.svg'
@ -16,11 +16,13 @@ import icon_undo_outlined from '@/assets/svg/icon_undo_outlined.svg'
import icon_redo_outlined from '@/assets/svg/icon_redo_outlined.svg' import icon_redo_outlined from '@/assets/svg/icon_redo_outlined.svg'
import icon_pc_fullscreen from '@/assets/svg/icon_pc_fullscreen.svg' import icon_pc_fullscreen from '@/assets/svg/icon_pc_fullscreen.svg'
import dvPreviewOuter from '@/assets/svg/dv-preview-outer.svg' import dvPreviewOuter from '@/assets/svg/dv-preview-outer.svg'
import { ElMessage, ElMessageBox } from 'element-plus-secondary' import dvRecoverOutlined from '@/assets/svg/dv-recover_outlined.svg'
import dvCancelPublish from '@/assets/svg/icon_undo_outlined.svg'
import { ElIcon, ElMessage, ElMessageBox } from 'element-plus-secondary'
import eventBus from '@/utils/eventBus' import eventBus from '@/utils/eventBus'
import { useEmbedded } from '@/store/modules/embedded' import { useEmbedded } from '@/store/modules/embedded'
import { deepCopy } from '@/utils/utils' import { deepCopy } from '@/utils/utils'
import { nextTick, reactive, ref, computed, toRefs, onBeforeUnmount, onMounted } from 'vue' import { nextTick, reactive, ref, computed, onBeforeUnmount, onMounted } from 'vue'
import { dvMainStoreWithOut } from '@/store/modules/data-visualization/dvMain' import { dvMainStoreWithOut } from '@/store/modules/data-visualization/dvMain'
import { useAppStoreWithOut } from '@/store/modules/app' import { useAppStoreWithOut } from '@/store/modules/app'
import { snapshotStoreWithOut } from '@/store/modules/data-visualization/snapshot' import { snapshotStoreWithOut } from '@/store/modules/data-visualization/snapshot'
@ -37,7 +39,13 @@ import MultiplexingCanvas from '@/views/common/MultiplexingCanvas.vue'
import { useI18n } from '@/hooks/web/useI18n' import { useI18n } from '@/hooks/web/useI18n'
import { getPanelAllLinkageInfo, saveLinkage } from '@/api/visualization/linkage' import { getPanelAllLinkageInfo, saveLinkage } from '@/api/visualization/linkage'
import { queryVisualizationJumpInfo } from '@/api/visualization/linkJump' import { queryVisualizationJumpInfo } from '@/api/visualization/linkJump'
import { canvasSave, checkCanvasChangePre, initCanvasData } from '@/utils/canvasUtils' import {
canvasSave,
canvasSaveWithParams,
checkCanvasChangePre,
findAllViewsId,
initCanvasData
} from '@/utils/canvasUtils'
import { useEmitt } from '@/hooks/web/useEmitt' import { useEmitt } from '@/hooks/web/useEmitt'
import { copyStoreWithOut } from '@/store/modules/data-visualization/copy' import { copyStoreWithOut } from '@/store/modules/data-visualization/copy'
import TabsGroup from '@/custom-component/component-group/TabsGroup.vue' import TabsGroup from '@/custom-component/component-group/TabsGroup.vue'
@ -49,8 +57,7 @@ import { useCache } from '@/hooks/web/useCache'
import DeFullscreen from '@/components/visualization/common/DeFullscreen.vue' import DeFullscreen from '@/components/visualization/common/DeFullscreen.vue'
import DeAppApply from '@/views/common/DeAppApply.vue' import DeAppApply from '@/views/common/DeAppApply.vue'
import { useUserStoreWithOut } from '@/store/modules/user' import { useUserStoreWithOut } from '@/store/modules/user'
import { useRoute } from 'vue-router' import { updatePublishStatus } from '@/api/visualization/dataVisualization'
const route = useRoute()
const { t } = useI18n() const { t } = useI18n()
const dvMainStore = dvMainStoreWithOut() const dvMainStore = dvMainStoreWithOut()
const snapshotStore = snapshotStoreWithOut() const snapshotStore = snapshotStoreWithOut()
@ -67,8 +74,7 @@ const {
batchOptStatus, batchOptStatus,
targetLinkageInfo, targetLinkageInfo,
curBatchOptComponents, curBatchOptComponents,
appData, appData
hiddenListStatus
} = storeToRefs(dvMainStore) } = storeToRefs(dvMainStore)
const dvModel = 'dashboard' const dvModel = 'dashboard'
const multiplexingRef = ref(null) const multiplexingRef = ref(null)
@ -86,16 +92,15 @@ const { wsCache } = useCache('localStorage')
const userStore = useUserStoreWithOut() const userStore = useUserStoreWithOut()
const isIframe = computed(() => appStore.getIsIframe) const isIframe = computed(() => appStore.getIsIframe)
const desktop = wsCache.get('app.desktop') const desktop = wsCache.get('app.desktop')
const emits = defineEmits(['recoverToPublished'])
const props = defineProps({ defineProps({
createType: { createType: {
type: String, type: String,
default: 'create' default: 'create'
} }
}) })
const { createType } = toRefs(props)
const editCanvasName = () => { const editCanvasName = () => {
nameEdit.value = true nameEdit.value = true
inputName.value = dvInfo.value.name inputName.value = dvInfo.value.name
@ -139,12 +144,12 @@ const previewInner = () => {
} }
const previewOuter = () => { const previewOuter = () => {
if (!dvInfo.value.id) { if (!dvInfo.value.id || dvInfo.value.dataState === 'prepare') {
ElMessage.warning(t('components.current_page_first')) ElMessage.warning(t('components.current_page_first'))
return return
} }
canvasSave(() => { canvasSave(() => {
let url = '#/preview?dvId=' + dvInfo.value.id + '&ignoreParams=true' let url = '#/preview?dvId=' + dvInfo.value.id + '&ignoreParams=true&editPreview=true'
if (embeddedStore.baseUrl) { if (embeddedStore.baseUrl) {
url = `${embeddedStore.baseUrl}${url}`.replaceAll('\/\/#', '\/#') url = `${embeddedStore.baseUrl}${url}`.replaceAll('\/\/#', '\/#')
} }
@ -177,11 +182,34 @@ const resourceOptFinish = param => {
dvInfo.value.dataState = 'ready' dvInfo.value.dataState = 'ready'
dvInfo.value.pid = param.pid dvInfo.value.pid = param.pid
dvInfo.value.name = param.name dvInfo.value.name = param.name
saveCanvasWithCheck() saveCanvasWithCheck(param.withPublish, param.status)
} }
} }
const saveCanvasWithCheck = () => { const recoverToPublished = () => {
emits('recoverToPublished')
}
const publishStatusChange = status => {
const targetViewIds = []
findAllViewsId(componentData.value, targetViewIds)
// do update
updatePublishStatus({
id: dvInfo.value.id,
name: dvInfo.value.name,
mobileLayout: dvInfo.value.mobileLayout,
activeViewIds: targetViewIds,
status,
type: 'dashboard'
}).then(() => {
dvMainStore.updateDvInfoCall(status)
status
? ElMessage.success(t('visualization.published_success'))
: ElMessage.success(t('visualization.cancel_publish_tips'))
})
}
const saveCanvasWithCheck = (withPublish = false, status?) => {
if (userStore.getOid && wsCache.get('user.oid') && userStore.getOid !== wsCache.get('user.oid')) { if (userStore.getOid && wsCache.get('user.oid') && userStore.getOid !== wsCache.get('user.oid')) {
ElMessageBox.confirm(t('components.from_other_organizations'), { ElMessageBox.confirm(t('components.from_other_organizations'), {
confirmButtonType: 'primary', confirmButtonType: 'primary',
@ -212,28 +240,27 @@ const saveCanvasWithCheck = () => {
}) })
} else { } else {
const params = { name: dvInfo.value.name, leaf: true, id: dvInfo.value.pid || '0' } const params = { name: dvInfo.value.name, leaf: true, id: dvInfo.value.pid || '0' }
resourceGroupOpt.value.optInit('leaf', params, 'newLeaf', true) resourceGroupOpt.value.optInit('leaf', params, 'newLeaf', true, { withPublish, status })
return return
} }
} }
checkCanvasChangePre(() => { checkCanvasChangePre(() => {
saveResource() saveResource({ withPublish, status })
}) })
} }
const saveResource = () => { const saveResource = (checkParams?) => {
wsCache.delete('DE-DV-CATCH-' + dvInfo.value.id) wsCache.delete('DE-DV-CATCH-' + dvInfo.value.id)
if (styleChangeTimes.value > 0) { if (styleChangeTimes.value > 0 || checkParams.withPublish) {
dvMainStore.matrixSizeAdaptor() dvMainStore.matrixSizeAdaptor()
queryList.value.forEach(ele => { queryList.value.forEach(ele => {
useEmitt().emitter.emit(`updateQueryCriteria${ele.id}`) useEmitt().emitter.emit(`updateQueryCriteria${ele.id}`)
}) })
try { try {
canvasSave(() => { canvasSaveWithParams(checkParams, () => {
snapshotStore.resetStyleChangeTimes() snapshotStore.resetStyleChangeTimes()
ElMessage.success(t('common.save_success'))
let url = window.location.href let url = window.location.href
url = url.replace(/\?opt=create/, `?resourceId=${dvInfo.value.id}`) url = url.replace(/(#\/[^?]*)(?:\?[^#]*)?/, `$1?resourceId=${dvInfo.value.id}`)
if (!embeddedStore.baseUrl) { if (!embeddedStore.baseUrl) {
window.history.replaceState( window.history.replaceState(
{ {
@ -243,15 +270,23 @@ const saveResource = () => {
url url
) )
} }
if (appData.value) { if (appData.value) {
initCanvasData(dvInfo.value.id, 'dashboard', () => { initCanvasData(
useEmitt().emitter.emit('refresh-dataset-selector') dvInfo.value.id,
useEmitt().emitter.emit('calcData-all') { busiFlag: 'dashboard', resourceTable: 'snapshot' },
resourceAppOpt.value.close() () => {
dvMainStore.setAppDataInfo(null) useEmitt().emitter.emit('refresh-dataset-selector')
snapshotStore.resetSnapshot() useEmitt().emitter.emit('calcData-all')
}) resourceAppOpt.value.close()
dvMainStore.setAppDataInfo(null)
snapshotStore.resetSnapshot()
}
)
}
if (checkParams.withPublish) {
publishStatusChange(checkParams.status)
} else {
ElMessage.success(t('commons.save_success'))
} }
}) })
} catch (e) { } catch (e) {
@ -408,7 +443,7 @@ const openOuterParamsSet = () => {
ElMessage.warning(t('components.add_components_first')) ElMessage.warning(t('components.add_components_first'))
return return
} }
if (!dvInfo.value.id) { if (!dvInfo.value.id || dvInfo.value.dataState === 'prepare') {
ElMessage.warning(t('components.current_page_first')) ElMessage.warning(t('components.current_page_first'))
return return
} }
@ -817,11 +852,10 @@ const initOpenHandler = newWindow => {
height: @top-bar-height; height: @top-bar-height;
white-space: nowrap; white-space: nowrap;
overflow-x: auto; overflow-x: auto;
background: #252626; background: #050e21;
color: #ffffff; color: #ffffff;
display: flex; display: flex;
transition: 0.5s; transition: 0.5s;
box-shadow: 0px 2px 4px 0px rgba(31, 35, 41, 0.12);
.back-icon { .back-icon {
margin-left: 20px; margin-left: 20px;
margin-top: 22px; margin-top: 22px;

View File

@ -70,12 +70,13 @@
:title="t('visualization.table_color_matching')" :title="t('visualization.table_color_matching')"
name="table_color_matching" name="table_color_matching"
class="inner-collapse" class="inner-collapse"
:effect="themes"
:class="`inner-collapse_${themes}`" :class="`inner-collapse_${themes}`"
> >
<div style="padding: 0 8px 8px"> <div style="padding: 0 8px 8px">
<el-row :gutter="8"> <el-row :gutter="8">
<el-col :span="12"> <el-col :span="12">
<el-form-item :label="t('chart.table_header_bg')" class="form-item"> <el-form-item :label="t('chart.table_header_row_bg')" class="form-item">
<el-color-picker <el-color-picker
:trigger-width="colorPickerWidth" :trigger-width="colorPickerWidth"
v-model="colorForm['tableHeader']['tableHeaderBgColor']" v-model="colorForm['tableHeader']['tableHeaderBgColor']"
@ -115,6 +116,34 @@
/> />
</el-form-item> </el-form-item>
</el-col> </el-col>
<el-col :span="12">
<el-form-item :label="t('chart.colBackgroundColor')" class="form-item">
<el-color-picker
:trigger-width="colorPickerWidth"
v-model="colorForm['tableHeader']['tableHeaderColBgColor']"
size="small"
:predefine="predefineColors"
color-format="rgb"
:effect="themes"
is-custom
@change="changeColorCase('tableHeaderColBgColor')"
/>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item :label="t('chart.cornerBackgroundColor')" class="form-item">
<el-color-picker
:trigger-width="colorPickerWidth"
v-model="colorForm['tableHeader']['tableHeaderCornerBgColor']"
size="small"
:predefine="predefineColors"
color-format="rgb"
:effect="themes"
is-custom
@change="changeColorCase('tableHeaderCornerBgColor')"
/>
</el-form-item>
</el-col>
<el-col :span="12"> <el-col :span="12">
<el-form-item :label="t('chart.table_item_font_color')" class="form-item"> <el-form-item :label="t('chart.table_item_font_color')" class="form-item">
<el-color-picker <el-color-picker
@ -128,8 +157,6 @@
/> />
</el-form-item> </el-form-item>
</el-col> </el-col>
</el-row>
<el-row :gutter="8">
<el-col :span="12"> <el-col :span="12">
<el-form-item :label="t('chart.table_border_color')" class="form-item"> <el-form-item :label="t('chart.table_border_color')" class="form-item">
<el-color-picker <el-color-picker
@ -425,7 +452,7 @@ span {
max-width: 192px; max-width: 192px;
} }
:deep(.custom-color-setting-btn) { :deep(.custom-color-setting-btn) {
margin-top: 31px; margin-top: 28px;
} }
} }

View File

@ -1,6 +1,6 @@
<template> <template>
<div style="width: 100%; padding-bottom: 8px"> <div style="width: 100%">
<el-form label-position="top" style="width: 100%"> <el-form label-position="top" size="small" style="width: 100%">
<div style="width: 100%; padding: 16px 8px 0"> <div style="width: 100%; padding: 16px 8px 0">
<el-row :gutter="8"> <el-row :gutter="8">
<el-col :span="12"> <el-col :span="12">

View File

@ -1,5 +1,5 @@
<template> <template>
<el-form label-position="top"> <el-form size="small" label-position="top">
<el-form-item <el-form-item
class="form-item" class="form-item"
:class="'form-item-' + themes" :class="'form-item-' + themes"
@ -38,17 +38,45 @@
/> />
</el-select> </el-select>
</el-form-item> </el-form-item>
<el-form-item <template v-if="dvInfo.type === 'dashboard'">
v-if="dvInfo.type === 'dashboard'" <el-form-item
class="form-item" class="form-item"
:class="'form-item-' + themes" :class="'form-item-' + themes"
:label="t('visualization.component_gap')" :label="t('visualization.component_gap')"
> >
<el-radio-group v-model="canvasStyleData.dashboard.gap" @change="themeChange"> <el-radio-group v-model="canvasStyleData.dashboard.gap" @change="themeChange">
<el-radio :effect="themes" label="yes">{{ t('visualization.gap') }}</el-radio> <el-radio :effect="themes" label="yes">{{ t('visualization.gap') }}</el-radio>
<el-radio :effect="themes" label="no">{{ t('visualization.no_gap') }}</el-radio> <el-radio :effect="themes" label="no">{{ t('visualization.no_gap') }}</el-radio>
</el-radio-group> </el-radio-group>
</el-form-item> </el-form-item>
<el-form-item
v-if="canvasStyleData.dashboard.gap === 'yes'"
class="form-item"
:class="'form-item-' + themes"
:label="t('visualization.gap_size')"
>
<el-radio-group v-model="canvasStyleData.dashboard.gapMode" @change="onGapModeChange">
<el-radio :effect="themes" label="small">{{ t('visualization.small') }}</el-radio>
<el-radio :effect="themes" label="middle">{{ t('visualization.middle') }}</el-radio>
<el-radio :effect="themes" label="large">{{ t('visualization.large') }}</el-radio>
<el-radio :effect="themes" label="custom">{{ t('visualization.custom') }}</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item
class="form-item"
:class="'form-item-' + themes"
v-show="canvasStyleData.dashboard.gapMode === 'custom'"
>
<el-input-number
v-model="canvasStyleData.dashboard.gapSize"
:effect="themes"
controls-position="right"
:min="0"
:max="10"
@change="themeChange"
/>
</el-form-item>
</template>
<el-form-item <el-form-item
v-if="dvInfo.type === 'dashboard'" v-if="dvInfo.type === 'dashboard'"
class="form-item" class="form-item"
@ -83,14 +111,12 @@
type="number" type="number"
:min="1" :min="1"
:max="3600" :max="3600"
size="middle"
:disabled="!canvasStyleData.refreshViewEnable" :disabled="!canvasStyleData.refreshViewEnable"
@change="onRefreshChange" @change="onRefreshChange"
> >
<template #append> <template #append>
<el-select <el-select
v-model="canvasStyleData.refreshUnit" v-model="canvasStyleData.refreshUnit"
size="middle"
:effect="themes" :effect="themes"
:disabled="!canvasStyleData.refreshViewEnable" :disabled="!canvasStyleData.refreshViewEnable"
style="width: 90px" style="width: 90px"
@ -133,14 +159,12 @@
type="number" type="number"
:min="1" :min="1"
:max="3600" :max="3600"
size="middle"
:disabled="!canvasStyleData.refreshBrowserEnable" :disabled="!canvasStyleData.refreshBrowserEnable"
@change="onRefreshChange" @change="onRefreshChange"
> >
<template #append> <template #append>
<el-select <el-select
v-model="canvasStyleData.refreshBrowserUnit" v-model="canvasStyleData.refreshBrowserUnit"
size="middle"
:effect="themes" :effect="themes"
:disabled="!canvasStyleData.refreshBrowserEnable" :disabled="!canvasStyleData.refreshBrowserEnable"
style="width: 90px" style="width: 90px"
@ -203,7 +227,6 @@
v-model="canvasStyleData.dashboard.resultCount" v-model="canvasStyleData.dashboard.resultCount"
:effect="themes" :effect="themes"
controls-position="right" controls-position="right"
size="middle"
:min="1" :min="1"
:max="10000" :max="10000"
@change="themeChange" @change="themeChange"
@ -308,7 +331,7 @@ const fontFamily = CHART_FONT_FAMILY_ORIGIN.concat(
) )
const toolTip = computed(() => { const toolTip = computed(() => {
return props.themes === 'dark' ? 'ndark' : 'dark' return props.themes === 'dark' ? 'light' : 'dark'
}) })
const resourceType = computed(() => const resourceType = computed(() =>
@ -338,6 +361,22 @@ const onKeepSizeChange = () => {
eventBus.emit('event-canvas-size-init') eventBus.emit('event-canvas-size-init')
snapshotStore.recordSnapshotCache('renderChart') snapshotStore.recordSnapshotCache('renderChart')
} }
const onGapModeChange = () => {
snapshotStore.recordSnapshotCache('renderChart')
switch (canvasStyleData.value.dashboard.gapMode) {
case 'small':
canvasStyleData.value.dashboard.gapSize = 3
break
case 'middle':
canvasStyleData.value.dashboard.gapSize = 5
break
case 'large':
canvasStyleData.value.dashboard.gapSize = 10
break
default:
break
}
}
const themeChange = (modifyName?) => { const themeChange = (modifyName?) => {
if (modifyName === 'themeColor') { if (modifyName === 'themeColor') {

View File

@ -1,17 +1,18 @@
<template> <template>
<div style="width: 100%; padding-bottom: 16px"> <div style="width: 100%; padding-bottom: 8px">
<el-form label-position="top" style="width: 100%"> <el-form label-position="top" style="width: 100%">
<div style="width: 100%; padding: 16px 8px 0"> <div style="width: 100%; padding: 16px 8px 0">
<el-row :gutter="8"> <el-row :gutter="8">
<el-col :span="12"> <el-col :span="12">
<el-form-item <el-form-item
:effect="themes" :effect="themes"
class="form-item" class="form-item h-auto"
:class="'form-item-' + themes" :class="'form-item-' + themes"
:label="t('components.jump_icon_color')" :label="t('components.jump_icon_color')"
> >
<el-color-picker <el-color-picker
:effect="themes" :effect="themes"
size="small"
v-model="seniorStyleSetting.linkageIconColor" v-model="seniorStyleSetting.linkageIconColor"
:trigger-width="100" :trigger-width="100"
is-custom is-custom
@ -23,7 +24,7 @@
<el-col :span="12"> <el-col :span="12">
<el-form-item <el-form-item
:effect="themes" :effect="themes"
class="form-item" class="form-item h-auto"
:class="'form-item-' + themes" :class="'form-item-' + themes"
:label="t('components.level_display_color')" :label="t('components.level_display_color')"
> >
@ -31,6 +32,7 @@
v-model="seniorStyleSetting.drillLayerColor" v-model="seniorStyleSetting.drillLayerColor"
:effect="themes" :effect="themes"
:trigger-width="100" :trigger-width="100"
size="small"
is-custom is-custom
:predefine="state.predefineColors" :predefine="state.predefineColors"
@change="themeChange" @change="themeChange"
@ -58,7 +60,7 @@ const seniorStyleSetting = computed<any>(() => {
return dvMainStore.canvasStyleData.component.seniorStyleSetting return dvMainStore.canvasStyleData.component.seniorStyleSetting
}) })
const props = defineProps({ defineProps({
themes: { themes: {
type: String, type: String,
default: 'light' default: 'light'
@ -109,7 +111,7 @@ onMounted(() => {
} }
} }
.ed-form-item { .ed-form-item {
margin-bottom: 16px; margin-bottom: 8px;
:deep(.ed-form-item__label) { :deep(.ed-form-item__label) {
color: #646a73; color: #646a73;
@ -118,6 +120,12 @@ onMounted(() => {
line-height: 20px; line-height: 20px;
} }
} }
.h-auto {
:deep(.ed-form-item__label) {
height: auto;
}
}
.form-item-dark { .form-item-dark {
:deep(.ed-form-item__label) { :deep(.ed-form-item__label) {
color: #6a6a6a; color: #6a6a6a;

View File

@ -11,6 +11,7 @@
v-model="titleForm.color" v-model="titleForm.color"
class="color-picker-style" class="color-picker-style"
is-custom is-custom
size="small"
:predefine="state.predefineColors" :predefine="state.predefineColors"
@change="changeTitleStyle('color')" @change="changeTitleStyle('color')"
/> />

View File

@ -159,7 +159,6 @@ onMounted(() => {
//inset: 0 0 30px; //inset: 0 0 30px;
box-sizing: border-box; box-sizing: border-box;
background-size: contain; background-size: contain;
// margin-bottom: 1px;
} }
.vertical-layout > i { .vertical-layout > i {

View File

@ -97,7 +97,7 @@ onMounted(() => {
<el-form-item class="form-item form-item-dark" label="W"> <el-form-item class="form-item form-item-dark" label="W">
<el-input-number <el-input-number
effect="dark" effect="dark"
size="middle" size="small"
:min="600" :min="600"
:max="50000" :max="50000"
v-model="canvasStyleData.width" v-model="canvasStyleData.width"
@ -110,7 +110,7 @@ onMounted(() => {
<el-form-item class="form-item form-item-dark" label="H"> <el-form-item class="form-item form-item-dark" label="H">
<el-input-number <el-input-number
effect="dark" effect="dark"
size="middle" size="small"
:min="600" :min="600"
:max="50000" :max="50000"
v-model="canvasStyleData.height" v-model="canvasStyleData.height"
@ -132,7 +132,7 @@ onMounted(() => {
</el-icon> </el-icon>
</el-tooltip> </el-tooltip>
<el-select <el-select
style="margin: 0 0 0 8px; flex: 1" style="width: 139px; margin: 0 0 0 8px; flex: 1"
effect="dark" effect="dark"
v-model="canvasStyleData.screenAdaptor" v-model="canvasStyleData.screenAdaptor"
@change="onStyleChange" @change="onStyleChange"

View File

@ -53,8 +53,6 @@ const reposition = () => {
} }
// wheel // wheel
let lastWheelNum = 0
// //
const checkDialog = () => { const checkDialog = () => {
let haveDialog = false let haveDialog = false
@ -145,7 +143,7 @@ onUnmounted(() => {
v-model="scale" v-model="scale"
:min="10" :min="10"
:max="200" :max="200"
tooltip-theme="ndark" tooltip-theme="light"
@change="handleScaleChange()" @change="handleScaleChange()"
size="small" size="small"
/> />
@ -153,7 +151,7 @@ onUnmounted(() => {
<Icon name="dv-max"><dvMax class="svg-icon"></dvMax></Icon <Icon name="dv-max"><dvMax class="svg-icon"></dvMax></Icon
></el-icon> ></el-icon>
<el-divider direction="vertical" class="custom-divider_scale" /> <el-divider direction="vertical" class="custom-divider_scale" />
<el-tooltip effect="dark" :content="t('visualization.locate_tips')" placement="top"> <el-tooltip effect="light" :content="t('visualization.locate_tips')" placement="top">
<el-icon @click="reposition" class="hover-icon-custom" style="margin-right: 12px"> <el-icon @click="reposition" class="hover-icon-custom" style="margin-right: 12px">
<Icon name="dv-reposition"><dvReposition class="svg-icon"></dvReposition></Icon <Icon name="dv-reposition"><dvReposition class="svg-icon"></dvReposition></Icon
></el-icon> ></el-icon>
@ -176,12 +174,16 @@ onUnmounted(() => {
.scale-area { .scale-area {
display: flex; display: flex;
align-items: center; align-items: center;
:deep(.ed-input-number__decrease) {
--ed-input-number-controls-height: 12px;
}
} }
} }
:deep(.ed-input--dark .ed-input__wrapper), :deep(.ed-input--dark .ed-input__wrapper),
:deep(.ed-input-number--dark:not(.is-disabled) .ed-input-number__decrease:not(.is-disabled)), :deep(.ed-input-number--dark:not(.is-disabled) .ed-input-number__decrease:not(.is-disabled)),
:deep(.ed-input-number--dark:not(.is-disabled) .ed-input-number__increase:not(.is-disabled)) { :deep(.ed-input-number--dark:not(.is-disabled) .ed-input-number__increase:not(.is-disabled)) {
background-color: #1a1a1a !important; background-color: #1a1a1a;
} }
.custom-divider_scale { .custom-divider_scale {
@ -203,6 +205,8 @@ onUnmounted(() => {
content: '%'; content: '%';
right: 35px; right: 35px;
top: 1px; top: 1px;
height: 24px;
line-height: 24px;
} }
} }
} }
@ -231,9 +235,5 @@ onUnmounted(() => {
&:active { &:active {
background: rgba(31, 35, 41, 1); background: rgba(31, 35, 41, 1);
} }
}
:deep(.scale-input-number .ed-input__wrapper::after){
top: -1px;
} }
</style> </style>

View File

@ -1,33 +1,21 @@
<script setup lang="ts"> <script setup lang="ts">
import dvFilter from '@/assets/svg/dv-filter.svg' import dvFilter from '@/assets/svg/dv-filter.svg'
import dvMaterial from '@/assets/svg/dv-material.svg' import dvMaterial from '@/assets/svg/dv-material.svg'
import dvMedia from '@/assets/newimg/camvassvg/dv-media.svg' // import dvMedia from '@/assets/svg/dv-media.svg'
import dvMap from '@/assets/newimg/camvassvg/dv-map.svg' //
import dvMoreCom from '@/assets/svg/dv-more-com.svg' import dvMoreCom from '@/assets/svg/dv-more-com.svg'
import dvTab from '@/assets/svg/dv-tab.svg' import dvTab from '@/assets/svg/dv-tab.svg'
import dvText from '@/assets/newimg/camvassvg/dv-text.svg' // import dvText from '@/assets/svg/dv-text.svg'
import dvView from '@/assets/newimg/camvassvg/dv-view.svg' // echarts import dvView from '@/assets/svg/dv-view.svg'
import dvForm from '@/assets/newimg/camvassvg/dv-form.svg' // echarts
import dvTemplate from '@/assets/newimg/camvassvg/dv-template.svg' //
// import dvView from '@/assets/newimg/dvCanvas/u4876.png'
import icon_params_setting from '@/assets/svg/icon_params_setting.svg' import icon_params_setting from '@/assets/svg/icon_params_setting.svg'
import icon_copy_filled from '@/assets/svg/icon_copy_filled.svg' import icon_copy_filled from '@/assets/svg/icon_copy_filled.svg'
import icon_left_outlined from '@/assets/svg/icon_left_outlined.svg' import icon_left_outlined from '@/assets/svg/icon_left_outlined.svg'
// import icon_undo_outlined from '@/assets/svg/icon_undo_outlined.svg' import icon_undo_outlined from '@/assets/svg/icon_undo_outlined.svg'
// import icon_redo_outlined from '@/assets/svg/icon_redo_outlined.svg' import icon_redo_outlined from '@/assets/svg/icon_redo_outlined.svg'
import { ElMessage, ElMessageBox } from 'element-plus-secondary' import dvRecoverOutlined from '@/assets/svg/dv-recover_outlined.svg'
import dvCancelPublish from '@/assets/svg/icon_undo_outlined.svg'
import { ElIcon, ElMessage, ElMessageBox } from 'element-plus-secondary'
import eventBus from '@/utils/eventBus' import eventBus from '@/utils/eventBus'
import { ref, nextTick, computed, toRefs, onBeforeUnmount, onMounted } from 'vue' import { ref, nextTick, computed, onBeforeUnmount, onMounted } from 'vue'
import { useEmbedded } from '@/store/modules/embedded' import { useEmbedded } from '@/store/modules/embedded'
import { dvMainStoreWithOut } from '@/store/modules/data-visualization/dvMain' import { dvMainStoreWithOut } from '@/store/modules/data-visualization/dvMain'
import { snapshotStoreWithOut } from '@/store/modules/data-visualization/snapshot' import { snapshotStoreWithOut } from '@/store/modules/data-visualization/snapshot'
@ -40,7 +28,13 @@ import MediaGroup from '@/custom-component/component-group/MediaGroup.vue'
import TextGroup from '@/custom-component/component-group/TextGroup.vue' import TextGroup from '@/custom-component/component-group/TextGroup.vue'
import CommonGroup from '@/custom-component/component-group/CommonGroup.vue' import CommonGroup from '@/custom-component/component-group/CommonGroup.vue'
import DeResourceGroupOpt from '@/views/common/DeResourceGroupOpt.vue' import DeResourceGroupOpt from '@/views/common/DeResourceGroupOpt.vue'
import { canvasSave, checkCanvasChangePre, initCanvasData } from '@/utils/canvasUtils' import {
canvasSave,
canvasSaveWithParams,
checkCanvasChangePre,
findAllViewsId,
initCanvasData
} from '@/utils/canvasUtils'
import { changeSizeWithScale } from '@/utils/changeComponentsSizeWithScale' import { changeSizeWithScale } from '@/utils/changeComponentsSizeWithScale'
import MoreComGroup from '@/custom-component/component-group/MoreComGroup.vue' import MoreComGroup from '@/custom-component/component-group/MoreComGroup.vue'
import { XpackComponent } from '@/components/plugin' import { XpackComponent } from '@/components/plugin'
@ -56,6 +50,8 @@ import { useEmitt } from '@/hooks/web/useEmitt'
import { useUserStoreWithOut } from '@/store/modules/user' import { useUserStoreWithOut } from '@/store/modules/user'
import TabsGroup from '@/custom-component/component-group/TabsGroup.vue' import TabsGroup from '@/custom-component/component-group/TabsGroup.vue'
import { useI18n } from '@/hooks/web/useI18n' import { useI18n } from '@/hooks/web/useI18n'
import { updatePublishStatus } from '@/api/visualization/dataVisualization'
let nameEdit = ref(false) let nameEdit = ref(false)
let inputName = ref('') let inputName = ref('')
let nameInput = ref(null) let nameInput = ref(null)
@ -73,19 +69,15 @@ const dvModel = 'dataV'
const outerParamsSetRef = ref(null) const outerParamsSetRef = ref(null)
const fullScreeRef = ref(null) const fullScreeRef = ref(null)
const userStore = useUserStoreWithOut() const userStore = useUserStoreWithOut()
import { useRoute } from 'vue-router'
const route = useRoute()
const { t } = useI18n() const { t } = useI18n()
const emits = defineEmits(['recoverToPublished'])
const props = defineProps({ defineProps({
createType: { createType: {
type: String, type: String,
default: 'create' default: 'create'
} }
}) })
const { createType } = toRefs(props)
const closeEditCanvasName = () => { const closeEditCanvasName = () => {
nameEdit.value = false nameEdit.value = false
if (!inputName.value || !inputName.value.trim()) { if (!inputName.value || !inputName.value.trim()) {
@ -103,6 +95,10 @@ const closeEditCanvasName = () => {
inputName.value = '' inputName.value = ''
} }
const recoverToPublished = () => {
emits('recoverToPublished')
}
const undo = () => { const undo = () => {
snapshotStore.undo() snapshotStore.undo()
} }
@ -131,11 +127,11 @@ const resourceOptFinish = param => {
dvInfo.value.dataState = 'ready' dvInfo.value.dataState = 'ready'
dvInfo.value.pid = param.pid dvInfo.value.pid = param.pid
dvInfo.value.name = param.name dvInfo.value.name = param.name
saveCanvasWithCheck() saveCanvasWithCheck(param.withPublish, param.status)
} }
} }
const saveCanvasWithCheck = () => { const saveCanvasWithCheck = (withPublish = false, status?) => {
if (userStore.getOid && wsCache.get('user.oid') && userStore.getOid !== wsCache.get('user.oid')) { if (userStore.getOid && wsCache.get('user.oid') && userStore.getOid !== wsCache.get('user.oid')) {
ElMessageBox.confirm('已切换至新组织,无权保存其他组织的资源', { ElMessageBox.confirm('已切换至新组织,无权保存其他组织的资源', {
confirmButtonType: 'primary', confirmButtonType: 'primary',
@ -165,26 +161,29 @@ const saveCanvasWithCheck = () => {
resourceAppOpt.value.init(params) resourceAppOpt.value.init(params)
}) })
} else { } else {
const params = { name: dvInfo.value.name, leaf: true, id: dvInfo.value.pid || '0' } const params = {
resourceGroupOpt.value.optInit('leaf', params, 'newLeaf', true) name: dvInfo.value.name,
leaf: true,
id: dvInfo.value.pid || '0'
}
resourceGroupOpt.value.optInit('leaf', params, 'newLeaf', true, { withPublish, status })
} }
return return
} }
checkCanvasChangePre(() => { checkCanvasChangePre(() => {
saveResource() saveResource({ withPublish, status })
}) })
} }
const saveResource = () => { const saveResource = (checkParams?) => {
if (styleChangeTimes.value > 0) { if (styleChangeTimes.value > 0 || checkParams.withPublish) {
eventBus.emit('hideArea-canvas-main') eventBus.emit('hideArea-canvas-main')
nextTick(() => { nextTick(() => {
canvasSave(() => { canvasSaveWithParams(checkParams, () => {
snapshotStore.resetStyleChangeTimes() snapshotStore.resetStyleChangeTimes()
wsCache.delete('DE-DV-CATCH-' + dvInfo.value.id) wsCache.delete('DE-DV-CATCH-' + dvInfo.value.id)
ElMessage.success(t('commons.save_success'))
let url = window.location.href let url = window.location.href
url = url.replace(/\?opt=create/, `?dvId=${dvInfo.value.id}`) url = url.replace(/(#\/[^?]*)(?:\?[^#]*)?/, `$1?dvId=${dvInfo.value.id}`)
if (!embeddedStore.baseUrl) { if (!embeddedStore.baseUrl) {
window.history.replaceState( window.history.replaceState(
{ {
@ -195,7 +194,7 @@ const saveResource = () => {
) )
} }
if (appData.value) { if (appData.value) {
initCanvasData(dvInfo.value.id, 'dataV', () => { initCanvasData(dvInfo.value.id, { busiFlag: 'dataV', resourceTable: 'snapshot' }, () => {
useEmitt().emitter.emit('refresh-dataset-selector') useEmitt().emitter.emit('refresh-dataset-selector')
resourceAppOpt.value.close() resourceAppOpt.value.close()
dvMainStore.setAppDataInfo(null) dvMainStore.setAppDataInfo(null)
@ -203,6 +202,11 @@ const saveResource = () => {
snapshotStore.resetSnapshot() snapshotStore.resetSnapshot()
}) })
} }
if (checkParams.withPublish) {
publishStatusChange(checkParams.status)
} else {
ElMessage.success(t('commons.save_success'))
}
}) })
}) })
} }
@ -223,13 +227,10 @@ const editCanvasName = () => {
} }
const backToMain = () => { const backToMain = () => {
let url = '#/module' let url = '#/screen/index'
const appId:any = route.query.appId if (dvInfo.value.id) {
if (appId) { url = url + '?dvId=' + dvInfo.value.id
url = url + '?id=' + appId
} }
if (styleChangeTimes.value > 0) { if (styleChangeTimes.value > 0) {
ElMessageBox.confirm(t('visualization.change_save_tips'), { ElMessageBox.confirm(t('visualization.change_save_tips'), {
confirmButtonType: 'primary', confirmButtonType: 'primary',
@ -283,7 +284,6 @@ const getFullScale = () => {
return (curWidth * 100) / canvasStyleData.value.width return (curWidth * 100) / canvasStyleData.value.width
} }
const appStore = useAppStoreWithOut() const appStore = useAppStoreWithOut()
const isDataEaseBi = computed(() => appStore.getIsDataEaseBi)
const multiplexingRef = ref(null) const multiplexingRef = ref(null)
onMounted(() => { onMounted(() => {
@ -304,7 +304,7 @@ const openOuterParamsSet = () => {
ElMessage.warning(t('components.add_components_first')) ElMessage.warning(t('components.add_components_first'))
return return
} }
if (!dvInfo.value.id) { if (!dvInfo.value.id || dvInfo.value.dataState === 'prepare') {
ElMessage.warning(t('components.current_page_first')) ElMessage.warning(t('components.current_page_first'))
return return
} }
@ -318,6 +318,25 @@ const multiplexingCanvasOpen = () => {
multiplexingRef.value.dialogInit('dataV') multiplexingRef.value.dialogInit('dataV')
} }
const publishStatusChange = status => {
const targetViewIds = []
findAllViewsId(componentData.value, targetViewIds)
// do update
updatePublishStatus({
id: dvInfo.value.id,
name: dvInfo.value.name,
mobileLayout: dvInfo.value.mobileLayout,
status,
activeViewIds: targetViewIds,
type: 'dataV'
}).then(() => {
dvMainStore.updateDvInfoCall(status)
status
? ElMessage.success(t('visualization.published_success'))
: ElMessage.success(t('visualization.cancel_publish_tips'))
})
}
const isIframe = computed(() => appStore.getIsIframe) const isIframe = computed(() => appStore.getIsIframe)
const fullScreenPreview = () => { const fullScreenPreview = () => {
dvMainStore.canvasStateChange({ key: 'curPointArea', value: 'base' }) dvMainStore.canvasStateChange({ key: 'curPointArea', value: 'base' })
@ -338,25 +357,27 @@ const fullScreenPreview = () => {
</template> </template>
<template v-else> <template v-else>
<el-icon class="custom-el-icon back-icon" @click="backToMain()"> <el-icon class="custom-el-icon back-icon" @click="backToMain()">
<Icon name="icon_left_outlined" <Icon name="icon_left_outlined">
><icon_left_outlined class="svg-icon toolbar-icon" <icon_left_outlined class="svg-icon toolbar-icon" />
/></Icon> </Icon>
</el-icon> </el-icon>
<div class="left-area"> <div class="left-area">
<span id="dv-canvas-name" class="name-area" @dblclick="editCanvasName"> <span id="dv-canvas-name" class="name-area" @dblclick="editCanvasName">
{{ dvInfo.name }} {{ dvInfo.name }}
</span> </span>
<!-- <div class="opt-area"> <div class="opt-area">
<el-tooltip effect="ndark" :content="$t('visualization.undo')" placement="bottom"> <el-tooltip effect="light" :content="$t('visualization.undo')" placement="bottom">
<el-icon <el-icon
class="toolbar-hover-icon" class="toolbar-hover-icon"
:class="{ 'toolbar-icon-disabled': snapshotIndex < 1 }" :class="{ 'toolbar-icon-disabled': snapshotIndex < 1 }"
@click="undo()" @click="undo()"
> >
<Icon name="icon_undo_outlined"><icon_undo_outlined class="svg-icon" /></Icon> <Icon name="icon_undo_outlined">
<icon_undo_outlined class="svg-icon" />
</Icon>
</el-icon> </el-icon>
</el-tooltip> </el-tooltip>
<el-tooltip effect="ndark" :content="$t('commons.reduction')" placement="bottom"> <el-tooltip effect="light" :content="$t('commons.reduction')" placement="bottom">
<el-icon <el-icon
class="toolbar-hover-icon opt-icon-redo" class="toolbar-hover-icon opt-icon-redo"
:class="{ :class="{
@ -364,25 +385,16 @@ const fullScreenPreview = () => {
}" }"
@click="redo()" @click="redo()"
> >
<Icon name="icon_redo_outlined"><icon_redo_outlined class="svg-icon" /></Icon> <Icon name="icon_redo_outlined">
<icon_redo_outlined class="svg-icon" />
</Icon>
</el-icon> </el-icon>
</el-tooltip> </el-tooltip>
</div> --> </div>
</div> </div>
<div class="middle-area"> <div class="middle-area">
<div class="undo-redo" @click="undo()">
<img src="@/assets/newimg/dvCanvas/u4860.png" alt="" srcset="">
<div class="undo-redo-text">撤销</div>
</div>
<div class="undo-redo" @click="redo()">
<img src="@/assets/newimg/dvCanvas/u4867.png" alt="" srcset="">
<div class="undo-redo-text">重做</div>
</div>
<div class="tabline"></div>
<component-group <component-group
show-split-line
is-label is-label
:base-width="410" :base-width="410"
:icon-name="dvView" :icon-name="dvView"
@ -390,35 +402,9 @@ const fullScreenPreview = () => {
> >
<user-view-group></user-view-group> <user-view-group></user-view-group>
</component-group> </component-group>
<component-group
is-label
placement="bottom"
:base-width="328"
:icon-name="dvMedia"
:title="t('visualization.media')"
>
<media-group></media-group>
</component-group>
<component-group
is-label
placement="bottom"
:base-width="328"
:icon-name="dvMap"
:title="'地图'"
>
<media-group></media-group>
</component-group>
<component-group <component-group
:base-width="115" :base-width="115"
:show-split-line="true"
is-label is-label
:icon-name="dvFilter" :icon-name="dvFilter"
:title="t('visualization.query_component')" :title="t('visualization.query_component')"
@ -433,7 +419,15 @@ const fullScreenPreview = () => {
> >
<text-group></text-group> <text-group></text-group>
</component-group> </component-group>
<component-group
is-label
placement="bottom"
:base-width="328"
:icon-name="dvMedia"
:title="t('visualization.media')"
>
<media-group></media-group>
</component-group>
<component-group is-label :base-width="115" :icon-name="dvTab" title="Tab"> <component-group is-label :base-width="115" :icon-name="dvTab" title="Tab">
<tabs-group :dv-model="dvModel"></tabs-group> <tabs-group :dv-model="dvModel"></tabs-group>
</component-group> </component-group>
@ -454,33 +448,12 @@ const fullScreenPreview = () => {
> >
<common-group></common-group> <common-group></common-group>
</component-group> </component-group>
<component-button-label <component-button-label
:icon-name="icon_copy_filled" :icon-name="icon_copy_filled"
:title="t('visualization.multiplexing')" :title="t('visualization.multiplexing')"
is-label is-label
@customClick="multiplexingCanvasOpen" @customClick="multiplexingCanvasOpen"
></component-button-label> ></component-button-label>
<component-group
is-label
placement="bottom"
:base-width="328"
:icon-name="dvForm"
:title="'表单'"
>
<media-group></media-group>
</component-group>
<component-group
is-label
placement="bottom"
:base-width="328"
:icon-name="dvTemplate"
:title="'模版'"
>
<media-group></media-group>
</component-group>
</div> </div>
</template> </template>
<div class="right-area"> <div class="right-area">
@ -522,6 +495,42 @@ const fullScreenPreview = () => {
> >
{{ t('visualization.save') }} {{ t('visualization.save') }}
</el-button> </el-button>
<el-dropdown
:disabled="dvInfo.status === 0"
popper-class="menu-outer-dv_popper-toolbar"
trigger="hover"
>
<el-button
@click="saveCanvasWithCheck(true, 1)"
style="float: right; margin: 0 12px 0 0"
type="primary"
>
{{ t('visualization.publish') }}
</el-button>
<template #dropdown>
<el-dropdown-menu>
<el-dropdown-item @click="recoverToPublished" v-if="dvInfo.status === 2">
<el-icon class="handle-icon">
<Icon name="icon_left_outlined">
<dv-recover-outlined class="svg-icon toolbar-icon" />
</Icon>
</el-icon>
{{ t('visualization.publish_recover') }}
</el-dropdown-item>
<el-dropdown-item
@click.stop="publishStatusChange(0)"
v-if="[1, 2].includes(dvInfo.status)"
>
<el-icon class="handle-icon">
<Icon name="icon_left_outlined">
<dv-cancel-publish class="svg-icon toolbar-icon" />
</Icon>
</el-icon>
{{ t('visualization.cancel_publish') }}
</el-dropdown-item>
</el-dropdown-menu>
</template>
</el-dropdown>
</div> </div>
</div> </div>
<Teleport v-if="nameEdit" :to="'#dv-canvas-name'"> <Teleport v-if="nameEdit" :to="'#dv-canvas-name'">
@ -553,7 +562,7 @@ const fullScreenPreview = () => {
</div> </div>
<de-fullscreen ref="fullScreeRef" show-position="dvEdit"></de-fullscreen> <de-fullscreen ref="fullScreeRef" show-position="dvEdit"></de-fullscreen>
<multiplexing-canvas ref="multiplexingRef"></multiplexing-canvas> <multiplexing-canvas ref="multiplexingRef"></multiplexing-canvas>
<outer-params-set ref="outerParamsSetRef"> </outer-params-set> <outer-params-set ref="outerParamsSetRef"></outer-params-set>
<XpackComponent ref="openHandler" jsname="L2NvbXBvbmVudC9lbWJlZGRlZC1pZnJhbWUvT3BlbkhhbmRsZXI=" /> <XpackComponent ref="openHandler" jsname="L2NvbXBvbmVudC9lbWJlZGRlZC1pZnJhbWUvT3BlbkhhbmRsZXI=" />
</template> </template>
@ -561,52 +570,54 @@ const fullScreenPreview = () => {
.toolbar-main { .toolbar-main {
position: relative; position: relative;
} }
.preview-state-head { .preview-state-head {
height: 0px !important; height: 0px !important;
overflow: hidden; overflow: hidden;
padding: 0; padding: 0;
margin: 0; margin: 0;
} }
.edit-button { .edit-button {
right: 10px; right: 10px;
top: 10px; top: 10px;
position: absolute; position: absolute;
z-index: 10; z-index: 10;
} }
.toolbar { .toolbar {
height: @top-bar-height; height: @top-bar-height;
white-space: nowrap; white-space: nowrap;
overflow-x: auto; overflow-x: auto;
background: rgb(37,38,38); background: #1a1a1a;
color: #ffffff; color: #ffffff;
box-shadow: 0px 2px 4px 0px rgba(31, 35, 41, 0.12); box-shadow: 0px 2px 4px 0px rgba(31, 35, 41, 0.12);
display: flex; display: flex;
transition: 0.5s; transition: 0.5s;
.back-icon { .back-icon {
margin-left: 20px; margin-left: 20px;
margin-top: 22px; margin-top: 22px;
font-size: 20px; font-size: 20px;
} }
.left-area { .left-area {
margin-top: 8px; margin-top: 8px;
margin-left: 14px; margin-left: 14px;
width: 300px; width: 300px;
display: flex; display: flex;
flex-direction: column; flex-direction: column;
.name-area { .name-area {
position: relative; position: relative;
line-height: 46px; line-height: 24px;
height: 46px; height: 24px;
font-size: 16px; font-size: 16px;
width: 300px; width: 300px;
overflow: hidden; overflow: hidden;
cursor: pointer; cursor: pointer;
color: @dv-canvas-main-font-color; color: @dv-canvas-main-font-color;
font-weight: 700;
font-style: normal;
font-size: 16px;
color: #F2F4F5;
input { input {
position: absolute; position: absolute;
left: 0; left: 0;
@ -620,6 +631,7 @@ const fullScreenPreview = () => {
height: 100%; height: 100%;
} }
} }
.opt-area { .opt-area {
width: 300px; width: 300px;
text-align: left; text-align: left;
@ -630,24 +642,28 @@ const fullScreenPreview = () => {
} }
} }
} }
.middle-area { .middle-area {
flex: 1; flex: 1;
display: flex; display: flex;
align-items: center; align-items: center;
justify-content: center; justify-content: center;
} }
.right-area { .right-area {
width: 400px; width: 400px;
display: flex; display: flex;
align-items: center; align-items: center;
justify-content: right; justify-content: right;
} }
.custom-el-icon { .custom-el-icon {
margin-left: 15px; margin-left: 15px;
color: #ffffff; color: #ffffff;
cursor: pointer; cursor: pointer;
vertical-align: -0.2em; vertical-align: -0.2em;
} }
.toolbar-icon { .toolbar-icon {
width: 20px; width: 20px;
height: 20px; height: 20px;
@ -658,6 +674,7 @@ const fullScreenPreview = () => {
border-color: rgba(255, 255, 255, 0.3); border-color: rgba(255, 255, 255, 0.3);
color: #ffffff; color: #ffffff;
background-color: transparent; background-color: transparent;
&:hover, &:hover,
&:focus { &:focus {
background-color: transparent; background-color: transparent;
@ -680,37 +697,6 @@ const fullScreenPreview = () => {
margin-right: 20px; margin-right: 20px;
margin-left: 10px; margin-left: 10px;
} }
.undo-redo{
width: 47px;
height: 47px;
display: flex;
justify-content: center;
// items-content: center;
align-content: center;
flex-wrap: wrap;
border-radius: 3px;
cursor: pointer;
.undo-redo-text{
width: 100%;
font-family: '微软雅黑';
font-weight: 400;
font-style: normal;
font-size: 12px;
color: #F2F4F5;
text-align: center;
padding-top: 5px;
}
}
.undo-redo:hover{
background-color: rgba(54, 55, 56, 1);
}
.tabline{
width: 1px;
height: 40px;
background-color: rgba(255, 255, 255, 0.15);
margin: 0px 10px;
}
</style> </style>
<style> <style>
.ed-message-box{ .ed-message-box{

View File

@ -77,6 +77,7 @@ import ComposeShow from '@/components/data-visualization/canvas/ComposeShow.vue'
import { composeStoreWithOut } from '@/store/modules/data-visualization/compose' import { composeStoreWithOut } from '@/store/modules/data-visualization/compose'
import circlePackingOrigin from '@/assets/svg/circle-packing-origin.svg' import circlePackingOrigin from '@/assets/svg/circle-packing-origin.svg'
import RealTimeTab from '@/components/data-visualization/RealTimeTab.vue' import RealTimeTab from '@/components/data-visualization/RealTimeTab.vue'
import bulletGraphOrigin from '@/assets/svg/bullet-graph-origin.svg'
import { syncViewTitle } from '@/utils/canvasUtils' import { syncViewTitle } from '@/utils/canvasUtils'
const dropdownMore = ref(null) const dropdownMore = ref(null)
const lockStore = lockStoreWithOut() const lockStore = lockStoreWithOut()
@ -245,7 +246,8 @@ const iconMap = {
'word-cloud-origin': wordCloudOrigin, 'word-cloud-origin': wordCloudOrigin,
't-heatmap-origin': tHeatmapOrigin, 't-heatmap-origin': tHeatmapOrigin,
group: group, group: group,
'circle-packing-origin': circlePackingOrigin 'circle-packing-origin': circlePackingOrigin,
'bullet-graph-origin': bulletGraphOrigin
} }
const getIconName = item => { const getIconName = item => {
if (item.component === 'UserView') { if (item.component === 'UserView') {

View File

@ -74,6 +74,7 @@ import ContextMenuAsideDetails from '@/components/data-visualization/canvas/Cont
import ComposeShow from '@/components/data-visualization/canvas/ComposeShow.vue' import ComposeShow from '@/components/data-visualization/canvas/ComposeShow.vue'
import { composeStoreWithOut } from '@/store/modules/data-visualization/compose' import { composeStoreWithOut } from '@/store/modules/data-visualization/compose'
import circlePackingOrigin from '@/assets/svg/circle-packing-origin.svg' import circlePackingOrigin from '@/assets/svg/circle-packing-origin.svg'
import bulletGraphOrigin from '@/assets/svg/bullet-graph-origin.svg'
import { syncViewTitle } from '@/utils/canvasUtils' import { syncViewTitle } from '@/utils/canvasUtils'
const dropdownMore = ref(null) const dropdownMore = ref(null)
const lockStore = lockStoreWithOut() const lockStore = lockStoreWithOut()
@ -242,7 +243,8 @@ const iconMap = {
'word-cloud-origin': wordCloudOrigin, 'word-cloud-origin': wordCloudOrigin,
't-heatmap-origin': tHeatmapOrigin, 't-heatmap-origin': tHeatmapOrigin,
group: group, group: group,
'circle-packing-origin': circlePackingOrigin 'circle-packing-origin': circlePackingOrigin,
'bullet-graph-origin': bulletGraphOrigin
} }
const getIconName = item => { const getIconName = item => {
if (item.component === 'UserView') { if (item.component === 'UserView') {

View File

@ -81,6 +81,7 @@ import { contextmenuStoreWithOut } from '@/store/modules/data-visualization/cont
import RealTimeTab from '@/components/data-visualization/RealTimeTab.vue' import RealTimeTab from '@/components/data-visualization/RealTimeTab.vue'
import { useI18n } from '@/hooks/web/useI18n' import { useI18n } from '@/hooks/web/useI18n'
import circlePackingOrigin from '@/assets/svg/circle-packing-origin.svg' import circlePackingOrigin from '@/assets/svg/circle-packing-origin.svg'
import bulletGraphOrigin from '@/assets/svg/bullet-graph-origin.svg'
import { checkJoinGroup, syncViewTitle } from '@/utils/canvasUtils' import { checkJoinGroup, syncViewTitle } from '@/utils/canvasUtils'
import { useEmitt } from '@/hooks/web/useEmitt' import { useEmitt } from '@/hooks/web/useEmitt'
const dropdownMore = ref(null) const dropdownMore = ref(null)
@ -242,6 +243,7 @@ const unlock = () => {
const hideComponent = () => { const hideComponent = () => {
setTimeout(() => { setTimeout(() => {
layerStore.hideComponent() layerStore.hideComponent()
layerStore.pausedTooltipCarousel(curComponent.value.id)
snapshotStore.recordSnapshotCache('realTime-hideComponent') snapshotStore.recordSnapshotCache('realTime-hideComponent')
}) })
} }
@ -249,6 +251,7 @@ const hideComponent = () => {
const showComponent = () => { const showComponent = () => {
setTimeout(() => { setTimeout(() => {
layerStore.showComponent() layerStore.showComponent()
layerStore.resumeTooltipCarousel(curComponent.value.id)
snapshotStore.recordSnapshotCache('showComponent') snapshotStore.recordSnapshotCache('showComponent')
}) })
} }
@ -333,7 +336,8 @@ const iconMap = {
't-heatmap-origin': tHeatmapOrigin, 't-heatmap-origin': tHeatmapOrigin,
'picture-group-origin': pictureGroupOrigin, 'picture-group-origin': pictureGroupOrigin,
group: group, group: group,
'circle-packing-origin': circlePackingOrigin 'circle-packing-origin': circlePackingOrigin,
'bullet-graph-origin': bulletGraphOrigin
} }
const getIconName = item => { const getIconName = item => {
if (item.component === 'UserView') { if (item.component === 'UserView') {

View File

@ -75,25 +75,13 @@ const closeEditComponentName = () => {
curEditComponent = null curEditComponent = null
} }
const dragOnEnd = ({ oldIndex, newIndex }) => { const dragOnEnd = ({ newIndex }) => {
const source = componentData.value[newIndex] const source = componentData.value[newIndex]
dvMainStore.setCurTabName(source.title) dvMainStore.setCurTabName(source.title)
eventBus.emit('onTabSortChange-' + tabElement.value?.id) eventBus.emit('onTabSortChange-' + tabElement.value?.id)
snapshotStore.recordSnapshotCache('dragOnEnd') snapshotStore.recordSnapshotCache('dragOnEnd')
} }
const menuAsideClose = (param, index) => {
const iconDom = document.getElementById('close-button')
if (iconDom) {
iconDom.click()
}
if (param?.opt === 'rename') {
setTimeout(() => {
editComponentName(getComponent(index))
}, 200)
}
}
const handleContextMenu = e => { const handleContextMenu = e => {
e.preventDefault() e.preventDefault()
// //

View File

@ -57,7 +57,6 @@ const contextmenuStore = contextmenuStoreWithOut()
const { curComponent, dvInfo, editMode, tabMoveOutComponentId, canvasState, mainScrollTop } = const { curComponent, dvInfo, editMode, tabMoveOutComponentId, canvasState, mainScrollTop } =
storeToRefs(dvMainStore) storeToRefs(dvMainStore)
const { editorMap, areaData, isCtrlOrCmdDown } = storeToRefs(composeStore) const { editorMap, areaData, isCtrlOrCmdDown } = storeToRefs(composeStore)
const emits = defineEmits(['scrollCanvasAdjust'])
const props = defineProps({ const props = defineProps({
themes: { themes: {
type: String, type: String,
@ -263,7 +262,7 @@ watch(
watch( watch(
() => areaData.value.components.length, () => areaData.value.components.length,
(val, oldVal) => { () => {
groupAreaClickChange() groupAreaClickChange()
} }
) )
@ -936,7 +935,7 @@ function removeItem(index) {
dvMainStore.removeLinkageInfo(item['id']) dvMainStore.removeLinkageInfo(item['id'])
if (isMainCanvas(canvasId.value)) { if (isMainCanvas(canvasId.value)) {
// componentData // componentData
dvMainStore.deleteComponentById(item.id) dvMainStore.deleteComponentById(item.id, undefined, false)
} else { } else {
componentData.value.splice(index, 1) componentData.value.splice(index, 1)
} }

View File

@ -1,28 +1,28 @@
<script setup lang="ts"> <script setup lang="ts">
import { getStyle } from '@/utils/style' import { getStyle } from '@/utils/style'
import eventBus from '@/utils/eventBus' import eventBus from '@/utils/eventBus'
import { ref, onMounted, toRefs, getCurrentInstance, computed, nextTick } from 'vue' import { ref, toRefs, computed, nextTick } from 'vue'
import findComponent from '@/utils/components' import findComponent from '@/utils/components'
import { downloadCanvas2, imgUrlTrans } from '@/utils/imgUtils' import { downloadCanvas2, imgUrlTrans } from '@/utils/imgUtils'
import ComponentEditBar from '@/components/visualization/ComponentEditBar.vue' import ComponentEditBar from '@/components/visualization/ComponentEditBar.vue'
import ComponentSelector from '@/components/visualization/ComponentSelector.vue' import ComponentSelector from '@/components/visualization/ComponentSelector.vue'
import { useEmitt } from '@/hooks/web/useEmitt' import { useEmitt } from '@/hooks/web/useEmitt'
import { useCache } from '@/hooks/web/useCache'
import Board from '@/components/de-board/Board.vue' import Board from '@/components/de-board/Board.vue'
import { dvMainStoreWithOut } from '@/store/modules/data-visualization/dvMain' import { dvMainStoreWithOut } from '@/store/modules/data-visualization/dvMain'
import { activeWatermarkCheckUser, removeActiveWatermark } from '@/components/watermark/watermark' import { activeWatermarkCheckUser, removeActiveWatermark } from '@/components/watermark/watermark'
import { isMobile } from '@/utils/utils' import { isMobile } from '@/utils/utils'
import { isDashboard } from '@/utils/canvasUtils' import { isDashboard, isMainCanvas } from '@/utils/canvasUtils'
import { XpackComponent } from '@/components/plugin' import { XpackComponent } from '@/components/plugin'
import { useAppStoreWithOut } from '@/store/modules/app' import DePreviewPopDialog from '@/components/visualization/DePreviewPopDialog.vue'
const appStore = useAppStoreWithOut() import Icon from '../../icon-custom/src/Icon.vue'
import replaceOutlined from '@/assets/svg/icon_replace_outlined.svg'
const componentWrapperInnerRef = ref(null) const componentWrapperInnerRef = ref(null)
const componentEditBarRef = ref(null) const componentEditBarRef = ref(null)
const dvMainStore = dvMainStoreWithOut() const dvMainStore = dvMainStoreWithOut()
const downLoading = ref(false) const downLoading = ref(false)
const { wsCache } = useCache('localStorage')
const commonFilterAttrs = ['width', 'height', 'top', 'left', 'rotate'] const commonFilterAttrs = ['width', 'height', 'top', 'left', 'rotate']
const dePreviewPopDialogRef = ref(null)
const commonFilterAttrsFilterBorder = [ const commonFilterAttrsFilterBorder = [
'width', 'width',
'height', 'height',
@ -122,6 +122,11 @@ const props = defineProps({
optType: { optType: {
type: String, type: String,
required: false required: false
},
//
scrollMain: {
type: Number,
default: 0
} }
}) })
const { const {
@ -133,9 +138,9 @@ const {
dvInfo, dvInfo,
searchCount, searchCount,
scale, scale,
suffixId suffixId,
scrollMain
} = toRefs(props) } = toRefs(props)
let currentInstance
const component = ref(null) const component = ref(null)
const emits = defineEmits(['userViewEnlargeOpen', 'datasetParamsInit', 'onPointClick']) const emits = defineEmits(['userViewEnlargeOpen', 'datasetParamsInit', 'onPointClick'])
const wrapperId = 'wrapper-outer-id-' + config.value.id const wrapperId = 'wrapper-outer-id-' + config.value.id
@ -145,7 +150,7 @@ const htmlToImage = () => {
useEmitt().emitter.emit('l7-prepare-picture', config.value.id) useEmitt().emitter.emit('l7-prepare-picture', config.value.id)
downLoading.value = true downLoading.value = true
setTimeout(() => { setTimeout(() => {
const vueDom = componentWrapperInnerRef.value const vueDom = document.getElementById(viewDemoInnerId.value)
activeWatermarkCheckUser(viewDemoInnerId.value, 'canvas-main', scale.value / 100) activeWatermarkCheckUser(viewDemoInnerId.value, 'canvas-main', scale.value / 100)
downloadCanvas2('img', vueDom, '图表', () => { downloadCanvas2('img', vueDom, '图表', () => {
// do callback // do callback
@ -160,27 +165,22 @@ const handleInnerMouseDown = e => {
// do setCurComponent // do setCurComponent
if (showPosition.value.includes('multiplexing')) { if (showPosition.value.includes('multiplexing')) {
componentEditBarRef.value.multiplexingCheckOut() componentEditBarRef.value.multiplexingCheckOut()
e.stopPropagation() e?.stopPropagation()
e.preventDefault() e?.preventDefault()
} }
if (showPosition.value.includes('popEdit') || dvMainStore.mobileInPc) { if (
(!['rich-text'].includes(config.value.innerType) &&
['popEdit', 'preview'].includes(showPosition.value)) ||
dvMainStore.mobileInPc
) {
onClick(e) onClick(e)
if (e.target?.className?.includes('ed-input__inner')) return
e?.stopPropagation()
e?.preventDefault()
} }
} }
onMounted(() => { const onClick = () => {
currentInstance = getCurrentInstance()
const methodName = 'componentImageDownload-' + config.value.id
useEmitt().emitter.off(methodName)
useEmitt({
name: methodName,
callback: () => {
htmlToImage()
}
})
})
const onClick = e => {
// //
eventBus.emit('componentClick') eventBus.emit('componentClick')
dvMainStore.setInEditorStatus(true) dvMainStore.setInEditorStatus(true)
@ -305,11 +305,20 @@ const eventEnable = computed(
['indicator', 'rich-text'].includes(config.value.innerType)) && ['indicator', 'rich-text'].includes(config.value.innerType)) &&
config.value.events && config.value.events &&
config.value.events.checked && config.value.events.checked &&
(isDashboard() || (!isDashboard() && !isMobile())) (isDashboard() || (!isDashboard() && !isMobile())) &&
showPosition.value !== 'canvas-multiplexing'
) )
const onWrapperClickCur = e => {
//
if (['indicator'].includes(config.value.innerType)) {
return
}
onWrapperClick(e)
}
const onWrapperClick = e => { const onWrapperClick = e => {
if (eventEnable.value && showPosition.value !== 'canvas-multiplexing') { if (eventEnable.value) {
if (config.value.events.type === 'showHidden') { if (config.value.events.type === 'showHidden') {
// //
nextTick(() => { nextTick(() => {
@ -320,15 +329,9 @@ const onWrapperClick = e => {
const jumpType = config.value.events.jump.type const jumpType = config.value.events.jump.type
try { try {
if ('newPop' === jumpType) { if ('newPop' === jumpType) {
window.open( dePreviewPopDialogRef.value.previewInit({ url, size: 'middle' })
url,
'_blank',
'width=800,height=600,left=200,top=100,toolbar=no,scrollbars=yes,resizable=yes,location=no'
)
} else if ('_blank' === jumpType) { } else if ('_blank' === jumpType) {
console.info('DataEase Component Jump _blank value:' + window['originOpen'])
if (window['originOpen']) { if (window['originOpen']) {
console.info('DataEase Component originOpen _blank')
window['originOpen'](url, '_blank') window['originOpen'](url, '_blank')
} else { } else {
window.open(url, '_blank') window.open(url, '_blank')
@ -346,8 +349,8 @@ const onWrapperClick = e => {
} else if (config.value.events.type === 'download') { } else if (config.value.events.type === 'download') {
useEmitt().emitter.emit('canvasDownload') useEmitt().emitter.emit('canvasDownload')
} }
e.preventDefault() e?.preventDefault()
e.stopPropagation() e?.stopPropagation()
} }
} }
@ -363,12 +366,47 @@ const initOpenHandler = newWindow => {
} }
const deepScale = computed(() => scale.value / 100) const deepScale = computed(() => scale.value / 100)
const showActive = computed(() => props.popActive || (dvMainStore.mobileInPc && props.active)) const showActive = computed(() => props.popActive || (dvMainStore.mobileInPc && props.active))
const freezeFlag = computed(() => {
return (
isMainCanvas(props.canvasId) &&
config.value.freeze &&
scrollMain.value - config.value.style?.top > 0
)
})
const commonParams = computed(() => {
return {
eventEnable: eventEnable.value,
eventType: config.value.events.type
}
})
const showCheck = computed(() => {
return dvMainStore.mobileInPc && showPosition.value === 'edit'
})
const updateFromMobile = (e, type) => {
if (type === 'syncPcDesign') {
e.preventDefault()
e.stopPropagation()
}
useEmitt().emitter.emit('onMobileStatusChange', {
type: type,
value: config.value.id
})
}
</script> </script>
<template> <template>
<div <div
class="wrapper-outer" class="wrapper-outer"
:class="showPosition + '-' + config.component" :class="[
showPosition + '-' + config.component,
{
'freeze-component': freezeFlag
}
]"
:id="wrapperId" :id="wrapperId"
@mousedown="handleInnerMouseDown" @mousedown="handleInnerMouseDown"
@mouseenter="onMouseEnter" @mouseenter="onMouseEnter"
@ -376,6 +414,16 @@ const showActive = computed(() => props.popActive || (dvMainStore.mobileInPc &&
element-loading-text="导出中..." element-loading-text="导出中..."
element-loading-background="rgba(255, 255, 255, 1)" element-loading-background="rgba(255, 255, 255, 1)"
> >
<div
:title="$t('visualization.sync_pc_design')"
v-if="showCheck"
class="refresh-from-pc"
@click="updateFromMobile($event, 'syncPcDesign')"
>
<el-icon>
<Icon name="icon_replace_outlined"><replaceOutlined class="svg-icon" /></Icon>
</el-icon>
</div>
<component-edit-bar <component-edit-bar
v-if="!showPosition.includes('canvas') && !props.isSelector" v-if="!showPosition.includes('canvas') && !props.isSelector"
class="wrapper-edit-bar" class="wrapper-edit-bar"
@ -385,6 +433,7 @@ const showActive = computed(() => props.popActive || (dvMainStore.mobileInPc &&
:element="config" :element="config"
:show-position="showPosition" :show-position="showPosition"
:class="{ 'wrapper-edit-bar-active': active }" :class="{ 'wrapper-edit-bar-active': active }"
@componentImageDownload="htmlToImage"
@userViewEnlargeOpen="opt => emits('userViewEnlargeOpen', opt)" @userViewEnlargeOpen="opt => emits('userViewEnlargeOpen', opt)"
@datasetParamsInit="() => emits('datasetParamsInit')" @datasetParamsInit="() => emits('datasetParamsInit')"
></component-edit-bar> ></component-edit-bar>
@ -406,7 +455,7 @@ const showActive = computed(() => props.popActive || (dvMainStore.mobileInPc &&
class="wrapper-inner-adaptor" class="wrapper-inner-adaptor"
:style="slotStyle" :style="slotStyle"
:class="{ 'pop-wrapper-inner': showActive, 'event-active': eventEnable }" :class="{ 'pop-wrapper-inner': showActive, 'event-active': eventEnable }"
@mousedown="onWrapperClick" @mousedown="onWrapperClickCur"
> >
<component <component
:is="findComponent(config['component'])" :is="findComponent(config['component'])"
@ -430,7 +479,10 @@ const showActive = computed(() => props.popActive || (dvMainStore.mobileInPc &&
:is-edit="false" :is-edit="false"
:suffix-id="suffixId" :suffix-id="suffixId"
:font-family="fontFamily" :font-family="fontFamily"
:active="active"
:common-params="commonParams"
@onPointClick="onPointClick" @onPointClick="onPointClick"
@onComponentEvent="onWrapperClick"
/> />
</div> </div>
<!--边框背景--> <!--边框背景-->
@ -444,6 +496,7 @@ const showActive = computed(() => props.popActive || (dvMainStore.mobileInPc &&
ref="openHandler" ref="openHandler"
jsname="L2NvbXBvbmVudC9lbWJlZGRlZC1pZnJhbWUvT3BlbkhhbmRsZXI=" jsname="L2NvbXBvbmVudC9lbWJlZGRlZC1pZnJhbWUvT3BlbkhhbmRsZXI="
/> />
<DePreviewPopDialog ref="dePreviewPopDialogRef"></DePreviewPopDialog>
</div> </div>
</template> </template>
@ -454,6 +507,15 @@ const showActive = computed(() => props.popActive || (dvMainStore.mobileInPc &&
} }
.wrapper-outer { .wrapper-outer {
position: absolute; position: absolute;
.refresh-from-pc {
position: absolute;
right: 38px;
top: 12px;
z-index: 2;
font-size: 16px;
cursor: pointer;
color: var(--ed-color-primary);
}
} }
.wrapper-inner { .wrapper-inner {
width: 100%; width: 100%;
@ -503,4 +565,11 @@ const showActive = computed(() => props.popActive || (dvMainStore.mobileInPc &&
.event-active { .event-active {
cursor: pointer; cursor: pointer;
} }
.freeze-component {
position: fixed;
z-index: 1;
top: var(--top-show-offset) px !important;
left: var(--left-show-offset) px !important;
}
</style> </style>

View File

@ -298,64 +298,73 @@ const editQueryCriteria = () => {
<el-divider class="custom-divider" /> <el-divider class="custom-divider" />
<li @click="deleteComponent">{{ t('visualization.delete') }}</li> <li @click="deleteComponent">{{ t('visualization.delete') }}</li>
</template> </template>
<li <template v-else>
v-show="!(!curComponent || curComponent['isLock'] || curComponent['component'] != 'Group')" <li
@click="decompose()" v-show="
> !(!curComponent || curComponent['isLock'] || curComponent['component'] != 'Group')
{{ t('visualization.cancel_group') }} "
</li> @click="decompose()"
<el-divider class="custom-divider" v-show="composeDivider" /> >
<template v-if="curComponent"> {{ t('visualization.cancel_group') }}
<template v-if="!curComponent['isLock'] && curComponent.category === 'hidden'"> </li>
<li @click="categoryChange('base')">{{ t('visualization.move_to_screen_show') }}</li> <el-divider class="custom-divider" v-show="composeDivider" />
<li @click="editQueryCriteria">{{ t('visualization.edit') }}</li> <template v-if="curComponent">
<li v-if="activePosition === 'aside'" @click="rename">{{ t('visualization.rename') }}</li> <template v-if="!curComponent['isLock'] && curComponent.category === 'hidden'">
<li @click="copy">{{ t('visualization.copy') }}</li> <li @click="categoryChange('base')">{{ t('visualization.move_to_screen_show') }}</li>
<li @click="paste">{{ t('visualization.paste') }}</li> <li @click="editQueryCriteria">{{ t('visualization.edit') }}</li>
<el-divider class="custom-divider" /> <li v-if="activePosition === 'aside'" @click="rename">
<li @click="deleteComponent">{{ t('visualization.delete') }}</li> {{ t('visualization.rename') }}
</li>
<li @click="copy">{{ t('visualization.copy') }}</li>
<li @click="paste">{{ t('visualization.paste') }}</li>
<el-divider class="custom-divider" />
<li @click="deleteComponent">{{ t('visualization.delete') }}</li>
</template>
<template v-if="!curComponent['isLock'] && curComponent.category !== 'hidden'">
<li v-if="curComponent.component === 'VQuery'" @click="editQueryCriteria">
{{ t('visualization.edit') }}
</li>
<li @click="upComponent">{{ t('visualization.up_component') }}</li>
<li @click="downComponent">{{ t('visualization.down_component') }}</li>
<li @click="topComponent">{{ t('visualization.top_component') }}</li>
<li @click="bottomComponent">{{ t('visualization.bottom_component') }}</li>
<li @click="customSort" v-if="curComponent.component === 'DeTabs'">
{{ t('visualization.sort') }}
</li>
<xpack-component
:chart="curComponent"
is-screen
resource-table="snapshot"
jsname="L2NvbXBvbmVudC90aHJlc2hvbGQtd2FybmluZy9FZGl0QmFySGFuZGxlcg=="
/>
<li @click="categoryChange('hidden')" v-show="showMoveMenu">
{{ t('visualization.move_to_pop_area') }}
</li>
<el-divider class="custom-divider" />
<li @click="hide" v-show="curComponent['isShow']">{{ t('visualization.hidden') }}</li>
<li @click="show" v-show="!curComponent['isShow'] || isGroupArea">
{{ t('visualization.cancel_hidden') }}
</li>
<li @click="lock">{{ t('visualization.lock') }}</li>
<li v-if="curComponent['isLock'] || isGroupArea" @click="unlock">
{{ t('visualization.unlock') }}
</li>
<el-divider class="custom-divider" />
<li v-if="activePosition === 'aside'" @click="rename">
{{ t('visualization.rename') }}
</li>
<li @click="copy">{{ t('visualization.copy') }}</li>
<li @click="paste">{{ t('visualization.paste') }}</li>
<li @click="cut">{{ t('visualization.cut') }}</li>
<el-divider class="custom-divider" />
<li @click="deleteComponent">{{ t('visualization.delete') }}</li>
</template>
<li v-if="curComponent['isLock']" @click="unlock">{{ t('visualization.unlock') }}</li>
</template> </template>
<template v-if="!curComponent['isLock'] && curComponent.category !== 'hidden'"> <li v-else-if="!curComponent && !areaData.components.length" @click="paste">
<li v-if="curComponent.component === 'VQuery'" @click="editQueryCriteria"> {{ t('visualization.paste') }}
{{ t('visualization.edit') }} </li>
</li>
<li @click="upComponent">{{ t('visualization.up_component') }}</li>
<li @click="downComponent">{{ t('visualization.down_component') }}</li>
<li @click="topComponent">{{ t('visualization.top_component') }}</li>
<li @click="bottomComponent">{{ t('visualization.bottom_component') }}</li>
<li @click="customSort" v-if="curComponent.component === 'DeTabs'">
{{ t('visualization.sort') }}
</li>
<xpack-component
:chart="curComponent"
is-screen
jsname="L2NvbXBvbmVudC90aHJlc2hvbGQtd2FybmluZy9FZGl0QmFySGFuZGxlcg=="
/>
<li @click="categoryChange('hidden')" v-show="showMoveMenu">
{{ t('visualization.move_to_pop_area') }}
</li>
<el-divider class="custom-divider" />
<li @click="hide" v-show="curComponent['isShow']">{{ t('visualization.hidden') }}</li>
<li @click="show" v-show="!curComponent['isShow'] || isGroupArea">
{{ t('visualization.cancel_hidden') }}
</li>
<li @click="lock">{{ t('visualization.lock') }}</li>
<li v-if="curComponent['isLock'] || isGroupArea" @click="unlock">
{{ t('visualization.unlock') }}
</li>
<el-divider class="custom-divider" />
<li v-if="activePosition === 'aside'" @click="rename">{{ t('visualization.rename') }}</li>
<li @click="copy">{{ t('visualization.copy') }}</li>
<li @click="paste">{{ t('visualization.paste') }}</li>
<li @click="cut">{{ t('visualization.cut') }}</li>
<el-divider class="custom-divider" />
<li @click="deleteComponent">{{ t('visualization.delete') }}</li>
</template>
<li v-if="curComponent['isLock']" @click="unlock">{{ t('visualization.unlock') }}</li>
</template> </template>
<li v-else-if="!curComponent && !areaData.components.length" @click="paste">
{{ t('visualization.paste') }}
</li>
</ul> </ul>
</div> </div>
</template> </template>

View File

@ -22,6 +22,7 @@ import EmptyBackground from '../../empty-background/src/EmptyBackground.vue'
import LinkOptBar from '@/components/data-visualization/canvas/LinkOptBar.vue' import LinkOptBar from '@/components/data-visualization/canvas/LinkOptBar.vue'
import { isDesktop } from '@/utils/ModelUtil' import { isDesktop } from '@/utils/ModelUtil'
import { isMobile } from '@/utils/utils' import { isMobile } from '@/utils/utils'
import { useI18n } from '@/hooks/web/useI18n'
const dvMainStore = dvMainStoreWithOut() const dvMainStore = dvMainStoreWithOut()
const { pcMatrixCount, curComponent, mobileInPc, canvasState, inMobile } = storeToRefs(dvMainStore) const { pcMatrixCount, curComponent, mobileInPc, canvasState, inMobile } = storeToRefs(dvMainStore)
const openHandler = ref(null) const openHandler = ref(null)
@ -30,6 +31,7 @@ const emits = defineEmits(['onResetLayout'])
const fullScreeRef = ref(null) const fullScreeRef = ref(null)
const isOverSize = ref(false) const isOverSize = ref(false)
const isDesktopFlag = isDesktop() const isDesktopFlag = isDesktop()
const { t } = useI18n()
const props = defineProps({ const props = defineProps({
canvasStyleData: { canvasStyleData: {
type: Object, type: Object,
@ -93,6 +95,11 @@ const props = defineProps({
type: String, type: String,
required: false, required: false,
default: 'inherit' default: 'inherit'
},
//
showLinkageButton: {
type: Boolean,
default: true
} }
}) })
@ -125,7 +132,8 @@ const dashboardActive = computed(() => {
return dvInfo.value.type === 'dashboard' return dvInfo.value.type === 'dashboard'
}) })
const state = reactive({ const state = reactive({
initState: true initState: true,
scrollMain: 0
}) })
const curSearchCount = computed(() => { const curSearchCount = computed(() => {
@ -171,6 +179,7 @@ const canvasStyle = computed(() => {
if (canvasStyleData.value?.screenAdaptor === 'keep') { if (canvasStyleData.value?.screenAdaptor === 'keep') {
style['height'] = canvasStyleData.value?.height + 'px' style['height'] = canvasStyleData.value?.height + 'px'
style['width'] = canvasStyleData.value?.width + 'px' style['width'] = canvasStyleData.value?.width + 'px'
style['margin'] = 'auto'
} else { } else {
style['height'] = dashboardActive.value style['height'] = dashboardActive.value
? downloadStatus.value ? downloadStatus.value
@ -470,6 +479,12 @@ const downloadAsPDF = () => {
// test // test
} }
const scrollPreview = () => {
state.scrollMain = previewCanvas.value.scrollTop
}
const showUnpublishFlag = computed(() => dvInfo.value?.status === 0 && isMainCanvas(canvasId.value))
defineExpose({ defineExpose({
restore restore
}) })
@ -480,9 +495,14 @@ defineExpose({
:id="domId" :id="domId"
class="canvas-container" class="canvas-container"
:style="canvasStyle" :style="canvasStyle"
:class="{ 'de-download-custom': downloadStatus, 'datav-preview': dataVPreview }" :class="{
'de-download-custom': downloadStatus,
'datav-preview': dataVPreview,
'datav-preview-unpublish': showUnpublishFlag
}"
ref="previewCanvas" ref="previewCanvas"
@mousedown="handleMouseDown" @mousedown="handleMouseDown"
@scroll="scrollPreview"
v-if="state.initState" v-if="state.initState"
> >
<!--弹框触发区域--> <!--弹框触发区域-->
@ -500,12 +520,14 @@ defineExpose({
:show-position="'preview'" :show-position="'preview'"
></PopArea> ></PopArea>
<canvas-opt-bar <canvas-opt-bar
v-if="showLinkageButton"
:canvas-id="canvasId" :canvas-id="canvasId"
:canvas-style-data="canvasStyleData" :canvas-style-data="canvasStyleData"
:component-data="baseComponentData" :component-data="baseComponentData"
:is-fixed="isOverSize"
></canvas-opt-bar> ></canvas-opt-bar>
<template v-if="renderReady"> <template v-if="renderReady && !showUnpublishFlag">
<ComponentWrapper <component-wrapper
v-for="(item, index) in baseComponentData" v-for="(item, index) in baseComponentData"
v-show="item.isShow" v-show="item.isShow"
:active="item.id === (curComponent || {})['id']" :active="item.id === (curComponent || {})['id']"
@ -522,11 +544,19 @@ defineExpose({
:scale="mobileInPc && isDashboard() ? 100 : scaleMin" :scale="mobileInPc && isDashboard() ? 100 : scaleMin"
:is-selector="props.isSelector" :is-selector="props.isSelector"
:font-family="canvasStyleData.fontFamily || fontFamily" :font-family="canvasStyleData.fontFamily || fontFamily"
:scroll-main="state.scrollMain"
@userViewEnlargeOpen="userViewEnlargeOpen($event, item)" @userViewEnlargeOpen="userViewEnlargeOpen($event, item)"
@datasetParamsInit="datasetParamsInit(item)" @datasetParamsInit="datasetParamsInit(item)"
@onPointClick="onPointClick" @onPointClick="onPointClick"
:index="index"
/> />
</template> </template>
<empty-background
v-if="showUnpublishFlag"
:description="t('visualization.resource_not_published')"
img-type="none"
>
</empty-background>
<user-view-enlarge ref="userViewEnlargeRef"></user-view-enlarge> <user-view-enlarge ref="userViewEnlargeRef"></user-view-enlarge>
</div> </div>
<empty-background v-if="!state.initState" description="参数不能为空" img-type="noneWhite" /> <empty-background v-if="!state.initState" description="参数不能为空" img-type="noneWhite" />
@ -567,4 +597,8 @@ defineExpose({
.datav-preview { .datav-preview {
overflow-y: hidden !important; overflow-y: hidden !important;
} }
.datav-preview-unpublish {
background-color: inherit !important;
}
</style> </style>

View File

@ -1,7 +1,11 @@
<template> <template>
<div <div
class="shape" class="shape"
:class="{ 'shape-group-area': isGroupArea }" :class="{
'shape-group-area': isGroupArea,
'freeze-component': freezeFlag,
'freeze-component-fullscreen': freezeFlag && fullscreenFlag
}"
ref="shapeInnerRef" ref="shapeInnerRef"
:id="domId" :id="domId"
v-loading="downLoading" v-loading="downLoading"
@ -55,6 +59,7 @@
:element="element" :element="element"
:show-position="showPosition" :show-position="showPosition"
:canvas-id="canvasId" :canvas-id="canvasId"
@componentImageDownload="htmlToImage"
@userViewEnlargeOpen="userViewEnlargeOpen" @userViewEnlargeOpen="userViewEnlargeOpen"
@datasetParamsInit="datasetParamsInit" @datasetParamsInit="datasetParamsInit"
@linkJumpSetOpen="linkJumpSetOpen" @linkJumpSetOpen="linkJumpSetOpen"
@ -177,7 +182,8 @@ const {
tabMoveOutComponentId, tabMoveOutComponentId,
mobileInPc, mobileInPc,
mainScrollTop, mainScrollTop,
hiddenListStatus hiddenListStatus,
fullscreenFlag
} = storeToRefs(dvMainStore) } = storeToRefs(dvMainStore)
const { editorMap, areaData, isCtrlOrCmdDown } = storeToRefs(composeStore) const { editorMap, areaData, isCtrlOrCmdDown } = storeToRefs(composeStore)
const emit = defineEmits([ const emit = defineEmits([
@ -326,6 +332,14 @@ const initialAngle = {
} }
const cursors = ref({}) const cursors = ref({})
const freezeFlag = computed(() => {
return (
isMainCanvas(canvasId.value) &&
element.value.freeze &&
mainScrollTop.value - defaultStyle.value.top > 0
)
})
const showCheck = computed(() => { const showCheck = computed(() => {
return mobileInPc.value && element.value.canvasId === 'canvas-main' return mobileInPc.value && element.value.canvasId === 'canvas-main'
}) })
@ -386,7 +400,7 @@ const getPointList = () => {
} }
const isActive = () => { const isActive = () => {
return active.value && !element.value['isLock'] && isEditMode.value return active.value && !element.value['isLock'] && isEditMode.value && !freezeFlag.value
} }
const userViewEnlargeOpen = opt => { const userViewEnlargeOpen = opt => {
@ -538,7 +552,8 @@ const handleMouseDownOnShape = e => {
// } // }
e.stopPropagation() e.stopPropagation()
if (element.value['isLock'] || !isEditMode.value) return //
if (element.value['isLock'] || !isEditMode.value || freezeFlag.value) return
cursors.value = getCursor() // cursors.value = getCursor() //
@ -897,30 +912,6 @@ const commonBackgroundSvgInner = computed(() => {
} }
}) })
const padding3D = computed(() => {
const width = defaultStyle.value.width //
const height = defaultStyle.value.height //
const rotateX = element.value['multiDimensional'].x // X
const rotateY = element.value['multiDimensional'].y // Y
//
const radX = (rotateX * Math.PI) / 180
const radY = (rotateY * Math.PI) / 180
//
const newWidth = Math.abs(width * Math.cos(radY)) + Math.abs(height * Math.sin(radX))
const newHeight = Math.abs(height * Math.cos(radX)) + Math.abs(width * Math.sin(radY))
// padding
const paddingX = (newWidth - width) / 2
const paddingY = (newHeight - height) / 2
return {
paddingX: `${paddingX}px`,
paddingY: `${paddingY}px`
}
})
const componentBackgroundStyle = computed(() => { const componentBackgroundStyle = computed(() => {
if (element.value.commonBackground && element.value.component !== 'GroupArea') { if (element.value.commonBackground && element.value.component !== 'GroupArea') {
const { const {
@ -1107,12 +1098,15 @@ const dragCollision = computed(() => {
const htmlToImage = () => { const htmlToImage = () => {
downLoading.value = true downLoading.value = true
useEmitt().emitter.emit('l7-prepare-picture', element.value.id)
setTimeout(() => { setTimeout(() => {
activeWatermarkCheckUser(viewDemoInnerId.value, 'canvas-main', scale.value) activeWatermarkCheckUser(viewDemoInnerId.value, 'canvas-main', scale.value)
downloadCanvas2('img', componentInnerRef.value, '图表', () => { const dom = document.getElementById(viewDemoInnerId.value)
downloadCanvas2('img', dom, '图表', () => {
// do callback // do callback
removeActiveWatermark(viewDemoInnerId.value) removeActiveWatermark(viewDemoInnerId.value)
downLoading.value = false downLoading.value = false
useEmitt().emitter.emit('l7-unprepare-picture', element.value.id)
}) })
}, 200) }, 200)
} }
@ -1138,13 +1132,11 @@ onMounted(() => {
}) })
settingAttribute() settingAttribute()
const methodName = 'componentImageDownload-' + element.value.id const methodName = 'componentImageDownload-' + element.value.id
useEmitt().emitter.off(methodName) if (!useEmitt().emitter.all.get(methodName)?.length) {
useEmitt({ useEmitt().emitter.on(methodName, () => {
name: methodName,
callback: () => {
htmlToImage() htmlToImage()
} })
}) }
}) })
</script> </script>
@ -1318,4 +1310,14 @@ onMounted(() => {
position: relative; position: relative;
transform-style: preserve-3d; transform-style: preserve-3d;
} }
.freeze-component {
position: fixed;
z-index: 1;
top: 66px !important;
}
.freeze-component-fullscreen {
top: 5px !important;
}
</style> </style>

View File

@ -2,7 +2,7 @@
<el-drawer <el-drawer
:title="t('visualization.app_export')" :title="t('visualization.app_export')"
v-model="state.applyDownloadDrawer" v-model="state.applyDownloadDrawer"
custom-class="de-user-drawer" modal-class="de-user-drawer"
size="600px" size="600px"
direction="rtl" direction="rtl"
> >
@ -55,11 +55,9 @@ import { ElButton, ElDrawer, ElForm, ElFormItem, ElInput } from 'element-plus-se
import { reactive, ref, toRefs } from 'vue' import { reactive, ref, toRefs } from 'vue'
import { useI18n } from '@/hooks/web/useI18n' import { useI18n } from '@/hooks/web/useI18n'
import { export2AppCheck } from '@/api/visualization/dataVisualization' import { export2AppCheck } from '@/api/visualization/dataVisualization'
import { dvMainStoreWithOut } from '@/store/modules/data-visualization/dvMain'
const { t } = useI18n() const { t } = useI18n()
const emits = defineEmits(['closeDraw', 'downLoadApp']) const emits = defineEmits(['closeDraw', 'downLoadApp'])
const applyDownloadForm = ref(null) const applyDownloadForm = ref(null)
const dvMainStore = dvMainStoreWithOut()
const props = defineProps({ const props = defineProps({
componentData: { componentData: {
@ -138,43 +136,28 @@ const close = () => {
state.applyDownloadDrawer = false state.applyDownloadDrawer = false
} }
const gatherAppInfo = (viewIds, dsIds) => { const gatherAppInfo = (viewIds, dsIds, componentDataCheck) => {
componentData.value.forEach(item => { componentDataCheck.forEach(item => {
if (item.component === 'UserView' && canvasViewInfo.value[item.id]) { if (item.component === 'UserView' && canvasViewInfo.value[item.id]) {
const viewDetails = canvasViewInfo.value[item.id] const viewDetails = canvasViewInfo.value[item.id]
const { id, tableId } = viewDetails const { id, tableId } = viewDetails
viewIds.push(id) viewIds.push(id)
dsIds.push(tableId) dsIds.push(tableId)
} else if (item.component === 'Group') { } else if (item.component === 'Group') {
item.propValue.forEach(groupItem => { gatherAppInfo(viewIds, dsIds, item.propValue)
if (groupItem.component === 'UserView') {
const viewDetails = canvasViewInfo.value[groupItem.id]
const { id, tableId } = viewDetails
viewIds.push(id)
dsIds.push(tableId)
}
})
} else if (item.component === 'DeTabs') { } else if (item.component === 'DeTabs') {
item.propValue.forEach(tabItem => { item.propValue.forEach(tabItem => {
tabItem.componentData.forEach(tabComponent => { gatherAppInfo(viewIds, dsIds, tabItem.componentData)
if (tabComponent.component === 'UserView') {
const viewDetails = canvasViewInfo.value[tabComponent.id]
const { id, tableId } = viewDetails
viewIds.push(id)
dsIds.push(tableId)
}
})
}) })
} }
}) })
} }
const downloadApp = () => { const downloadApp = () => {
applyDownloadForm.value?.validate(valid => { applyDownloadForm.value?.validate(valid => {
if (valid) { if (valid) {
const viewIds = [] const viewIds = []
const dsIds = [] const dsIds = []
gatherAppInfo(viewIds, dsIds) gatherAppInfo(viewIds, dsIds, componentData.value)
export2AppCheck({ dvId: dvInfo.value.id, viewIds, dsIds }).then(rsp => { export2AppCheck({ dvId: dvInfo.value.id, viewIds, dsIds }).then(rsp => {
const params = { const params = {
...rsp.data, ...rsp.data,

View File

@ -119,7 +119,7 @@ defineExpose({
:title="t('common.filter_condition')" :title="t('common.filter_condition')"
v-model="userDrawer" v-model="userDrawer"
size="600px" size="600px"
custom-class="drawer-main-container" modal-class="drawer-main-container"
direction="rtl" direction="rtl"
> >
<div v-for="(component, index) in componentList" :key="index"> <div v-for="(component, index) in componentList" :key="index">
@ -164,7 +164,6 @@ defineExpose({
<style lang="less"> <style lang="less">
.drawer-main-container { .drawer-main-container {
width: 600px;
.ed-drawer__body { .ed-drawer__body {
padding: 16px 24px 80px !important; padding: 16px 24px 80px !important;
} }

View File

@ -6,7 +6,7 @@ import nothingTable from '@/assets/img/nothing-table.png'
import none from '@/assets/img/none.png' import none from '@/assets/img/none.png'
import error from '@/assets/img/error.png' import error from '@/assets/img/error.png'
import nothingTree from '@/assets/img/nothing-tree.png' import nothingTree from '@/assets/img/nothing-tree.png'
import nothingNone from '@/assets/img/nothing-none-black.png' import nothingNone from '@/assets/img/nothing-none.png'
defineProps({ defineProps({
imgType: { imgType: {
type: String as PropType< type: String as PropType<
@ -60,7 +60,4 @@ const getAssetsFile = {
font-weight: 400; font-weight: 400;
line-height: 22px; line-height: 22px;
} }
:deep(.ed-empty__image){
width: 106px !important;
}
</style> </style>

View File

@ -127,7 +127,6 @@ defineExpose({
<template> <template>
<div class="flex-table" :class="!tableData.length && 'no-data'"> <div class="flex-table" :class="!tableData.length && 'no-data'">
<el-table <el-table
header-cell-class-name="header-cell"
ref="table" ref="table"
:border="border" :border="border"
v-bind="state.tableAttrs" v-bind="state.tableAttrs"

View File

@ -7,7 +7,9 @@ import { ref, PropType, computed } from 'vue'
import ShareHandler from '@/views/share/share/ShareHandler.vue' import ShareHandler from '@/views/share/share/ShareHandler.vue'
import { useShareStoreWithOut } from '@/store/modules/share' import { useShareStoreWithOut } from '@/store/modules/share'
import { isDesktop } from '@/utils/ModelUtil' import { isDesktop } from '@/utils/ModelUtil'
import { useI18n } from '@/hooks/web/useI18n'
const shareStore = useShareStoreWithOut() const shareStore = useShareStoreWithOut()
const { t } = useI18n()
export interface Menu { export interface Menu {
svgName?: string svgName?: string
@ -64,11 +66,15 @@ const callBack = param => {
return return
} }
if (props.node.leaf && props.node?.weight >= 7) { if (props.node.leaf && props.node?.weight >= 7) {
menus.value[0]['divided'] = true
menus.value.splice(0, 0, param) menus.value.splice(0, 0, param)
} }
} }
const emit = defineEmits(['handleCommand']) const emit = defineEmits(['handleCommand'])
const menuDisabledCheck = ele => {
// do return
return ele.disabled || (props.node.extraFlag1 === 0 && ['share', 'copy'].includes(ele.command))
}
</script> </script>
<template> <template>
@ -88,13 +94,30 @@ const emit = defineEmits(['handleCommand'])
:command="ele.command" :command="ele.command"
v-for="ele in menus" v-for="ele in menus"
:key="ele.label" :key="ele.label"
:disabled="ele.disabled" :disabled="menuDisabledCheck(ele)"
:class="{ 'de-hidden-drop-item': ele.hidden }" :class="{
'de-hidden-drop-item':
ele.hidden || (ele.command === 'cancelPublish' && node.extraFlag1 === 0)
}"
> >
<el-icon class="handle-icon" color="#646a73" size="16" v-if="ele.svgName"> <el-icon class="handle-icon" color="#646a73" size="16" v-if="ele.svgName">
<Icon><component class="svg-icon" :is="ele.svgName"></component></Icon> <Icon
><component
class="svg-icon"
:class="{ 'custom-disable': menuDisabledCheck(ele) }"
:is="ele.svgName"
></component
></Icon>
</el-icon> </el-icon>
{{ ele.label }} <el-tooltip
class="box-item"
effect="dark"
:content="t('visualization.publish_tips2', [ele.label])"
:disabled="!menuDisabledCheck(ele)"
placement="top-start"
>
{{ ele.label }}
</el-tooltip>
</el-dropdown-item> </el-dropdown-item>
</el-dropdown-menu> </el-dropdown-menu>
</template> </template>
@ -110,11 +133,14 @@ const emit = defineEmits(['handleCommand'])
</template> </template>
<style lang="less"> <style lang="less">
.custom-disable {
color: var(--ed-text-color-disabled) !important;
}
.de-hidden-drop-item { .de-hidden-drop-item {
display: none; display: none !important;
} }
.menu-more-dv_popper { .menu-more-dv_popper {
width: 120px; min-width: 120px;
margin-top: -2px !important; margin-top: -2px !important;
} }

View File

@ -20,7 +20,7 @@ withDefaults(
inTable?: boolean inTable?: boolean
}>(), }>(),
{ {
placement: 'right-start', placement: 'bottom-end',
iconSize: '16px', iconSize: '16px',
inTable: false inTable: false
} }
@ -53,9 +53,9 @@ const emit = defineEmits(['handleCommand'])
:key="ele.label" :key="ele.label"
:disabled="ele.disabled" :disabled="ele.disabled"
> >
<!-- <el-icon class="handle-icon" :style="{ fontSize: iconSize }" v-if="ele.svgName"> <el-icon class="handle-icon" :style="{ fontSize: iconSize }" v-if="ele.svgName">
<Icon><component class="svg-icon" :is="ele.svgName"></component></Icon> <Icon><component class="svg-icon" :is="ele.svgName"></component></Icon>
</el-icon> --> </el-icon>
{{ ele.label }} {{ ele.label }}
</el-dropdown-item> </el-dropdown-item>
</el-dropdown-menu> </el-dropdown-menu>

View File

@ -43,6 +43,7 @@ import waterfallDark from '@/assets/svg/waterfall-dark.svg'
import wordCloudDark from '@/assets/svg/word-cloud-dark.svg' import wordCloudDark from '@/assets/svg/word-cloud-dark.svg'
import tHeatmapDark from '@/assets/svg/t-heatmap-dark.svg' import tHeatmapDark from '@/assets/svg/t-heatmap-dark.svg'
import circlePackingDark from '@/assets/svg/circle-packing-dark.svg' import circlePackingDark from '@/assets/svg/circle-packing-dark.svg'
import bulletGraphDark from '@/assets/svg/bullet-graph-dark.svg'
const iconChartDarkMap = { const iconChartDarkMap = {
'area-dark': areaDark, 'area-dark': areaDark,
@ -89,7 +90,8 @@ const iconChartDarkMap = {
'waterfall-dark': waterfallDark, 'waterfall-dark': waterfallDark,
'word-cloud-dark': wordCloudDark, 'word-cloud-dark': wordCloudDark,
't-heatmap-dark': tHeatmapDark, 't-heatmap-dark': tHeatmapDark,
'circle-packing-dark': circlePackingDark 'circle-packing-dark': circlePackingDark,
'bullet-graph-dark': bulletGraphDark
} }
export { iconChartDarkMap } export { iconChartDarkMap }

View File

@ -46,6 +46,7 @@ import pictureGroup from '@/assets/svg/picture-group.svg'
import filter from '@/assets/svg/filter.svg' import filter from '@/assets/svg/filter.svg'
import outerParams from '@/assets/svg/icon_params_setting.svg' import outerParams from '@/assets/svg/icon_params_setting.svg'
import circlePacking from '@/assets/svg/circle-packing.svg' import circlePacking from '@/assets/svg/circle-packing.svg'
import bulletGraph from '@/assets/svg/bullet-graph.svg'
const iconChartMap = { const iconChartMap = {
'area-stack': areaStack, 'area-stack': areaStack,
@ -95,7 +96,8 @@ const iconChartMap = {
'picture-group': pictureGroup, 'picture-group': pictureGroup,
filter: filter, filter: filter,
outerParams: outerParams, outerParams: outerParams,
'circle-packing': circlePacking 'circle-packing': circlePacking,
'bullet-graph': bulletGraph
} }
export { iconChartMap } export { iconChartMap }

View File

@ -12,6 +12,7 @@ import db2Ds from '@/assets/svg/db2-ds.svg'
import redshiftDs from '@/assets/svg/redshift-ds.svg' import redshiftDs from '@/assets/svg/redshift-ds.svg'
import APIDs from '@/assets/svg/API-ds.svg' import APIDs from '@/assets/svg/API-ds.svg'
import ExcelDs from '@/assets/svg/Excel-ds.svg' import ExcelDs from '@/assets/svg/Excel-ds.svg'
import ExcelRemoteDs from '@/assets/svg/Excel-remote-ds.svg'
import dorisDs from '@/assets/svg/doris-ds.svg' import dorisDs from '@/assets/svg/doris-ds.svg'
import esDs from '@/assets/svg/es-ds.svg' import esDs from '@/assets/svg/es-ds.svg'
const iconDatasourceMap = { const iconDatasourceMap = {
@ -29,6 +30,7 @@ const iconDatasourceMap = {
redshift: redshiftDs, redshift: redshiftDs,
API: APIDs, API: APIDs,
Excel: ExcelDs, Excel: ExcelDs,
ExcelRemote: ExcelRemoteDs,
doris: dorisDs, doris: dorisDs,
es: esDs es: esDs
} }

View File

@ -94,7 +94,7 @@ defineExpose({
<el-drawer <el-drawer
title="血缘关系图" title="血缘关系图"
v-model="relationDrawer" v-model="relationDrawer"
custom-class="de-relation-drawer" modal-class="de-relation-drawer"
size="1200px" size="1200px"
direction="rtl" direction="rtl"
> >

View File

@ -70,7 +70,7 @@ const init = ref({
toolbar: toolbar:
'undo redo |fontselect fontsizeselect |forecolor backcolor bold italic |underline strikethrough | splitDateButton lineheight| formatselect |' + 'undo redo |fontselect fontsizeselect |forecolor backcolor bold italic |underline strikethrough | splitDateButton lineheight| formatselect |' +
'alignleft aligncenter alignright | bullist numlist |' + 'alignleft aligncenter alignright | bullist numlist |' +
' blockquote subscript superscript removeformat | table image media link', ' blockquote subscript superscript removeformat',
toolbar_location: '/', toolbar_location: '/',
font_formats: font_formats:
'微软雅黑=Microsoft YaHei;宋体=SimSun;黑体=SimHei;仿宋=FangSong;华文黑体=STHeiti;华文楷体=STKaiti;华文宋体=STSong;华文仿宋=STFangsong;Andale Mono=andale mono,times;Arial=arial,helvetica,sans-serif;Arial Black=arial black,avant garde;Book Antiqua=book antiqua,palatino;Comic Sans MS=comic sans ms,sans-serif;Courier New=courier new,courier;Georgia=georgia,palatino;Helvetica=helvetica;Impact=impact,chicago;Symbol=symbol;Tahoma=tahoma,arial,helvetica,sans-serif;Terminal=terminal,monaco;Times New Roman=times new roman,times;Trebuchet MS=trebuchet ms,geneva;Verdana=verdana,geneva;Webdings=webdings;Wingdings=wingdings', '微软雅黑=Microsoft YaHei;宋体=SimSun;黑体=SimHei;仿宋=FangSong;华文黑体=STHeiti;华文楷体=STKaiti;华文宋体=STSong;华文仿宋=STFangsong;Andale Mono=andale mono,times;Arial=arial,helvetica,sans-serif;Arial Black=arial black,avant garde;Book Antiqua=book antiqua,palatino;Comic Sans MS=comic sans ms,sans-serif;Courier New=courier new,courier;Georgia=georgia,palatino;Helvetica=helvetica;Impact=impact,chicago;Symbol=symbol;Tahoma=tahoma,arial,helvetica,sans-serif;Terminal=terminal,monaco;Times New Roman=times new roman,times;Trebuchet MS=trebuchet ms,geneva;Verdana=verdana,geneva;Webdings=webdings;Wingdings=wingdings',

View File

@ -1,6 +1,6 @@
<template> <template>
<div style="width: 100%" ref="bgForm"> <div style="width: 100%" ref="bgForm">
<el-form label-position="top" style="width: 100%; margin-bottom: 16px"> <el-form size="small" label-position="top" style="width: 100%; margin-bottom: 16px">
<el-form-item <el-form-item
class="form-item no-margin-bottom" class="form-item no-margin-bottom"
:class="'form-item-' + themes" :class="'form-item-' + themes"

View File

@ -33,12 +33,8 @@
import warnTree from '@/assets/svg/warn-tree.svg' import warnTree from '@/assets/svg/warn-tree.svg'
import { ref } from 'vue' import { ref } from 'vue'
import { useI18n } from '@/hooks/web/useI18n' import { useI18n } from '@/hooks/web/useI18n'
import { dvMainStoreWithOut } from '@/store/modules/data-visualization/dvMain'
const dvMainStore = dvMainStoreWithOut()
const dialogShow = ref(false) const dialogShow = ref(false)
const { t } = useI18n() const { t } = useI18n()
import { useCache } from '@/hooks/web/useCache'
const { wsCache } = useCache()
const emits = defineEmits(['doUseCache']) const emits = defineEmits(['doUseCache'])
const dialogInfo = { const dialogInfo = {

View File

@ -2,10 +2,13 @@
<div <div
v-if="existLinkage && (!dvMainStore.mobileInPc || isMobile())" v-if="existLinkage && (!dvMainStore.mobileInPc || isMobile())"
class="bar-main-right" class="bar-main-right"
:class="{ 'bar-main-edit-right': dvEditMode }" :class="{
'bar-main-preview-fixed': dvPreviewMode,
'bar-main-preview-fixed-fullscreen': fullscreenFlag
}"
@mousedown="handOptBarMousedown" @mousedown="handOptBarMousedown"
> >
<el-button size="mini" type="warning" @click="clearAllLinkage" <el-button type="warning" @click="clearAllLinkage"
><el-icon class="bar-base-icon"> ><el-icon class="bar-base-icon">
<Icon name="dv-bar-unLinkage"><dvBarUnLinkage class="svg-icon" /></Icon></el-icon <Icon name="dv-bar-unLinkage"><dvBarUnLinkage class="svg-icon" /></Icon></el-icon
>{{ $t('visualization.remove_all_linkage') }}</el-button >{{ $t('visualization.remove_all_linkage') }}</el-button
@ -20,7 +23,9 @@ import { computed } from 'vue'
import { isMainCanvas } from '@/utils/canvasUtils' import { isMainCanvas } from '@/utils/canvasUtils'
import { useEmitt } from '@/hooks/web/useEmitt' import { useEmitt } from '@/hooks/web/useEmitt'
import { isMobile } from '@/utils/utils' import { isMobile } from '@/utils/utils'
import { storeToRefs } from 'pinia'
const dvMainStore = dvMainStoreWithOut() const dvMainStore = dvMainStoreWithOut()
const { fullscreenFlag } = storeToRefs(dvMainStore)
const props = defineProps({ const props = defineProps({
canvasStyleData: { canvasStyleData: {
@ -35,6 +40,10 @@ const props = defineProps({
type: String, type: String,
required: false, required: false,
default: 'canvas-main' default: 'canvas-main'
},
isFixed: {
type: Boolean,
default: false
} }
}) })
@ -48,9 +57,10 @@ const clearAllLinkage = () => {
useEmitt().emitter.emit('clearPanelLinkage', { viewId: 'all' }) useEmitt().emitter.emit('clearPanelLinkage', { viewId: 'all' })
} }
const dvEditMode = computed(() => { const dvPreviewMode = computed(() => {
return dvMainStore.dvInfo.type === 'dataV' && dvMainStore.editMode === 'preview' && !isMobile() return dvMainStore.dvInfo.type === 'dataV' && props.isFixed
}) })
const existLinkage = computed(() => { const existLinkage = computed(() => {
if (isMainCanvas(props.canvasId)) { if (isMainCanvas(props.canvasId)) {
let linkageFiltersCount = 0 let linkageFiltersCount = 0
@ -87,7 +97,7 @@ const existLinkage = computed(() => {
top: 2px; top: 2px;
right: 2px; right: 2px;
opacity: 0.8; opacity: 0.8;
z-index: 1; z-index: 2;
position: absolute; position: absolute;
} }
@ -104,4 +114,14 @@ const existLinkage = computed(() => {
opacity: 0.8; opacity: 0.8;
} }
} }
.bar-main-preview-fixed {
position: fixed;
top: 120px;
right: 5px;
}
.bar-main-preview-fixed-fullscreen {
top: 5px !important;
}
</style> </style>

View File

@ -85,6 +85,5 @@ const emits = defineEmits(['customClick'])
.toolbar-icon { .toolbar-icon {
font-size: 20px; font-size: 20px;
color: #fff;
} }
</style> </style>

View File

@ -21,9 +21,7 @@ const emits = defineEmits(['customClick'])
<el-row class="group_icon" :title="tips" @click="emits('customClick')"> <el-row class="group_icon" :title="tips" @click="emits('customClick')">
<el-col :span="24" class="group_inner" :class="{ 'inner-active': active }"> <el-col :span="24" class="group_inner" :class="{ 'inner-active': active }">
<Icon><component class="svg-icon toolbar-icon" :is="iconName"></component></Icon> <Icon><component class="svg-icon toolbar-icon" :is="iconName"></component></Icon>
<span>{{ title }}</span>
<!-- <img src="@/assets/newimg/avatar.png" alt="" srcset=""> -->
<span >{{ title }}</span>
</el-col> </el-col>
</el-row> </el-row>
<el-divider class="group-right-border" v-if="showSplitLine" direction="vertical" /> <el-divider class="group-right-border" v-if="showSplitLine" direction="vertical" />

View File

@ -171,6 +171,7 @@
<xpack-component <xpack-component
:chart="element" :chart="element"
resource-table="snapshot"
jsname="L2NvbXBvbmVudC90aHJlc2hvbGQtd2FybmluZy9FZGl0QmFySGFuZGxlcg==" jsname="L2NvbXBvbmVudC90aHJlc2hvbGQtd2FybmluZy9FZGl0QmFySGFuZGxlcg=="
@close-item="closeItem" @close-item="closeItem"
/> />
@ -250,9 +251,7 @@ import CustomTabsSort from '@/custom-component/de-tabs/CustomTabsSort.vue'
import { exportPivotExcel } from '@/views/chart/components/js/panel/common/common_table' import { exportPivotExcel } from '@/views/chart/components/js/panel/common/common_table'
import { XpackComponent } from '@/components/plugin' import { XpackComponent } from '@/components/plugin'
import { exportPermission, isMobile } from '@/utils/utils' import { exportPermission, isMobile } from '@/utils/utils'
import { layerStoreWithOut } from '@/store/modules/data-visualization/layer'
import { isMainCanvas } from '@/utils/canvasUtils' import { isMainCanvas } from '@/utils/canvasUtils'
const layerStore = layerStoreWithOut()
const dvMainStore = dvMainStoreWithOut() const dvMainStore = dvMainStoreWithOut()
const snapshotStore = snapshotStoreWithOut() const snapshotStore = snapshotStoreWithOut()
const copyStore = copyStoreWithOut() const copyStore = copyStoreWithOut()
@ -267,7 +266,8 @@ const emits = defineEmits([
'showViewDetails', 'showViewDetails',
'amRemoveItem', 'amRemoveItem',
'linkJumpSetOpen', 'linkJumpSetOpen',
'linkageSetOpen' 'linkageSetOpen',
'componentImageDownload'
]) ])
const { t } = useI18n() const { t } = useI18n()
const { emitter } = useEmitt() const { emitter } = useEmitt()
@ -479,13 +479,12 @@ const exportAsExcel = () => {
const chartExtRequest = dvMainStore.getLastViewRequestInfo(element.value.id) const chartExtRequest = dvMainStore.getLastViewRequestInfo(element.value.id)
const viewInfo = dvMainStore.getViewDetails(element.value.id) const viewInfo = dvMainStore.getViewDetails(element.value.id)
const chart = { ...viewInfo, chartExtRequest, data: viewDataInfo, busiFlag: dvInfo.value.type } const chart = { ...viewInfo, chartExtRequest, data: viewDataInfo, busiFlag: dvInfo.value.type }
exportExcelDownload(chart, () => { exportExcelDownload(chart, dvInfo.value.name, () => {
openMessageLoading(callbackExport) openMessageLoading(callbackExport)
}) })
} }
const exportAsImage = () => { const exportAsImage = () => {
// do export emits('componentImageDownload')
useEmitt().emitter.emit('componentImageDownload-' + element.value.id)
} }
const deleteComponent = () => { const deleteComponent = () => {
eventBus.emit('removeMatrixItem-' + canvasId.value, index.value) eventBus.emit('removeMatrixItem-' + canvasId.value, index.value)

View File

@ -1,12 +1,10 @@
<script lang="ts" setup> <script lang="ts" setup>
import { computed, reactive, ref } from 'vue' import { computed, reactive, ref } from 'vue'
import { useI18n } from '@/hooks/web/useI18n'
import { deepCopy } from '@/utils/utils' import { deepCopy } from '@/utils/utils'
import { useEmitt } from '@/hooks/web/useEmitt' import { useEmitt } from '@/hooks/web/useEmitt'
import { dvMainStoreWithOut } from '@/store/modules/data-visualization/dvMain' import { dvMainStoreWithOut } from '@/store/modules/data-visualization/dvMain'
import { storeToRefs } from 'pinia' import { storeToRefs } from 'pinia'
import { ElMessage } from 'element-plus-secondary' import { ElMessage } from 'element-plus-secondary'
const { t } = useI18n()
const loading = ref(false) const loading = ref(false)
const subject = ref() const subject = ref()
const subjectDialogShow = ref(false) const subjectDialogShow = ref(false)
@ -67,8 +65,6 @@ defineExpose({
statesCheck, statesCheck,
resetForm resetForm
}) })
const emits = defineEmits(['finish'])
</script> </script>
<template> <template>

View File

@ -1,7 +1,7 @@
<template> <template>
<el-dialog <el-dialog
ref="previewPopDialog" ref="previewPopDialog"
:custom-class="'preview_pop_custom'" modal-class="preview_pop_custom"
:append-to-body="true" :append-to-body="true"
:fullscreen="state.fullscreen" :fullscreen="state.fullscreen"
v-model="state.dialogShow" v-model="state.dialogShow"
@ -20,11 +20,13 @@
/> />
</div> </div>
</el-dialog> </el-dialog>
<XpackComponent ref="xpackIframe" jsname="L2NvbXBvbmVudC9lbWJlZGRlZC1pZnJhbWUvSWZyYW1lU2VsZg==" />
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { computed, reactive } from 'vue' import { computed, reactive, ref } from 'vue'
import { useEmbedded } from '@/store/modules/embedded'
import { XpackComponent } from '@/components/plugin'
const state = reactive({ const state = reactive({
dialogShow: false, dialogShow: false,
name: '', name: '',
@ -33,7 +35,8 @@ const state = reactive({
width: '70vw', width: '70vw',
height: '70%' height: '70%'
}) })
const xpackIframe = ref()
const embeddedStore = useEmbedded()
const dialogStyle = computed(() => { const dialogStyle = computed(() => {
if (state.fullscreen) { if (state.fullscreen) {
return {} return {}
@ -46,7 +49,7 @@ const previewInit = params => {
if (params.url.includes('?')) { if (params.url.includes('?')) {
state.url = `${params.url}&popWindow=true` state.url = `${params.url}&popWindow=true`
} else { } else {
state.url = `${params.url}&popWindow=true` state.url = `${params.url}?popWindow=true`
} }
if (params.size === 'large') { if (params.size === 'large') {
state.fullscreen = true state.fullscreen = true
@ -60,6 +63,15 @@ const previewInit = params => {
state.height = '65%' state.height = '65%'
} }
state.dialogShow = true state.dialogShow = true
if (embeddedStore.getToken && state.url.includes('#/preview?dvId=')) {
if (xpackIframe?.value) {
const pm = {
methodName: 'iframeInit',
args: null
}
xpackIframe.value.invokeMethod(pm)
}
}
} }
defineExpose({ defineExpose({

View File

@ -5,21 +5,15 @@ import { dvMainStoreWithOut } from '@/store/modules/data-visualization/dvMain'
import { storeToRefs } from 'pinia' import { storeToRefs } from 'pinia'
import { snapshotStoreWithOut } from '@/store/modules/data-visualization/snapshot' import { snapshotStoreWithOut } from '@/store/modules/data-visualization/snapshot'
import Icon from '../icon-custom/src/Icon.vue' import Icon from '../icon-custom/src/Icon.vue'
import dvInfoSvg from '@/assets/svg/dv-info.svg'
import { useI18n } from '@/hooks/web/useI18n'
import combinationSvg from '@/assets/svg/combinationpage.svg'
import scatterSvg from '@/assets/svg/scatterpage.svg'
import { composeStoreWithOut } from '@/store/modules/data-visualization/compose'
const dvMainStore = dvMainStoreWithOut() const dvMainStore = dvMainStoreWithOut()
const { canvasCollapse,curComponent } = storeToRefs(dvMainStore) const { canvasCollapse } = storeToRefs(dvMainStore)
let componentNameEdit = ref(false) let componentNameEdit = ref(false)
let inputComponentName = ref({ id: null, name: null }) let inputComponentName = ref({ id: null, name: null })
let componentNameInputAttr = ref(null) let componentNameInputAttr = ref(null)
import dvInfoSvg from '@/assets/svg/dv-info.svg'
import { useI18n } from '@/hooks/web/useI18n'
const snapshotStore = snapshotStoreWithOut() const snapshotStore = snapshotStoreWithOut()
const composeStore = composeStoreWithOut()
const { areaData } = storeToRefs(composeStore)
const { t } = useI18n() const { t } = useI18n()
const emit = defineEmits(['close', 'rename'])
const props = defineProps({ const props = defineProps({
element: { element: {
required: false, required: false,
@ -64,13 +58,10 @@ const props = defineProps({
type: String as PropType<EditorTheme>, type: String as PropType<EditorTheme>,
default: 'light' default: 'light'
}, },
title: String, title: String
activePosition: {
type: String,
default: 'canvas'
}
}) })
const { width, asidePosition, sideName, themeInfo, view, themes, element,activePosition } = toRefs(props)
const { width, asidePosition, sideName, themeInfo, view, themes, element } = toRefs(props)
const collapseChange = () => { const collapseChange = () => {
canvasCollapse.value[sideName.value] = !canvasCollapse.value[sideName.value] canvasCollapse.value[sideName.value] = !canvasCollapse.value[sideName.value]
} }
@ -131,33 +122,6 @@ const editComponentName = () => {
const onComponentNameChange = () => { const onComponentNameChange = () => {
snapshotStore.recordSnapshotCache('onComponentNameChange') snapshotStore.recordSnapshotCache('onComponentNameChange')
} }
//
const combinationclick = () => {
if(areaData.value.components.length){
composeStore.compose()
snapshotStore.recordSnapshotCache('componentCompose')
menuOpt('componentCompose')
}else{
ElMessage.warning('请选择多个组件进行组合!')
return
}
}
//
const scatterclick= () => {
if(curComponent.value['component'] == 'Group'){
composeStore.decompose()
snapshotStore.recordSnapshotCache('decompose')
menuOpt('decompose')
}else{
ElMessage.warning('请选择组合!')
return
}
}
const menuOpt = optName => {
const param = { opt: optName }
activePosition.value === 'aside' && emit('close', param)
}
</script> </script>
<template> <template>
@ -173,7 +137,7 @@ const menuOpt = optName => {
:id="'attr-slide-component-name' + slideIndex" :id="'attr-slide-component-name' + slideIndex"
v-if="!canvasCollapse[sideName]" v-if="!canvasCollapse[sideName]"
class="name-area-attr" class="name-area-attr"
style="max-width: 180px; text-overflow: ellipsis; white-space: nowrap;" style="max-width: 180px; text-overflow: ellipsis; white-space: nowrap"
:style="{ width: componentNameEdit ? '300px' : 'auto' }" :style="{ width: componentNameEdit ? '300px' : 'auto' }"
:class="{ 'component-name-dark': themeInfo === 'dark' }" :class="{ 'component-name-dark': themeInfo === 'dark' }"
@dblclick="editComponentName" @dblclick="editComponentName"
@ -191,7 +155,7 @@ const menuOpt = optName => {
<span> <span>
<el-icon <el-icon
v-show="element && element['id']" v-show="element && element['id']"
style="margin: 6px 0 0 4px; cursor: pointer" style="margin: 2px 0 0 4px; cursor: pointer"
><Icon><dvInfoSvg class="svg-icon" /></Icon ><Icon><dvInfoSvg class="svg-icon" /></Icon
></el-icon> ></el-icon>
</span> </span>
@ -204,30 +168,20 @@ const menuOpt = optName => {
</div> </div>
</el-popover> </el-popover>
</div> </div>
<div style="display: flex;"> <el-icon
<div v-if="!canvasCollapse[sideName] && asidePosition === 'left'"> :title="title"
<el-icon title="组合" style="font-size: 16px;margin-right: 8px;cursor: pointer" @click="combinationclick"> :class="['custom-icon-' + themeInfo, 'collapse-icon-' + themeInfo]"
<Icon><combinationSvg class="svg-icon" /></Icon> size="20px"
</el-icon> @click="collapseChange"
<el-icon title="打散" style="font-size: 16px;margin-right: 5px;cursor: pointer" @click="scatterclick"> >
<Icon><scatterSvg class="svg-icon" /></Icon> <Expand
</el-icon> v-if="
</div> (canvasCollapse[sideName] && asidePosition === 'left') ||
<el-icon (!canvasCollapse[sideName] && asidePosition === 'right')
:title="title" "
:class="['custom-icon-' + themeInfo, 'collapse-icon-' + themeInfo]" />
size="20px" <Fold v-else />
@click="collapseChange" </el-icon>
>
<Expand
v-if="
(canvasCollapse[sideName] && asidePosition === 'left') ||
(!canvasCollapse[sideName] && asidePosition === 'right')
"
/>
<Fold v-else />
</el-icon>
</div>
</el-row> </el-row>
<div class="main-content" v-if="!canvasCollapse[sideName]"> <div class="main-content" v-if="!canvasCollapse[sideName]">
<el-scrollbar> <el-scrollbar>
@ -393,7 +347,7 @@ const menuOpt = optName => {
height: 100%; height: 100%;
} }
.ed-icon{ .ed-icon{
} }
} }
</style> </style>

View File

@ -40,7 +40,7 @@ const setNameIdTrans = (from, to, originName, name2Auto?: string[]) => {
pre[next[from]] = next[to] pre[next[from]] = next[to]
return pre return pre
}, {}) }, {})
const on = originName.match(/\[(.+?)\]/g) const on = originName.match(/\[(.+?)\]/g) || []
if (on) { if (on) {
on.forEach(itm => { on.forEach(itm => {
const ele = itm.slice(1, -1) const ele = itm.slice(1, -1)

View File

@ -236,7 +236,12 @@
state.linkJumpInfo?.jumpType === 'newPop' state.linkJumpInfo?.jumpType === 'newPop'
}" }"
> >
<el-scrollbar height="fit-content" max-height="178px"> <el-scrollbar
height="fit-content"
:max-height="
state.linkJumpInfo?.jumpType === 'newPop' ? '138px' : '178px'
"
>
<div <div
style="display: flex; margin-bottom: 6px" style="display: flex; margin-bottom: 6px"
v-for="( v-for="(
@ -663,15 +668,10 @@ const resourceType = computed(() =>
dvInfo.value.type === 'dashboard' ? t('work_branch.dashboard') : t('work_branch.big_data_screen') dvInfo.value.type === 'dashboard' ? t('work_branch.dashboard') : t('work_branch.big_data_screen')
) )
const selectSourceTips = t('visualization.select_target_resource') const selectSourceTips = t('visualization.select_target_resource')
const targetSource = t('visualization.target_dashboard_dataV') const targetSource = t('visualization.target_dashboard_dataV')
const curSource =
dvInfo.value.type === 'dashboard'
? t('visualization.cur_dashboard')
: t('visualization.cur_screen')
const state = reactive({ const state = reactive({
curDataVWeight: 0, curDataVWeight: 0,
activeCollapse: 'view', activeCollapse: 'view',
@ -746,6 +746,28 @@ const dialogInit = viewItem => {
init(viewItem) init(viewItem)
} }
const initCurFilterFieldArray = componentDataCheck => {
componentDataCheck.forEach(componentItem => {
if (componentItem.component === 'VQuery' && componentItem.propValue instanceof Array) {
componentItem.propValue.forEach(filterItem => {
if (filterItem.checkedFields.includes(state.viewId)) {
state.linkJumpCurFilterFieldArray.push({
id: filterItem.id,
name: filterItem.name,
deType: 'filter'
})
}
})
} else if (componentItem.component === 'Group') {
initCurFilterFieldArray(componentItem.propValue)
} else if (componentItem.component === 'DeTabs') {
componentItem.propValue.forEach(tabItem => {
initCurFilterFieldArray(tabItem.componentData)
})
}
})
}
const init = viewItem => { const init = viewItem => {
state.initState = false state.initState = false
state.viewId = viewItem.id state.viewId = viewItem.id
@ -792,19 +814,7 @@ const init = viewItem => {
// 1. 2. // 1. 2.
state.linkJumpCurFilterFieldArray = [] state.linkJumpCurFilterFieldArray = []
componentData.value.forEach(componentItem => { initCurFilterFieldArray(componentData.value)
if (componentItem.component === 'VQuery' && componentItem.propValue instanceof Array) {
componentItem.propValue.forEach(filterItem => {
if (filterItem.checkedFields.includes(state.viewId)) {
state.linkJumpCurFilterFieldArray.push({
id: filterItem.id,
name: filterItem.name,
deType: 'filter'
})
}
})
}
})
if (chartDetails.tableId) { if (chartDetails.tableId) {
// //
@ -1108,7 +1118,7 @@ defineExpose({
.preview { .preview {
margin-top: 5px; margin-top: 5px;
border: 1px solid #434343; border: 1px solid #e6e6e6;
border-radius: 4px; border-radius: 4px;
height: 470px !important; height: 470px !important;
overflow: hidden; overflow: hidden;

View File

@ -158,7 +158,23 @@
</el-col> </el-col>
<el-col :span="16" class="preview-show"> <el-col :span="16" class="preview-show">
<el-row class="content-head">{{ t('visualization.linkage_setting_tips1') }}</el-row> <el-row class="content-head">{{ t('visualization.linkage_setting_tips1') }}</el-row>
<el-row v-if="state.linkageInfo && state.linkageInfo.linkageActive"> <el-row
v-if="
state.linkageInfo &&
state.linkageInfo.linkageActive &&
curComponent?.innerType === 'indicator'
"
style="height: 100%"
class="custom-position"
>
<Icon name="dv-empty"
><dvEmpty style="width: 125px; height: 125px" class="svg-icon"
/></Icon>
<span style="margin-top: 8px; font-size: 14px">
{{ t('visualization.indicator_linkage') }}</span
>
</el-row>
<el-row v-else-if="state.linkageInfo && state.linkageInfo.linkageActive">
<el-row style="margin-top: 5px"> <el-row style="margin-top: 5px">
<div style="display: flex" class="inner-content"> <div style="display: flex" class="inner-content">
<div style="flex: 1">{{ t('visualization.current_chart_source_field') }}</div> <div style="flex: 1">{{ t('visualization.current_chart_source_field') }}</div>
@ -367,7 +383,10 @@ const sameDsShow = computed(
) )
const diffDsShow = computed( const diffDsShow = computed(
() => curLinkageTargetViewsInfoDiffDs.value && curLinkageTargetViewsInfoDiffDs.value.length > 0 () =>
curLinkageTargetViewsInfoDiffDs.value &&
curLinkageTargetViewsInfoDiffDs.value.length > 0 &&
curComponent.value.innerType !== 'indicator'
) )
const dialogInit = viewItem => { const dialogInit = viewItem => {
@ -387,7 +406,8 @@ const linkageSetting = curViewId => {
dvId: dvInfo.value.id, dvId: dvInfo.value.id,
sourceViewId: curViewId, sourceViewId: curViewId,
targetViewIds: targetViewIds, targetViewIds: targetViewIds,
linkageInfo: null linkageInfo: null,
resourceTable: 'snapshot'
} }
getViewLinkageGatherArray(requestInfo).then(rsp => { getViewLinkageGatherArray(requestInfo).then(rsp => {
// () // ()
@ -554,14 +574,22 @@ const linkageFieldAdaptor = async data => {
const curCheckAllAxisStr = const curCheckAllAxisStr =
JSON.stringify(state.curLinkageViewInfo.xAxis) + JSON.stringify(state.curLinkageViewInfo.xAxis) +
JSON.stringify(state.curLinkageViewInfo.xAxisExt) + JSON.stringify(state.curLinkageViewInfo.xAxisExt) +
JSON.stringify(state.curLinkageViewInfo.extStack) +
(state.curLinkageViewInfo.type.includes('chart-mix') (state.curLinkageViewInfo.type.includes('chart-mix')
? JSON.stringify(state.curLinkageViewInfo.extBubble) ? JSON.stringify(state.curLinkageViewInfo.extBubble)
: '') +
(['indicator'].includes(state.curLinkageViewInfo.type)
? JSON.stringify(state.curLinkageViewInfo.yAxis)
: '') : '')
const targetCheckAllAxisStr = const targetCheckAllAxisStr =
JSON.stringify(targetChartDetails.xAxis) + JSON.stringify(targetChartDetails.xAxis) +
JSON.stringify(targetChartDetails.xAxisExt) + JSON.stringify(targetChartDetails.xAxisExt) +
JSON.stringify(state.curLinkageViewInfo.extStack) +
(targetChartDetails.type.includes('chart-mix') (targetChartDetails.type.includes('chart-mix')
? JSON.stringify(targetChartDetails.extBubble) ? JSON.stringify(targetChartDetails.extBubble)
: '') +
(['indicator'].includes(state.curLinkageViewInfo.type)
? JSON.stringify(state.curLinkageViewInfo.yAxis)
: '') : '')
state.sourceLinkageInfo.targetViewFields.forEach(item => { state.sourceLinkageInfo.targetViewFields.forEach(item => {
if ( if (
@ -586,10 +614,11 @@ const sourceLinkageInfoFilter = computed(() => {
JSON.stringify(state.curLinkageViewInfo.xAxis) + JSON.stringify(state.curLinkageViewInfo.xAxis) +
JSON.stringify(state.curLinkageViewInfo.drillFields) + JSON.stringify(state.curLinkageViewInfo.drillFields) +
JSON.stringify(state.curLinkageViewInfo.xAxisExt) + JSON.stringify(state.curLinkageViewInfo.xAxisExt) +
JSON.stringify(state.curLinkageViewInfo.extStack) +
(state.curLinkageViewInfo.type.includes('chart-mix') (state.curLinkageViewInfo.type.includes('chart-mix')
? JSON.stringify(state.curLinkageViewInfo.extBubble) ? JSON.stringify(state.curLinkageViewInfo.extBubble)
: '') + : '') +
(state.curLinkageViewInfo.type.includes('table-normal') (['table-normal', 'indicator'].includes(state.curLinkageViewInfo.type)
? JSON.stringify(state.curLinkageViewInfo.yAxis) ? JSON.stringify(state.curLinkageViewInfo.yAxis)
: '') : '')
return state.sourceLinkageInfo.targetViewFields.filter(item => return state.sourceLinkageInfo.targetViewFields.filter(item =>
@ -644,7 +673,7 @@ defineExpose({
.preview { .preview {
margin-top: 5px; margin-top: 5px;
border: 1px solid rgb(61,61,61); border: 1px solid #e6e6e6;
border-radius: 4px; border-radius: 4px;
height: 470px !important; height: 470px !important;
overflow: hidden; overflow: hidden;
@ -652,7 +681,7 @@ defineExpose({
} }
.preview-show { .preview-show {
border-left: 1px solid #5f5f5f; border-left: 1px solid #e6e6e6;
height: 470px; height: 470px;
background-size: 100% 100% !important; background-size: 100% 100% !important;
} }
@ -701,7 +730,7 @@ defineExpose({
flex-direction: column; flex-direction: column;
span { span {
line-height: 22px; line-height: 22px;
color: #909399; color: #646a73;
} }
} }
@ -742,7 +771,7 @@ defineExpose({
margin-right: 16px; margin-right: 16px;
font-weight: 400; font-weight: 400;
font-size: 12px; font-size: 12px;
color: #d2d2d2; color: #646a73;
.ed-switch { .ed-switch {
margin-left: 8px; margin-left: 8px;
} }

View File

@ -1,5 +1,5 @@
<script setup lang="ts"> <script setup lang="ts">
import { ref, toRefs } from 'vue' import { toRefs } from 'vue'
import { propTypes } from '@/utils/propTypes' import { propTypes } from '@/utils/propTypes'
import { useI18n } from '@/hooks/web/useI18n' import { useI18n } from '@/hooks/web/useI18n'
const { t } = useI18n() const { t } = useI18n()
@ -21,13 +21,11 @@ const props = defineProps({
} }
}) })
const selection = ref()
const selectionChange = () => { const selectionChange = () => {
// do selection // do selection
} }
const { title, themes, actionSelection } = toRefs(props) const { actionSelection } = toRefs(props)
</script> </script>
<template> <template>
@ -44,7 +42,7 @@ const { title, themes, actionSelection } = toRefs(props)
<el-icon style="margin: 5px 0 0 5px"><Setting /></el-icon <el-icon style="margin: 5px 0 0 5px"><Setting /></el-icon
></span> ></span>
</template> </template>
<el-row style="color: #fff;"> <el-row>
{{ t('visualization.select_linkage_tips') }} {{ t('visualization.select_linkage_tips') }}
</el-row> </el-row>
<el-row> <el-row>

View File

@ -50,7 +50,7 @@
style="width: 100%" style="width: 100%"
v-model="data.paramName" v-model="data.paramName"
:placeholder="$t('visualization.input_param_name')" :placeholder="$t('visualization.input_param_name')"
@blur="closeEdit" @blur="closeEdit(data)"
/> />
</div> </div>
<span class="tree-select-field" v-else-if="data.paramName"> <span class="tree-select-field" v-else-if="data.paramName">
@ -62,8 +62,7 @@
</span> </span>
<span class="icon-more" v-if="!(curEditDataId === data.paramsInfoId)"> <span class="icon-more" v-if="!(curEditDataId === data.paramsInfoId)">
<handle-more <handle-more
style="margin-right: 15px;" style="margin-right: 15px"
class="icon-more-box"
@handle-command="cmd => outerParamsOperation(cmd, node, data)" @handle-command="cmd => outerParamsOperation(cmd, node, data)"
:menu-list="state.optMenu" :menu-list="state.optMenu"
:icon-name="icon_more_vertical_outlined" :icon-name="icon_more_vertical_outlined"
@ -324,10 +323,10 @@
<script setup lang="ts"> <script setup lang="ts">
import _delete from '@/assets/svg/icon_delete-trash_outlined.svg' import _delete from '@/assets/svg/icon_delete-trash_outlined.svg'
import edit from '@/assets/svg/icon_rename_outlined.svg' import edit from '@/assets/svg/icon_rename_outlined.svg'
import icon_more_vertical_outlined from '@/assets/svg/icon_more-vertical_outlined_white.svg' import icon_more_vertical_outlined from '@/assets/svg/icon_more-vertical_outlined.svg'
import filterParams from '@/assets/svg/filter-params.svg' import filterParams from '@/assets/svg/filter-params.svg'
import icon_dataset from '@/assets/svg/icon_dataset.svg' import icon_dataset from '@/assets/svg/icon_dataset.svg'
import { ref, reactive, computed, nextTick } from 'vue' import { ref, reactive, nextTick } from 'vue'
import { dvMainStoreWithOut } from '@/store/modules/data-visualization/dvMain' import { dvMainStoreWithOut } from '@/store/modules/data-visualization/dvMain'
import { storeToRefs } from 'pinia' import { storeToRefs } from 'pinia'
import { ElCol, ElIcon, ElInput, ElMessage } from 'element-plus-secondary' import { ElCol, ElIcon, ElInput, ElMessage } from 'element-plus-secondary'
@ -465,11 +464,18 @@ const validateArgs = (val, id) => {
} }
} }
const viewSelectedField = computed(() => const closeEdit = params => {
state.outerParamsInfo?.targetViewInfoList?.map(targetViewInfo => targetViewInfo.targetViewId) if (!params.paramName || params.paramName.length < 2 || params.paramName.length > 25) {
) ElMessage({
message: t('commons.params_value') + t('common.input_limit', [2, 25]),
const closeEdit = () => { type: 'warning',
showClose: true
})
if (params.paramName.length > 25) {
params.paramName = params.paramName.splice(0.25)
}
return
}
curEditDataId.value = null curEditDataId.value = null
} }
@ -481,18 +487,6 @@ const outerParamsOperation = (cmd, node, data) => {
} }
} }
const fieldIdDisabledCheck = targetViewInfo => {
return (
state.viewIdFieldArrayMap[targetViewInfo.targetViewId] &&
state.viewIdFieldArrayMap[targetViewInfo.targetViewId].length === 1 &&
state.viewIdFieldArrayMap[targetViewInfo.targetViewId][0].id === 'empty'
)
}
const getFieldArray = id => {
return state.viewIdFieldArrayMap[id]
}
const initParams = async () => { const initParams = async () => {
state.baseFilterInfo = [] state.baseFilterInfo = []
state.baseDatasetInfo = [] state.baseDatasetInfo = []
@ -720,28 +714,6 @@ const getPanelViewList = dvId => {
}) })
} }
const addOuterParamsField = () => {
state.outerParamsInfo.targetViewInfoList.push({
targetViewId: '',
targetFieldId: ''
})
}
const deleteOuterParamsField = index => {
state.outerParamsInfo.targetViewInfoList.splice(index, 1)
}
const viewInfoOnChange = targetViewInfo => {
if (
state.viewIdFieldArrayMap[targetViewInfo.targetViewId] &&
state.viewIdFieldArrayMap[targetViewInfo.targetViewId].length === 1 &&
state.viewIdFieldArrayMap[targetViewInfo.targetViewId][0].id === 'empty'
) {
targetViewInfo.targetFieldId = 'empty'
} else {
targetViewInfo.targetFieldId = null
}
}
const initSelected = data => { const initSelected = data => {
nextTick(() => { nextTick(() => {
outerParamsInfoTree.value.setCurrentKey(data.paramsInfoId) outerParamsInfoTree.value.setCurrentKey(data.paramsInfoId)
@ -809,20 +781,11 @@ defineExpose({
.root-class { .root-class {
margin: 15px 0px 5px; margin: 15px 0px 5px;
justify-content: right; justify-content: right;
.ed-button{
color: #F2F4F5;
background-color: #212121;
border: 1px solid #434343;
}
.ed-button--primary{
background-color:#0089FF;
border: 1px solid #0089FF;
}
} }
.preview { .preview {
margin-top: 5px; margin-top: 5px;
border: 1px solid #434343; border: 1px solid #e6e6e6;
border-radius: 4px; border-radius: 4px;
height: 470px !important; height: 470px !important;
overflow: hidden; overflow: hidden;
@ -922,18 +885,13 @@ defineExpose({
margin-left: auto; margin-left: auto;
display: none; display: none;
} }
&:hover {
.icon-more { &:hover .icon-more {
margin-left: auto; margin-left: auto;
display: unset; display: unset;
}
} }
.icon-more-box:hover{
border-radius: 4px;
background: #434343;
}
} }
rgb(2, 1, 1)
.link-icon-join { .link-icon-join {
font-size: 20px; font-size: 20px;
margin-top: 7px; margin-top: 7px;
@ -1156,7 +1114,7 @@ rgb(2, 1, 1)
} }
.params-attach-setting { .params-attach-setting {
border-left: 1px solid #434343; border-left: 1px solid #e6e6e6;
} }
.params-attach-content { .params-attach-content {

View File

@ -7,6 +7,7 @@
width="70vw" width="70vw"
trigger="click" trigger="click"
class="userViewEnlarge-class" class="userViewEnlarge-class"
@close="handleClose"
> >
<template #header v-if="!isIframe"> <template #header v-if="!isIframe">
<div class="header-title"> <div class="header-title">
@ -34,7 +35,7 @@
size="middle" size="middle"
@click="downloadViewImage" @click="downloadViewImage"
> >
<el-icon color="#ffffff" size="16" style="margin-right: 3px" <el-icon color="#1F2329" size="16" style="margin-right: 3px"
><icon_download_outlined ><icon_download_outlined
/></el-icon> /></el-icon>
{{ t('chart.export_img') }} {{ t('chart.export_img') }}
@ -68,7 +69,7 @@
state.dataFrom === 'template' state.dataFrom === 'template'
" "
> >
<el-icon color="#ffffff" size="16" style="margin-right: 3px" <el-icon color="#1F2329" size="16" style="margin-right: 3px"
><icon_download_outlined ><icon_download_outlined
/></el-icon> /></el-icon>
{{ t('chart.export_raw_details') }} {{ t('chart.export_raw_details') }}
@ -181,6 +182,8 @@ import { activeWatermarkCheckUser } from '@/components/watermark/watermark'
import { getCanvasStyle } from '@/utils/style' import { getCanvasStyle } from '@/utils/style'
import { exportPermission } from '@/utils/utils' import { exportPermission } from '@/utils/utils'
import EmptyBackground from '../empty-background/src/EmptyBackground.vue' import EmptyBackground from '../empty-background/src/EmptyBackground.vue'
import { supportExtremumChartType } from '@/views/chart/components/js/extremumUitl'
import ChartCarouselTooltip from '@/views/chart/components/js/g2plot_tooltip_carousel'
const downLoading = ref(false) const downLoading = ref(false)
const dvMainStore = dvMainStoreWithOut() const dvMainStore = dvMainStoreWithOut()
const dialogShow = ref(false) const dialogShow = ref(false)
@ -188,13 +191,12 @@ const requestStore = useRequestStoreWithOut()
const permissionStore = usePermissionStoreWithOut() const permissionStore = usePermissionStoreWithOut()
let viewInfo = ref<DeepPartial<ChartObj>>(null) let viewInfo = ref<DeepPartial<ChartObj>>(null)
const config = ref(null) const config = ref(null)
const canvasStyleData = ref(null)
const viewContainer = ref(null) const viewContainer = ref(null)
const { t } = useI18n() const { t } = useI18n()
const optType = ref(null) const optType = ref(null)
const chartComponentDetails = ref(null) const chartComponentDetails = ref(null)
const chartComponentDetails2 = ref(null) const chartComponentDetails2 = ref(null)
const { dvInfo, editMode, isIframe } = storeToRefs(dvMainStore) const { dvInfo, isIframe, canvasStyleData } = storeToRefs(dvMainStore)
const exportLoading = ref(false) const exportLoading = ref(false)
const sourceViewType = ref() const sourceViewType = ref()
const activeName = ref('left') const activeName = ref('left')
@ -311,7 +313,6 @@ const dialogInit = (canvasStyle, view, item, opt, params = { scale: 0.5 }) => {
viewInfo.value = deepCopy(view) as DeepPartial<ChartObj> viewInfo.value = deepCopy(view) as DeepPartial<ChartObj>
viewInfo.value.customStyle.text.show = false viewInfo.value.customStyle.text.show = false
config.value = deepCopy(item) config.value = deepCopy(item)
canvasStyleData.value = canvasStyle
if (opt === 'details') { if (opt === 'details') {
if (!viewInfo.value.type?.includes('table')) { if (!viewInfo.value.type?.includes('table')) {
assign(viewInfo.value, DETAIL_CHART_ATTR) assign(viewInfo.value, DETAIL_CHART_ATTR)
@ -324,6 +325,7 @@ const dialogInit = (canvasStyle, view, item, opt, params = { scale: 0.5 }) => {
} }
nextTick(() => { nextTick(() => {
initWatermark() initWatermark()
ChartCarouselTooltip.paused()
}) })
} }
@ -375,7 +377,7 @@ const downloadViewDetails = (downloadType = 'view') => {
busiFlag: dvInfo.value.type busiFlag: dvInfo.value.type
} }
exportLoading.value = true exportLoading.value = true
exportExcelDownload(chart, () => { exportExcelDownload(chart, dvInfo.value.name, () => {
openMessageLoading(exportData) openMessageLoading(exportData)
}) })
exportLoading.value = false exportLoading.value = false
@ -419,10 +421,18 @@ const openMessageLoading = cb => {
customClass customClass
}) })
} }
//
const mapChartTypes = ['bubble-map', 'flow-map', 'heat-map', 'map', 'symbolic-map']
const htmlToImage = () => { const htmlToImage = () => {
downLoading.value = true downLoading.value = mapChartTypes.includes(viewInfo.value.type) ? false : true
useEmitt().emitter.emit('renderChart-' + viewInfo.value.id) useEmitt().emitter.emit('renderChart-' + viewInfo.value.id)
const renderTime = viewInfo.value.type?.includes('table') ? 2000 : 500 useEmitt().emitter.emit('l7-prepare-picture', viewInfo.value.id)
// 2000500
const renderTime =
viewInfo.value.type?.includes('table') ||
supportExtremumChartType({ type: viewInfo.value.type })
? 2000
: 500
setTimeout(() => { setTimeout(() => {
initWatermark() initWatermark()
toPng(viewContainer.value) toPng(viewContainer.value)
@ -432,12 +442,14 @@ const htmlToImage = () => {
a.setAttribute('download', viewInfo.value.title) a.setAttribute('download', viewInfo.value.title)
a.href = dataUrl a.href = dataUrl
a.click() a.click()
useEmitt().emitter.emit('l7-unprepare-picture', viewInfo.value.id)
useEmitt().emitter.emit('renderChart-' + viewInfo.value.id) useEmitt().emitter.emit('renderChart-' + viewInfo.value.id)
initWatermark() initWatermark()
}) })
.catch(error => { .catch(error => {
downLoading.value = false downLoading.value = false
initWatermark() initWatermark()
useEmitt().emitter.emit('l7-unprepare-picture', viewInfo.value.id)
useEmitt().emitter.emit('renderChart-' + viewInfo.value.id) useEmitt().emitter.emit('renderChart-' + viewInfo.value.id)
console.error('oops, something went wrong!', error) console.error('oops, something went wrong!', error)
}) })
@ -447,7 +459,9 @@ const htmlToImage = () => {
const initWatermark = () => { const initWatermark = () => {
activeWatermarkCheckUser('enlarge-inner-content', 'canvas-main', state.scale) activeWatermarkCheckUser('enlarge-inner-content', 'canvas-main', state.scale)
} }
const handleClose = () => {
ChartCarouselTooltip.closeEnlargeDialogDestroy(viewInfo.value.id)
}
defineExpose({ defineExpose({
dialogInit dialogInit
}) })
@ -596,7 +610,7 @@ defineExpose({
} }
.ed-dropdown-menu{ .ed-dropdown-menu{
background-color: rgb(41, 41, 41); background-color: rgb(41, 41, 41);
} }
.ed-dropdown-menu__item{ .ed-dropdown-menu__item{
color: #fff; color: #fff;

View File

@ -1,6 +1,11 @@
<template> <template>
<div> <div>
<el-dropdown :teleported="false" trigger="click"> <el-dropdown
:id="'view-track-bar-' + chartId"
:teleported="false"
trigger="click"
@visible-change="visibleChange"
>
<input id="input" ref="trackButton" type="button" hidden /> <input id="input" ref="trackButton" type="button" hidden />
<template #dropdown> <template #dropdown>
<div :class="{ 'data-mobile': isDataVMobile }"> <div :class="{ 'data-mobile': isDataVMobile }">
@ -12,6 +17,7 @@
<el-dropdown-item <el-dropdown-item
v-for="(item, key) in trackMenu" v-for="(item, key) in trackMenu"
:key="key" :key="key"
@mousedown.stop
@click="trackMenuClick(item)" @click="trackMenuClick(item)"
><span class="menu-item">{{ state.i18n_map[item] }}</span></el-dropdown-item ><span class="menu-item">{{ state.i18n_map[item] }}</span></el-dropdown-item
> >
@ -52,11 +58,27 @@ const state = reactive({
linkage: t('visualization.linkage'), linkage: t('visualization.linkage'),
linkageAndDrill: t('visualization.linkage_and_drill'), linkageAndDrill: t('visualization.linkage_and_drill'),
jump: t('visualization.jump'), jump: t('visualization.jump'),
enlarge: t('visualization.enlarge') enlarge: t('visualization.enlarge'),
event_jump: t('visualization.jump'),
event_download: t('visualization.download'),
event_share: t('visualization.share'),
event_fullScreen: t('visualization.fullscreen'),
event_showHidden: t('visualization.pop_area'),
event_refreshDataV: t('visualization.refresh'),
event_refreshView: t('visualization.refresh_view')
} }
}) })
const visibleChange = () => {
const trackButtonClick = () => { document.querySelectorAll('.g2-tooltip')?.forEach(tooltip => {
if (tooltip.id?.includes(chartId.value)) {
tooltip.classList.toggle('hidden-tooltip', true)
}
})
}
// tooltip
const chartId = ref(null)
const trackButtonClick = (id?: string) => {
chartId.value = id
setTimeout(() => { setTimeout(() => {
trackButton.value.click() trackButton.value.click()
}, 50) }, 50)

View File

@ -1,5 +1,5 @@
<template> <template>
<el-form label-position="left" :label-width="14"> <el-form size="small" label-position="left" :label-width="14">
<el-row :gutter="8" v-for="(x, i) in positionKeysGroup" :key="i"> <el-row :gutter="8" v-for="(x, i) in positionKeysGroup" :key="i">
<el-col :span="12" v-for="({ key, label, min, max, step }, j) in x" :key="j"> <el-col :span="12" v-for="({ key, label, min, max, step }, j) in x" :key="j">
<el-form-item class="form-item" :class="'form-item-' + themes" :label="label"> <el-form-item class="form-item" :class="'form-item-' + themes" :label="label">
@ -239,7 +239,7 @@ watch(
display: flex !important; display: flex !important;
.ed-form-item__label { .ed-form-item__label {
line-height: 24px; line-height: 24px;
margin-bottom: 0; margin: 3px 0 !important;
} }
} }
</style> </style>

View File

@ -1,10 +1,9 @@
<script lang="ts" setup> <script lang="ts" setup>
import { dvMainStoreWithOut } from '@/store/modules/data-visualization/dvMain' import { dvMainStoreWithOut } from '@/store/modules/data-visualization/dvMain'
import { onBeforeUnmount, onMounted } from 'vue'
import { useEmitt } from '@/hooks/web/useEmitt'
const dvMainStore = dvMainStoreWithOut() const dvMainStore = dvMainStoreWithOut()
import screenfull from 'screenfull'
import { onBeforeUnmount, onMounted, toRefs } from 'vue'
import { useEmitt } from '@/hooks/web/useEmitt'
const props = defineProps({ const props = defineProps({
themes: { themes: {
@ -21,41 +20,46 @@ const props = defineProps({
default: 'preview' default: 'preview'
} }
}) })
const { themes } = toRefs(props)
const fullscreenChange = () => { const fullscreenChange = () => {
if (screenfull.isEnabled) { const isFullscreen = !!document.fullscreenElement
dvMainStore.setFullscreenFlag(screenfull.isFullscreen) dvMainStore.setFullscreenFlag(isFullscreen)
// 使
if (props.showPosition === 'edit') { // 使
if (screenfull.isFullscreen) { if (props.showPosition === 'edit') {
dvMainStore.setEditMode('preview') dvMainStore.setEditMode(isFullscreen ? 'preview' : 'edit')
} else { }
dvMainStore.setEditMode('edit')
} // 使
} if (props.showPosition === 'dvEdit') {
// 使 useEmitt().emitter.emit('canvasScrollRestore')
if (props.showPosition === 'dvEdit') {
useEmitt().emitter.emit('canvasScrollRestore')
}
} }
} }
const toggleFullscreen = () => { const toggleFullscreen = () => {
if (screenfull.isEnabled) { const bodyNode = document.querySelector('body')
const bodyNode = document.querySelector('body') if (!document.fullscreenElement) {
screenfull.toggle(bodyNode) bodyNode?.requestFullscreen()
} else {
document.exitFullscreen()
}
}
// windows退 退
const handleKeydown = event => {
if (event.key === 'Escape' && document.fullscreenElement) {
document.exitFullscreen()
} }
} }
onMounted(() => { onMounted(() => {
if (screenfull.isEnabled) { document.addEventListener('fullscreenchange', fullscreenChange)
screenfull.on('change', fullscreenChange) document.addEventListener('keydown', handleKeydown)
}
}) })
onBeforeUnmount(() => { onBeforeUnmount(() => {
screenfull.off('change', fullscreenChange) document.removeEventListener('fullscreenchange', fullscreenChange)
document.removeEventListener('keydown', handleKeydown)
}) })
defineExpose({ defineExpose({

View File

@ -107,7 +107,7 @@ const reUpload = e => {
} }
const sizeMessage = () => { const sizeMessage = () => {
ElMessage.success('图片大小不符合') ElMessage.success('图片大小不能超过15M')
} }
onMounted(() => { onMounted(() => {

View File

@ -13,7 +13,7 @@
" "
@change="reUpload" @change="reUpload"
/> />
<el-form label-position="top" style="width: 100%; margin-bottom: 8px"> <el-form size="small" label-position="top" style="width: 100%">
<el-row :gutter="8"> <el-row :gutter="8">
<el-col :span="12"> <el-col :span="12">
<el-form-item <el-form-item
@ -25,7 +25,6 @@
style="width: 100%" style="width: 100%"
:effect="themes" :effect="themes"
controls-position="right" controls-position="right"
size="middle"
:min="0" :min="0"
:max="100" :max="100"
v-model="state.commonBackground.innerPadding" v-model="state.commonBackground.innerPadding"
@ -43,7 +42,6 @@
style="width: 100%" style="width: 100%"
:effect="themes" :effect="themes"
controls-position="right" controls-position="right"
size="middle"
:min="0" :min="0"
:max="100" :max="100"
v-model="state.commonBackground.borderRadius" v-model="state.commonBackground.borderRadius"
@ -70,7 +68,6 @@
style="width: 100%" style="width: 100%"
:effect="themes" :effect="themes"
controls-position="right" controls-position="right"
size="middle"
:min="0" :min="0"
:max="30" :max="30"
:disabled="!state.commonBackground.backdropFilterEnable" :disabled="!state.commonBackground.backdropFilterEnable"
@ -148,7 +145,6 @@
:disabled="!state.commonBackground.backgroundImageEnable" :disabled="!state.commonBackground.backgroundImageEnable"
:effect="themes" :effect="themes"
:title="t('visualization.border_color_setting')" :title="t('visualization.border_color_setting')"
style="position: absolute; top: -3px; left: 60px"
is-custom is-custom
show-alpha show-alpha
class="color-picker-style" class="color-picker-style"
@ -164,7 +160,6 @@
<el-select <el-select
:style="{ width: computedBackgroundBorderSelectWidth + 'px' }" :style="{ width: computedBackgroundBorderSelectWidth + 'px' }"
v-model="state.commonBackground.innerImage" v-model="state.commonBackground.innerImage"
size="middle"
popper-class="board-select" popper-class="board-select"
:effect="themes" :effect="themes"
:disabled="!state.commonBackground.backgroundImageEnable" :disabled="!state.commonBackground.backgroundImageEnable"
@ -302,7 +297,7 @@ const goFile = () => {
} }
const sizeMessage = () => { const sizeMessage = () => {
ElMessage.success('图片大小不符合') ElMessage.success('图片大小不能超过15M')
} }
const reUpload = e => { const reUpload = e => {
@ -584,5 +579,9 @@ watch(
.ed-select-dropdown__item.selected { .ed-select-dropdown__item.selected {
background-color: rgba(0, 0, 0, 0) !important; background-color: rgba(0, 0, 0, 0) !important;
} }
.is-selected::after {
display: none;
}
} }
</style> </style>

View File

@ -13,7 +13,7 @@
" "
@change="reUpload" @change="reUpload"
/> />
<el-form label-position="top" style="width: 100%; margin-bottom: 16px"> <el-form size="small" label-position="top" style="width: 100%; margin-bottom: 16px">
<el-form-item class="form-item" :class="'form-item-' + themes" v-if="showWatermarkSetting"> <el-form-item class="form-item" :class="'form-item-' + themes" v-if="showWatermarkSetting">
<el-checkbox <el-checkbox
size="small" size="small"

View File

@ -3,6 +3,8 @@ import { storeToRefs } from 'pinia'
import { dvMainStoreWithOut } from '@/store/modules/data-visualization/dvMain' import { dvMainStoreWithOut } from '@/store/modules/data-visualization/dvMain'
import { ref } from 'vue' import { ref } from 'vue'
import { ipInfoApi } from '@/api/user' import { ipInfoApi } from '@/api/user'
import { isISOMobile } from '@/utils/utils'
const dvMainStore = dvMainStoreWithOut() const dvMainStore = dvMainStoreWithOut()
const { dvInfo } = storeToRefs(dvMainStore) const { dvInfo } = storeToRefs(dvMainStore)
@ -233,7 +235,7 @@ export function activeWatermark(
watermark_color: watermarkForm.watermark_color, watermark_color: watermarkForm.watermark_color,
watermark_x_space: watermarkForm.watermark_x_space * scale, watermark_x_space: watermarkForm.watermark_x_space * scale,
watermark_y_space: watermarkForm.watermark_y_space * scale, watermark_y_space: watermarkForm.watermark_y_space * scale,
watermark_fontsize: watermarkForm.watermark_fontsize * scale + 'px' watermark_fontsize: watermarkForm.watermark_fontsize * scale * (isISOMobile() ? 2.5 : 1) + 'px'
} }
watermark(settings, domId) watermark(settings, domId)
} }