diff --git a/frontend/src/components/canvas/custom-component/UserView.vue b/frontend/src/components/canvas/custom-component/UserView.vue index 9047970434..d8440509d3 100644 --- a/frontend/src/components/canvas/custom-component/UserView.vue +++ b/frontend/src/components/canvas/custom-component/UserView.vue @@ -119,7 +119,7 @@ import DrillPath from '@/views/chart/view/DrillPath' import { areaMapping } from '@/api/map/map' import ChartComponentG2 from '@/views/chart/components/ChartComponentG2' import EditBarView from '@/components/canvas/components/Editor/EditBarView' -import { customAttrTrans, customStyleTrans, recursionTransObj } from '@/components/canvas/utils/style' +import { adaptCurTheme, customAttrTrans, customStyleTrans, recursionTransObj } from '@/components/canvas/utils/style' import ChartComponentS2 from '@/views/chart/components/ChartComponentS2' import PluginCom from '@/views/system/plugin/PluginCom' import LabelNormalText from '@/views/chart/components/normal/LabelNormalText' @@ -354,7 +354,7 @@ export default { // deep监听panel 如果改变 提交到 store canvasStyleData: { handler(newVal, oldVla) { - this.mergeStyle() + // this.mergeStyle() // 如果视图结果模式模式 或者 视图结果获取数量改变 刷新视图 if (!this.preCanvasPanel || this.preCanvasPanel.resultCount !== newVal.panel.resultCount || this.preCanvasPanel.resultMode !== newVal.panel.resultMode) { this.getData(this.element.propValue.viewId, false) @@ -421,31 +421,45 @@ export default { }, 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.modifyName] = param.value[param.value.modifyName] - this.sourceCustomAttrStr = JSON.stringify(sourceCustomAttr) - this.chart.customAttr = this.sourceCustomAttrStr - updateParams['customAttr'] = this.sourceCustomAttrStr - } else if (param.custom === 'customStyle') { - const sourceCustomStyle = JSON.parse(this.sourceCustomStyleStr) - // view's title use history - // if (param.property === 'text') { - // param.value.title = sourceCustomStyle.text.title - // } - sourceCustomStyle[param.property][param.value.modifyName] = param.value[param.value.modifyName] - 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() + this.optFromBatchSingleProp(param) } }, + optFromBatchSingleProp(param) { + this.$store.state.styleChangeTimes++ + const updateParams = { } + if (param.custom === 'customAttr') { + const sourceCustomAttr = JSON.parse(this.sourceCustomAttrStr) + sourceCustomAttr[param.property][param.value.modifyName] = param.value[param.value.modifyName] + this.sourceCustomAttrStr = JSON.stringify(sourceCustomAttr) + this.chart.customAttr = this.sourceCustomAttrStr + updateParams['customAttr'] = this.sourceCustomAttrStr + } else if (param.custom === 'customStyle') { + const sourceCustomStyle = JSON.parse(this.sourceCustomStyleStr) + sourceCustomStyle[param.property][param.value.modifyName] = param.value[param.value.modifyName] + 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() + }, + optFromBatchThemeChange() { + const updateParams = { } + const sourceCustomAttr = JSON.parse(this.sourceCustomAttrStr) + const sourceCustomStyle = JSON.parse(this.sourceCustomStyleStr) + adaptCurTheme(sourceCustomStyle, sourceCustomAttr) + this.sourceCustomAttrStr = JSON.stringify(sourceCustomAttr) + this.chart.customAttr = this.sourceCustomAttrStr + updateParams['customAttr'] = this.sourceCustomAttrStr + + 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() @@ -473,6 +487,15 @@ export default { bus.$on('batch-opt-change', param => { this.batchOptChange(param) }) + bus.$on('onSubjectChange', () => { + this.optFromBatchThemeChange() + }) + bus.$on('onThemeColorChange', () => { + this.optFromBatchThemeChange() + }) + bus.$on('onThemeAttrChange', (param) => { + this.optFromBatchSingleProp(param) + }) }, addViewTrackFilter(linkageParam) { @@ -485,7 +508,6 @@ export default { const customStyleChart = JSON.parse(this.sourceCustomStyleStr) recursionTransObj(customAttrTrans, customAttrChart, this.scale, this.scaleCoefficientType) recursionTransObj(customStyleTrans, customStyleChart, this.scale, this.scaleCoefficientType) - // 移动端地图标签不显示 if (this.chart.type === 'map' && this.scaleCoefficientType === 'mobile') { customAttrChart.label.show = false @@ -495,32 +517,6 @@ export default { customAttr: JSON.stringify(customAttrChart), customStyle: JSON.stringify(customStyleChart) } - this.mergeStyle() - }, - mergeStyle() { - if ((this.requestStatus === 'success' || this.requestStatus === 'merging') && this.chart.stylePriority === 'panel' && this.canvasStyleData.chart) { - const customAttrChart = JSON.parse(this.chart.customAttr) - const customStyleChart = JSON.parse(this.chart.customStyle) - const customAttrPanel = JSON.parse(this.canvasStyleData.chart.customAttr) - const customStylePanel = JSON.parse(this.canvasStyleData.chart.customStyle) - if (customStyleChart.background) { - // 组件样式-背景设置 - customStyleChart.background = customStylePanel.background - } - // 图形属性-颜色设置 - if (this.chart.type.includes('table')) { - customAttrChart.color = customAttrPanel.tableColor - } else { - customAttrChart.color['value'] = customAttrPanel.color['value'] - customAttrChart.color['colors'] = customAttrPanel.color['colors'] - customAttrChart.color['alpha'] = customAttrPanel.color['alpha'] - } - this.chart = { - ...this.chart, - customAttr: JSON.stringify(customAttrChart), - customStyle: JSON.stringify(customStyleChart) - } - } }, getData(id, cache = true, dataBroadcast = false) { if (id) { diff --git a/frontend/src/components/canvas/custom-component/component-list.js b/frontend/src/components/canvas/custom-component/component-list.js index 31c5e98e34..b38fa05afc 100644 --- a/frontend/src/components/canvas/custom-component/component-list.js +++ b/frontend/src/components/canvas/custom-component/component-list.js @@ -17,18 +17,23 @@ export const BASE_MOBILE_STYLE = { } // 组件仪表板样式 -export const COMMON_BACKGROUND = { - enable: false, +export const COMMON_BACKGROUND_BASE = { backgroundColorSelect: true, - backgroundType: 'innerImage', color: '#FFFFFF', - innerImage: 'board/blue_1.svg', - outerImage: null, alpha: 100, borderRadius: 5, innerPadding: 0 } +// 组件仪表板样式 +export const COMMON_BACKGROUND = { + ...COMMON_BACKGROUND_BASE, + enable: false, + backgroundType: 'innerImage', + innerImage: 'board/blue_1.svg', + outerImage: null +} + // 空组件仪表板样式 export const COMMON_BACKGROUND_NONE = { enable: false, diff --git a/frontend/src/components/canvas/store/snapshot.js b/frontend/src/components/canvas/store/snapshot.js index 25dc34c8cd..6a464f14a4 100644 --- a/frontend/src/components/canvas/store/snapshot.js +++ b/frontend/src/components/canvas/store/snapshot.js @@ -34,6 +34,7 @@ export default { recordSnapshot(state) { state.changeTimes++ + state.styleChangeTimes++ // 添加新的快照 state.snapshotData[++state.snapshotIndex] = deepCopy(state.componentData) state.snapshotStyleData[state.snapshotIndex] = deepCopy(state.canvasStyleData) diff --git a/frontend/src/components/canvas/utils/style.js b/frontend/src/components/canvas/utils/style.js index 9fc58db439..c4ea8ab0f2 100644 --- a/frontend/src/components/canvas/utils/style.js +++ b/frontend/src/components/canvas/utils/style.js @@ -1,4 +1,15 @@ import { sin, cos } from '@/components/canvas/utils/translate' +import store from '@/store' + +export const LIGHT_THEME_COLOR_MAIN = '#000000' +export const LIGHT_THEME_COLOR_SLAVE1 = '#CCCCCC' +export const LIGHT_THEME_PANEL_BACKGROUND = '#F1F3F5' +export const LIGHT_THEME_COMPONENT_BACKGROUND = '#FFFFFF' + +export const DARK_THEME_COLOR_MAIN = '#FFFFFF' +export const DARK_THEME_COLOR_SLAVE1 = '#CCCCCC' +export const DARK_THEME_PANEL_BACKGROUND = '#030B2E' +export const DARK_THEME_COMPONENT_BACKGROUND = '#131E42' export function getStyle(style, filter = []) { const needUnit = [ @@ -148,6 +159,104 @@ export const customStyleTrans = { } } +export const THEME_STYLE_TRANS_MAIN_BACK = { + 'legend': { + 'textStyle': ['color'] + }, + 'xAxis': { + 'nameTextStyle': ['color'], + 'axisLabel': ['color'], + 'splitLine': { + 'lineStyle': ['color'] + } + }, + 'yAxis': { + 'nameTextStyle': ['color'], + 'axisLabel': ['color'], + 'splitLine': { + 'lineStyle': ['color'] + } + }, + 'yAxisExt': { + 'nameTextStyle': ['color'], + 'axisLabel': ['color'], + 'splitLine': { + 'lineStyle': ['color'] + } + }, + 'split': { + 'name': ['color'], + 'axisLine': { + 'lineStyle': ['color'] + }, + 'axisTick': { + 'lineStyle': ['color'] + }, + 'axisLabel': ['color'], + 'splitLine': { + 'lineStyle': ['color'] + } + } +} + +export const THEME_STYLE_TRANS_MAIN = { + 'legend': { + 'textStyle': ['color'] + }, + 'xAxis': { + 'nameTextStyle': ['color'], + 'axisLabel': ['color'] + }, + 'yAxis': { + 'nameTextStyle': ['color'], + 'axisLabel': ['color'] + }, + 'yAxisExt': { + 'nameTextStyle': ['color'], + 'axisLabel': ['color'] + }, + 'split': { + 'name': ['color'], + 'axisLine': { + 'lineStyle': ['color'] + }, + 'axisTick': { + 'lineStyle': ['color'] + }, + 'axisLabel': ['color'] + } +} + +export const THEME_STYLE_TRANS_SLAVE1 = { + 'xAxis': { + 'splitLine': { + 'lineStyle': ['color'] + } + }, + 'yAxis': { + 'splitLine': { + 'lineStyle': ['color'] + } + }, + 'yAxisExt': { + 'splitLine': { + 'lineStyle': ['color'] + } + }, + 'split': { + 'splitLine': { + 'lineStyle': ['color'] + } + } +} + +export const THEME_ATTR_TRANS_MAIN = { + 'label': ['color'], + 'tooltip': { + 'textStyle': ['color'] + } +} + // 移动端特殊属性 export const mobileSpecialProps = { 'lineWidth': 3, // 线宽固定值 @@ -182,6 +291,24 @@ export function recursionTransObj(template, infoObj, scale, terminal) { } } +export function recursionThemTransObj(template, infoObj, color) { + for (const templateKey in template) { + // 如果是数组 进行赋值计算 + if (template[templateKey] instanceof Array) { + template[templateKey].forEach(templateProp => { + if (infoObj[templateKey] && infoObj[templateKey][templateProp]) { + infoObj[templateKey][templateProp] = color + } + }) + } else { + // 如果是对象 继续进行递归 + if (infoObj[templateKey]) { + recursionTransObj(template[templateKey], infoObj[templateKey], color) + } + } + } +} + export function componentScalePublic(chartInfo, heightScale, widthScale) { const scale = Math.min(heightScale, widthScale) // attr 缩放转换 @@ -191,3 +318,34 @@ export function componentScalePublic(chartInfo, heightScale, widthScale) { return chartInfo } +export function adaptCurTheme(customStyle, customAttr) { + const canvasStyle = store.state.canvasStyleData + const themeColor = canvasStyle.panel.themeColor + if (themeColor === 'light') { + recursionThemTransObj(THEME_STYLE_TRANS_MAIN, customStyle, LIGHT_THEME_COLOR_MAIN) + recursionThemTransObj(THEME_STYLE_TRANS_SLAVE1, customStyle, LIGHT_THEME_COLOR_SLAVE1) + recursionThemTransObj(THEME_ATTR_TRANS_MAIN, customAttr, LIGHT_THEME_COLOR_MAIN) + } else { + recursionThemTransObj(THEME_STYLE_TRANS_MAIN, customStyle, DARK_THEME_COLOR_MAIN) + recursionThemTransObj(THEME_STYLE_TRANS_SLAVE1, customStyle, DARK_THEME_COLOR_SLAVE1) + recursionThemTransObj(THEME_ATTR_TRANS_MAIN, customAttr, DARK_THEME_COLOR_MAIN) + } + customAttr['color'] = { ...canvasStyle.chartInfo.chartColor } + customStyle['text'] = { ...canvasStyle.chartInfo.chartTitle, title: customStyle['text']['title'] } +} + +export function adaptCurThemeCommonStyle(component) { + const commonStyle = store.state.canvasStyleData.chartInfo.chartCommonStyle + for (const key in commonStyle) { + component.commonBackground[key] = commonStyle[key] + } + return component +} + +export function adaptCurThemeCommonStyleAll() { + const componentData = store.state.componentData + componentData.forEach((item) => { + adaptCurThemeCommonStyle(item) + }) +} + diff --git a/frontend/src/components/canvas/utils/utils.js b/frontend/src/components/canvas/utils/utils.js index fab83fde7d..97a233fbf1 100644 --- a/frontend/src/components/canvas/utils/utils.js +++ b/frontend/src/components/canvas/utils/utils.js @@ -8,7 +8,7 @@ import { } from '@/utils/ApplicationContext' import { uuid } from 'vue-uuid' import store from '@/store' -import { AIDED_DESIGN } from '@/views/panel/panel' +import { AIDED_DESIGN, PANEL_CHART_INFO } from '@/views/panel/panel' import html2canvas from 'html2canvasde' export function deepCopy(target) { @@ -81,6 +81,9 @@ export function panelDataPrepare(componentData, componentStyle, callback) { componentStyle.refreshViewLoading = (componentStyle.refreshViewLoading || false) componentStyle.refreshUnit = (componentStyle.refreshUnit || 'minute') componentStyle.aidedDesign = (componentStyle.aidedDesign || deepCopy(AIDED_DESIGN)) + componentStyle.chartInfo = (componentStyle.chartInfo || deepCopy(PANEL_CHART_INFO)) + componentStyle.themeId = (componentStyle.themeId || 'NO_THEME') + componentStyle.panel.themeColor = (componentStyle.panel.themeColor || 'light') componentData.forEach((item, index) => { if (item.component && item.component === 'de-date') { if (item.options.attrs && diff --git a/frontend/src/lang/en.js b/frontend/src/lang/en.js index ffe3fbfcbb..e13cce5709 100644 --- a/frontend/src/lang/en.js +++ b/frontend/src/lang/en.js @@ -1462,6 +1462,17 @@ export default { sure_bt: 'Confirm' }, panel: { + theme_change_warn: 'Subject Change', + theme_change_tips: 'Changing the theme will overwrite the view related theme attributes. It is recommended to back up in advance. Do you want to continue the replacement?', + theme_color_change_warn: 'Theme Color Change', + theme_color_change_tips: 'Theme Color change will overwrite the original view properties', + theme_color: 'Theme Color', + theme_color_dark: 'Dark', + theme_color_light: 'Light', + refresh_frequency: 'Refresh Frequency', + card_color_matching: 'Card Color Matching', + table_color_matching: 'Table Color Matching', + background_color: 'Background Color', more: 'More', level: 'Level', enlarge: 'Enlarge', @@ -1702,7 +1713,7 @@ export default { web_url: 'Web URL', video_add_tips: 'Please Add Video Info...', web_add_tips: 'Please Add Web Url Info...', - panel_view_result_show: 'View Result Show', + panel_view_result_show: 'View Result', panel_view_result_tips: 'Chose "Panel" Will Overwrite View`s Result,Range 1~10000', timeout_refresh: 'Timeout,Will Refresh...', mobile_layout: 'Mobile Layout', diff --git a/frontend/src/lang/tw.js b/frontend/src/lang/tw.js index bb8c4e40f8..26a5d2960e 100644 --- a/frontend/src/lang/tw.js +++ b/frontend/src/lang/tw.js @@ -664,9 +664,9 @@ export default { cas_selected_warn: '選擇CAS方式保存後會註銷當前回話,重新登錄' }, chart: { - view_reset: '视图重置', - view_reset_tips: '放弃对视图的修改?', - export_img: '导出图片', + view_reset: '視圖重置', + view_reset_tips: '放棄對視圖的修改?', + export_img: '導出圖片', title_repeat: '當前標題已存在', save_snapshot: '保存縮略圖', datalist: '視圖', @@ -1260,7 +1260,7 @@ export default { exec: '執行一次', confirm_exec: '手動觸發執行?', change_success: '狀態切換成功', - excel_replace_msg: '可能會影響計算欄位、自定義數据集、關聯數据集、儀錶板等,確認替換?', + excel_replace_msg: '可能會影響計算欄位、自定義數據集、關聯數據集、儀錶板等,確認替換?', effect_ext_field: '會影響計算欄位' }, field_group_type: '分類', @@ -1463,10 +1463,21 @@ export default { sure_bt: '確定' }, panel: { + theme_change_warn: '主題更換', + theme_change_tips: '更換主題將會覆蓋視圖相關主題屬性建議提前備份,是否繼續更換?', + theme_color_change_warn: '主題色更換', + theme_color_change_tips: '主題色變更將會覆蓋原有視圖屬性', + theme_color: '主題色', + theme_color_dark: '深色', + theme_color_light: '淺色', + refresh_frequency: '刷新頻率', + card_color_matching: '卡片配色', + table_color_matching: '表格配色', + background_color: '背景顏色', more: '更多', - level: '层级', + level: '層級', enlarge: '放大', - panel_style: '仪表板样式', + panel_style: '儀表板樣式', multiplexing: '復用', panel_off: '儀表板已下架', batch_opt: '批量操作', @@ -1703,7 +1714,7 @@ export default { web_url: '網頁地址', video_add_tips: '請點擊添加配置視頻信息...', web_add_tips: '請點擊添加網頁信息...', - panel_view_result_show: '視圖結果展示', + panel_view_result_show: '視圖結果', panel_view_result_tips: '選擇儀錶闆會覆蓋視圖的結果展示數量,取值範圍1~10000', timeout_refresh: '請求超時,稍後刷新...', mobile_layout: '移動端佈局', @@ -1916,7 +1927,7 @@ export default { placeholder: '請選擇' }, detextselectTree: { - label: '下拉树', + label: '下拉樹', placeholder: '請選擇' }, detextgridselect: { diff --git a/frontend/src/lang/zh.js b/frontend/src/lang/zh.js index 43389d11ad..f4112dfb6d 100644 --- a/frontend/src/lang/zh.js +++ b/frontend/src/lang/zh.js @@ -1470,6 +1470,17 @@ export default { sure_bt: '确定' }, panel: { + theme_change_warn: '主题更换', + theme_change_tips: '更换主题将会覆盖视图相关主题属性建议提前备份,是否继续更换?', + theme_color_change_warn: '主题色更换', + theme_color_change_tips: '主题色变更将会覆盖原有视图属性', + theme_color: '主题色', + theme_color_dark: '深色', + theme_color_light: '浅色', + refresh_frequency: '刷新频率', + card_color_matching: '卡片配色', + table_color_matching: '表格配色', + background_color: '背景颜色', more: '更多', level: '层级', enlarge: '放大', @@ -1712,7 +1723,7 @@ export default { web_url: '网页地址', video_add_tips: '请点击添加配置视频信息...', web_add_tips: '请点击添加网页信息...', - panel_view_result_show: '视图结果展示', + panel_view_result_show: '视图结果', panel_view_result_tips: '选择仪表板会覆盖视图的结果展示数量,取值范围1~10000', timeout_refresh: '请求超时,稍后刷新...', mobile_layout: '移动端布局', diff --git a/frontend/src/styles/deicon/demo_index.html b/frontend/src/styles/deicon/demo_index.html index 189268df16..a4ac5390dd 100644 --- a/frontend/src/styles/deicon/demo_index.html +++ b/frontend/src/styles/deicon/demo_index.html @@ -54,6 +54,12 @@