DesignDatavItem.vue 11.5 KB
<template>
  <vue-draggable-resizable
      :style="{position:'absolute',cursor:'move'}"
      :w="element.width?parseInt(element.width):0"
      :h="element.height"
      :x="element.x"
      :y="element.y"
      :min-width="5"
      :min-height="5"
      :parent="true"
      :grid="[10,10]"
      :z="element.zIndex?parseInt(element.zIndex):0"
      class-name="dragging"
      :class="((selectWidget && selectWidget.key == element.key) || selectWidgetMap[element.key])?'active':''"
      :key="switchStatus"
      @dragging="onDrag"
      @resizing="onResize"
      @dragstop="onDragstop"
      @resizestop="onResizstop"
      @activated="onActivated"
    >
    <div class="widget-form-item" :style="'margin:0px'" :label="element.name" @click.ctrl="handleClickCtrl(index)">
      <div class="widget-mask" @click.capture="handleSelectWidget(index)"></div>
      <div
        class="widget-view"
        v-if="element && element.key"
        :class="{active: ((selectWidget && selectWidget.key == element.key) || selectWidgetMap[element.key])}"
        :label="element.name"
      >
        <template v-if="element.type == 'chart'">
          <EchartItem :height="element.height+'px'" :width="element.width+'px'" :key="getEleKey(element)" :options="element.options" />
        </template>
        <template v-if="element.alias == 'ring-chart'">
          <dv-active-ring-chart :config="element.options.config" :style="'width:'+(element.width-15)+'px;height:'+element.height+'px;'" :key="getEleKey(element)"/>
        </template>
        <template v-if="element.alias == 'capsule-chart'">
          <dv-capsule-chart :config="element.options.config" :style="'width:'+(element.width-15)+'px;height:'+element.height+'px;'" :key="getEleKey(element)" />
        </template>
        <template v-if="element.alias == 'water-level-pond'">
          <dv-water-level-pond :config="element.options.config" :style="'width:'+(element.width-15)+'px;height:'+element.height+'px;'" :key="getEleKey(element)" />
        </template>
        <template v-if="element.alias == 'percent-pond'">
          <dv-percent-pond :config="element.options.config" :style="'width:'+(element.width-15)+'px;height:'+element.height+'px;'" :key="getEleKey(element)" />
        </template>
        <template v-if="element.alias == 'flyline-chart'">
          <dv-flyline-chart :config="element.options.config" :style="'width:'+(element.width-15)+'px;height:'+element.height+'px;'" :key="getEleKey(element)" />
        </template>
        <template v-if="element.alias == 'flyline-chart-enhanced'">
          <dv-flyline-chart-enhanced :config="element.options.config" :dev="true" :style="'width:'+(element.width-15)+'px;height:'+element.height+'px;'" :key="getEleKey(element)" />
        </template>
        <template v-if="element.alias == 'conical-column-chart'">
          <dv-conical-column-chart :config="element.options.config" :style="'width:'+(element.width-15)+'px;height:'+element.height+'px;'" :key="getEleKey(element)" />
        </template>
        <template v-if="element.alias == 'digital-flop'">
          <dv-digital-flop :config="element.options.config" :style="'width:'+(element.width-15)+'px;height:'+element.height+'px;'" :key="getEleKey(element)" />
        </template>
        <template v-if="element.alias == 'scroll-board'">
          <dv-scroll-board :config="element.options.config" :style="'width:'+(element.width-15)+'px;height:'+element.height+'px;'" :key="getEleKey(element)" />
        </template>
        <template v-if="element.alias == 'scroll-ranking-board'">
          <dv-scroll-ranking-board :config="element.options.config" :style="'width:'+(element.width-15)+'px;height:'+element.height+'px;'" :key="getEleKey(element)" />
        </template>
        <template v-if="element.type == 'decoration' || element.alias.indexOf('decoration')===0">
          <dv-decoration :width="parseInt(element.width)-15" :height="parseInt(element.height)" :element="element" :key="getEleKey(element)"></dv-decoration>
        </template>
        <template v-if="element.type == 'border'">
          <dv-border-box :width="parseInt(element.width)-15" :height="parseInt(element.height)" :element="element" :key="getEleKey(element)"></dv-border-box>
        </template>
        <template v-if="element.alias == 'display-text'">
          <Display-text :config="element.options.config" :style="'width:'+(element.width-15)+'px;height:'+element.height+'px;lineHeight:'+element.height+'px;'" :key="getEleKey(element)" />
        </template>

        <template v-if="element.alias == 'localtime'">
          <Local-time :config="element.options.config" :style="'width:'+(element.width-15)+'px;height:'+element.height+'px;lineHeight:'+element.height+'px;'" :key="getEleKey(element)" />
        </template>
      </div>
    </div>

  </vue-draggable-resizable>
