diff --git a/backend/src/main/java/io/dataease/controller/chart/ChartViewController.java b/backend/src/main/java/io/dataease/controller/chart/ChartViewController.java index 8dab4b89a3..34e6002cd1 100644 --- a/backend/src/main/java/io/dataease/controller/chart/ChartViewController.java +++ b/backend/src/main/java/io/dataease/controller/chart/ChartViewController.java @@ -173,4 +173,11 @@ public class ChartViewController { return chartViewService.getFieldData(id, requestList, false, fieldId); } + @ApiIgnore + @ApiOperation("更新视图属性") + @PostMapping("/viewPropsSave/{panelId}") + public void viewPropsSave(@PathVariable String panelId, @RequestBody ChartViewWithBLOBs chartViewWithBLOBs) { + chartViewService.viewPropsSave(chartViewWithBLOBs); + } + } diff --git a/backend/src/main/java/io/dataease/service/chart/ChartViewService.java b/backend/src/main/java/io/dataease/service/chart/ChartViewService.java index bcc3990bec..1eb5fc4d91 100644 --- a/backend/src/main/java/io/dataease/service/chart/ChartViewService.java +++ b/backend/src/main/java/io/dataease/service/chart/ChartViewService.java @@ -1423,4 +1423,14 @@ public class ChartViewService { return res; } + /** + * @param chartView + * @Description Save the properties and style information of the view + */ + public void viewPropsSave(ChartViewWithBLOBs chartView) { + long timestamp = System.currentTimeMillis(); + chartView.setUpdateTime(timestamp); + chartViewMapper.updateByPrimaryKeySelective(chartView); + } + } diff --git a/frontend/src/api/chart/chart.js b/frontend/src/api/chart/chart.js index 42ed1fdd90..14149acae7 100644 --- a/frontend/src/api/chart/chart.js +++ b/frontend/src/api/chart/chart.js @@ -125,3 +125,12 @@ export function checkTitle(data) { loading: false }) } + +export function viewPropsSave(panelId, data) { + return request({ + url: '/chart/view/viewPropsSave/' + panelId, + method: 'post', + loading: false, + data + }) +} diff --git a/frontend/src/components/DeDrag/index.vue b/frontend/src/components/DeDrag/index.vue index 92d86c0959..be2eccc549 100644 --- a/frontend/src/components/DeDrag/index.vue +++ b/frontend/src/components/DeDrag/index.vue @@ -11,6 +11,7 @@ [classNameRotatable]: rotatable, [classNameActive]: enabled , ['linkageSetting']:linkageActive, + ['batchSetting']:batchOptActive, ['positionChange']:!(dragging || resizing||rotating) }, className @@ -332,6 +333,11 @@ export default { linkageActive: { type: Boolean, default: false + }, + // batch operation + batchOptActive: { + type: Boolean, + default: false } }, data: function() { @@ -381,8 +387,8 @@ export default { computed: { // 编辑组件显示 editBarShow() { - // 编辑组件显示条件:1.当前组件存在 2.组件是激活状态或者当前在联动设置撞他 3.当前不在移动端画布编辑状态 - return this.curComponent && (this.active || this.linkageSettingStatus) && !this.mobileLayoutStatus + // 编辑组件显示条件:1.当前组件存在 2.组件是激活状态或者当前在联动设置状态 3.当前不在移动端画布编辑状态 4.或者批量操作状态 + return (this.curComponent && (this.active || this.linkageSettingStatus) && !this.mobileLayoutStatus) || this.batchOptStatus }, // 移动端编辑组件选择按钮显示 mobileCheckBarShow() { @@ -580,7 +586,8 @@ export default { 'linkageSettingStatus', 'mobileLayoutStatus', 'componentGap', - 'scrollAutoMove' + 'scrollAutoMove', + 'batchOptStatus' ]) }, watch: { @@ -1858,6 +1865,10 @@ export default { opacity: 0.5; } +.batchSetting{ + opacity: 0.7; +} + .positionChange{ transition: 0.2s } diff --git a/frontend/src/components/canvas/components/Editor/EditBar.vue b/frontend/src/components/canvas/components/Editor/EditBar.vue index 39b75e3237..c6ea63b57b 100644 --- a/frontend/src/components/canvas/components/Editor/EditBar.vue +++ b/frontend/src/components/canvas/components/Editor/EditBar.vue @@ -5,6 +5,9 @@ +
+ +
@@ -44,10 +47,9 @@ import bus from '@/utils/bus' import SettingMenu from '@/components/canvas/components/Editor/SettingMenu' import LinkageField from '@/components/canvas/components/Editor/LinkageField' import toast from '@/components/canvas/utils/toast' -import Hyperlinks from '@/components/canvas/components/Editor/Hyperlinks' export default { - components: { Hyperlinks, SettingMenu, LinkageField }, + components: { SettingMenu, LinkageField }, props: { element: { @@ -87,13 +89,17 @@ export default { showJumpFlag() { return this.curComponent && this.curComponent.hyperlinks && this.curComponent.hyperlinks.enable }, + // batch operation area + batchOptAreaShow() { + return this.batchOptStatus && this.element.type === 'view' + }, // 联动区域按钮显示 linkageAreaShow() { return this.linkageSettingStatus && this.element !== this.curLinkageView && this.element.type === 'view' }, // 编辑或预览区域显示 normalAreaShow() { - return !this.linkageSettingStatus + return !this.linkageSettingStatus && !this.batchOptStatus }, existLinkage() { let linkageFiltersCount = 0 @@ -131,7 +137,9 @@ export default { 'linkageSettingStatus', 'targetLinkageInfo', 'curLinkageView', - 'curCanvasScale' + 'curCanvasScale', + 'batchOptStatus', + 'curBatchOptComponents' ]) }, beforeDestroy() { @@ -264,6 +272,17 @@ export default { }, boardSet() { this.$emit('boardSet') + }, + batchOptChange(val) { + if (val) { + // push + this.$store.commit('addCurBatchComponent', this.element.propValue.viewId) + console.log('push') + } else { + // remove + this.$store.commit('removeCurBatchComponentWithId', this.element.propValue.viewId) + console.log('remove') + } } } } @@ -279,7 +298,7 @@ export default { padding-left: 5px; padding-right: 2px; cursor:pointer!important; - background-color: #0a7be0; + background-color: rgba(10,123,224, 1); } .bar-main i{ color: white; diff --git a/frontend/src/components/canvas/components/Editor/index.vue b/frontend/src/components/canvas/components/Editor/index.vue index 231ba8fd2e..a10207c549 100644 --- a/frontend/src/components/canvas/components/Editor/index.vue +++ b/frontend/src/components/canvas/components/Editor/index.vue @@ -41,9 +41,10 @@ :snap="true" :snap-tolerance="2" :change-style="customStyle" - :draggable="!linkageSettingStatus" - :resizable="!linkageSettingStatus" - :linkage-active="linkageSettingStatus&&item===curLinkageView" + :draggable="deDraggable" + :resizable="deResizable" + :linkage-active="linkageActiveCheck(item)" + :batch-opt-active="batchOptActiveCheck(item)" @refLineParams="getRefLineParams" @showViewDetails="showViewDetails(index)" @resizeView="resizeView(index,item)" @@ -955,6 +956,12 @@ export default { } }, computed: { + deDraggable() { + return !this.linkageSettingStatus && !this.batchOptStatus + }, + deResizable() { + return !this.linkageSettingStatus && !this.batchOptStatus + }, showExportImgButton() { // if the chart type belong to table,'export image' button should be hidden return this.showChartInfo.type && !this.showChartInfo.type.includes('table') @@ -1016,7 +1023,8 @@ export default { 'doSnapshotIndex', 'componentGap', 'mobileLayoutStatus', - 'curCanvasScale' + 'curCanvasScale', + 'batchOptStatus' ]), filterMap() { return buildFilterMap(this.componentData) @@ -1090,6 +1098,12 @@ export default { created() { }, methods: { + linkageActiveCheck(item) { + return this.linkageSettingStatus && item === this.curLinkageView + }, + batchOptActiveCheck(item) { + return this.batchOptStatus && item.type === 'view' + }, canvasInit() { this.editShow = false setTimeout(() => { diff --git a/frontend/src/components/canvas/components/Toolbar.vue b/frontend/src/components/canvas/components/Toolbar.vue index eb373fae53..444c81dd96 100644 --- a/frontend/src/components/canvas/components/Toolbar.vue +++ b/frontend/src/components/canvas/components/Toolbar.vue @@ -47,6 +47,9 @@ + + + {{ $t('commons.save') }} @@ -135,7 +138,8 @@ export default { 'targetLinkageInfo', 'mobileLayoutStatus', 'mobileComponentData', - 'componentDataCache' + 'componentDataCache', + 'batchOptStatus' ]) }, created() { @@ -382,6 +386,11 @@ export default { this.$store.state.styleChangeTimes++ this.canvasStyleData.aidedDesign.showGrid = !this.canvasStyleData.aidedDesign.showGrid }, + // batch option + batchOption() { + bus.$emit('change_panel_right_draw', !this.batchOptStatus) + this.$store.commit('setBatchOptStatus', !this.batchOptStatus) + }, // 启用移动端布局 openMobileLayout() { this.$store.commit('openMobileLayout') diff --git a/frontend/src/components/canvas/custom-component/UserView.vue b/frontend/src/components/canvas/custom-component/UserView.vue index 3dfc26d96a..b27f4ad796 100644 --- a/frontend/src/components/canvas/custom-component/UserView.vue +++ b/frontend/src/components/canvas/custom-component/UserView.vue @@ -115,6 +115,7 @@ import { customAttrTrans, customStyleTrans, recursionTransObj } from '@/componen import ChartComponentS2 from '@/views/chart/components/ChartComponentS2' import PluginCom from '@/views/system/plugin/PluginCom' import LabelNormalText from '@/views/chart/components/normal/LabelNormalText' +import { viewPropsSave } from '@/api/chart/chart' export default { name: 'UserView', components: { LabelNormalText, PluginCom, ChartComponentS2, EditBarView, ChartComponent, TableNormal, LabelNormal, DrillPath, ChartComponentG2 }, @@ -185,8 +186,14 @@ export default { changeScaleIndex: 0, pre: null, preCanvasPanel: null, + // string sourceCustomAttrStr: null, + // obj + sourceCustomAttr: null, + // string sourceCustomStyleStr: null, + // obj + sourceCustomStyle: null, scale: 1 } }, @@ -299,7 +306,8 @@ export default { 'mobileLayoutStatus', 'componentData', 'panelViewDetailsInfo', - 'componentViewsData' + 'componentViewsData', + 'curBatchOptComponents' ]) }, @@ -392,6 +400,30 @@ export default { } }, methods: { + batchOptChange(param) { + if (this.curBatchOptComponents.includes(this.element.propValue.viewId)) { + this.$store.state.styleChangeTimes++ + // stylePriority change to 'view' + const updateParams = { 'id': this.chart.id, 'stylePriority': 'view' } + if (param.custom === 'customAttr') { + const sourceCustomAttr = JSON.parse(this.sourceCustomAttrStr) + sourceCustomAttr[param.property] = param.value + this.sourceCustomAttrStr = JSON.stringify(sourceCustomAttr) + this.chart.customAttr = this.sourceCustomAttrStr + updateParams['customAttr'] = this.sourceCustomAttrStr + } else if (param.custom === 'customStyle') { + this.sourceCustomStyleStr = this.chart.customStyle + const sourceCustomStyle = JSON.parse(this.sourceCustomStyleStr) + sourceCustomStyle[param.property] = param.value + this.sourceCustomStyleStr = JSON.stringify(sourceCustomStyle) + this.chart.customStyle = this.sourceCustomStyleStr + updateParams['customStyle'] = this.sourceCustomStyleStr + } + viewPropsSave(this.panelInfo.id, updateParams) + this.$store.commit('recordViewEdit', { viewId: this.chart.id, hasEdit: true }) + this.mergeScale() + } + }, resizeChart() { if (this.chart.type === 'map') { this.destroyTimeMachine() @@ -416,6 +448,9 @@ export default { bus.$on('view-in-cache', param => { param.viewId && param.viewId === this.element.propValue.viewId && this.getDataEdit(param) }) + bus.$on('batch-opt-change', param => { + this.batchOptChange(param) + }) }, addViewTrackFilter(linkageParam) { @@ -488,7 +523,10 @@ export default { this.chart = response.data if (this.isEdit) { this.componentViewsData[this.chart.id] = { - 'title': this.chart.title + 'title': this.chart.title, + 'render': this.chart.render, + 'type': this.chart.type, + 'isPlugin': this.chart.isPlugin } } this.chart['position'] = this.inTab ? 'tab' : 'panel' @@ -797,7 +835,6 @@ export default { this.sourceCustomAttrStr = this.chart.customAttr this.sourceCustomStyleStr = this.chart.customStyle this.mergeScale() - this.mergeStyle() } } } diff --git a/frontend/src/lang/en.js b/frontend/src/lang/en.js index 59ef185a7e..76691da170 100644 --- a/frontend/src/lang/en.js +++ b/frontend/src/lang/en.js @@ -1430,6 +1430,7 @@ export default { sure_bt: 'Confirm' }, panel: { + batch_opt: 'Batch Operation', edit_leave_tips: 'Do You Want To Abandon And Leave The Current Page?', hyperlinks: 'Hyperlinks', is_live: 'Is Live', diff --git a/frontend/src/lang/tw.js b/frontend/src/lang/tw.js index 837c20f253..acba9f3ab6 100644 --- a/frontend/src/lang/tw.js +++ b/frontend/src/lang/tw.js @@ -1431,6 +1431,7 @@ export default { sure_bt: '確定' }, panel: { + batch_opt: '批量操作', edit_leave_tips: '是否放弃编辑离开当前界面?', hyperlinks: '超鏈接', is_live: '是否直播', diff --git a/frontend/src/lang/zh.js b/frontend/src/lang/zh.js index a6b3511b1f..3dae91a45a 100644 --- a/frontend/src/lang/zh.js +++ b/frontend/src/lang/zh.js @@ -1438,6 +1438,7 @@ export default { sure_bt: '确定' }, panel: { + batch_opt: '批量操作', edit_leave_tips: '是否放弃编辑离开当前界面?', hyperlinks: '超链接', is_live: '是否直播', diff --git a/frontend/src/store/index.js b/frontend/src/store/index.js index 66fb352c25..87409ebf58 100644 --- a/frontend/src/store/index.js +++ b/frontend/src/store/index.js @@ -29,6 +29,8 @@ import { } from '@/views/panel/panel' import bus from '@/utils/bus' import { BASE_MOBILE_STYLE } from '@/components/canvas/custom-component/component-list' +import { TYPE_CONFIGS } from '@/views/chart/chart/util' +import { deepCopy } from '@/components/canvas/utils/utils' Vue.use(Vuex) @@ -111,7 +113,19 @@ const data = { // 当前tab页内组件 curActiveTabInner: null, // static resource local path - staticResourcePath: '/static-resource/' + staticResourcePath: '/static-resource/', + // panel edit batch operation status + batchOptStatus: false, + // Currently selected components + curBatchOptComponents: [], + mixProperties: [], + batchOptChartInfo: null, + batchOptViews: {}, + // properties changed + changeProperties: { + customStyle: {}, + customAttr: {} + } }, mutations: { ...animation.mutations, @@ -512,6 +526,115 @@ const data = { }, resetViewEditInfo(state) { state.panelViewEditInfo = {} + }, + removeCurBatchComponentWithId(state, id) { + for (let index = 0; index < state.curBatchOptComponents.length; index++) { + const element = state.curBatchOptComponents[index] + if (element === id) { + delete state.batchOptViews[id] + state.curBatchOptComponents.splice(index, 1) + this.commit('setBatchOptChartInfo') + break + } + } + }, + addCurBatchComponent(state, id) { + if (id) { + state.curBatchOptComponents.push(id) + // get view base info + const viewBaseInfo = state.componentViewsData[id] + // get properties + const viewConfig = TYPE_CONFIGS.filter(item => item.render === viewBaseInfo.render && item.value === viewBaseInfo.type) + const viewProperties = viewConfig ? viewConfig[0].properties : [] + if (state.mixProperties.length > 0) { + // If it exists , taking the intersection + state.mixProperties = state.mixProperties.filter(property => viewProperties.indexOf(property) > -1) + } else { + // If it doesn't exist, assignment directly + state.mixProperties = deepCopy(viewProperties) + } + + if (viewConfig && viewConfig.length > 0) { + state.batchOptViews[id] = viewConfig[0] + this.commit('setBatchOptChartInfo') + } + } + }, + setBatchOptChartInfo(state) { + let render = null + let type = null + let isPlugin = null + state.mixProperties = [] + if (state.batchOptViews && JSON.stringify(state.batchOptViews) !== '{}') { + for (const key in state.batchOptViews) { + if (state.mixProperties.length > 0) { + // If it exists , taking the intersection + state.mixProperties = state.mixProperties.filter(property => state.batchOptViews[key].properties.indexOf(property) > -1) + } else { + // If it doesn't exist, assignment directly + state.mixProperties = deepCopy(state.batchOptViews[key].properties) + } + + if (render && render !== state.batchOptViews[key].render) { + render = 'mix' + } else { + render = state.batchOptViews[key].render + } + + if (type && type !== state.batchOptViews[key].value) { + type = 'mix' + } else { + type = state.batchOptViews[key].value + } + + if (isPlugin && isPlugin !== state.batchOptViews[key].isPlugin) { + isPlugin = 'mix' + } else { + isPlugin = state.batchOptViews[key].isPlugin + } + } + // Assembly history settings 'customAttr' & 'customStyle' + state.batchOptChartInfo = { + 'mode': 'batchOpt', + 'render': render, + 'type': type, + 'isPlugin': isPlugin, + 'customAttr': state.changeProperties.customAttr, + 'customStyle': state.changeProperties.customStyle + } + } else { + state.batchOptChartInfo = null + } + }, + setBatchOptStatus(state, status) { + state.batchOptStatus = status + // Currently selected components + state.curBatchOptComponents = [] + state.mixProperties = [] + state.batchOptChartInfo = null + state.batchOptViews = {} + state.changeProperties = { + customStyle: {}, + customAttr: {} + } + }, + setChangeProperties(state, propertyInfo) { + state.changeProperties[propertyInfo.custom][propertyInfo.property] = propertyInfo.value + }, + initCanvas(state) { + this.commit('setCurComponent', { component: null, index: null }) + this.commit('clearLinkageSettingInfo', false) + this.commit('resetViewEditInfo') + state.batchOptStatus = false + // Currently selected components + state.curBatchOptComponents = [] + state.mixProperties = [] + state.batchOptChartInfo = null + state.batchOptViews = {} + state.changeProperties = { + customStyle: {}, + customAttr: {} + } } }, modules: { diff --git a/frontend/src/views/chart/chart/util.js b/frontend/src/views/chart/chart/util.js index 8189e32b5a..86e3662b45 100644 --- a/frontend/src/views/chart/chart/util.js +++ b/frontend/src/views/chart/chart/util.js @@ -33,65 +33,121 @@ export const TYPE_CONFIGS = [ category: 'chart.chart_type_table', value: 'table-normal', title: 'chart.chart_table_normal', - icon: 'table-normal' + icon: 'table-normal', + properties: [ + 'color-selector', + 'size-selector-ant-v', + 'title-selector-ant-v' + ] }, { render: 'antv', category: 'chart.chart_type_table', value: 'table-info', title: 'chart.chart_table_info', - icon: 'table-info' + icon: 'table-info', + properties: [ + 'color-selector', + 'size-selector-ant-v', + 'title-selector-ant-v' + ] }, { render: 'antv', category: 'chart.chart_type_table', value: 'table-pivot', title: 'chart.chart_table_pivot', - icon: 'table-pivot' + icon: 'table-pivot', + properties: [ + 'color-selector', + 'size-selector-ant-v', + 'total-cfg', + 'title-selector-ant-v' + ] }, - { render: 'antv', category: 'chart.chart_type_quota', value: 'label', title: 'chart.chart_label', - icon: 'label' + icon: 'label', + properties: [ + 'color-selector', + 'size-selector-ant-v', + 'title-selector-ant-v' + ] }, { render: 'antv', category: 'chart.chart_type_quota', value: 'text', title: 'chart.chart_card', - icon: 'text' + icon: 'text', + properties: [ + 'color-selector', + 'size-selector-ant-v', + 'title-selector-ant-v' + ] }, { render: 'antv', category: 'chart.chart_type_quota', value: 'gauge', title: 'chart.chart_gauge', - icon: 'gauge' + icon: 'gauge', + properties: [ + 'color-selector', + 'size-selector-ant-v', + 'label-selector-ant-v', + 'title-selector-ant-v' + ] }, { render: 'antv', category: 'chart.chart_type_quota', value: 'liquid', title: 'chart.chart_liquid', - icon: 'liquid' + icon: 'liquid', + properties: [ + 'color-selector', + 'size-selector-ant-v', + 'label-selector-ant-v', + 'title-selector-ant-v' + ] }, - { render: 'antv', category: 'chart.chart_type_trend', value: 'line', title: 'chart.chart_line', - icon: 'line' + icon: 'line', + properties: [ + 'color-selector', + 'size-selector-ant-v', + 'label-selector-ant-v', + 'tooltip-selector-ant-v', + 'x-axis-selector-ant-v', + 'y-axis-selector-ant-v', + 'title-selector-ant-v', + 'legend-selector-ant-v' + ] }, { render: 'antv', category: 'chart.chart_type_trend', value: 'line-stack', title: 'chart.chart_line_stack', - icon: 'line-stack' + icon: 'line-stack', + properties: [ + 'color-selector', + 'size-selector-ant-v', + 'label-selector-ant-v', + 'tooltip-selector-ant-v', + 'x-axis-selector-ant-v', + 'y-axis-selector-ant-v', + 'title-selector-ant-v', + 'legend-selector-ant-v' + ] }, { @@ -99,35 +155,82 @@ export const TYPE_CONFIGS = [ category: 'chart.chart_type_compare', value: 'bar', title: 'chart.chart_bar', - icon: 'bar' + icon: 'bar', + properties: [ + 'color-selector', + 'size-selector-ant-v', + 'label-selector-ant-v', + 'tooltip-selector-ant-v', + 'x-axis-selector-ant-v', + 'y-axis-selector-ant-v', + 'title-selector-ant-v', + 'legend-selector-ant-v' + ] }, { render: 'antv', category: 'chart.chart_type_compare', value: 'bar-stack', title: 'chart.chart_bar_stack', - icon: 'bar-stack' + icon: 'bar-stack', + properties: [ + 'color-selector', + 'label-selector-ant-v', + 'tooltip-selector-ant-v', + 'x-axis-selector-ant-v', + 'y-axis-selector-ant-v', + 'title-selector-ant-v', + 'legend-selector-ant-v' + ] }, { render: 'antv', category: 'chart.chart_type_compare', value: 'waterfall', title: 'chart.chart_waterfall', - icon: 'waterfall' + icon: 'waterfall', + properties: [ + 'color-selector', + 'label-selector-ant-v', + 'tooltip-selector-ant-v', + 'x-axis-selector-ant-v', + 'y-axis-selector-ant-v', + 'title-selector-ant-v' + ] }, { render: 'antv', category: 'chart.chart_type_compare', value: 'bar-horizontal', title: 'chart.chart_bar_horizontal', - icon: 'bar-horizontal' + icon: 'bar-horizontal', + properties: [ + 'color-selector', + 'size-selector-ant-v', + 'label-selector-ant-v', + 'tooltip-selector-ant-v', + 'x-axis-selector-ant-v', + 'y-axis-selector-ant-v', + 'title-selector-ant-v', + 'legend-selector-ant-v' + ] }, { render: 'antv', category: 'chart.chart_type_compare', value: 'bar-stack-horizontal', title: 'chart.chart_bar_stack_horizontal', - icon: 'bar-stack-horizontal' + icon: 'bar-stack-horizontal', + properties: [ + 'color-selector', + 'size-selector-ant-v', + 'label-selector-ant-v', + 'tooltip-selector-ant-v', + 'x-axis-selector-ant-v', + 'y-axis-selector-ant-v', + 'title-selector-ant-v', + 'legend-selector-ant-v' + ] }, { @@ -135,35 +238,72 @@ export const TYPE_CONFIGS = [ category: 'chart.chart_type_distribute', value: 'pie', title: 'chart.chart_pie', - icon: 'pie' + icon: 'pie', + properties: [ + 'color-selector', + 'size-selector-ant-v', + 'label-selector-ant-v', + 'tooltip-selector-ant-v', + 'title-selector-ant-v', + 'legend-selector-ant-v' + ] }, { render: 'antv', category: 'chart.chart_type_distribute', value: 'pie-rose', title: 'chart.chart_pie_rose', - icon: 'pie-rose' + icon: 'pie-rose', + properties: [ + 'color-selector', + 'size-selector-ant-v', + 'label-selector-ant-v', + 'tooltip-selector-ant-v', + 'title-selector-ant-v', + 'legend-selector-ant-v' + ] }, { render: 'antv', category: 'chart.chart_type_distribute', value: 'radar', title: 'chart.chart_radar', - icon: 'radar' + icon: 'radar', + properties: [ + 'color-selector', + 'size-selector-ant-v', + 'label-selector-ant-v', + 'tooltip-selector-ant-v', + 'split-selector-ant-v', + 'title-selector-ant-v', + 'legend-selector-ant-v' + ] }, { render: 'antv', category: 'chart.chart_type_distribute', value: 'treemap', title: 'chart.chart_treemap', - icon: 'treemap' + icon: 'treemap', + properties: [ + 'color-selector', + 'label-selector-ant-v', + 'tooltip-selector-ant-v', + 'title-selector-ant-v', + 'legend-selector-ant-v' + ] }, { render: 'antv', category: 'chart.chart_type_distribute', value: 'word-cloud', title: 'chart.chart_word_cloud', - icon: 'word-cloud' + icon: 'word-cloud', + properties: [ + 'color-selector', + 'tooltip-selector-ant-v', + 'title-selector-ant-v' + ] }, { @@ -171,14 +311,31 @@ export const TYPE_CONFIGS = [ category: 'chart.chart_type_relation', value: 'scatter', title: 'chart.chart_scatter', - icon: 'scatter' + icon: 'scatter', + properties: [ + 'color-selector', + 'size-selector-ant-v', + 'label-selector-ant-v', + 'tooltip-selector-ant-v', + 'x-axis-selector-ant-v', + 'y-axis-selector-ant-v', + 'title-selector-ant-v', + 'legend-selector-ant-v' + ] }, { render: 'antv', category: 'chart.chart_type_relation', value: 'funnel', title: 'chart.chart_funnel', - icon: 'funnel' + icon: 'funnel', + properties: [ + 'color-selector', + 'label-selector-ant-v', + 'tooltip-selector-ant-v', + 'title-selector-ant-v', + 'legend-selector-ant-v' + ] }, /* 下面是echarts图表类型 */ { @@ -186,14 +343,24 @@ export const TYPE_CONFIGS = [ category: 'chart.chart_type_table', value: 'table-normal', title: 'chart.chart_table_normal', - icon: 'table-normal' + icon: 'table-normal', + properties: [ + 'color-selector', + 'size-selector', + 'title-selector' + ] }, { render: 'echarts', category: 'chart.chart_type_table', value: 'table-info', title: 'chart.chart_table_info', - icon: 'table-info' + icon: 'table-info', + properties: [ + 'color-selector', + 'size-selector', + 'title-selector' + ] }, { @@ -201,21 +368,37 @@ export const TYPE_CONFIGS = [ category: 'chart.chart_type_quota', value: 'label', title: 'chart.chart_label', - icon: 'label' + icon: 'label', + properties: [ + 'color-selector', + 'size-selector', + 'title-selector' + ] }, { render: 'echarts', category: 'chart.chart_type_quota', value: 'text', title: 'chart.chart_card', - icon: 'text' + icon: 'text', + properties: [ + 'color-selector', + 'size-selector', + 'title-selector' + ] }, { render: 'echarts', category: 'chart.chart_type_quota', value: 'gauge', title: 'chart.chart_gauge', - icon: 'gauge' + icon: 'gauge', + properties: [ + 'color-selector', + 'size-selector', + 'label-selector', + 'title-selector', + ] }, { @@ -223,21 +406,52 @@ export const TYPE_CONFIGS = [ category: 'chart.chart_type_trend', value: 'line', title: 'chart.chart_line', - icon: 'line' + icon: 'line', + properties: [ + 'color-selector', + 'size-selector', + 'label-selector', + 'tooltip-selector', + 'x-axis-selector', + 'y-axis-selector', + 'title-selector', + 'legend-selector' + ] }, { render: 'echarts', category: 'chart.chart_type_trend', value: 'line-stack', title: 'chart.chart_line_stack', - icon: 'line-stack' + icon: 'line-stack', + properties: [ + 'color-selector', + 'size-selector', + 'label-selector', + 'tooltip-selector', + 'x-axis-selector', + 'y-axis-selector', + 'title-selector', + 'legend-selector' + ] }, { render: 'echarts', category: 'chart.chart_type_trend', value: 'chart-mix', title: 'chart.chart_mix', - icon: 'chart-mix' + icon: 'chart-mix', + properties: [ + 'color-selector', + 'size-selector', + 'label-selector', + 'tooltip-selector', + 'x-axis-selector', + 'y-axis-selector', + 'y-axis-ext-selector', + 'title-selector', + 'legend-selector' + ] }, { @@ -245,28 +459,68 @@ export const TYPE_CONFIGS = [ category: 'chart.chart_type_compare', value: 'bar', title: 'chart.chart_bar', - icon: 'bar' + icon: 'bar', + properties: [ + 'color-selector', + 'size-selector', + 'label-selector', + 'tooltip-selector', + 'x-axis-selector', + 'y-axis-selector', + 'title-selector', + 'legend-selector' + ] }, { render: 'echarts', category: 'chart.chart_type_compare', value: 'bar-stack', title: 'chart.chart_bar_stack', - icon: 'bar-stack' + icon: 'bar-stack', + properties: [ + 'color-selector', + 'size-selector', + 'label-selector', + 'tooltip-selector', + 'x-axis-selector', + 'y-axis-selector', + 'title-selector', + 'legend-selector' + ] }, { render: 'echarts', category: 'chart.chart_type_compare', value: 'bar-horizontal', title: 'chart.chart_bar_horizontal', - icon: 'bar-horizontal' + icon: 'bar-horizontal', + properties: [ + 'color-selector', + 'size-selector', + 'label-selector', + 'tooltip-selector', + 'x-axis-selector', + 'y-axis-selector', + 'title-selector', + 'legend-selector' + ] }, { render: 'echarts', category: 'chart.chart_type_compare', value: 'bar-stack-horizontal', title: 'chart.chart_bar_stack_horizontal', - icon: 'bar-stack-horizontal' + icon: 'bar-stack-horizontal', + properties: [ + 'color-selector', + 'size-selector', + 'label-selector', + 'tooltip-selector', + 'x-axis-selector', + 'y-axis-selector', + 'title-selector', + 'legend-selector' + ] }, { @@ -274,28 +528,60 @@ export const TYPE_CONFIGS = [ category: 'chart.chart_type_distribute', value: 'pie', title: 'chart.chart_pie', - icon: 'pie' + icon: 'pie', + properties: [ + 'color-selector', + 'size-selector', + 'label-selector', + 'tooltip-selector', + 'title-selector', + 'legend-selector' + ] }, { render: 'echarts', category: 'chart.chart_type_distribute', value: 'pie-rose', title: 'chart.chart_pie_rose', - icon: 'pie-rose' + icon: 'pie-rose', + properties: [ + 'color-selector', + 'size-selector', + 'label-selector', + 'tooltip-selector', + 'title-selector', + 'legend-selector' + ] }, { render: 'echarts', category: 'chart.chart_type_distribute', value: 'radar', title: 'chart.chart_radar', - icon: 'radar' + icon: 'radar', + properties: [ + 'color-selector', + 'size-selector', + 'label-selector', + 'tooltip-selector', + 'split-selector', + 'title-selector', + 'legend-selector' + ] }, { render: 'echarts', category: 'chart.chart_type_distribute', value: 'treemap', title: 'chart.chart_treemap', - icon: 'treemap' + icon: 'treemap', + properties: [ + 'color-selector', + 'size-selector', + 'label-selector', + 'tooltip-selector', + 'title-selector' + ] }, { @@ -303,14 +589,32 @@ export const TYPE_CONFIGS = [ category: 'chart.chart_type_relation', value: 'scatter', title: 'chart.chart_scatter', - icon: 'scatter' + icon: 'scatter', + properties: [ + 'color-selector', + 'size-selector', + 'label-selector', + 'tooltip-selector', + 'x-axis-selector', + 'y-axis-selector', + 'title-selector', + 'legend-selector' + ] }, { render: 'echarts', category: 'chart.chart_type_relation', value: 'funnel', title: 'chart.chart_funnel', - icon: 'funnel' + icon: 'funnel', + properties: [ + 'color-selector', + 'size-selector', + 'label-selector', + 'tooltip-selector', + 'title-selector', + 'legend-selector' + ] }, { @@ -318,7 +622,14 @@ export const TYPE_CONFIGS = [ category: 'chart.chart_type_space', value: 'map', title: 'chart.chart_map', - icon: 'map' + icon: 'map', + properties: [ + 'color-selector', + 'size-selector', + 'label-selector', + 'tooltip-selector', + 'title-selector' + ] } ] diff --git a/frontend/src/views/chart/components/shape-attr/SizeSelectorCommon.vue b/frontend/src/views/chart/components/shape-attr/SizeSelectorCommon.vue new file mode 100644 index 0000000000..460b97c369 --- /dev/null +++ b/frontend/src/views/chart/components/shape-attr/SizeSelectorCommon.vue @@ -0,0 +1,39 @@ + + + + + diff --git a/frontend/src/views/chart/view/ChartEdit.vue b/frontend/src/views/chart/view/ChartEdit.vue index 6d329f9725..9c0142839e 100644 --- a/frontend/src/views/chart/view/ChartEdit.vue +++ b/frontend/src/views/chart/view/ChartEdit.vue @@ -652,9 +652,11 @@ item.render === _this.chart.render && item.value === _this.chart.type) + if (viewConfig) { + return viewConfig[0].properties + } else { + return null + } + } else { + return null + } + }, chartType() { return this.chart.type }, diff --git a/frontend/src/views/chart/view/ChartStyle.vue b/frontend/src/views/chart/view/ChartStyle.vue index efd155ec04..81ff79bcb3 100644 --- a/frontend/src/views/chart/view/ChartStyle.vue +++ b/frontend/src/views/chart/view/ChartStyle.vue @@ -12,7 +12,7 @@ style="overflow:auto;border-right: 1px solid #e6e6e6;height: 100%;width: 100%;padding-right: 6px" class="attr-style theme-border-class" > - + {{ $t('chart.style_priority') }} @@ -46,11 +46,11 @@ :param="param" class="attr-selector" :chart="chart" - @onSizeChange="onSizeChange" + @onSizeChange="onSizeChange($event,'size-selector')" /> @@ -58,51 +58,51 @@ :param="param" class="attr-selector" :chart="chart" - @onSizeChange="onSizeChange" + @onSizeChange="onSizeChange($event,'size-selector-ant-v')" /> @@ -110,7 +110,7 @@ :param="param" class="attr-selector" :chart="chart" - @onTotalCfgChange="onTotalCfgChange" + @onTotalCfgChange="onTotalCfgChange($event,'total-cfg')" /> @@ -119,119 +119,119 @@ {{ $t('chart.module_style') }} - @@ -267,22 +267,24 @@ import YAxisSelector from '@/views/chart/components/component-style/YAxisSelecto import YAxisSelectorAntV from '@/views/chart/components/component-style/YAxisSelectorAntV' import YAxisExtSelector from '@/views/chart/components/component-style/YAxisExtSelector' import YAxisExtSelectorAntV from '@/views/chart/components/component-style/YAxisExtSelectorAntV' -import SplitSelector from '@/views/chart/components/component-style/SplitSelector' import TitleSelector from '@/views/chart/components/component-style/TitleSelector' import TitleSelectorAntV from '@/views/chart/components/component-style/TitleSelectorAntV' import LegendSelector from '@/views/chart/components/component-style/LegendSelector' import LegendSelectorAntV from '@/views/chart/components/component-style/LegendSelectorAntV' import BackgroundColorSelector from '@/views/chart/components/component-style/BackgroundColorSelector' +import SplitSelector from '@/views/chart/components/component-style/SplitSelector' +import SplitSelectorAntV from '@/views/chart/components/component-style/SplitSelectorAntV' export default { name: 'ChartStyle', components: { + SplitSelectorAntV, + SplitSelector, BackgroundColorSelector, LegendSelectorAntV, LegendSelector, TitleSelectorAntV, TitleSelector, - SplitSelector, YAxisExtSelectorAntV, YAxisExtSelector, YAxisSelectorAntV, @@ -306,6 +308,10 @@ export default { view: { type: Object, required: true + }, + properties: { + type: Array, + required: true } }, data() { @@ -313,48 +319,78 @@ export default { attrActiveNames: [], styleActiveNames: [] } + }, + computed: { + }, created() { }, methods: { + showProperties(property) { + return this.properties.includes(property) + }, + showPropertiesCollapse(propertiesInfo) { + let includeCount = 0 + // Property does not support mixed mode + if (propertiesInfo.includes('no-mix') && this.chart.type === 'mix') { + return false + } else { + propertiesInfo.forEach(property => { + this.properties.includes(property) && includeCount++ + }) + return includeCount > 0 + } + }, calcStyle() { this.$emit('calcStyle') }, - onColorChange(val) { + onColorChange(val, propertyName) { + val['propertyName'] = propertyName this.$emit('onColorChange', val) }, - onSizeChange(val) { + onSizeChange(val, propertyName) { + val['propertyName'] = propertyName this.$emit('onSizeChange', val) }, - onLabelChange(val) { + onLabelChange(val, propertyName) { + val['propertyName'] = propertyName this.$emit('onLabelChange', val) }, - onTooltipChange(val) { + onTooltipChange(val, propertyName) { + val['propertyName'] = propertyName this.$emit('onTooltipChange', val) }, - onTotalCfgChange(val) { + onTotalCfgChange(val, propertyName) { + val['propertyName'] = propertyName this.$emit('onTotalCfgChange', val) }, - onChangeXAxisForm(val) { + onChangeXAxisForm(val, propertyName) { + val['propertyName'] = propertyName this.$emit('onChangeXAxisForm', val) }, - onChangeYAxisForm(val) { + onChangeYAxisForm(val, propertyName) { + val['propertyName'] = propertyName this.$emit('onChangeYAxisForm', val) }, - onChangeYAxisExtForm(val) { + onChangeYAxisExtForm(val, propertyName) { + val['propertyName'] = propertyName this.$emit('onChangeYAxisExtForm', val) }, - onChangeSplitForm(val) { + onChangeSplitForm(val, propertyName) { + val['propertyName'] = propertyName this.$emit('onChangeSplitForm', val) }, - onTextChange(val) { + onTextChange(val, propertyName) { + val['propertyName'] = propertyName this.$emit('onTextChange', val) }, - onLegendChange(val) { + onLegendChange(val, propertyName) { + val['propertyName'] = propertyName this.$emit('onLegendChange', val) }, - onChangeBackgroundForm(val) { + onChangeBackgroundForm(val, propertyName) { + val['propertyName'] = propertyName this.$emit('onChangeBackgroundForm', val) } } diff --git a/frontend/src/views/chart/view/ChartStyleBack.vue b/frontend/src/views/chart/view/ChartStyleBack.vue new file mode 100644 index 0000000000..299f67f350 --- /dev/null +++ b/frontend/src/views/chart/view/ChartStyleBack.vue @@ -0,0 +1,609 @@ + + + + diff --git a/frontend/src/views/chart/view/ChartStyleBatchSet.vue b/frontend/src/views/chart/view/ChartStyleBatchSet.vue new file mode 100644 index 0000000000..3c64c45b0e --- /dev/null +++ b/frontend/src/views/chart/view/ChartStyleBatchSet.vue @@ -0,0 +1,143 @@ + + + + + diff --git a/frontend/src/views/panel/edit/index.vue b/frontend/src/views/panel/edit/index.vue index 380c0b7b9f..d489ed6cd0 100644 --- a/frontend/src/views/panel/edit/index.vue +++ b/frontend/src/views/panel/edit/index.vue @@ -226,11 +226,14 @@ -
-
- +
+
+
-
+
+ +
+
@@ -368,10 +371,12 @@ import ComponentWait from '@/views/panel/edit/ComponentWait' import { deleteEnshrine, saveEnshrine, starStatus } from '@/api/panel/enshrine' import ChartEdit from '@/views/chart/view/ChartEdit' import OuterParamsSet from '@/views/panel/OuterParamsSet/index' +import ChartStyleBatchSet from '@/views/chart/view/ChartStyleBatchSet' export default { name: 'PanelEdit', components: { + ChartStyleBatchSet, OuterParamsSet, ComponentWait, DeMainContainer, @@ -473,7 +478,10 @@ export default { }, // 显示视图工具栏 showViewToolsAside() { - return this.curComponent && (this.curComponent.type === 'view' || this.curComponent.type === 'de-tabs') + return !this.batchOptStatus && this.curComponent && (this.curComponent.type === 'view' || this.curComponent.type === 'de-tabs') + }, + showBatchViewToolsAside() { + return this.batchOptStatus }, showViewToolAsideType() { if (this.curComponent) { @@ -571,7 +579,8 @@ export default { 'pcMatrixCount', 'mobileMatrixCount', 'mobileLayoutStyle', - 'scrollAutoMove' + 'scrollAutoMove', + 'batchOptStatus' ]) }, @@ -598,13 +607,6 @@ export default { }, created() { this.init(this.$store.state.panel.panelInfo.id) - // this.restore() - // 全局监听按键事件 - // listenGlobalKeyDown() - - this.$store.commit('setCurComponent', { component: null, index: null }) - this.$store.commit('clearLinkageSettingInfo', false) - this.$store.commit('resetViewEditInfo') }, mounted() { // this.insertToBody() @@ -657,6 +659,7 @@ export default { init(panelId) { const _this = this _this.initHasStar() + this.$store.commit('initCanvas') if (panelId) { initPanelData(panelId, function() { // 初始化视图缓存