Merge branch 'dev-v2' into pr@dev-v2@refactor_i18n

This commit is contained in:
王嘉豪 2024-11-25 23:32:58 +08:00 committed by GitHub
commit 682bb94cf9
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
32 changed files with 506 additions and 75 deletions

View File

@ -120,7 +120,7 @@ public class YoyChartHandler extends DefaultChartHandler {
expandedResult.setQuerySql(originSql);
}
// 同环比数据排序
expandedResult.setOriginData(sortData(view, expandedResult.getOriginData(),formatResult));
expandedResult.setOriginData(sortData(view, expandedResult.getOriginData(), formatResult));
return expandedResult;
}
@ -128,7 +128,14 @@ public class YoyChartHandler extends DefaultChartHandler {
// 维度排序
List<ChartViewFieldDTO> xAxisSortList = view.getXAxis().stream().filter(x -> !StringUtils.equalsIgnoreCase("none", x.getSort())).toList();
// 指标排序
List<ChartViewFieldDTO> yAxisSortList = view.getYAxis().stream().filter(y -> !StringUtils.equalsIgnoreCase("none", y.getSort())).toList();
List<ChartViewFieldDTO> yAxisSortList = view.getYAxis().stream().filter(y -> {
//需要针对区间条形图的时间类型判断一下
if (StringUtils.equalsIgnoreCase("bar-range", view.getType()) && StringUtils.equalsIgnoreCase(y.getGroupType(), "d") && y.getDeType() == 1) {
return false;
} else {
return !StringUtils.equalsIgnoreCase("none", y.getSort());
}
}).toList();
// 不包含维度排序时指标排序生效
if (!data.isEmpty() && CollectionUtils.isEmpty(xAxisSortList) && CollectionUtils.isNotEmpty(yAxisSortList)) {
// 指标排序仅第一个生效

View File

@ -31,6 +31,7 @@ import jakarta.servlet.http.HttpServletResponse;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.exception.ExceptionUtils;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.ss.util.CellRangeAddress;
import org.apache.poi.xssf.streaming.SXSSFWorkbook;
@ -89,7 +90,7 @@ public class ChartDataServer implements ChartDataApi {
return chartDataManage.calcData(chartViewDTO);
}
} catch (Exception e) {
DEException.throwException(ResultCode.DATA_IS_WRONG.code(), e.getMessage());
DEException.throwException(ResultCode.DATA_IS_WRONG.code(), e.getMessage() + "\n\n" + ExceptionUtils.getStackTrace(e));
}
return null;
}

View File

@ -11,8 +11,9 @@ ALTER TABLE `visualization_link_jump_target_view_info`
ADD COLUMN `target_type` varchar(50) NULL COMMENT '联动目标类型 view 图表 filter 过滤组件 outParams 外部参数';
ALTER TABLE `visualization_link_jump_target_view_info`
MODIFY COLUMN `target_view_id` varchar(50) NULL DEFAULT NULL COMMENT '目标图表ID' AFTER `source_field_active_id`,
MODIFY COLUMN `target_field_id` varchar(50) NULL DEFAULT NULL COMMENT '目标字段ID' AFTER `target_view_id`;
MODIFY COLUMN `target_view_id` varchar(50) NULL DEFAULT NULL COMMENT '目标图表ID';
ALTER TABLE `visualization_link_jump_target_view_info`
MODIFY COLUMN `target_field_id` varchar(50) NULL DEFAULT NULL COMMENT '目标字段ID';
update visualization_link_jump_target_view_info set target_type = 'view';
ALTER TABLE `data_visualization_info`

View File