</template>

<script>
import VueDraggableResizable from 'vue-draggable-resizable';
import 'vue-draggable-resizable/dist/VueDraggableResizable.css';
import EchartItem from "@/components/portal/echart/EchartItem.vue";
import LocalTime from "@/components/portal/datav/LocalTime.vue";
import DisplayText from "@/components/portal/datav/DisplayText.vue";
import DvDecoration from "@/components/portal/datav/DvDecoration.vue";
import DvBorderBox from "@/components/portal/datav/DvBorderBox.vue";
export default {
  props:{
    element: {
      type: Object,
      default: {}
    },
    select: {
      type: Object,
      default: {}
    },
    index: {
      type: Number,
      default: 0
    },
    data: {
      type: Object,
      default: {}
    },
    selectKeyMap: {
      type: Object,
      default: {}
    },
  },
  components: {
    EchartItem,
    VueDraggableResizable,
    LocalTime,
    DisplayText,
    DvDecoration,
    DvBorderBox,
  },
  data() {
    return {
      selectWidget: this.select,
      x: 0,
      y: 0,
      itemStyle:'',
      menuVisible:false,
      top: 0,
      left: 0,
      switchStatus:'single',
      selectIndex:-1,
      selectWidgetMap:this.selectKeyMap,
    };
  },
  methods: {
    onResize: function(x, y, width, height) {
        this.selectWidget = this.element;
        this.selectWidget.x = parseInt(x);
        this.selectWidget.y = parseInt(y);
        this.selectWidget.width = parseInt(width);
        this.selectWidget.height = parseInt(height);
    },
    onDrag: function(x, y) {
      this.selectWidget = this.element;
      this.selectWidget.x = parseInt(x);
      this.selectWidget.y = parseInt(y);
      this.$emit('onDrag',parseInt(x),parseInt(y))
    },
    onDragstop: function(x, y) {
      if(this.selectWidget && this.selectWidget.key == this.element.key){
        this.$set(this.selectWidget,'x', parseInt(x));
        this.$set(this.selectWidget,'y', parseInt(y));
        if(this.element.type != 'chart'){
          this.getItemStayle(this.selectWidget.width, this.selectWidget.height, this.selectWidget.zIndex);
        }
      }
      this.$emit('onDragstop',parseInt(x),parseInt(y))
    },
    onResizstop: function(x, y) {
      this.selectWidget = this.element;
      this.$set(this.selectWidget,'x', parseInt(x));
      this.$set(this.selectWidget,'y', parseInt(y));
    },
    onActivated: function(x, y) {
    },
    handleSelectWidget(index) {
      if(!window.event.ctrlKey){
        this.selectIndex = index;
        this.selectWidget = this.data.list[index];
        this.selectWidgetMap = {};
        this.switchStatus = 'single';
      }
    },
    handleWidgetDelete(index) {
      if (this.data.list.length - 1 === index) {
        if (index === 0) {
          this.selectWidget = {};
        } else {
          this.selectWidget = this.data.list[index - 1];
        }
      } else {
        this.selectWidget = this.data.list[index + 1];
      }

      this.$nextTick(() => {
        this.data.list.splice(index, 1);
      });
    },
    handleWidgetRank(index){

    },
    handleWidgetClone(index) {
      let cloneData = {
        ...this.data.list[index],
        options: { ...this.data.list[index].options },
        key: Date.parse(new Date()) + "_" + Math.ceil(Math.random() * 99999)
      };
      this.data.list.splice(index, 0, cloneData);

      this.$nextTick(() => {
        this.selectWidget = this.data.list[index + 1];
      });
    },
    getItemStayle(width, height, zIndex){
      let itemStyle =  'width:'+(width-15)+'px;height:'+height+'px;';
      if(zIndex){
        itemStyle += 'z-index:'+zIndex+';';
      }
      this.itemStyle =  itemStyle;
    },
    getFontStyle(obj){
      if(obj.options.config.isDiyStyle && obj.options.config.diyStyle){
        return JSON.parse(obj.options.config.diyStyle);
      }else{
        return {fontSize:obj.options.config.text.fontSize,color:obj.options.config.text.color,fontWeight:obj.options.config.text.fontWeight};
      }
    },
    getEleKey(element){
      const key = element.key+element.width+(element.zIndex?element.zIndex:0)+''+element.state+''+Math.ceil(Math.random() * 99999);
      return key;
    },
    handleClickCtrl(index) {
      const key = this.data.list[index].key;
      if(this.selectWidgetMap[key] === true){
        this.$set(this.selectWidgetMap, key, false);
      }else{
        this.$set(this.selectWidgetMap, key, true);
      }
      this.selectWidget = null;
      this.switchStatus = 'multiple';
    },
    getTextContent(ele){
      const content = ele.options.config.text.content;
      const formatter = ele.options.config.text.formatter;
      if(content!='' && content != null && formatter){
        return this.execReplace(formatter, content);
      }
      return content;
    },
    execReplace(formatterText,replacement){
        return formatterText.replace(new RegExp("\\{c\\}",'g'),replacement);
    },
  },
  watch: {
    select:{
       handler(val) {
        this.selectWidget = val;
      },
      deep: true
    },
    selectWidget: {
      handler(val) {
        this.menuVisible = false;
        this.$emit("update:select", val);
      },
      deep: true
    },
    selectKeyMap:{
       handler(val) {
        this.selectWidgetMap = val;
      },
      deep: true
    },
    selectWidgetMap: {
      handler(val) {
        this.$emit("update:selectKeyMap", val);
      },
      deep: true
    },
    'element.width': {
      handler (nval) {
        this.menuVisible = false;
        if(this.element.type != 'chart'){
          this.getItemStayle(nval, this.element.height, this.element.zIndex);
        }
      }
    },
    'element.height': {
      handler (nval) {
        this.menuVisible = false;
        if(this.element.type != 'chart'){
          this.getItemStayle(this.element.width, nval, this.element.zIndex);
        }
      }
    },
    menuVisible(value) {
      if (value) {
        document.body.addEventListener('click', this.closeMenu)
      } else {
        document.body.removeEventListener('click', this.closeMenu)
      }
    }
  }
};
</script>
<style lang="scss" scoped>
@import "@/assets/css/form-editor.scss";

div.widget-view {
  // padding: 10px 0;
  position: relative;
  overflow: hidden;
  cursor:move;
}

.widget-view.active {
  outline: 2px solid $--color-primary;
}

.text-event {
  float: left;
  height: 99%;
  width: 99%;
  position: relative;
}
// .dragging >>> .handle {
//   border: 1px solid #409eff;
// }
.dragging >>> .handle-tl {
  left: 0px;
  top: -2px;
}
.dragging >>> .handle-tr {
  right: 0px;
  top: -2px;
}
.dragging >>> .handle-tm {
  top: -2px;
}
.dragging >>> .handle-br {
  right: -2px;
  bottom: -15px;
}
.dragging >>> .handle-bl {
  left: -0px;
}
.dragging >>> .handle-ml {
  left: -2px;
}
.dragging >>> .handle-mr {
  right: -2px;
}
.dragging >>> .handle-bm {
  bottom: -18px;
}
.dragging >>> .handle-bl {
  left: -2px;
  bottom: -15px;
}
</style>