Forráskód Böngészése

refacto: 代码合并

wu.jian2 1 éve
szülő
commit
dff1e9bb5b
27 módosított fájl, 618 hozzáadás és 342 törlés
  1. 1 1
      data-room-ui/package.json
  2. 1 9
      data-room-ui/packages/BasicComponents/Numbers/index.vue
  3. 19 5
      data-room-ui/packages/BasicComponents/Numbers/setting.vue
  4. 7 9
      data-room-ui/packages/BasicComponents/Texts/index.vue
  5. 19 5
      data-room-ui/packages/BasicComponents/Texts/setting.vue
  6. 28 9
      data-room-ui/packages/BigScreenDesign/MouseSelect/index.vue
  7. 12 2
      data-room-ui/packages/BigScreenDesign/OverallSetting/BgImgDialog.vue
  8. 34 2
      data-room-ui/packages/BigScreenDesign/OverallSetting/index.vue
  9. 15 11
      data-room-ui/packages/BigScreenDesign/RightSetting/ExpressionDialog.vue
  10. 38 4
      data-room-ui/packages/BigScreenDesign/RightSetting/GradualSetting/index.vue
  11. 177 183
      data-room-ui/packages/BigScreenDesign/RightSetting/MoveDialog/index.vue
  12. 5 42
      data-room-ui/packages/BigScreenDesign/RulerTool/SketchRuler.vue
  13. 0 1
      data-room-ui/packages/BigScreenDesign/index.vue
  14. 11 2
      data-room-ui/packages/BigScreenRun/index.vue
  15. 19 7
      data-room-ui/packages/BorderComponents/GcBorder16/index.vue
  16. 2 2
      data-room-ui/packages/BorderComponents/GcBorder16/setting.js
  17. 1 1
      data-room-ui/packages/G2Plots/柱状图/基础柱状图.js
  18. 18 1
      data-room-ui/packages/G2Plots/进度图/仪表盘.js
  19. 16 1
      data-room-ui/packages/G2Plots/进度图/进度仪表盘.js
  20. 52 1
      data-room-ui/packages/G2Plots/饼图/基础环图.js
  21. 31 0
      data-room-ui/packages/G2Plots/饼图/基础饼图.js
  22. 23 5
      data-room-ui/packages/PlotRender/index.vue
  23. 14 4
      data-room-ui/packages/Render/index.vue
  24. 20 12
      data-room-ui/packages/js/mixins/commonMixins.js
  25. 29 20
      data-room-ui/packages/js/store/actions.js
  26. 23 2
      data-room-ui/packages/js/store/mutations.js
  27. 3 1
      data-room-ui/packages/js/store/state.js

+ 1 - 1
data-room-ui/package.json