@ -1,3 +1,3 @@
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M6.30394 16.5H17.6959C17.9459 16.35 18.2149 16.23 18.4999 16.145V14.5C18.4999 14.2348 18.3946 13.9804 18.207 13.7929C18.0195 13.6054 17.7652 13.5 17.4999 13.5H6.49994C6.23472 13.5 5.98037 13.6054 5.79283 13.7929C5.6053 13.9804 5.49994 14.2348 5.49994 14.5V16.145C5.78494 16.23 6.05444 16.35 6.30394 16.5ZM3.49994 16.145V14.5C3.49994 13.7044 3.81601 12.9413 4.37862 12.3787C4.94123 11.8161 5.70429 11.5 6.49994 11.5H10.9999V9.37402C10.0573 9.13063 9.23575 8.55179 8.68934 7.74601C8.14292 6.94023 7.90915 5.96283 8.03182 4.99702C8.15449 4.03121 8.6252 3.14329 9.35571 2.4997C10.0862 1.85611 11.0264 1.50104 11.9999 1.50104C12.9735 1.50104 13.9137 1.85611 14.6442 2.4997C15.3747 3.14329 15.8454 4.03121 15.9681 4.99702C16.0907 5.96283 15.857 6.94023 15.3105 7.74601C14.7641 8.55179 13.9426 9.13063 12.9999 9.37402V11.5H17.4999C18.2956 11.5 19.0586 11.8161 19.6213 12.3787C20.1839 12.9413 20.4999 13.7044 20.4999 14.5V16.145C21.2693 16.3744 21.9365 16.8613 22.3896 17.5241C22.8426 18.1869 23.0541 18.9853 22.9884 19.7854C22.9227 20.5856 22.584 21.3389 22.0289 21.9189C21.4738 22.499 20.7362 22.8706 19.9397 22.9715C19.1432 23.0723 18.3363 22.8962 17.6542 22.4728C16.9721 22.0494 16.4563 21.4043 16.1932 20.6457C15.9302 19.8872 15.936 19.0613 16.2096 18.3065C16.4832 17.5517 17.008 16.9139 17.6959 16.5H6.30394C6.99191 16.9139 7.51668 17.5517 7.79027 18.3065C8.06386 19.0613 8.06964 19.8872 7.80663 20.6457C7.54362 21.4043 7.02782 22.0494 6.34571 22.4728C5.6636 22.8962 4.85665 23.0723 4.06015 22.9715C3.26366 22.8706 2.52604 22.499 1.97098 21.9189C1.41592 21.3389 1.07715 20.5856 1.01149 19.7854C0.945821 18.9853 1.15725 18.1869 1.61031 17.5241C2.06338 16.8613 2.73054 16.3744 3.49994 16.145ZM11.9999 7.50002C12.5304 7.50002 13.0391 7.28931 13.4142 6.91423C13.7892 6.53916 13.9999 6.03045 13.9999 5.50002C13.9999 4.96959 13.7892 4.46088 13.4142 4.08581C13.0391 3.71073 12.5304 3.50002 11.9999 3.50002C11.4695 3.50002 10.9608 3.71073 10.5857 4.08581C10.2107 4.46088 9.99994 4.96959 9.99994 5.50002C9.99994 6.03045 10.2107 6.53916 10.5857 6.91423C10.9608 7.28931 11.4695 7.50002 11.9999 7.50002V7.50002ZM19.4999 21C19.8978 21 20.2793 20.842 20.5606 20.5607C20.8419 20.2794 20.9999 19.8978 20.9999 19.5C20.9999 19.1022 20.8419 18.7207 20.5606 18.4394C20.2793 18.1581 19.8978 18 19.4999 18C19.1021 18 18.7206 18.1581 18.4393 18.4394C18.158 18.7207 17.9999 19.1022 17.9999 19.5C17.9999 19.8978 18.158 20.2794 18.4393 20.5607C18.7206 20.842 19.1021 21 19.4999 21V21ZM4.49994 21C4.89776 21 5.2793 20.842 5.5606 20.5607C5.8419 20.2794 5.99994 19.8978 5.99994 19.5C5.99994 19.1022 5.8419 18.7207 5.5606 18.4394C5.2793 18.1581 4.89776 18 4.49994 18C4.10212 18 3.72058 18.1581 3.43928 18.4394C3.15798 18.7207 2.99994 19.1022 2.99994 19.5C2.99994 19.8978 3.15798 20.2794 3.43928 20.5607C3.72058 20.842 4.10212 21 4.49994 21V21Z" fill="#1F2329"/>
<svg width="24" height="24" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
<path d="M6.30394 16.5H17.6959C17.9459 16.35 18.2149 16.23 18.4999 16.145V14.5C18.4999 14.2348 18.3946 13.9804 18.207 13.7929C18.0195 13.6054 17.7652 13.5 17.4999 13.5H6.49994C6.23472 13.5 5.98037 13.6054 5.79283 13.7929C5.6053 13.9804 5.49994 14.2348 5.49994 14.5V16.145C5.78494 16.23 6.05444 16.35 6.30394 16.5ZM3.49994 16.145V14.5C3.49994 13.7044 3.81601 12.9413 4.37862 12.3787C4.94123 11.8161 5.70429 11.5 6.49994 11.5H10.9999V9.37402C10.0573 9.13063 9.23575 8.55179 8.68934 7.74601C8.14292 6.94023 7.90915 5.96283 8.03182 4.99702C8.15449 4.03121 8.6252 3.14329 9.35571 2.4997C10.0862 1.85611 11.0264 1.50104 11.9999 1.50104C12.9735 1.50104 13.9137 1.85611 14.6442 2.4997C15.3747 3.14329 15.8454 4.03121 15.9681 4.99702C16.0907 5.96283 15.857 6.94023 15.3105 7.74601C14.7641 8.55179 13.9426 9.13063 12.9999 9.37402V11.5H17.4999C18.2956 11.5 19.0586 11.8161 19.6213 12.3787C20.1839 12.9413 20.4999 13.7044 20.4999 14.5V16.145C21.2693 16.3744 21.9365 16.8613 22.3896 17.5241C22.8426 18.1869 23.0541 18.9853 22.9884 19.7854C22.9227 20.5856 22.584 21.3389 22.0289 21.9189C21.4738 22.499 20.7362 22.8706 19.9397 22.9715C19.1432 23.0723 18.3363 22.8962 17.6542 22.4728C16.9721 22.0494 16.4563 21.4043 16.1932 20.6457C15.9302 19.8872 15.936 19.0613 16.2096 18.3065C16.4832 17.5517 17.008 16.9139 17.6959 16.5H6.30394C6.99191 16.9139 7.51668 17.5517 7.79027 18.3065C8.06386 19.0613 8.06964 19.8872 7.80663 20.6457C7.54362 21.4043 7.02782 22.0494 6.34571 22.4728C5.6636 22.8962 4.85665 23.0723 4.06015 22.9715C3.26366 22.8706 2.52604 22.499 1.97098 21.9189C1.41592 21.3389 1.07715 20.5856 1.01149 19.7854C0.945821 18.9853 1.15725 18.1869 1.61031 17.5241C2.06338 16.8613 2.73054 16.3744 3.49994 16.145ZM11.9999 7.50002C12.5304 7.50002 13.0391 7.28931 13.4142 6.91423C13.7892 6.53916 13.9999 6.03045 13.9999 5.50002C13.9999 4.96959 13.7892 4.46088 13.4142 4.08581C13.0391 3.71073 12.5304 3.50002 11.9999 3.50002C11.4695 3.50002 10.9608 3.71073 10.5857 4.08581C10.2107 4.46088 9.99994 4.96959 9.99994 5.50002C9.99994 6.03045 10.2107 6.53916 10.5857 6.91423C10.9608 7.28931 11.4695 7.50002 11.9999 7.50002V7.50002ZM19.4999 21C19.8978 21 20.2793 20.842 20.5606 20.5607C20.8419 20.2794 20.9999 19.8978 20.9999 19.5C20.9999 19.1022 20.8419 18.7207 20.5606 18.4394C20.2793 18.1581 19.8978 18 19.4999 18C19.1021 18 18.7206 18.1581 18.4393 18.4394C18.158 18.7207 17.9999 19.1022 17.9999 19.5C17.9999 19.8978 18.158 20.2794 18.4393 20.5607C18.7206 20.842 19.1021 21 19.4999 21V21ZM4.49994 21C4.89776 21 5.2793 20.842 5.5606 20.5607C5.8419 20.2794 5.99994 19.8978 5.99994 19.5C5.99994 19.1022 5.8419 18.7207 5.5606 18.4394C5.2793 18.1581 4.89776 18 4.49994 18C4.10212 18 3.72058 18.1581 3.43928 18.4394C3.15798 18.7207 2.99994 19.1022 2.99994 19.5C2.99994 19.8978 3.15798 20.2794 3.43928 20.5607C3.72058 20.842 4.10212 21 4.49994 21V21Z" />
</svg>

