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

This commit is contained in:
fit2cloud-chenyw 2024-04-25 17:16:35 +08:00
commit 3aae2ab6bb
16 changed files with 219 additions and 57 deletions

View File

@ -24,7 +24,7 @@
"axios": "^1.3.3",
"crypto-js": "^4.1.1",
"dayjs": "^1.11.9",
"element-plus-secondary": "^0.5.6",
"element-plus-secondary": "^0.5.8",
"element-resize-detector": "^1.2.4",
"file-saver": "^2.0.5",
"html-to-image": "^1.11.11",

View File

@ -0,0 +1,4 @@
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M2.5 4H19.5C19.7761 4 20 4.22386 20 4.5V5.5C20 5.77614 19.7761 6 19.5 6H2.5C2.22386 6 2 5.77614 2 5.5V4.5C2 4.22386 2.22386 4 2.5 4ZM2.5 18H19.5C19.7761 18 20 18.2239 20 18.5V19.5C20 19.7761 19.7761 20 19.5 20H2.5C2.22386 20 2 19.7761 2 19.5V18.5C2 18.2239 2.22386 18 2.5 18ZM2.5 11H13.5C13.7761 11 14 11.2239 14 11.5V12.5C14 12.7761 13.7761 13 13.5 13H2.5C2.22386 13 2 12.7761 2 12.5V11.5C2 11.2239 2.22386 11 2.5 11Z" fill="#1F2329"/>
<path d="M21.4107 12.3072C21.3607 12.3901 21.2913 12.4596 21.2083 12.5096L16.9643 15.0679C16.6829 15.2375 16.3173 15.1469 16.1477 14.8655C16.0918 14.7728 16.0623 14.6667 16.0623 14.5584L16.0622 9.44156C16.0622 9.11302 16.3285 8.84667 16.6571 8.84666C16.7653 8.84666 16.8715 8.87619 16.9642 8.93208L21.2084 11.4906C21.4897 11.6602 21.5803 12.0258 21.4107 12.3072Z" fill="#1F2329"/>
</svg>

After

Width:  |  Height:  |  Size: 930 B

View File

@ -0,0 +1,4 @@
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M4.43781 4H21.4378C21.7139 4 21.9378 4.22386 21.9378 4.5V5.5C21.9378 5.77614 21.7139 6 21.4378 6H4.43781C4.16166 6 3.93781 5.77614 3.93781 5.5V4.5C3.93781 4.22386 4.16166 4 4.43781 4ZM4.43781 18H21.4378C21.7139 18 21.9378 18.2239 21.9378 18.5V19.5C21.9378 19.7761 21.7139 20 21.4378 20H4.43781C4.16166 20 3.93781 19.7761 3.93781 19.5V18.5C3.93781 18.2239 4.16166 18 4.43781 18ZM10.4378 11H21.4378C21.7139 11 21.9378 11.2239 21.9378 11.5V12.5C21.9378 12.7761 21.7139 13 21.4378 13H10.4378C10.1617 13 9.93781 12.7761 9.93781 12.5V11.5C9.93781 11.2239 10.1617 11 10.4378 11Z" fill="#1F2329"/>
<path d="M2.0855 12.3072C2.13548 12.3901 2.20494 12.4596 2.28785 12.5096L6.53189 15.0679C6.81326 15.2375 7.17886 15.1469 7.34848 14.8655C7.40435 14.7729 7.43388 14.6667 7.43389 14.5584L7.43401 9.44158C7.43401 9.11303 7.16768 8.84669 6.83914 8.84668C6.73089 8.84668 6.6247 8.87621 6.532 8.93209L2.28785 11.4906C2.00647 11.6602 1.91588 12.0259 2.0855 12.3072Z" fill="#1F2329"/>
</svg>

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