@@ -1,6 +1,6 @@
 {
   "name": "@gcpaas/data-room-ui",
-  "version": "2.0.1-2023102702-Alpha",
+  "version": "2.0.1-2023110701-Alpha",
   "description": "自定义大屏",
   "author": "gcpaas",
   "license": "MIT",

+ 1 - 9
data-room-ui/packages/BasicComponents/Numbers/index.vue

@@ -39,18 +39,10 @@ export default {
   methods: {
     // 通过表达式计算得来的值
     getDataByExpression (config) {
-      // 如果表达式是由其他组件的值构成的
-      // const len = this.config.expressionCodes ? this.config.expressionCodes.length : 0
-      // const len1 = this.currentComputedDatas ? Object.keys(this.currentComputedDatas).length : 0
-      // const len2 = this.currentDataset ? Object.keys(this.currentDataset).length : 0
-      // if (len && len === len1 + len2) {
-      // eslint-disable-next-line no-new-func
       const result = new Function('dataset', 'computedDatas', this.config.expression)
       config.customize.title = result(this.dataset, this.computedDatas)
       // 同时将计算得来的值保存到公共的数据存储的地方
-      this.updateComputedDatas({ code: config.code, name: config.name, data: config.customize.title })
-      // this.changeChartConfig(config)
-      // }
+      this.updateComputedDatas({ code: config.code, title: config.title, data: config.customize.title, isExpression: true })
     },
     dataFormatting (config, data) {
       // 文本数据配置原则:选择数据集则以后端返回的数据为主,否则以设置面板中标题设置为准

+ 19 - 5
data-room-ui/packages/BasicComponents/Numbers/setting.vue

@@ -43,11 +43,11 @@
         />
       </div>
       <SettingTitle>旋转</SettingTitle>
-          <div class="lc-field-body">
-            <RotateSetting
-              :config="config"
-            />
-          </div>
+      <div class="lc-field-body">
+        <RotateSetting
+          :config="config"
+        />
+      </div>
       <SettingTitle>基础</SettingTitle>
       <div class="lc-field-body">
         <el-form-item
@@ -106,6 +106,7 @@ import TextGradient from 'data-room-ui/BigScreenDesign/RightSetting/TextGradient
 import PosWhSetting from 'data-room-ui/BigScreenDesign/RightSetting/PosWhSetting.vue'
 import RotateSetting from 'data-room-ui/BigScreenDesign/RightSetting/RotateSetting.vue'
 import fontList from 'data-room-ui/js/utils/fontList'
+import { mapMutations } from 'vuex'
 export default {
   name: 'TextSetting',
   components: {
@@ -136,9 +137,22 @@ export default {
     }
   },
   watch: {
+    // 标题发生变化时需要及时更新表达式中的数据集库的字段名
+    'config.title': {
+      handler (val, oldVal) {
+        if (val) {
+          this.updateDataset({ code: this.config.code, title: val, data: [], oldTitle: oldVal })
+          this.updateComputedDatas({ code: this.config.code, title: val, data: [], oldTitle: oldVal })
+        }
+      }
+    }
   },
   mounted () {},
   methods: {
+    ...mapMutations({
+      updateDataset: 'bigScreen/updateDataset',
+      updateComputedDatas: 'bigScreen/updateComputedDatas'
+    })
   }
 }
 </script>

+ 7 - 9
data-room-ui/packages/BasicComponents/Texts/index.vue

@@ -40,17 +40,15 @@ export default {
     // 通过表达式计算得来的值
     getDataByExpression (config) {
       // 如果表达式是由其他组件的值构成的
-      // const len = this.config.expressionCodes ? this.config.expressionCodes.length : 0
-      // const len1 = this.currentComputedDatas ? Object.keys(this.currentComputedDatas).length : 0
-      // const len2 = this.currentDataset ? Object.keys(this.currentDataset).length : 0
-      // console.log('len', len, len1, len2)
-      // if (len && len === len1 + len2) {
       // eslint-disable-next-line no-new-func
-      const result = new Function('dataset', 'computedDatas', this.config.expression)
-      config.customize.title = result(this.dataset, this.computedDatas)
-      console.log(result(this.dataset, this.computedDatas))
+      try {
+        const result = new Function('dataset', 'computedDatas', this.config.expression)
+        config.customize.title = result(this.dataset, this.computedDatas)
+      } catch (e) {
+
+      }
       // 同时将计算得来的值保存到公共的数据存储的地方
-      this.updateComputedDatas({ code: config.code, name: config.name, data: config.customize.title })
+      this.updateComputedDatas({ code: config.code, title: config.title, data: config.customize.title })
       // this.changeChartConfig(config)
       // }
     },

+ 19 - 5
data-room-ui/packages/BasicComponents/Texts/setting.vue

@@ -43,11 +43,11 @@
         />
       </div>
       <SettingTitle>旋转</SettingTitle>
-          <div class="lc-field-body">
-            <RotateSetting
-              :config="config"
-            />
-          </div>
+      <div class="lc-field-body">
+        <RotateSetting
+          :config="config"
+        />
+      </div>
       <SettingTitle>基础</SettingTitle>
       <div class="lc-field-body">
         <el-form-item
@@ -103,6 +103,7 @@ import TextGradient from 'data-room-ui/BigScreenDesign/RightSetting/TextGradient
 import PosWhSetting from 'data-room-ui/BigScreenDesign/RightSetting/PosWhSetting.vue'
 import RotateSetting from 'data-room-ui/BigScreenDesign/RightSetting/RotateSetting.vue'
 import fontList from 'data-room-ui/js/utils/fontList'
+import { mapMutations } from 'vuex'
 export default {
   name: 'TextSetting',
   components: {
@@ -133,9 +134,22 @@ export default {
     }
   },
   watch: {
+    // 标题发生变化时需要及时更新表达式中的数据集库的字段名
+    'config.title': {
+      handler (val, oldVal) {
+        if (val) {
+          this.updateDataset({ code: this.config.code, title: val, data: [], oldTitle: oldVal })
+          this.updateComputedDatas({ code: this.config.code, title: val, data: [], oldTitle: oldVal })
+        }
+      }
+    }
   },
   mounted () {},
   methods: {
+    ...mapMutations({
+      updateDataset: 'bigScreen/updateDataset',
+      updateComputedDatas: 'bigScreen/updateComputedDatas'
+    })
   }
 }
 </script>

+ 28 - 9
data-room-ui/packages/BigScreenDesign/MouseSelect/index.vue

@@ -51,8 +51,10 @@ export default {
     }),
     getSelectionBoxStyle () {
       // 计算虚线框的样式
-      const left = Math.min(this.startX, this.endX) + 'px'
-      const top = Math.min(this.startY, this.endY) + 'px'
+      let left = Math.min(this.startX, this.endX) + 'px'
+      let top = Math.min(this.startY, this.endY) + 'px'
+      const left1 = Math.min(this.startX, this.endX) + 50 * this.scale + 'px'
+      const top1 = Math.min(this.startY, this.endY) + 50 * this.scale + 'px'
       const width = Math.abs(this.endX - this.startX) + 'px'
       const height = Math.abs(this.endY - this.startY) + 'px'
       if (!this.isSelecting) {
@@ -79,6 +81,7 @@ export default {
       ]
     ),
     handleMouseDown (event) {
+      // 点击在底部背景上
       if (event.button === 0) {
         time = new Date()
         // 避免和shift + 点击多选组件冲突
@@ -86,11 +89,22 @@ export default {
           return
         }
         this.isSelectDown = true
-
-        this.startX = (event.x - this.offsetX) / this.scale
-        this.startY = (event.y - this.offsetY) / this.scale
-        this.endX = (event.x - this.offsetX) / this.scale
-        this.endY = (event.y - this.offsetY) / this.scale
+        // 点击在底部背景上
+        if (event.target.className.indexOf('mouse-select-wrap') !== -1) {
+          this.startX = event.offsetX
+          this.endX = event.offsetX
+          this.startY = event.offsetY
+          this.endY = event.offsetY
+        } else if (event.target.className.indexOf('design-drag-wrap') !== -1) {
+          this.startX = event.offsetX + 50
+          this.endX = event.offsetX + 50
+          this.startY = event.offsetY + 50
+          this.endY = event.offsetY + 50
+        }
+        // this.startX = (event.x - this.offsetX + 50) / this.scale
+        // this.startY = (event.y - this.offsetY + 50) / this.scale
+        // this.endX = (event.x - this.offsetX + 50) / this.scale
+        // this.endY = (event.y - this.offsetY + 50) / this.scale
       }
     },
     handleMouseMove (event) {
@@ -102,8 +116,13 @@ export default {
         this.isSelecting = true
       }
       if (this.isSelecting) {
-        this.endX = (event.x - this.offsetX) / this.scale
-        this.endY = (event.y - this.offsetY) / this.scale
+        if (event.target.className.indexOf('mouse-select-wrap') !== -1) {
+          this.endX = event.offsetX
+          this.endY = event.offsetY
+        } else if (event.target.className.indexOf('design-drag-wrap') !== -1) {
+          this.startX = event.offsetX + 50
+          this.endY = event.offsetY + 50
+        }
       }
     },
     handleMouseUp (event) {

+ 12 - 2
data-room-ui/packages/BigScreenDesign/OverallSetting/BgImgDialog.vue

@@ -82,6 +82,8 @@
   </el-dialog>
 </template>
 <script>
+import { getFileUrl } from 'data-room-ui/js/utils/file'
+
 export default {
   name: 'BgImgDialog',
   props: {
@@ -114,10 +116,10 @@ export default {
     init () {
       this.dialogVisible = true
       this.imgUrl = this.form.customTheme === 'light' ? this.form.bg : this.form.lightBg
-      this.fileList = this.imgUrl
+      this.fileList = this.getCoverPicture(this.imgUrl)
         ? [{
             name: '背景图',
-            url: this.imgUrl
+            url: this.getCoverPicture(this.imgUrl)
           }]
         : []
       this.hideUploadImgBtn = this.fileList.length !== 0
@@ -155,6 +157,14 @@ export default {
     },
     confirm () {
       this.dialogVisible = false
+    },
+    /**
+     * 获取图片访问地址,如果是相对路径则拼接上文件访问前缀地址
+     * @param url
+     * @returns {*}
+     */
+    getCoverPicture (url) {
+      return getFileUrl(url)
     }
   }
 }

+ 34 - 2
data-room-ui/packages/BigScreenDesign/OverallSetting/index.vue

@@ -59,6 +59,16 @@
               />
             </el-select>
           </el-form-item>
+          <el-form-item label="开启磁吸">
+            <el-switch
+              v-model="currentSnap"
+              class="bs-el-switch"
+              active-color="#007aff"
+              :active-value="30"
+              :inactive-value="3"
+              @change="snapHandler"
+            />
+          </el-form-item>
           <el-form-item label="主题">
             <el-select
               v-model="form.customTheme"
@@ -87,7 +97,7 @@
             <el-image
               v-if="form[currentBg]"
               class="bg-img bs-el-img"
-              :src="form[currentBg]"
+              :src="getCoverPicture(form[currentBg])"
               fit="cover"
               @click="$refs.bgImg.init()"
             />
@@ -190,6 +200,7 @@ import BgImg from './BgImgDialog.vue'
 import { mapState, mapMutations } from 'vuex'
 import { themeToSetting } from 'data-room-ui/js/utils/themeFormatting'
 import {predefineColors} from 'data-room-ui/js/utils/colorList'
+import { getFileUrl } from 'data-room-ui/js/utils/file'
 export default {
   name: 'OverallSetting',
   components: {
@@ -304,6 +315,14 @@ export default {
       pageInfo: state => state.bigScreen.pageInfo,
       config: state => state.bigScreen.activeItemConfig
     }),
+    currentSnap: {
+      get () {
+        // return this.snap
+        return this.$store.state.bigScreen.snapTolerance
+      },
+      set (val) {
+      }
+    },
     isPreview () {
       return (this.$route.path === window?.BS_CONFIG?.routers?.previewUrl) || (this.$route.path === '/big-screen/preview')
     },
@@ -361,7 +380,8 @@ export default {
       'changeLayout',
       'changeChartKey',
       'changeRefreshConfig',
-      'changePageInfo'
+      'changePageInfo',
+      'snapChange'
     ]),
     // 切换主题时更新主题配置
     changeTheme (theme) {
@@ -465,6 +485,18 @@ export default {
     },
     timerEmptyState () {
       return this.pageInfo.chartList.every(chart => chart.dataSource?.businessKey === '' && chart.type !== 'marquee')
+    },
+    snapHandler (val) {
+      // this.$emit('changeSnap', val)
+      this.snapChange(val)
+    },
+    /**
+     * 获取图片访问地址,如果是相对路径则拼接上文件访问前缀地址
+     * @param url
+     * @returns {*}
+     */
+    getCoverPicture (url) {
+      return getFileUrl(url)
     }
   }
 }

+ 15 - 11
data-room-ui/packages/BigScreenDesign/RightSetting/ExpressionDialog.vue

@@ -129,17 +129,21 @@ export default {
     treeData () {
       const list = []
       for (const item in this.dataset) {
-        const fields = Object.keys(this.dataset[item][0])
-        const children = fields.map((field) => {
-          return {
-            label: field,
-            code: item,
-            value: `dataset.${item}[0].${field}`,
-            disabled: item.includes(this.config.code)
-          }
-        })
+        let children = []
+        if (this.dataset[item][0]) {
+          const fields = Object.keys(this.dataset[item][0])
+          children = fields.map((field) => {
+            return {
+              label: field,
+              code: item,
+              value: `dataset.${item}[0].${field}`,
+              disabled: item.includes(this.config.code)
+            }
+          })
+        }
+
         list.push({
-          label: item,
+          label: item.split('_')[0],
           code: item,
           value: `dataset.${item}`,
           disabled: item.includes(this.config.code),
@@ -148,7 +152,7 @@ export default {
       }
       for (const item in this.computedDatas) {
         list.push({
-          label: item,
+          label: item.split('_')[0],
           code: item,
           value: `computedDatas.${item}`,
           disabled: item.includes(this.config.code)

+ 38 - 4
data-room-ui/packages/BigScreenDesign/RightSetting/GradualSetting/index.vue

@@ -6,7 +6,7 @@
       class="bs-el-color-picker"
       popper-class="bs-el-color-picker"
     />
-    <div class="el-icon-right" />
+    <div :class="positionIcon" @click="positionChange" />
     <el-color-picker
       v-model="endColor"
       class="bs-el-color-picker"
@@ -33,7 +33,15 @@ export default {
       startColor: '', // 初始颜色
       endColor: '', // 终止颜色
       position: '', // 渐变方向
-      colorsValue: ''// 拼接后的符合g2语法的颜色值
+      colorsValue: '',// 拼接后的符合g2语法的颜色值
+      positionList: ['l(0)', 'l(90)', 'l(180)', 'l(270)'],
+      positionIconList: {
+        'l(0)': 'el-icon-right',
+        'l(90)': 'el-icon-bottom',
+        'l(180)': 'el-icon-back',
+        'l(270)': 'el-icon-top'
+      },
+      positionIcon: 'el-icon-right'
     }
   },
   computed: {
@@ -51,8 +59,10 @@ export default {
   },
   methods: {
     init () {
+      // color 格式是 'l(0) 0:#ffffff 1:#000000'
       const arr = this.colors?.split(' ') || []
-      this.position = arr[0]
+      this.position = arr[0] || 'l(0)'
+      this.positionIcon = this.positionIconList[this.position] || 'el-icon-right'
       const s = arr[1].split(':')[1] && arr[1].split(':')[1] !== 'null' ? arr[1].split(':')[1] : ''
       const e = arr[2].split(':')[1] && arr[2].split(':')[1] !== 'null' ? arr[2].split(':')[1] : ''
       this.startColor = s
@@ -61,7 +71,14 @@ export default {
     colorChange (val) {
       this.colorsValue = `${this.position} 0:${this.startColor} 1:${this.endColor}`
       this.$emit('change', this.colorsValue)
-    }
+    },
+    positionChange(){
+      // 将position的值循环移动一位
+      const index = this.positionList.indexOf(this.position)
+      this.position = this.positionList[(index + 1) % 4]
+      this.positionIcon = this.positionIconList[this.position]
+      this.colorChange()
+    },
   }
 }
 </script>
@@ -75,6 +92,23 @@ export default {
     .el-icon-right{
       width: 40px;
       text-align: center;
+      cursor: pointer;
+
+    }
+    .el-icon-bottom{
+      width: 40px;
+      text-align: center;
+      cursor: pointer;
+    }
+    .el-icon-back{
+      width: 40px;
+      text-align: center;
+      cursor: pointer;
+    }
+    .el-icon-top {
+      width: 40px;
+      text-align: center;
+      cursor: pointer;
     }
   }
 

+ 177 - 183
data-room-ui/packages/BigScreenDesign/RightSetting/MoveDialog/index.vue

@@ -10,55 +10,57 @@
     @closed="close"
     @opened="getDom"
   >
-      <div class="content">
-      <div>
-        <table
-          border="1"
-          cellspacing="0"
-        >
-          <tr>
-            <th>方向</th>
-            <th>描述</th>
-          </tr>
-          <tr>
-            <td>左上角</td>
-            <td>不能拉伸</td>
-          </tr>
-          <tr>
-            <td>右上角</td>
-            <td>不能拉伸</td>
-          </tr>
-          <tr>
-            <td>左下角</td>
-            <td>不能拉伸</td>
-          </tr>
-          <tr>
-            <td>右下角</td>
-            <td>不能拉伸</td>
-          </tr>
-          <tr>
-            <td>左侧</td>
-            <td>宽度不变,高度自动拉伸</td>
-          </tr>
-          <tr>
-            <td>右侧</td>
-            <td>宽度不变,高度自动拉伸</td>
-          </tr>
-          <tr>
-            <td>顶部</td>
-            <td>高度不变,宽度自动拉伸</td>
-          </tr>
-          <tr>
-            <td>底部</td>
-            <td>高度不变,宽度自动拉伸</td>
-          </tr>
-          <tr>
-            <td>中部</td>
-            <td>宽度,高度自动拉伸</td>
-          </tr>
-        </table>
-      </div>
-      <div class="img">
+    <div class="contentTable">
+      <table
+        border="1"
+        cellspacing="0"
+      >
+        <tr>
+          <th>方向</th>
+          <th>描述</th>
+        </tr>
+        <tr>
+          <td>左上角</td>
+          <td>不能拉伸</td>
+        </tr>
+        <tr>
+          <td>右上角</td>
+          <td>不能拉伸</td>
+        </tr>
+        <tr>
+          <td>左下角</td>
+          <td>不能拉伸</td>
+        </tr>
+        <tr>
+          <td>右下角</td>
+          <td>不能拉伸</td>
+        </tr>
+        <tr>
+          <td>左侧</td>
+          <td>宽度不变,高度自动拉伸</td>
+        </tr>
+        <tr>
+          <td>右侧</td>
+          <td>宽度不变,高度自动拉伸</td>
+        </tr>
+        <tr>
+          <td>顶部</td>
+          <td>高度不变,宽度自动拉伸</td>
+        </tr>
+        <tr>
+          <td>底部</td>
+          <td>高度不变,宽度自动拉伸</td>
+        </tr>
+        <tr>
+          <td>中部</td>
+          <td>宽度,高度自动拉伸</td>
+        </tr>
+      </table>
+    </div>
+    <div
+      class="imgContent"
+    >
+      <div class="imgContainer">
         <span class="toptitle">
           <!-- <InputCom @changeStyle='changeTop' :Fx="['上','下']" :number="top" /> -->
           <el-input-number
@@ -66,7 +68,7 @@
             class="bs-el-input-number"
             :step=" 1"
             :min="0"
-            :max="100000"
+            :max="49"
             @change="changeTop"
           />
         </span>
@@ -76,7 +78,7 @@
             class="bs-el-input-number"
             :step=" 1"
             :min="0"
-            :max="100000"
+            :max="49"
             @change="changeRight"
           />
         </span>
@@ -86,7 +88,7 @@
             class="bs-el-input-number"
             :step=" 1"
             :min="0"
-            :max="100000"
+            :max="49"
             @change="changeBottom"
           />
         </span>
@@ -96,14 +98,14 @@
             class="bs-el-input-number"
             :step=" 1"
             :min="0"
-            :max="100000"
+            :max="49"
             @change="changeLeft"
           />
         </span>
         <el-image
-          style="max-width:550px"
+          style="max-width:550px;object-fit: cover;"
           :src="imgUrl||url"
-          fit="fill"
+          fit="cover"
         />
         <div
           id="top"
@@ -149,13 +151,14 @@
     </div>
   </el-dialog>
 </template>
+
 <script>
 import { getFileUrl } from 'data-room-ui/js/utils/file'
-
 export default {
   name: 'SourceDialog',
   data () {
     return {
+      contentHeight: 300,
       dialogVisible: false,
       imgUrl: '',
       top: 0,
@@ -175,13 +178,28 @@ export default {
       return require('data-room-ui/BorderComponents/GcBorder16/component.png')
     }
   },
-  mounted () {
-  },
   methods: {
     confirm () {
       this.$emit('getArray', [this.top, this.right, this.bottom, this.left])
       this.dialogVisible = false
     },
+    init (val, array) {
+      if (!val.startsWith('http')) {
+        this.imgUrl = getFileUrl(val)
+      } else {
+        this.imgUrl = val
+      }
+      if (array) {
+        [this.top, this.right, this.bottom, this.left] = array
+        this.$nextTick(() => {
+          this.changeTop(this.top)
+          this.changeRight(this.right)
+          this.changeBottom(this.bottom)
+          this.changeLeft(this.left)
+        })
+      }
+      this.dialogVisible = true
+    },
     getDom () {
       //  const a=document.getElementById('top')
       //  const b=document.getElementById('right')
@@ -192,6 +210,25 @@ export default {
       //  this.bottom=getComputedStyle(c).bottom.slice(0,-2)
       //  this.left=getComputedStyle(d).left.slice(0,-2)
     },
+    close () {
+
+    },
+    changeTop (val) {
+      const a = document.getElementById('top')
+      a.style.top = val + '%'
+    },
+    changeRight (val) {
+      const a = document.getElementById('right')
+      a.style.right = val + '%'
+    },
+    changeBottom (val) {
+      const a = document.getElementById('bottom')
+      a.style.bottom = val + '%'
+    },
+    changeLeft (val) {
+      const a = document.getElementById('left')
+      a.style.left = val + '%'
+    },
     onMouseUp () {
       // this.isDown=false;
     },
@@ -208,152 +245,109 @@ export default {
     },
     onMouseDown (e) {
       // this.y=e.layerY
-	    // this.t=this.top;
+      // this.t=this.top;
       // this.isDown=true
       // console.log(this.x,this.l)
     },
     changeSymbol (val) {
       this.symbol = val
-    },
-
-    close () {
-
-    },
-    changeTop (val) {
-      const a = document.getElementById('top')
-      a.style.top = val + 'px'
-    },
-    changeRight (val) {
-      const a = document.getElementById('right')
-      a.style.right = val + 'px'
-    },
-    changeBottom (val) {
-      const a = document.getElementById('bottom')
-      a.style.bottom = val + 'px'
-    },
-    changeLeft (val) {
-      const a = document.getElementById('left')
-      a.style.left = val + 'px'
-    },
-    init (val, array) {
-      if (!val.startsWith('http')) {
-        this.imgUrl = getFileUrl(val)
-      } else {
-        this.imgUrl = val
-      }
-      if (array) {
-        [this.top, this.right, this.bottom, this.left] = array
-        this.$nextTick(() => {
-          this.changeTop(this.top)
-          this.changeRight(this.right)
-          this.changeBottom(this.bottom)
-          this.changeLeft(this.left)
-        })
-      }
-      this.dialogVisible = true
     }
   }
 }
 </script>
 
 <style lang="scss" scoped>
-// @import '../../assets/style/bsTheme.scss';
-::v-deep .el-dialog__body{
-  background-color: #232832;
-  position: relative;
-  min-height: 450px;
-  align-items: center;
-  justify-content: center;
-  display: flex;
-  padding: 16px 16px 16px 16px !important;
-}
-.content{
-  margin: 20px 0;
-  width: 100%;
-  display: flex;
-  justify-content: center;
-  align-items: center;
+  ::v-deep .el-dialog__body{
+    position: relative;
+    background-color: #232832;
+    min-height: 450px;
+    padding: 16px 16px 16px 16px !important;
+    overflow: auto;
+  }
+.contentTable{
+  position: absolute;
+  top: 0;
+  left: 0;
+  width: 400px;
+  margin-top: 50px;
+  margin-left: 80px;
+  margin-right: 200px;
+  table{
+    color: #fff;
+    border: 1px solid #fff;
+  }
   td,th{
     padding: 8px 20px;
     text-align: center;
     vertical-align: middle;
   }
-  .img{
-    position: relative;
-    .toptitle{
+}
+  .imgContent{
+    width: 400px;
+    position: absolute;
+    left: 600px;
+    top: 50%;
+    transform: translateY(-50%);
+    margin-top: 0px;
+    .imgContainer{
+      width: 100%;
+      height: 100%;
+      position: relative;
+      .toptitle{
         position: absolute;
         top: -43px;
         left: 50%;
         transform: translateX(-50%);
       }
-    .righttitle{
-      position: absolute;
-      top: 50%;
-      transform: translateY(-50%);
-      right: -123px;
-    }
-    .bottomtitle{
-      position: absolute;
-      bottom: -43px;
-      left: 50%;
-      transform: translateX(-50%);
-    }
-    .lefttitle{
-      position: absolute;
-      top: 50%;
-      transform: translateY(-50%);
-      left: -123px;
-    }
-    // height: 100%;
-    .top{
-      position: absolute;
-      top: 0;
-      height: 1px;
-      background-color: #fff;
-      width: 100%;
-    }
-    .right{
-      position: absolute;
-      right: 0;
-      top: 0;
-      height: 100%;
-      background-color: #fff;
-      width: 1px;
-    }
-    .bottom{
-      position: absolute;
-      bottom: 0;
-      height: 1px;
-      background-color: #fff;
-      width: 100%;
-    }
-    .left{
-      position: absolute;
-      left: 0;
-      top: 0;
-      height: 100%;
-      background-color: #fff;
-      width: 1px;
+      .righttitle{
+        position: absolute;
+        top: 50%;
+        transform: translateY(-50%);
+        right: -150px;
+      }
+      .bottomtitle{
+        position: absolute;
+        bottom: -43px;
+        left: 50%;
+        transform: translateX(-50%);
+      }
+      .lefttitle{
+        position: absolute;
+        top: 50%;
+        transform: translateY(-50%);
+        left: -150px;
+      }
+      // height: 100%;
+      .top{
+        position: absolute;
+        top: 0;
+        height: 1px;
+        background-color: #fff;
+        width: 100%;
+      }
+      .right{
+        position: absolute;
+        right: 0;
+        top: 0;
+        height: 100%;
+        background-color: #fff;
+        width: 1px;
+      }
+      .bottom{
+        position: absolute;
+        bottom: 0;
+        height: 1px;
+        background-color: #fff;
+        width: 100%;
+      }
+      .left{
+        position: absolute;
+        left: 0;
+        top: 0;
+        height: 100%;
+        background-color: #fff;
+        width: 1px;
+      }
     }
   }
-
-}
-::v-deep .el-input-number--mini{
-  width: 100px;
-  .el-input__inner{
-    padding-right: 30px;
-  }
-}
-table{
-  margin-right: 200px;
-  color: #fff;
-  border: 1px solid #fff;
-}
-th{
-  padding: 4px;
-}
-td{
-  padding: 8px;
-}
-
 </style>

+ 5 - 42
data-room-ui/packages/BigScreenDesign/RulerTool/SketchRuler.vue

@@ -214,6 +214,10 @@ export default {
         scrollLeft = screenElement.scrollLeft
         scrollTop = screenElement.scrollTop
         maxContainer.addEventListener('mousemove', function (event) {
+          // 在鼠标移动过程中判断出鼠标左键未点击,则停止拖拽
+          if (event.buttons !== 1) {
+            that.isDrag = false
+          }
           if (that.isDrag) {
             event.preventDefault()
             // 鼠标移动距离
@@ -427,52 +431,11 @@ export default {
 
 .screen-container {
   position: absolute;
+  overflow:hidden;
   width: 6000px;
   height: 6000px;
 }
 
-.minimap{
-  position: fixed;
-  bottom: 15px;
-  right: 15px;
-  border: 1px solid #f6f7fb;
-  z-index:10000;
-  /*cursor: move;*/
-}
-.minimap .mapHeader{
-  background-color:#303640;
-  padding: 0 10px;
-  display: flex;
-  justify-content: space-between;
-  height: 20px;
-  width: 150px;
-  font-size: 12px;
-  border-bottom: 1px solid #fff;
-  color: #ffffff;
-  cursor: pointer;
-  span {
-    user-select: none;
-  }
-}
-
-.minimap .selectWin{
-  background-color: #232832;
-  height: 150px;
-  width: 150px;
-  position: relative;
-}
-
-.minimap .selectionWin{
-  position: absolute;
-  left: 0px;
-  top: 0px;
-  width: 30px;
-  height: 30px;
-  background-color: white;
-  opacity: 0.5;
-  cursor: move;
-}
-
 .scale-value {
   position: absolute;
   left: 0;

+ 0 - 1
data-room-ui/packages/BigScreenDesign/index.vue

@@ -55,7 +55,6 @@
               class="selectionWin"
             />
           </div>
-          <div class="miniView" />
         </div>
         <SketchDesignRuler
           ref="Rules"

+ 11 - 2
data-room-ui/packages/BigScreenRun/index.vue

@@ -42,6 +42,7 @@ import { compile } from 'tiny-sass-compiler/dist/tiny-sass-compiler.esm-browser.
 import NotPermission from 'data-room-ui/NotPermission'
 import Configuration from 'data-room-ui/Render/Configuration.vue'
 import DataViewDialog from 'data-room-ui/BigScreenDesign/DataViewDialog/index.vue'
+import { getFileUrl } from 'data-room-ui/js/utils/file'
 export default {
   name: 'BigScreenRun',
   components: {
@@ -99,7 +100,7 @@ export default {
       const bg = this.fitMode !== 'none'
         ? {
             backgroundColor: this.fitPageConfig.customTheme === 'light' ? this.fitPageConfig.lightBgColor : this.fitPageConfig.bgColor,
-            backgroundImage: this.fitPageConfig.customTheme === 'light' ? `url(${this.fitPageConfig.lightBg})` : `url(${this.fitPageConfig.bg})`,
+            backgroundImage: this.fitPageConfig.customTheme === 'light' ? `url(${this.getCoverPicture(this.fitPageConfig.lightBg)})` : `url(${this.getCoverPicture(this.fitPageConfig.bg)})`,
             backgroundSize: 'cover'
           }
         : {}
@@ -121,7 +122,7 @@ export default {
       const bg = this.fitMode === 'none'
         ? {
             backgroundColor: this.fitPageConfig.customTheme === 'light' ? this.fitPageConfig.lightBgColor : this.fitPageConfig.bgColor,
-            backgroundImage: this.fitPageConfig.customTheme === 'light' ? `url(${this.fitPageConfig.lightBg})` : `url(${this.fitPageConfig.bg})`,
+            backgroundImage: this.fitPageConfig.customTheme === 'light' ? `url(${this.getCoverPicture(this.fitPageConfig.lightBg)})` : `url(${this.getCoverPicture(this.fitPageConfig.bg)})`,
             backgroundSize: 'cover'
           }
         : {}
@@ -378,6 +379,14 @@ export default {
       }
 
       return newPageConfig
+    },
+    /**
+     * 获取图片访问地址,如果是相对路径则拼接上文件访问前缀地址
+     * @param url
+     * @returns {*}
+     */
+    getCoverPicture (url) {
+      return getFileUrl(url)
     }
   }
 }

+ 19 - 7
data-room-ui/packages/BorderComponents/GcBorder16/index.vue

@@ -1,12 +1,12 @@
 <template>
   <div
-    style="width: 100%;height: 100%"
+    style="width: 100%;height: 100%;object-fit: cover"
     class="bs-design-wrap"
     :id="'border'+ config.code"
     :style="{
       opacity: opacity,
-      borderImageSlice:`${borderArray[0]} ${borderArray[1]} ${borderArray[2]} ${borderArray[3]} fill`,
-      borderImageWidth:`${borderArray[0]}px ${borderArray[1]}px ${borderArray[2]}px ${borderArray[3]}px`,
+      borderImageSlice:`${borderImageArray[0]} ${borderImageArray[1]} ${borderImageArray[2]} ${borderImageArray[3]} fill`,
+      borderImageWidth:`${borderImageArray[0]}px ${borderImageArray[1]}px ${borderImageArray[2]}px ${borderImageArray[3]}px`,
     }"
   >
   </div>
@@ -32,18 +32,26 @@ export default {
   },
   data () {
     return {
+      borderWidth: 0,
+      borderHeight: 0
     }
   },
   computed: {
-    url(){
+    url () {
       return require('data-room-ui/BorderComponents/GcBorder16/component.png')
     },
     opacity () {
       return this.config.border.opacity || 100
     },
-    borderArray(){
-      return this.config.border.borderArray ? this.config.border.borderArray
-        : [50,50,50,50]
+    borderImageArray () {
+      const borderArr = this.config.border.borderArray ? this.config.border.borderArray
+        : [10, 10, 10, 10]
+      const arr = []
+      arr[0] = borderArr[0] * this.borderHeight / 100
+      arr[1] = borderArr[1] * this.borderWidth / 100
+      arr[2] = borderArr[2] * this.borderHeight / 100
+      arr[3] = borderArr[3] * this.borderWidth / 100
+      return arr
     }
   },
   watch: {
@@ -64,6 +72,10 @@ export default {
     }
   },
   mounted () {
+    // 获取边框大小
+    const element = document.querySelector('.bs-design-wrap')
+    this.borderWidth = element.offsetWidth
+    this.borderHeight = element.offsetHeight
     if(this.config.border.imgUrl){
       let ur=this.config.border.imgUrl
       if(!this.config.border.imgUrl.startsWith('http')){

+ 2 - 2
data-room-ui/packages/BorderComponents/GcBorder16/setting.js

@@ -54,8 +54,8 @@ const setting = [
     // 是否多选
     multiple: false,
     // 绑定的值
-    value: [50,50,50,50],
-  },
+    value: [10, 10, 10, 10]
+  }
 ]
 
 

+ 1 - 1
data-room-ui/packages/G2Plots/柱状图/基础柱状图.js

@@ -389,7 +389,7 @@ const setting = [
     value: '#d0d0d0',
     tabName: 'custom',
     groupName: 'yAxis'
-  },
+  }
   // 边距 padding
 ]
 

+ 18 - 1
data-room-ui/packages/G2Plots/进度图/仪表盘.js

@@ -99,6 +99,18 @@ const setting = [
     tabName: 'custom',
     groupName: 'graph'
   },
+  {
+    label: '指标小数位',
+    // 设置组件类型
+    type: 'inputNumber',
+    // 字段
+    field: 'statistic_fixed',
+    // 对应options中的字段
+    optionField: 'statisticFixed',
+    value: 0,
+    tabName: 'custom',
+    groupName: 'graph'
+  },
   {
     label: '指标字体类型',
     // 设置组件类型
@@ -185,7 +197,11 @@ const data = [
   }
 ]
 // 配置处理脚本
-const optionHandler ='option.range.color = [option.color1, option.color2]'
+const optionHandler ='option.range.color = [option.color1, option.color2]\n' +
+  '  let fix = option.statisticFixed\n' +
+  '  option.statistic.title.formatter = ({ percent }) => `${(percent * 100).toFixed(fix)}%`'
+
+
 
 // 数据处理脚本
 const dataHandler = '// 取返回数据列表的第一项指标值\noption.percent = data[0][setting.filter(settingItem=>settingItem.field === \'percent\')[0].value]'
@@ -226,6 +242,7 @@ const option = {
   // shapeStyle: {
   //   fill: 'rgba(208,208,208,0)'
   // },
+  statisticFixed: 0,
   statistic: {
     title: {
       offsetY: 0,

+ 16 - 1
data-room-ui/packages/G2Plots/进度图/进度仪表盘.js

@@ -75,6 +75,18 @@ const setting = [
     tabName: 'custom',
     groupName: 'graph'
   },
+  {
+    label: '指标小数位',
+    // 设置组件类型
+    type: 'inputNumber',
+    // 字段
+    field: 'statistic_fixed',
+    // 对应options中的字段
+    optionField: 'statisticFixed',
+    value: 0,
+    tabName: 'custom',
+    groupName: 'graph'
+  },
   {
     label: '指标字体类型',
     // 设置组件类型
@@ -160,7 +172,9 @@ const data = [
   }
 ]
 // 配置处理脚本
-const optionHandler ='option.range.color = [option.color1, option.color2]'
+const optionHandler ='option.range.color = [option.color1, option.color2]\n' +
+  '  let fix = option.statisticFixed\n' +
+  '  option.statistic.title.formatter = ({ percent }) => `${(percent * 100).toFixed(fix)}%`'
 // 数据处理脚本
 const dataHandler = '// 取返回数据列表的第一项指标值\noption.percent = data[0][setting.filter(settingItem=>settingItem.field === \'percent\')[0].value]'
 
@@ -175,6 +189,7 @@ const option = {
   range: {
     color: ['l(0) 0:#6b74e4 1:#4391f4','#d0d0d0']
   },
+  statisticFixed: 0,
   startAngle: Math.PI,
   endAngle: 2 * Math.PI,
   indicator: null,

+ 52 - 1
data-room-ui/packages/G2Plots/饼图/基础环图.js

@@ -41,6 +41,37 @@ const setting = [
   },
   /** 样式配置 **/
   // 图表 graph
+  {
+    label: '标签文本来源',
+    // 设置组件类型
+    type: 'select',
+    // 字段
+    field: 'label_contentList',
+    // 对应options中的字段
+    optionField: 'label.contentList',
+    value: ['{value}'],
+    tabName: 'custom',
+    multiple: true,
+    options: [
+      { label: '维度', value: '{name}' },
+      { label: '指标', value: '{value}' },
+      { label: '百分比', value: '{percentage}' },
+    ],
+    step: 0.1,
+    max: 1,
+    groupName: 'graph'
+  },
+  {
+    label: '旋转内部标签',
+    type: 'switch', // 设置组件类型
+    field: 'labelAutoRotate', // 字段
+    optionField: 'label.autoRotate', // 对应options中的字段
+    value: false,
+    active: true,
+    inactive: false,
+    tabName: 'custom',
+    groupName: 'graph'
+  },
   {
     label: '标签位置',
     // 设置组件类型
@@ -347,7 +378,25 @@ const data = [
 const optionHandler = 'option.legend = option.legendEnable ? {position: setting.find(settingItem=>settingItem.field === \'legendPosition\').value} : false;' +
   '\n  if (option.legendEnable) {\n' +
   '    option.legend.itemName = option.legendItemName\n' +
-  '  }'
+  '  }' +
+  `if (option.label.contentList && option.label.contentList.length > 0) {
+  let content = ''
+  if (option.label.contentList.length === 1) {
+    content = option.label.contentList[0]
+  } else {
+    // 多行文本,加换行符,但是最后一行不加
+    option.label.contentList.forEach((item, index) => {
+      if (index === option.label.contentList.length - 1) {
+        content += item
+      } else {
+        content += item + '\\n'
+      }
+    })
+  }
+  option.label.content = content
+}`
+
+
 
 // 数据处理脚本
 const dataHandler = ''
@@ -376,6 +425,7 @@ const option = {
   color: ['#6b74e4', '#4391f4', '#38bbe5', '#69d6fd', '#36c6a0'],
   label: {
     type: 'inner',
+    autoRotate: false,
     labelLine: {
       style: {
         stroke: '#5B8FF9',
@@ -383,6 +433,7 @@ const option = {
         lineWidth: 1
       }
     },
+    contentList: [],
     content: '{value}',
     style: {
       fill: '#ffffff',

+ 31 - 0
data-room-ui/packages/G2Plots/饼图/基础饼图.js

@@ -41,6 +41,25 @@ const setting = [
   },
   /** 样式配置 **/
   // 图表 graph
+  {
+    label: '标签文本来源',
+    // 设置组件类型
+    type: 'select',
+    // 字段
+    field: 'label_content',
+    // 对应options中的字段
+    optionField: 'label.content',
+    value: '{value}',
+    tabName: 'custom',
+    options: [
+      { label: '维度', value: '{name}' },
+      { label: '指标', value: '{value}' },
+      { label: '百分比', value: '{percentage}' }
+    ],
+    step: 0.1,
+    max: 1,
+    groupName: 'graph'
+  },
   {
     label: '标签位置',
     // 设置组件类型
@@ -58,6 +77,17 @@ const setting = [
     ],
     groupName: 'graph'
   },
+  {
+    label: '旋转内部标签',
+    type: 'switch', // 设置组件类型
+    field: 'labelAutoRotate', // 字段
+    optionField: 'label.autoRotate', // 对应options中的字段
+    value: true,
+    active: true,
+    inactive: false,
+    tabName: 'custom',
+    groupName: 'graph'
+  },
   {
     label: '标签颜色',
     // 设置组件类型
@@ -239,6 +269,7 @@ const option = {
   },
   color: ['#6b74e4', '#4391f4', '#38bbe5', '#69d6fd', '#36c6a0'],
   label: {
+    autoRotate: true,
     type: 'inner',
     labelHeight: 50,
     labelLine: {

+ 23 - 5
data-room-ui/packages/PlotRender/index.vue

@@ -147,7 +147,9 @@ export default {
       let option = null
       config.setting.forEach(set => {
         if (set.optionField) {
+          // 例 point.style.fill
           const optionField = set.optionField.split('.')
+          // 例 [point,style,fill]
           option = config.option
           optionField.forEach((field, index) => {
             if (index === optionField.length - 1) {
@@ -156,6 +158,10 @@ export default {
                 option[field] = set.value
               }
             } else {
+              // 如果没有这个属性,则创建该属性,并赋值为空对值
+              if (!option[field]) {
+                option[field] = {}
+              }
               option = option[field]
             }
           })
@@ -180,7 +186,7 @@ export default {
             console.error(e)
           }
         }
-        if(config.chartType=='Treemap'){
+        if (config.chartType == 'Treemap') {
           const xAxis = config.setting.find(item => item.field === 'xField')?.value
           const listData = data.children.map(item => {
             if (xAxis && typeof item[xAxis] === 'number') {
@@ -188,14 +194,26 @@ export default {
             }
             return item
           })
-          config.option.data={name:'root',children:[...listData]}
+          config.option.data = { name: 'root', children: [...listData] }
           // console.log(config.option.data)
-        }else{
-           // 如果维度为数字类型则转化为字符串,否则在不增加其他配置的情况下会导致图标最后一项不显示(g2plot官网已说明)
+        } else {
+          // 如果维度为数字类型则转化为字符串,否则在不增加其他配置的情况下会导致图标最后一项不显示(g2plot官网已说明)
           const xAxis = config.setting.find(item => item.field === 'xField')?.value
+          const yAxis = config.setting.find(item => item.field === 'yField')?.value
           config.option.data = data?.map(item => {
-            if (xAxis && typeof item[xAxis] === 'number') {
+            // 此处函数处理data
+            if (config.dataHandler) {
+              try {
+                // 此处函数处理data
+                eval(config.dataHandler)
+              } catch (e) {
+                console.error(e)
+              }
+            }
+            if (config.chartType !== 'Bar' && xAxis && typeof item[xAxis] === 'number') {
               item[xAxis] = (item[xAxis]).toString()
+            } else if (config.chartType === 'Bar' && yAxis && typeof item[yAxis] === 'number') {
+              item[yAxis] = (item[yAxis]).toString()
             }
             return item
           })

+ 14 - 4
data-room-ui/packages/Render/index.vue

@@ -7,7 +7,7 @@
       width: pageInfo.pageConfig.w + 'px',
       height: pageInfo.pageConfig.h + 'px',
       backgroundColor:pageInfo.pageConfig.customTheme ==='light' ? pageInfo.pageConfig.lightBgColor:pageInfo.pageConfig.bgColor ,
-      backgroundImage:pageInfo.pageConfig.customTheme ==='light' ? `url(${pageInfo.pageConfig.lightBg})`:`url(${pageInfo.pageConfig.bg})`
+      backgroundImage:pageInfo.pageConfig.customTheme ==='light' ? `url(${this.getCoverPicture(pageInfo.pageConfig.lightBg)})`:`url(${this.getCoverPicture(pageInfo.pageConfig.bg)})`
     }"
     @drop="drop($event)"
     @dragover.prevent
@@ -34,7 +34,7 @@
       :debug="false"
       :is-conflict-check="false"
       :snap="true"
-      :snap-tolerance="2"
+      :snap-tolerance="snapTolerance"
       :style="{
         zIndex: chart.z || 0,
       }"
@@ -92,6 +92,7 @@ import { randomString } from '../js/utils'
 import { compile } from 'tiny-sass-compiler/dist/tiny-sass-compiler.esm-browser.prod.js'
 import plotList, { getCustomPlots } from '../G2Plots/plotList'
 import { settingToTheme } from 'data-room-ui/js/utils/themeFormatting'
+import { getFileUrl } from 'data-room-ui/js/utils/file'
 
 export default {
   name: 'BigScreenRender',
@@ -128,7 +129,8 @@ export default {
       hoverCode: (state) => state.bigScreen.hoverCode,
       themeJson: (state) => state.bigScreen.pageInfo.pageConfig.themeJson,
       isInit: (state) => !state.bigScreen.pageLoading,
-      scale: (state) => state.bigScreen.zoom / 100
+      scale: (state) => state.bigScreen.zoom / 100,
+      snapTolerance: (state) => state.bigScreen.snapTolerance
     })
   },
   watch: {
@@ -370,7 +372,7 @@ export default {
         code: !chart.code ? randomString(8) : chart.code,
         option
       }
-      config.key = config.code
+      config.key = isComponent ? randomString(8) : config.code
       // isComponent = false 从左侧新增时需要初始化theme的内容
       // isComponent = true从组件库添加自定义组件时不用初始化
       if (!isComponent) {
@@ -454,6 +456,14 @@ export default {
           })
         })
       }
+    },
+    /**
+     * 获取图片访问地址,如果是相对路径则拼接上文件访问前缀地址
+     * @param url
+     * @returns {*}
+     */
+    getCoverPicture (url) {
+      return getFileUrl(url)
     }
   }
 }

+ 20 - 12
data-room-ui/packages/js/mixins/commonMixins.js

@@ -26,8 +26,8 @@ export default {
       }
     },
     currentDataset: { // 关联的数据发生变化
-      handler (val) {
-        if (val && Object.keys(val).length) {
+      handler (val, old) {
+        if (val && Object.keys(val).length && JSON.stringify(val) !== JSON.stringify(old)) {
           this.getDataByExpression(this.config)
         }
       },
@@ -35,8 +35,8 @@ export default {
       immediate: true
     },
     currentComputedDatas: { // 关联的数据发生变化
-      handler (val) {
-        if (val && Object.keys(val).length) {
+      handler (val, old) {
+        if (val && Object.keys(val).length && JSON.stringify(val) !== JSON.stringify(old)) {
           this.getDataByExpression(this.config)
         }
       },
@@ -62,9 +62,13 @@ export default {
     // 跟当前组件计算表达式关联的组件的数据集合
     currentDataset () {
       const newDataset = {}
-      this.config.expressionCodes?.forEach(code => {
-        if (this.dataset[code]) {
-          newDataset[code] = this.dataset[code]
+      this.config.expressionCodes?.forEach(item => {
+        const code = item.split('_')[1]
+        for (const key in this.dataset) {
+          const objCode = key.split('_')[1]
+          if (objCode === code) {
+            newDataset[code] = this.dataset[key]
+          }
         }
       })
       return newDataset
@@ -72,9 +76,13 @@ export default {
     // 跟当前组件计算表达式关联的组件的数据集合
     currentComputedDatas () {
       const newDataset = {}
-      this.config.expressionCodes?.forEach(code => {
-        if (this.computedDatas[code]) {
-          newDataset[code] = this.computedDatas[code]
+      this.config.expressionCodes?.forEach(item => {
+        const code = item.split('_')[1]
+        for (const key in this.computedDatas) {
+          const objCode = key.split('_')[1]
+          if (objCode === code) {
+            newDataset[code] = this.computedDatas[key]
+          }
         }
       })
       return newDataset
@@ -170,7 +178,7 @@ export default {
           }
           // 将后端返回的数据保存
           if (_res.success) {
-            this.updateDataset({ code: config.code, name: config.name, data: _res?.data })
+            this.updateDataset({ code: config.code, title: config.title, data: _res?.data })
           }
           config = this.dataFormatting(config, _res)
           this.changeChartConfig(config)
@@ -242,7 +250,7 @@ export default {
           }
           // 将后端返回的数据保存
           if (_res.success) {
-            this.updateDataset({ code: config.code, name: config.name, data: _res?.data })
+            this.updateDataset({ code: config.code, title: config.title, data: _res?.data })
           }
           config = this.dataFormatting(config, _res)
           if (this.chart) {

+ 29 - 20
data-room-ui/packages/js/store/actions.js

@@ -17,32 +17,41 @@ export default {
         // 配置兼容
         const pageInfo = handleResData(data)
         // 兼容边框配置
-        pageInfo.chartList.forEach((item) => {
-          if (item.dataSource) {
-            item.dataSource.source = item.dataSource?.source || 'dataset'
+        pageInfo.chartList.forEach((chart) => {
+          if (chart.dataSource) {
+            chart.dataSource.source = chart.dataSource?.source || 'dataset'
           }
 
-          if (!item.border) {
-            item.border = { type: '', titleHeight: 60, fontSize: 16, isTitle: true, padding: [0, 0, 0, 0] }
+          if (!chart.border) {
+            chart.border = { type: '', titleHeight: 60, fontSize: 16, isTitle: true, padding: [0, 0, 0, 0] }
           }
-          if (!item.border.padding) {
-            item.border.padding = [0, 0, 0, 0]
+          if (!chart.border.padding) {
+            chart.border.padding = [0, 0, 0, 0]
           }
-          if (item.type == 'customComponent') {
-            plotSettings[Symbol.iterator] = function * () {
-              const keys = Object.keys(plotSettings)
-              for (const k of keys) {
-                yield [k, plotSettings[k]]
+          let plotSettingsIterator = false
+          if (chart.type == 'customComponent') {
+            // 为本地G2组件配置添加迭代器
+            if (!plotSettingsIterator) {
+              plotSettings[Symbol.iterator] = function * () {
+                const keys = Object.keys(plotSettings)
+                for (const k of keys) {
+                  yield [k, plotSettings[k]]
+                }
               }
             }
-            for (const [key, value] of plotSettings) {
-              if (item.name == value.name) {
-                const settings = JSON.parse(JSON.stringify(value.setting))
-                item.setting = settings.map((x) => {
-                  const index = item.setting.findIndex(y => y.field == x.field)
-                  x.field = item.setting[index].field
-                  x.value = item.setting[index].value
-                  return x
+            for (const [key, localPlotSetting] of plotSettings) {
+              if (chart.name == localPlotSetting.name) {
+                // 本地配置项
+                const localSettings = JSON.parse(JSON.stringify(localPlotSetting.setting))
+                chart.setting = localSettings.map((localSet) => {
+                  // 在远程组件配置中找到 与 本地组件的配置项 相同的项索引
+                  const index = chart.setting.findIndex(remoteSet => remoteSet.field == localSet.field)
+                  if (index !== -1) {
+                    // 使用远程的值替换本地值
+                    localSet.field = chart.setting[index].field
+                    localSet.value = chart.setting[index].value
+                  }
+                  return localSet
                 })
               }
             }

+ 23 - 2
data-room-ui/packages/js/store/mutations.js

@@ -14,6 +14,7 @@ import { defaultData } from './state'
 import moment from 'moment'
 import { randomString } from 'data-room-ui/js/utils'
 import { EventBus } from 'data-room-ui/js/utils/eventBus'
+import CloneDeep from 'lodash-es/cloneDeep'
 export default {
   // 改变页面基本信息,后端请求的页面信息存储到此处
   changePageInfo (state, pageInfo) {
@@ -372,11 +373,27 @@ export default {
   },
   // 更新数据集库中的内容
   updateDataset (state, res) {
-    Vue.set(state.dataset, res.name + res.code, res.data)
+    // 如果只是更新了组件的标题
+    if (res.oldTitle && state.dataset.hasOwnProperty(res.oldTitle + '_' + res.code)) {
+      const _dataset = CloneDeep(state.dataset)
+      _dataset[res.title + '_' + res.code] = _dataset[res.oldTitle + '_' + res.code]
+      delete _dataset[res.oldTitle + '_' + res.code]
+      state.dataset = CloneDeep(_dataset)
+    } else {
+      Vue.set(state.dataset, res.title + '_' + res.code, res.data)
+    }
   },
   // 更新数据集库中的内容
   updateComputedDatas (state, res) {
-    Vue.set(state.computedDatas, res.name + res.code, res.data)
+    // 如果只是更新了组件的标题
+    if (res.oldTitle && state.computedDatas.hasOwnProperty(res.oldTitle + '_' + res.code)) {
+      const _computedDatas = CloneDeep(state.computedDatas)
+      _computedDatas[res.title + '_' + res.code] = _computedDatas[res.oldTitle + '_' + res.code]
+      delete _computedDatas[res.oldTitle + '_' + res.code]
+      state.computedDatas = CloneDeep(_computedDatas)
+    } else if (res.isExpression) {
+      Vue.set(state.computedDatas, res.title + '_' + res.code, res.data)
+    }
   },
   // 清空数据集库
   emptyDataset (state) {
@@ -385,6 +402,10 @@ export default {
   // 清空数据集库
   emptyComputedDatas (state) {
     state.computedDatas = {}
+  },
+  // 修改磁吸状态
+  snapChange (state, snap) {
+    state.snapTolerance = snap
   }
 }
 function deldataset (state, type, codes) {

+ 3 - 1
data-room-ui/packages/js/store/state.js

@@ -68,7 +68,9 @@ export const defaultData = {
   // 页面上所有组件的数据集的数据信息
   dataset: {},
   // 页面上所有组件的数据集的数据信息
-  computedDatas: {}
+  computedDatas: {},
+  // 是否开启磁吸
+  snapTolerance: 3
 }
 
 export default () => ({