Before

Width:  |  Height:  |  Size: 2.9 KiB

After

Width:  |  Height:  |  Size: 2.8 KiB

View File

@ -64,7 +64,7 @@ defineExpose({
.custom-sort_filter {
.drag-list {
overflow: auto;
max-height: 800px;
max-height: 400px;
.item-dimension {
padding: 2px;
margin: 2px;

View File

@ -3491,7 +3491,7 @@ defineExpose({
}
}
.label {
width: 100px;
width: 80px;
color: #1f2329;
}

View File

@ -291,9 +291,18 @@ const setOldMapValue = arr => {
const customSort = () => {
if (config.value.sortList?.length && config.value.sort === 'customSort') {
options.value = [
...options.value.sort(
(a, b) => config.value.sortList.indexOf(a.value) - config.value.sortList.indexOf(b.value)
)
...options.value
.sort(a => {
if (config.value.sortList.indexOf(a.value) !== -1) {
return -1
}
})
.sort((a, b) => {
if (config.value.sortList.indexOf(a.value) === -1) {
return 0
}
return config.value.sortList.indexOf(a.value) - config.value.sortList.indexOf(b.value)
})
]
}
}
@ -517,7 +526,7 @@ const setOptions = (num: number) => {
handleFieldIdChange({
queryId: field.id,
displayId: displayId || field.id,
sort: sort === 'customSort' ? '' : sort,
sort: sort === 'customSort' ? 'asc' : sort,
sortId,
resultMode: config.value.resultMode || 0,
searchText: searchText.value,

View File

@ -0,0 +1,55 @@
<script lang="ts" setup>
import iconSetting from '@/assets/svg/icon-setting.svg'
import { useRouter } from 'vue-router'
import { useAppearanceStoreWithOut } from '@/store/modules/appearance'
import { computed } from 'vue'
const appearanceStore = useAppearanceStoreWithOut()
const navigateBg = computed(() => appearanceStore.getNavigateBg)
const { push, resolve } = useRouter()
const redirectUser = () => {
const sysMenu = resolve('/sys-setting')
const kidPath = sysMenu.matched[0].children[0].path
push(`${sysMenu.path}/${kidPath}`)
}
</script>
<template>
<el-tooltip class="box-item" effect="dark" content="系统设置" placement="top">
<div
class="sys-setting in-iframe-setting"
:class="{
'is-light-setting': navigateBg && navigateBg === 'light'
}"
>
<el-icon @click="redirectUser">
<Icon class="icon-setting" name="icon-setting"
><iconSetting class="svg-icon icon-setting"
/></Icon>
</el-icon>
</div>
</el-tooltip>
</template>
<style lang="less" scoped>
.sys-setting {
margin: 0 10px 0 0;
padding: 5px;
height: 28px;
width: 28px;
border-radius: 4px;
overflow: hidden;
cursor: pointer;
&:hover {
background-color: #1e2738;
}
}
.in-iframe-setting {
margin-left: 10px !important;
}
.is-light-setting {
&:hover {
background-color: #1f23291a !important;
}
}
</style>

View File

@ -23,6 +23,7 @@ import AiComponent from '@/layout/components/AiComponent.vue'
import { findBaseParams } from '@/api/aiComponent'
import AiTips from '@/layout/components/AiTips.vue'
import CopilotCom from '@/layout/components/Copilot.vue'
import DesktopSetting from './DesktopSetting.vue'
const appearanceStore = useAppearanceStoreWithOut()
const { push } = useRouter()
@ -119,7 +120,7 @@ const copilotConfirm = () => {
wsCache.set('DE-COPILOT-TIPS-CHECK', 'CHECKED')
showOverlayCopilot.value = false
}
const badgeCount = ref(0)
const badgeCount = ref('0')
onMounted(() => {
initShowSystem()
@ -128,7 +129,7 @@ onMounted(() => {
initCopilotBase()
msgCountApi().then(res => {
badgeCount.value = res?.data || 0
badgeCount.value = (res?.data > 99 ? '99+' : res?.data) || '0'
})
})
</script>
@ -189,10 +190,14 @@ onMounted(() => {
<ToolboxCfg v-if="showToolbox" />
<TopDoc v-if="appearanceStore.getShowDoc" />
<el-tooltip effect="dark" :content="$t('v_query.msg_center')" placement="bottom">
<el-badge :hidden="badgeCount === 0" :value="badgeCount" class="item">
<el-badge
style="margin-right: 10px"
:hidden="[0, '0'].includes(badgeCount)"
:value="badgeCount"
class="ed-badge_custom"
>
<el-icon
class="preview-download_icon"
style="margin-right: 10px"
:class="navigateBg === 'light' && 'is-light-setting'"
>
<Icon name="dv-preview-download"
@ -211,10 +216,23 @@ onMounted(() => {
<div v-if="showOverlay && appearanceStore.getShowAi" class="overlay"></div>
<div v-if="showOverlayCopilot && appearanceStore.getShowCopilot" class="overlay"></div>
</div>
<div v-else class="operate-setting">
<desktop-setting />
</div>
</el-header>
</template>
<style lang="less" scoped>
:deep(.ed-badge_custom) {
--ed-badge-size: 14px;
.ed-badge__content {
right: 0;
padding: 3px;
border: none;
font-size: 8px;
transform: translateX(20%) translateY(-30%);
}
}
.preview-download_icon {
padding: 5px;
height: 28px;

View File

@ -7,10 +7,11 @@ import { useRouter } from 'vue-router'
import AccountOperator from '@/layout/components/AccountOperator.vue'
import { useAppearanceStoreWithOut } from '@/store/modules/appearance'
import { useI18n } from '@/hooks/web/useI18n'
import { isDesktop } from '@/utils/ModelUtil'
const appearanceStore = useAppearanceStoreWithOut()
const { push } = useRouter()
const { t } = useI18n()
const desktop = isDesktop()
const props = withDefaults(
defineProps<{
title: string
@ -43,7 +44,7 @@ const navigate = computed(() => appearanceStore.getNavigate)
<span class="work">{{ t('work_branch.back_to_work_branch') }}</span>
</span>
<AccountOperator />
<AccountOperator v-if="!desktop" />
</div>
</el-header>
</template>

View File

@ -1,5 +1,5 @@
<script lang="ts" setup>
import iconSetting from '@/assets/svg/icon-setting.svg'
import iconSetting from '@/assets/svg/icon_organization_outlined.svg'
import { useRouter } from 'vue-router'
import { useAppearanceStoreWithOut } from '@/store/modules/appearance'
import { computed } from 'vue'

View File

@ -83,9 +83,8 @@ onMounted(() => {
<style lang="less">
.toolbox-top-popover {
height: 82px;
min-width: 208px !important;
padding: 16px !important;
padding: 8px !important;
display: flex;
.doc-card {
margin: auto;

View File

@ -29,17 +29,15 @@ const cardInfoList = [
:show-arrow="false"
popper-class="top-popover"
placement="bottom-end"
width="208"
width="210"
trigger="hover"
>
<el-row>
<top-doc-card
:span="12"
v-for="(item, index) in cardInfoList"
:key="index"
:card-info="item"
></top-doc-card>
</el-row>
<top-doc-card
:span="12"
v-for="(item, index) in cardInfoList"
:key="index"
:card-info="item"
></top-doc-card>
<template #reference>
<div
class="sys-setting"
@ -75,6 +73,11 @@ const cardInfoList = [
<style lang="less">
.top-popover {
padding: 0 0 16px 0 !important;
display: flex;
padding: 8px !important;
flex-wrap: wrap;
.doc-card {
margin: auto;
}
}
</style>

View File

@ -27,33 +27,28 @@ const openBlank = () => {
<template>
<div class="doc-card" @click="openBlank">
<el-row class="base-show">
<Icon class-name="item-top-icon"
><component class="svg-icon item-top-icon" :is="cardInfo.icon"></component
></Icon>
</el-row>
<el-row class="base-show show-content"> {{ cardInfo.name }}</el-row>
<div class="base-show">
<Icon><component class="svg-icon item-top-icon" :is="cardInfo.icon"></component></Icon>
</div>
<div class="base-show show-content">{{ cardInfo.name }}</div>
</div>
</template>
<style lang="less" scoped>
.doc-card {
padding-top: 2px;
margin-top: 16px;
margin-left: 16px;
width: 80px;
height: 50px;
padding: 8px 0;
width: 96px;
height: 66px;
cursor: pointer;
&:hover {
background-color: rgba(30, 39, 56, 0.05);
}
display: flex;
flex-direction: column;
align-items: center;
&:hover,
&:active {
background-color: rgba(30, 39, 56, 0.1);
background-color: #1f23291a;
border-radius: 4px;
}
}
.base-show {
justify-content: center;
}
.show-content {
font-size: 14px;

View File

@ -48,7 +48,9 @@ const { t } = useI18n()
>
{{ msgFillMenu ? t('v_query.msg_center') : t('toolbox.org_center') }}
</div>
<Menu :style="{ height: systemMenu ? 'calc(100% - 48px)' : '100%' }"></Menu>
<Menu
:style="{ height: systemMenu || msgFillMenu ? 'calc(100% - 48px)' : '100%' }"
></Menu>
</Sidebar>
<el-aside class="layout-sidebar layout-sidebar-collapse" v-else>
<Menu

View File

@ -1378,7 +1378,8 @@ export default {
chartName: 'New Chart',
chart_show_error: 'Cannot display normally',
chart_error_tips:
'Abnormal data acquisition, if you have any questions, please contact the administrator',
'Abnormal data acquisition, if you have any questions, please contact the administrator, ',
chart_show_error_info: 'click to show error info',
title_cannot_empty: 'Title cannot be empty',
table_title_height: 'Header row height',
table_item_height: 'Table row height',

View File

@ -996,7 +996,7 @@ export default {
primary_key_change: '主鍵不能改變:',
api_field_not_empty: '欄位不能為空',
success_copy: '複製成功',
primary_key_length: '键必须设置长: ',
primary_key_length: '鍵必須設置長: ',
valid: '有效',
invalid: '無效',
api_step_1: '連結API',
@ -1048,7 +1048,7 @@ export default {
set_key: '設為主鍵',
field_rename: '重命名',
select_type: '選擇資料來源類型',
length: '字段',
length: '字段',
sync_table: '同步指定表',
req_completed: '請求成功',
sync_rate: '更新頻率',
@ -1348,7 +1348,8 @@ export default {
date_split: 'yyyy/MM/dd',
chartName: '新建圖表',
chart_show_error: '無法正常顯示',
chart_error_tips: '取得資料異常如有疑問請聯絡管理員',
chart_error_tips: '取得資料異常如有疑問請聯絡管理員',
chart_show_error_info: '查看異常原因',
title_cannot_empty: '標題不能為空',
table_title_height: '表頭行高',
table_item_height: '表格行高',

View File

@ -1350,7 +1350,8 @@ export default {
date_split: 'yyyy/MM/dd',
chartName: '新建图表',
chart_show_error: '无法正常显示',
chart_error_tips: '获取数据异常如有疑问请联系管理员',
chart_error_tips: '获取数据异常如有疑问请联系管理员',
chart_show_error_info: '查看异常原因',
title_cannot_empty: '标题不能为空',
table_title_height: '表头行高',
table_item_height: '表格行高',
@ -4079,6 +4080,8 @@ export default {
single_del_tips_dataset: '该数据集存在如下血缘关系删除会造成相关视图失效确定删除',
single_del_tips_datasource: ' {0} 个数据集正在使用此数据源删除后数据集不可用确定删除',
folder: '文件夹',
del_folder_tips: '删除后此文件夹下的所有资源都会被删除请谨慎操作'
del_folder_tips: '删除后此文件夹下的所有资源都会被删除请谨慎操作',
sync_to_org: '迁移至目标组织',
sync_org_placeholder: '请选择目标组织'
}
}

View File

@ -946,6 +946,10 @@ declare interface ChartLabelAttr {
* 全部显示
*/
fullDisplay: boolean
/**
* 仪表盘占比显示格式
*/
proportionSeriesFormatter: SeriesFormatter
}
/**
* 提示设置

View File

@ -127,7 +127,8 @@ export const customAttrTrans = {
],
label: {
fontSize: '',
seriesLabelFormatter: ['fontSize']
seriesLabelFormatter: ['fontSize'],
proportionSeriesFormatter: ['fontSize']
},
tooltip: {
fontSize: '',

View File

@ -193,7 +193,7 @@ const syncFree = () => {
<template>
<el-dialog
:append-to-body="true"
title="关于"
:title="t('common.about')"
width="840px"
v-model="dialogVisible"
class="about-dialog"

View File

@ -238,7 +238,8 @@ const state = reactive<{ labelForm: DeepPartial<ChartLabelAttr> }>({
seriesLabelFormatter: [],
labelFormatter: DEFAULT_LABEL.labelFormatter,
conversionTag: DEFAULT_LABEL.conversionTag,
totalFormatter: DEFAULT_LABEL.totalFormatter
totalFormatter: DEFAULT_LABEL.totalFormatter,
proportionSeriesFormatter: DEFAULT_LABEL.proportionSeriesFormatter
}
})
@ -303,7 +304,10 @@ const showSeriesLabelFormatter = computed(() => {
const showDivider = computed(() => {
const DIVIDER_PROPS = ['labelFormatter', 'showDimension', 'showQuota', 'showProportion']
return (
includesAny(props.propertyInner, ...DIVIDER_PROPS) && !isBarRangeTime.value && !isGroupBar.value
includesAny(props.propertyInner, ...DIVIDER_PROPS) &&
!isBarRangeTime.value &&
!isGroupBar.value &&
!isGauge.value
)
})
@ -460,6 +464,9 @@ const conversionPrecision = [
const noFullDisplay = computed(() => {
return !['liquid', 'gauge', 'indicator'].includes(props.chart.type)
})
const isGauge = computed(() => {
return props.chart.type === 'gauge'
})
</script>
<template>
@ -509,7 +516,7 @@ const noFullDisplay = computed(() => {
/>
</el-form-item>
</div>
<div v-if="!isGroupBar">
<div v-if="!isGroupBar && !isGauge">
<el-space>
<el-form-item
class="form-item"
@ -681,7 +688,7 @@ const noFullDisplay = computed(() => {
:class="{ 'divider-dark': themes === 'dark' }"
v-if="showDivider"
/>
<template v-if="showProperty('labelFormatter') && !isBarRangeTime && !isGroupBar">
<template v-if="showProperty('labelFormatter') && !isBarRangeTime && !isGroupBar && !isGauge">
<el-form-item
:label="$t('chart.value_formatter_type')"
class="form-item"
@ -1588,6 +1595,230 @@ const noFullDisplay = computed(() => {
</el-col>
</el-row>
</div>
<template v-if="isGauge">
<el-form-item class="form-item form-item-checkbox" :class="'form-item-' + themes">
<el-checkbox
:effect="themes"
size="small"
@change="changeLabelAttr('childrenShow')"
v-model="state.labelForm.childrenShow"
label="quota"
>
{{ t('chart.quota') }}
</el-checkbox>
</el-form-item>
<div style="padding-left: 22px">
<el-space>
<el-form-item
class="form-item"
:class="'form-item-' + themes"
v-if="showProperty('color')"
:label="t('chart.text')"
>
<el-color-picker
:disabled="!state.labelForm.childrenShow"
:effect="themes"
v-model="state.labelForm.color"
class="color-picker-style"
:predefine="COLOR_PANEL"
@change="changeLabelAttr('color')"
is-custom
/>
</el-form-item>
<el-form-item
class="form-item"
:class="'form-item-' + themes"
v-if="showProperty('fontSize')"
>
<template #label>&nbsp;</template>
<el-tooltip content="字号" :effect="toolTip" placement="top">
<el-select
:disabled="!state.labelForm.childrenShow"
size="small"
style="width: 108px"
:effect="themes"
v-model.number="state.labelForm.fontSize"
:placeholder="t('chart.text_fontsize')"
@change="changeLabelAttr('fontSize')"
>
<el-option
v-for="option in fontSizeList"
:key="option.value"
:label="option.name"
:value="option.value"
/>
</el-select>
</el-tooltip>
</el-form-item>
</el-space>
<el-form-item
:label="$t('chart.value_formatter_type')"
class="form-item"
:class="'form-item-' + themes"
>
<el-select
:disabled="!state.labelForm.childrenShow"
size="small"
:effect="themes"
v-model="state.labelForm.labelFormatter.type"
@change="changeLabelAttr('labelFormatter.type')"
>
<el-option
v-for="type in formatterType"
:key="type.value"
:label="$t('chart.' + type.name)"
:value="type.value"
/>
</el-select>
</el-form-item>
<el-form-item
v-if="state.labelForm.labelFormatter && state.labelForm.labelFormatter.type !== 'auto'"
:label="$t('chart.value_formatter_decimal_count')"
class="form-item"
:class="'form-item-' + themes"
>
<el-input-number
:disabled="!state.labelForm.childrenShow"
controls-position="right"
:effect="themes"
v-model="state.labelForm.labelFormatter.decimalCount"
:precision="0"
:min="0"
:max="10"
@change="changeLabelAttr('labelFormatter.decimalCount')"
/>
</el-form-item>
<el-row
:gutter="8"
v-if="state.labelForm.labelFormatter && state.labelForm.labelFormatter.type !== 'percent'"
>
<el-col :span="12">
<el-form-item
:label="$t('chart.value_formatter_unit')"
class="form-item"
:class="'form-item-' + themes"
>
<el-select
:disabled="!state.labelForm.childrenShow"
size="small"
:effect="themes"
v-model="state.labelForm.labelFormatter.unit"
:placeholder="$t('chart.pls_select_field')"
@change="changeLabelAttr('labelFormatter.unit')"
>
<el-option
v-for="item in unitType"
:key="item.value"
:label="$t('chart.' + item.name)"
:value="item.value"
/>
</el-select>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item
:label="$t('chart.value_formatter_suffix')"
class="form-item"
:class="'form-item-' + themes"
>
<el-input
:disabled="!state.labelForm.childrenShow"
:effect="themes"
v-model="state.labelForm.labelFormatter.suffix"
clearable
:placeholder="$t('commons.input_content')"
@change="changeLabelAttr('labelFormatter.suffix')"
/>
</el-form-item>
</el-col>
</el-row>
<el-form-item class="form-item" :class="'form-item-' + themes">
<el-checkbox
size="small"
:effect="themes"
v-model="state.labelForm.labelFormatter.thousandSeparator"
@change="changeLabelAttr('labelFormatter.thousandSeparator')"
:label="t('chart.value_formatter_thousand_separator')"
:disabled="!state.labelForm.childrenShow"
/>
</el-form-item>
</div>
<el-form-item class="form-item form-item-checkbox" :class="'form-item-' + themes">
<el-checkbox
:effect="themes"
size="small"
@change="changeLabelAttr('proportionSeriesFormatter')"
v-model="state.labelForm.proportionSeriesFormatter.show"
label="quota"
>
{{ t('chart.proportion') }}
</el-checkbox>
</el-form-item>
<div style="padding-left: 22px">
<el-space>
<el-form-item
class="form-item"
:class="'form-item-' + themes"
v-if="showProperty('color')"
:label="t('chart.text')"
>
<el-color-picker
:disabled="!state.labelForm.proportionSeriesFormatter.show"
:effect="themes"
v-model="state.labelForm.proportionSeriesFormatter.color"
class="color-picker-style"
:predefine="COLOR_PANEL"
@change="changeLabelAttr('proportionSeriesFormatter.color')"
is-custom
/>
</el-form-item>
<el-form-item
class="form-item"
:class="'form-item-' + themes"
v-if="showProperty('fontSize')"
>
<template #label>&nbsp;</template>
<el-tooltip content="字号" :effect="toolTip" placement="top">
<el-select
:disabled="!state.labelForm.proportionSeriesFormatter.show"
size="small"
style="width: 108px"
:effect="themes"
v-model.number="state.labelForm.proportionSeriesFormatter.fontSize"
:placeholder="t('chart.text_fontsize')"
@change="changeLabelAttr('proportionSeriesFormatter.fontSize')"
>
<el-option
v-for="option in fontSizeList"
:key="option.value"
:label="option.name"
:value="option.value"
/>
</el-select>
</el-tooltip>
</el-form-item>
</el-space>
<el-form-item
:label="t('chart.label_reserve_decimal_count')"
class="form-item"
:class="'form-item-' + themes"
>
<el-select
size="small"
:effect="themes"
:disabled="!state.labelForm.proportionSeriesFormatter.show"
v-model="state.labelForm.proportionSeriesFormatter.formatterCfg.decimalCount"
@change="changeLabelAttr('proportionSeriesFormatter')"
>
<el-option :label="t('chart.reserve_zero')" :value="0" />
<el-option :label="t('chart.reserve_one')" :value="1" />
<el-option :label="t('chart.reserve_two')" :value="2" />
</el-select>
</el-form-item>
</div>
</template>
</el-form>
</template>

View File

@ -308,7 +308,7 @@ onMounted(() => {
controls-position="right"
v-model="state.tableCellForm.tableItemHeight"
:min="20"
:max="100"
:max="1000"
@change="changeTableCell('tableItemHeight')"
/>
</el-form-item>

View File

@ -275,7 +275,7 @@ onMounted(() => {
controls-position="right"
v-model="state.tableHeaderForm.tableTitleHeight"
:min="20"
:max="100"
:max="1000"
@change="changeTableHeader('tableTitleHeight')"
/>
</el-form-item>

View File

@ -343,7 +343,15 @@ export const DEFAULT_LABEL: ChartLabelAttr = {
totalColor: '#FFF',
totalFormatter: formatterItem,
showStackQuota: false,
fullDisplay: false
fullDisplay: false,
proportionSeriesFormatter: {
show: false,
color: '#000',
fontSize: 12,
formatterCfg: {
decimalCount: 2
}
}
}
export const DEFAULT_TOOLTIP: ChartTooltipAttr = {
show: true,

View File

@ -106,6 +106,18 @@ export class SymbolicMap extends L7ChartView<Scene, L7Config> {
if (basicStyle.autoFit === false) {
center = [basicStyle.mapCenter.longitude, basicStyle.mapCenter.latitude]
}
// 联动时聚焦到数据点多个取第一个
if (
chart.chartExtRequest?.linkageFilters?.length &&
xAxis?.length === 2 &&
chart.data?.tableRow.length
) {
// 经度
const lng = chart.data?.tableRow?.[0][chart.xAxis[0].dataeaseName]
// 纬度
const lat = chart.data?.tableRow?.[0][chart.xAxis[1].dataeaseName]
center = [lng, lat]
}
const chartObj = drawOption.chartObj as unknown as L7Wrapper<L7Config, Scene>
let scene = chartObj?.getScene()
if (!scene) {

View File

@ -243,11 +243,12 @@ export class Gauge extends G2PlotChartView<GaugeOptions, G2Gauge> {
): GaugeOptions {
const customAttr = parseJson(chart.customAttr)
const data = chart.data.series[0].data[0]
let labelTitle: GaugeOptions['statistic']['title'] = false
let labelContent: GaugeOptions['statistic']['content'] = false
const label = customAttr.label
const labelFormatter = label.labelFormatter ?? DEFAULT_LABEL.labelFormatter
if (label.show) {
labelContent = {
if (label.show && label.childrenShow) {
labelTitle = {
style: {
fontSize: `${label.fontSize}px`,
color: label.color
@ -261,13 +262,33 @@ export class Gauge extends G2PlotChartView<GaugeOptions, G2Gauge> {
}
return valueFormatter(value, labelFormatter)
}
} as GaugeOptions['statistic']['title']
}
const { min, max } = context
if (label.show && label.proportionSeriesFormatter.show) {
const proportionFormatter = label.proportionSeriesFormatter
labelContent = {
offsetY: proportionFormatter.fontSize + label.fontSize,
style: {
fontSize: `${proportionFormatter.fontSize}px`,
color: proportionFormatter.color
},
formatter: function () {
const proportionValue = ((parseFloat(data) - min) / (max - min)) * 100
return (
t('chart.proportion') +
' ' +
proportionValue.toFixed(proportionFormatter.formatterCfg.decimalCount) +
'%'
)
}
} as GaugeOptions['statistic']['content']
}
const statistic = {
title: labelTitle,
content: labelContent
}
const { gaugeAxisLine, gaugePercentLabel } = customAttr.basicStyle
const { min, max } = context
const tmp = {
axis: {
label: {
@ -276,7 +297,10 @@ export class Gauge extends G2PlotChartView<GaugeOptions, G2Gauge> {
return ''
}
if (gaugePercentLabel === false) {
return v === '0' ? min : v === '1' ? max : min + (max - min) * v
const resultV = v === '0' ? min : v === '1' ? max : min + (max - min) * v
return labelFormatter.type === 'value'
? valueFormatter(resultV, labelFormatter)
: resultV
}
return v === '0' ? v : v * 100 + '%'
}

View File

@ -1,5 +1,6 @@
<script lang="tsx" setup>
import { useI18n } from '@/hooks/web/useI18n'
import { ref } from 'vue'
const { t } = useI18n()
@ -10,11 +11,38 @@ const props = defineProps({
default: ''
}
})
const dialogVisible = ref(false)
function showInfo() {
dialogVisible.value = true
}
</script>
<template>
<div class="canvas-content error-info">
<span>[{{ t('chart.chart_error_tips') }}]</span>
<span
>[{{ t('chart.chart_error_tips')
}}<a style="color: #0969da; cursor: pointer" @click="showInfo">{{
t('chart.chart_show_error_info')
}}</a
>]</span
>
<el-dialog
:append-to-body="true"
v-model="dialogVisible"
width="80%"
:close-on-click-modal="false"
center
>
<el-main style="height: 400px">
<span style="white-space: pre-line" v-html="errMsg"></span>
</el-main>
<template #footer>
<span class="m-dialog-footer">
<el-button @click="dialogVisible = false">{{ t('commons.close') }}</el-button>
</span>
</template>
</el-dialog>
</div>
</template>
@ -30,4 +58,10 @@ const props = defineProps({
height: 100%;
flex-direction: column;
}
.m-dialog-footer {
display: flex;
flex-direction: row;
align-items: center;
justify-content: center;
}
</style>

View File

@ -879,6 +879,9 @@ const toolTip = computed(() => {
})
const marginBottom = computed<string | 0>(() => {
if (!titleShow.value) {
return 0
}
if (titleShow.value || trackMenu.value.length > 0 || state.title_remark.show) {
return 12 * scale.value + 'px'
}
@ -890,8 +893,22 @@ const iconSize = computed<string>(() => {
})
const titleIconStyle = computed(() => {
//
const style = {
position: 'absolute',
color: 'rgb(255, 252, 252)',
position: 'absolute',
border: '1px solid rgb(173, 170, 170)',
'background-color': 'rgba(173, 170, 170)',
'border-radius': '2px',
padding: '0 2px 0 2px',
top: '2px',
'z-index': 1,
left: '6px'
}
return {
color: canvasStyleData.value.component.seniorStyleSetting.linkageIconColor
color: canvasStyleData.value.component.seniorStyleSetting.linkageIconColor,
...(titleShow.value ? {} : style)
}
})
const chartHover = ref(false)

View File

@ -132,6 +132,7 @@ const createDataset = (tableName?: string) => {
useEmitt().emitter.emit('changeCurrentComponent', 'DatasetEditor')
return
}
wsCache.set('ds-info-id', nodeInfo.id)
router.push({
path: '/dataset-form',
query: {
@ -989,7 +990,9 @@ const loadInit = () => {
}
onMounted(() => {
nodeInfo.id = (route.params.id as string) || (route.query.id as string) || ''
const dsId = wsCache.get('ds-info-id') || route.params.id
nodeInfo.id = (dsId as string) || (route.query.id as string) || ''
wsCache.delete('ds-info-id')
loadInit()
listDs()
const { opt } = router.currentRoute.value.query

@ -1 +1 @@
Subproject commit 0b3d7d7ed645f0332d4d42f5ee29ba9454d9c3e2
Subproject commit 8ac18a900ac4744d62ff3c7e4ee6ec3c8fb82933

View File

@ -1,5 +1,6 @@
package io.dataease.api.free;
import io.dataease.api.free.dto.FreeBatchDelRequest;
import io.dataease.api.free.dto.FreeBatchSyncRequest;
import io.dataease.api.free.dto.FreeQueryRequest;
import io.dataease.api.free.dto.FreeSyncRequest;
@ -24,5 +25,5 @@ public interface FreeApi {
void syncBatch(@RequestBody FreeBatchSyncRequest request);
@PostMapping("/deleteBatch")
void deleteBatch(@RequestBody FreeBatchSyncRequest request);
void deleteBatch(@RequestBody FreeBatchDelRequest request);
}