@ -103,21 +103,19 @@ onUnmounted(() => {
<template>
<el-row class="custom-main">
<div class="scale-area">
<el-input
<el-input-number
@keydown.stop
@keyup.stop
type="number"
size="small"
effect="dark"
v-model="scale"
effect="dark"
:min="10"
:max="200"
:controls="false"
size="small"
controls-position="right"
@change="handleScaleChange()"
class="scale-input-number"
>
<template #suffix> % </template>
</el-input>
/>
<el-icon @click="scaleDecrease(1)" class="hover-icon-custom" style="margin-right: 12px">
<Icon name="dv-min"></Icon
></el-icon>
@ -160,16 +158,19 @@ onUnmounted(() => {
}
.scale-input-number {
height: 28px;
width: 80px !important;
height: 24px;
line-height: 24px;
width: 80px;
margin-right: 16px;
input {
-webkit-appearance: none;
-moz-appearance: textfield;
&::-webkit-inner-spin-button,
&::-webkit-outer-spin-button {
-webkit-appearance: none;
:deep(.ed-input__wrapper) {
position: relative;
padding: 0 38px 0 8px;
&::after {
position: absolute;
content: '%';
right: 35px;
top: 1px;
}
}
}

View File

@ -14,7 +14,6 @@ import 'vant/es/popup/style'
import 'vant/es/date-picker/style'
import 'vant/es/picker-group/style'
import 'vant/es/time-picker/style'
import { Icon } from '@/components/icon-custom'
interface SelectConfig {
selectValue: any

View File

@ -42,6 +42,7 @@ onMounted(() => {
.ai-popper-tips {
z-index: 10001 !important;
padding: 24px !important;
box-shadow: none;
background: var(--ed-color-primary) !important;
.ed-popper__arrow::before {
border: 1px solid var(--ed-color-primary) !important;
@ -67,6 +68,7 @@ onMounted(() => {
line-height: 22px;
text-align: right;
button {
border-color: #ffffff !important;
font-weight: 500;
color: rgba(51, 112, 255, 1) !important;
}

View File

@ -0,0 +1,41 @@
<script lang="ts" setup>
const props = defineProps({
isCollapse: Boolean
})
const emits = defineEmits(['setCollapse'])
const setCollapse = () => {
emits('setCollapse', !props.isCollapse)
}
</script>
<template>
<div class="de-collapse-bar" @click="setCollapse">
<el-icon>
<Icon :name="!isCollapse ? 'icon_side-fold_outlined' : 'icon_side-expand_outlined'"></Icon>
</el-icon>
{{ !isCollapse ? '收起导航' : '' }}
</div>
</template>
<style lang="less" scoped>
.de-collapse-bar {
position: fixed;
cursor: pointer;
z-index: 10;
left: 0;
bottom: 0;
height: 48px;
padding: 14px 22px;
font-size: 14px;
font-weight: 400;
line-height: 22px;
color: #646a73;
display: flex;
align-items: center;
.ed-icon {
font-size: 20px;
margin-right: 10px;
}
}
</style>

View File

@ -1,5 +1,5 @@
<script lang="ts" setup>
import { ref, computed } from 'vue'
import { computed } from 'vue'
import { ElMenu } from 'element-plus-secondary'
import { useRoute, useRouter } from 'vue-router'
import { isExternal } from '@/utils/validate'
@ -12,7 +12,10 @@ const tempColor = computed(() => {
(appearanceStore.themeColor === 'custom' ? appearanceStore.customColor : '#3370FF') + '1A'
}
})
const isCollapse = ref(false)
defineProps({
collapse: Boolean
})
const route = useRoute()
const { push } = useRouter()
const menuList = computed(() => route.matched[0]?.children || [])
@ -38,7 +41,7 @@ const menuSelect = (index: string, indexPath: string[]) => {
@select="menuSelect"
:default-active="activeIndex"
class="el-menu-vertical"
:collapse="isCollapse"
:collapse="collapse"
>
<MenuItem v-for="menu in menuList" :key="menu.path" :menu="menu"></MenuItem>
</el-menu>

View File

@ -3,7 +3,7 @@ import { h } from 'vue'
import { Icon } from '@/components/icon-custom'
import { ElMenuItem, ElSubMenu, ElIcon } from 'element-plus-secondary'
const title = props => {
const titleWithIcon = props => {
const { title, icon } = props.menu?.meta || {}
return [
h(ElIcon, null, { default: () => h(Icon, { className: 'logo', name: icon }) }),
@ -21,16 +21,18 @@ const MenuItem = props => {
ElSubMenu,
{ index: path },
{
title: () => title(props),
title: () => titleWithIcon(props),
default: () => children.map(ele => h(MenuItem, { menu: ele }))
}
)
}
const { title, icon } = props.menu?.meta || {}
return h(
ElMenuItem,
{ index: path },
{
title: () => title(props)
title: h('span', null, { default: () => title }),
default: h(ElIcon, null, { default: () => h(Icon, { className: 'logo', name: icon }) })
}
)
}

View File

@ -1,10 +1,11 @@
<script lang="ts" setup>
import { computed } from 'vue'
import { computed, ref } from 'vue'
import Header from './components/Header.vue'
import HeaderSystem from './components/HeaderSystem.vue'
import Sidebar from './components/Sidebar.vue'
import Menu from './components/Menu.vue'
import Main from './components/Main.vue'
import CollapseBar from './components/CollapseBar.vue'
import { ElContainer } from 'element-plus-secondary'
import { useRoute } from 'vue-router'
const route = useRoute()
@ -12,6 +13,10 @@ const systemMenu = computed(() => route.path.includes('system'))
const settingMenu = computed(() => route.path.includes('sys-setting'))
const marketMenu = computed(() => route.path.includes('template-market'))
const toolboxMenu = computed(() => route.path.includes('toolbox'))
const isCollapse = ref(false)
const setCollapse = () => {
isCollapse.value = !isCollapse.value
}
</script>
<template>
@ -22,10 +27,22 @@ const toolboxMenu = computed(() => route.path.includes('toolbox'))
/>
<Header v-else></Header>
<el-container class="layout-container">
<Sidebar v-if="systemMenu || settingMenu || toolboxMenu" class="layout-sidebar">
<div v-if="systemMenu" class="org-config-center">组织管理中心</div>
<Menu :style="{ height: systemMenu ? 'calc(100% - 48px)' : '100%' }"></Menu>
</Sidebar>
<template v-if="systemMenu || settingMenu || toolboxMenu">
<Sidebar v-if="!isCollapse" class="layout-sidebar">
<div @click="setCollapse" v-if="systemMenu && !isCollapse" class="org-config-center">
组织管理中心
</div>
<Menu :style="{ height: systemMenu ? 'calc(100% - 48px)' : '100%' }"></Menu>
</Sidebar>
<el-aside class="layout-sidebar layout-sidebar-collapse" v-else>
<Menu
:collapse="isCollapse"
:style="{ height: systemMenu ? 'calc(100% - 48px)' : '100%' }"
></Menu>
</el-aside>
<CollapseBar @setCollapse="setCollapse" :isCollapse="isCollapse"></CollapseBar>
</template>
<Main
class="layout-main"
:class="{ 'with-sider': systemMenu || settingMenu || toolboxMenu }"
@ -47,6 +64,20 @@ const toolboxMenu = computed(() => route.path.includes('toolbox'))
.layout-container {
.layout-sidebar {
height: calc(100vh - 56px);
position: relative;
&::after {
content: '';
width: 100%;
height: 1px;
background: #1f232926;
position: absolute;
bottom: 48px;
left: 0;
}
}
.layout-sidebar-collapse {
width: 64px;
}
.org-config-center {

View File

@ -710,6 +710,8 @@ declare interface MapCfg {
* 象限属性
*/
declare interface QuadrantAttr {
xBaseline?: number
yBaseline?: number
lineStyle: QuadrantLineStyle
regionStyle: QuadrantCommonStyle[]
labels: QuadrantLabelConf[]

View File

@ -804,7 +804,7 @@ onMounted(() => {
v-model="state.basicStyleForm.topNLabel"
size="small"
:maxlength="50"
@blur="changeBasicStyle('topNLabel')"
@change="changeBasicStyle('topNLabel')"
/>
</el-form-item>
</div>

View File

@ -1,8 +1,13 @@
<script lang="tsx" setup>
import { computed, onMounted, PropType, reactive, watch } from 'vue'
import { computed, inject, onMounted, PropType, reactive, ref, watch } from 'vue'
import { useI18n } from '@/hooks/web/useI18n'
import { COLOR_PANEL, DEFAULT_QUADRANT_STYLE } from '@/views/chart/components/editor/util/chart'
import { useEmitt } from '@/hooks/web/useEmitt'
useEmitt({
name: 'quadrant-default-baseline',
callback: args => quadrantDefaultBaseline(args)
})
const quotaData = ref<Axis[]>(inject('quotaData'))
const { t } = useI18n()
const props = defineProps({
@ -63,6 +68,10 @@ const fillOpacityList = computed(() => {
const changeStyle = () => {
emit('onChangeQuadrantForm', state.quadrantForm)
}
const quadrantDefaultBaseline = quadrant => {
state.quadrantForm.xBaseline = quadrant.xBaseline
state.quadrantForm.yBaseline = quadrant.yBaseline
}
const init = () => {
const chart = JSON.parse(JSON.stringify(props.chart))
@ -136,6 +145,42 @@ onMounted(() => {
</el-tooltip>
</el-form-item>
</div>
<div style="display: flex">
<el-form-item
class="form-item"
label="X 轴恒线"
:class="'form-item-' + themes"
style="padding-left: 4px"
>
<el-input-number
controls-position="right"
style="width: 100%"
:effect="props.themes"
v-model="state.quadrantForm.xBaseline"
:precision="0"
:min="0"
size="small"
@change="changeStyle()"
/>
</el-form-item>
<el-form-item
class="form-item"
label="Y 轴恒线"
:class="'form-item-' + themes"
style="padding-left: 4px"
>
<el-input-number
controls-position="right"
style="width: 100%"
:effect="props.themes"
v-model="state.quadrantForm.yBaseline"
:precision="0"
:min="0"
size="small"
@change="changeStyle()"
/>
</el-form-item>
</div>
</template>
<div
v-for="(l, index) in state.quadrantForm.labels"

View File

@ -7,7 +7,6 @@ import { flow, parseJson } from '../../../util'
import { valueFormatter } from '../../../formatter'
import { useI18n } from '@/hooks/web/useI18n'
import { isEmpty } from 'lodash-es'
import { Datum } from '@antv/g2plot/esm/types/common'
import { DEFAULT_QUADRANT_STYLE } from '@/views/chart/components/editor/util/chart'
const { t } = useI18n()
@ -31,7 +30,7 @@ export class Quadrant extends G2PlotChartView<ScatterOptions, G2Scatter> {
]
propertyInner: EditorPropertyInner = {
'basic-style-selector': ['colors', 'alpha', 'scatterSymbol', 'scatterSymbolSize'],
'label-selector': ['fontSize', 'color', 'labelFormatter'],
'label-selector': ['fontSize', 'color'],
'tooltip-selector': ['fontSize', 'color', 'backgroundColor', 'seriesTooltipFormatter'],
'x-axis-selector': [
'position',
@ -118,7 +117,7 @@ export class Quadrant extends G2PlotChartView<ScatterOptions, G2Scatter> {
}
public drawChart(drawOptions: G2PlotDrawOptions<G2Scatter>) {
const { chart, container, action } = drawOptions
const { chart, container, action, quadrantDefaultBaseline } = drawOptions
if (!chart.data?.data) {
return
}
@ -150,6 +149,8 @@ export class Quadrant extends G2PlotChartView<ScatterOptions, G2Scatter> {
const dataLength = chart.data?.data.length / chart.data?.fields.length
for (let index = 0; index < dataLength; index++) {
const tmpData = {
dimensionList: groupedData[xFieldObj.name][index].dimensionList,
quotaList: groupedData[xFieldObj.name][index].quotaList,
[xFieldObj.name]: groupedData[xFieldObj.name][index].value
}
if (groupedData[yFieldObj.name]) {
@ -167,21 +168,41 @@ export class Quadrant extends G2PlotChartView<ScatterOptions, G2Scatter> {
}
data.push(tmpData)
}
chart.customAttr['quadrant'].xBaseline = (
data.reduce((valueSoFar, currentItem) => {
return valueSoFar + currentItem[xFieldObj.name]
}, 0) / data.length
// x轴基准线 默认值
const xBaseline = (
(data.reduce((valueSoFar, currentItem) => {
return Math.max(valueSoFar, currentItem[xFieldObj.name])
}, 0) +
data.reduce((valueSoFar, currentItem) => {
return Math.min(valueSoFar, currentItem[xFieldObj.name])
}, Infinity)) /
2
).toFixed()
chart.customAttr['quadrant'].yBaseline = (
data.reduce((valueSoFar, currentItem) => {
return valueSoFar + currentItem[yFieldObj.name]
}, 0) / data.length
// y轴基准线 默认值
const yBaseline = (
(data.reduce((valueSoFar, currentItem) => {
return Math.max(valueSoFar, currentItem[yFieldObj.name])
}, 0) +
data.reduce((valueSoFar, currentItem) => {
return Math.min(valueSoFar, currentItem[yFieldObj.name])
}, Infinity)) /
2
).toFixed()
const defaultBaselineQuadrant = {
...chart.customAttr['quadrant']
}
// 新建图表
if (!defaultBaselineQuadrant.xBaseline) {
// 默认基准线值
defaultBaselineQuadrant.xBaseline = xBaseline
defaultBaselineQuadrant.yBaseline = yBaseline
}
const colorField = colorFieldObj.name ? { colorField: colorFieldObj.name } : {}
const quadrant = chart.customAttr['quadrant'] ? { quadrant: chart.customAttr['quadrant'] } : {}
const baseOptions: ScatterOptions = {
...colorField,
...quadrant,
quadrant: {
...defaultBaselineQuadrant
},
data: data,
xField: xFieldObj.name,
yField: yFieldObj.name,
@ -195,6 +216,7 @@ export class Quadrant extends G2PlotChartView<ScatterOptions, G2Scatter> {
const options = this.setupOptions(chart, baseOptions)
const newChart = new G2Scatter(container, options)
newChart.on('point:click', action)
newChart.on('click', () => quadrantDefaultBaseline(defaultBaselineQuadrant))
return newChart
}
@ -205,7 +227,7 @@ export class Quadrant extends G2PlotChartView<ScatterOptions, G2Scatter> {
if (chart.extBubble?.length) {
return {
...options,
size: [5, 30],
size: [4, 30],
sizeField: extBubbleObj.name,
shape: basicStyle.scatterSymbol
}
@ -283,18 +305,15 @@ export class Quadrant extends G2PlotChartView<ScatterOptions, G2Scatter> {
const l = customAttr.label
if (l.show) {
label = {
position: l.position,
offsetY: 5,
offset: 0,
style: {
fill: l.color,
fontSize: l.fontSize
},
formatter: function (param: Datum, item) {
const text = String(param[chart.xAxis[0]?.['originName']])
const radius = item.size
const textWidth = text.length * 10
return textWidth > 2 * radius ? '' : param[chart.xAxis[0]?.['originName']]
}
content: datum => {
return datum[chart.xAxis[0]?.['originName']]
},
layout: [{ type: 'limit-in-shape' }]
}
} else {
label = false

View File

@ -25,6 +25,11 @@ export interface G2PlotDrawOptions<O> extends AntVDrawOptions<O> {
* 缩放比例
*/
scale?: number
/**
* 特殊处理象限图设置分割线的默认值
* @param args
*/
quadrantDefaultBaseline?: (...args: any) => void
}
/**

View File

@ -16,10 +16,11 @@ import { BASE_VIEW_CONFIG } from '../../editor/util/chart'
import { customAttrTrans, customStyleTrans, recursionTransObj } from '@/utils/canvasStyle'
import { deepCopy } from '@/utils/utils'
import { trackBarStyleCheck } from '@/utils/canvasUtils'
import { useEmitt } from '@/hooks/web/useEmitt'
const dvMainStore = dvMainStoreWithOut()
const { nowPanelTrackInfo, nowPanelJumpInfo, mobileInPc } = storeToRefs(dvMainStore)
const { emitter } = useEmitt()
const props = defineProps({
element: {
type: Object,
@ -149,7 +150,8 @@ const renderG2Plot = (chart, chartView: G2PlotChartView<any, any>) => {
container: containerId,
chart: chart,
scale: 1,
action
action,
quadrantDefaultBaseline
})
myChart?.render()
}
@ -296,7 +298,9 @@ const trackMenu = computed(() => {
}
return trackMenuInfo
})
const quadrantDefaultBaseline = defaultQuadrant => {
emitter.emit('quadrant-default-baseline', defaultQuadrant)
}
defineExpose({
calcData,
renderChart,