<template>
  <div class="newbi-bigdata">
    <!-- 顶部操作条 -->
    <div class="top-panel">
      <div class="ret" @click="onGoIndex">
        <i class="el-icon-back" style="margin-right: 3px"></i>返回首页
      </div>
      <div class="left">
        <el-popover
          placement="bottom-start"
          trigger="click"
          v-for="group of chartLib"
          :key="group.group"
          width="50%"
          popper-class="bigdata-chart-list"
        >
          <template #reference>
            <div class="group">
              <i :class="['el-icon', group.icon]"></i>{{ group.group }}
            </div>
          </template>
          <div @dragstart="handleDragStart">
            <div
              class="chart"
              v-for="chart of group.charts"
              :key="chart.name"
              :data-index="JSON.stringify(chart)"
              draggable
              @click="onAddChart(chart)"
            >
              <img :src="chart.img" alt="" style="pointer-events: none" />
              <div class="name">{{ chart.title }}</div>
            </div>
          </div>
        </el-popover>
      </div>
      <div style="flex: 1"></div>
      <div class="right">
        <el-button size="mini" type="primary" plain @click="some">
          测试
        </el-button>
        <el-button
          size="mini"
          type="primary"
          plain
          @click="onBigdataSave"
          icon="el-icon-folder-checked"
          style="margin-right: 30px"
        >
          保存大屏
        </el-button>
        <span style="font-size: 14px">缩放</span>
        <el-slider
          style="width: 100px; margin: 0 10px"
          v-model="scale"
          :step="5"
          :min="50"
          :max="200"
        >
        </el-slider>
      </div>
    </div>
    <div class="main-panel">
      <div :class="{ 'left-panel': 1, active: showLeftPanel }">
        <div class="tabs">
          <div class="tab active">选择图层</div>
        </div>
        <!-- 已添加组件列表 -->
        <div class="slide-panel chart-list">
          <div
            :class="{ item: 1, active: !nowChart }"
            @click="onSelectBg"
            style="background-color: #f3f3f3"
          >
            背景
          </div>
          <div
            :class="{ item: 1, active: chart.select }"
            v-for="chart of chartList"
            :key="chart.title"
            @click="onSelectChart(chart)"
          >
            {{ chart.title }}
          </div>
        </div>
        <div class="toggle left-toggle" @click="showLeftPanel = !showLeftPanel">
          <i class="el-icon el-icon-caret-right" v-if="!showLeftPanel"></i>
          <i class="el-icon el-icon-caret-left" v-else></i>
        </div>
      </div>
      <div class="center-panel" @wheel="handleWheel">
        <div class="center" :style="centerStyle">
          <div
            id="my-canvas"
            :style="canvasStyle"
            @click="onSelectBg"
            @drop="handleDrop"
            @dragover="handleDragOver"
            @contextmenu="showBgMenu($event)"
          >
            <base-chart
              v-for="chart of chartList"
              v-bind="chart"
              :key="chart.key"
              @click.native.stop="onSelectChart(chart)"
              @contextmenu.native.stop="showMenu($event, chart)"
              :ref="chart.key"
              :config="chart.dataconfig"
              :index="chart.key"
              :nowChart="nowChart"
              :scale="scale"
              :isEdit="true"
              :charts="chartList"
              @getRefLineParams="getRefLineParams"
            ></base-chart>
            <span
              class="ref-line v-line"
              v-for="(item, i) in vLine"
              :key="i"
              v-show="item.display"
              :style="{
                left: item.position,
                top: item.origin,
                height: item.lineLength,
              }"
            />
            <span
              class="ref-line h-line"
              v-for="(item, i) in hLine"
              :key="i"
              v-show="item.display"
              :style="{
                top: item.position,
                left: item.origin,
                width: item.lineLength,
              }"
            />
          </div>
        </div>
      </div>
      <div
        :class="{
          'right-panel': 1,
          active: showRightPanel,
          high: highRightPanel,
        }"
      >
        <div
          class="toggle right-toggle"
          @click="showRightPanel = !showRightPanel"
        >
          <i class="el-icon el-icon-caret-left" v-if="!showRightPanel"></i>
          <i class="el-icon el-icon-caret-right" v-else></i>
        </div>
        <!-- 组件设置 -->
        <template v-if="nowChart">
          <div class="tabs">
            <div
              :class="{ tab: 1, active: rightPanelIndex == 0 }"
              @click="rightPanelIndex = 0"
            >
              组件设置
            </div>
            <div
              v-if="nowChart.dataconfig"
              :class="{ tab: 1, active: rightPanelIndex == 1 }"
              @click="rightPanelIndex = 1"
            >
              数据设置
            </div>
          </div>
          <!-- 组件样式设置 -->
          <div
            class="slide-panel slide-style-panel"
            v-show="rightPanelIndex == 0"
          >
            <style-common
              :site="nowChart.site"
              :chart="nowChart"
              :bigdataOption="bigdataOption"
            ></style-common>
            <component
              :is="nowChart.name + '-option'"
              :option="nowChart.option"
              :nowChart="nowChart"
            ></component>
            <template v-if="nowChart.optionSet">
              <component
                v-for="name of nowChart.optionSet"
                :key="name"
                :is="name"
                :option="nowChart.option"
              ></component>
            </template>
          </div>
          <!-- 组件数据设置 -->
          <div
            class="slide-panel"
            v-show="rightPanelIndex == 1"
            style="padding: 0"
          >
            <data-setting
              v-if="nowChart.dataconfig"
              :config="nowChart.dataconfig"
              :option="nowChart.option"
              :modalSet="nowChart.modalSet"
              :cube-list="cubeList"
              :apiList="apiList"
              :rightPanelIndex="rightPanelIndex"
              :showRightPanel="showRightPanel"
              @toggleHigh="toggleHigh"
              @preview="onChartPreview"
              @refresh="getDataList"
            ></data-setting>
          </div>
        </template>
        <!-- 大屏背景设置 -->
        <template v-else>
          <div class="tabs">
            <div class="tab active">大屏设置</div>
          </div>
          <div class="bigdata-set-panel">
            <div class="setting-title" style="border-top: none">
              <div>背景设置</div>
            </div>
            <div class="settings">
              <el-form size="mini" label-width="80px">
                <el-form-item label="大屏宽度">
                  <el-input
                    type="number"
                    v-model="bigdataOption.width"
                  ></el-input>
                </el-form-item>
                <el-form-item label="大屏高度">
                  <el-input
                    type="number"
                    v-model="bigdataOption.height"
                  ></el-input>
                </el-form-item>
                <el-form-item label="背景颜色">
                  <el-color-picker
                    v-model="bigdataOption.bgColor"
                    show-alpha
                    size="mini"
                  ></el-color-picker>
                </el-form-item>
                <el-form-item label="背景图片">
                  <img
                    v-if="bigdataOption.bgImg"
                    :src="bigdataOption.bgImg"
                    alt=""
                    width="100%"
                  />
                  <el-input v-model="bigdataOption.bgImg">
                    <div slot="append" @click="handleOpenImg">
                      <i class="iconfont icon-img"></i>
                    </div>
                  </el-input>
                </el-form-item>
                <el-form-item label="预览页面开启配置按钮" label-width="166px">
                  <el-switch v-model="bigdataOption.editSwitch"></el-switch>
                </el-form-item>
              </el-form>
            </div>
            <div class="form">
              <el-form size="mini" label-width="80px">
                <el-form-item label="大屏名称">
                  <el-input v-model="bigdataForm.title"></el-input>
                </el-form-item>
                <el-form-item label="大屏分类">
                  <el-cascader
                    v-model="bigdataForm.category"
                    :options="categoryList"
                    :props="{
                      expandTrigger: 'hover',
                      emitPath: false,
                      value: 'id',
                      label: 'categoryValue',
                    }"
                    :show-all-levels="false"
                  ></el-cascader>
                </el-form-item>
              </el-form>
              <el-button
                class="btn"
                type="primary"
                size="small"
                icon="el-icon-folder-checked"
                @click="onBigdataSave"
              >
                保存
              </el-button>
            </div>
          </div>
        </template>
      </div>
    </div>
    <vue-context-menu
      :contextMenuData="contextMenuData"
      @del="onChartDel"
      @copy="onChartCopy"
      @copynow="onChartCopynow"
    ></vue-context-menu>
    <vue-context-menu
      :contextMenuData="contextBgMenuData"
      @paste="onChartPaste"
    ></vue-context-menu>
    <imglist ref="imglist" @change="handleSetimg"></imglist>
  </div>
</template>
<script>
import baseChart from "../comps/baseChart.vue";
import styleCommon from "../comps/styleCommon.vue";
import dataSetting from "../comps/dataSetting.vue";
import chartLib from "../../../newCharts/loadCharts";
import styleLib from "../../../newStyles/load";
import util from "../../../util/wey";
import 'vue3-draggable-resizable/dist/Vue3DraggableResizable.css'
import {
  cubeList,
  categoryList as cubeCategoryList,
} from "../../../api/newbi/dataset";
import {
  categoryList,
  bigdataSave,
  bigdataDetail,
  chartDetail,
  chartDel,
} from "../../../api/newbi/bigdata";
import { dataapiList, dataapicategoryList } from "../../../api/report/report";
import {
  fieldDateFormats,
  dateTypeMap,
  columnKeys,
  defaultFieldExtJson,
} from "../dict";
import { objkey, uploadImg } from "../../../api/bigdata/visual";
import imglist from "../comps/imglist.vue";
export default {
  components: { baseChart, styleCommon, dataSetting, imglist },
  data() {
    return {
      vLine: [],
      hLine: [],
      fieldDateFormats,
      dateTypeMap,
      showLeftPanel: false,
      showRightPanel: true,
      highRightPanel: false,
      scale: 100,
      chartList: [],
      nowChart: null,
      rightPanelIndex: 0,
      chartLib,
      styleLib,
      contextMenuData: {
        menuName: "chart",
        axis: { x: null, y: null },
        menulists: [
          { btnName: "本页复制", fnHandler: "copynow" },
          { btnName: "跨屏复制", fnHandler: "copy" },
          { btnName: "删除组件", fnHandler: "del" },
        ],
      },
      contextBgMenuData: {
        menuName: "bg",
        axis: { x: null, y: null },
        menulists: [{ btnName: "粘贴组件", fnHandler: "paste" }],
      },
      cubeList: [],
      apiList: [],
      editType: "add",
      bigdataId: 0,
      bigdataForm: {},
      bigdataOption: {
        bgColor: "#ffffff",
        bgImg: "",
        width: 1920,
        height: 1080,
        editSwitch: false,
      },
      categoryList: [],
      columnKeys,
      oldIndex: 0,
      canRefresh: false,
      defaultCube: "",
    };
  },
  computed: {
    canvasStyle() {
      let { width, height, bgColor, bgImg } = this.bigdataOption;
      return {
        backgroundColor: bgColor,
        width: width + "px",
        height: height + "px",
        transform: `scale(${this.scale / 100})`,
        backgroundImage: bgImg ? `url(${bgImg})` : "none",
      };
    },
    centerStyle() {
      let { width, height } = this.bigdataOption;
      return {
        height: (height * this.scale) / 100 + 100 + "px",
        width: (width * this.scale) / 100 + 100 + "px",
      };
    },
  },
  watch: {
    showRightPanel(flag) {
      if (!flag) {
        this.highRightPanel = false;
      }
    },
    rightPanelIndex(index) {
      if (!index) {
        this.highRightPanel = false;
      }
    },
    nowChart(chart) {
      if (!chart) {
        this.highRightPanel = false;
      } else {
        this.showRightPanel = true;
      }
    },
  },
  async created() {
    this.getDataList();
    let { id, cg, ds } = this.$route.query;
    if (ds) {
      this.defaultCube = parseInt(ds);
    }
    if (!id) {
      this.editType = "add";
      this.bigdataForm = {
        backgroundUrl: "",
        category: "",
        content: "",
        title: "",
      };
      if (cg) {
        this.bigdataForm.category = parseInt(cg);
      }
    } else {
      this.editType = "update";
      bigdataDetail({ id }).then((res) => {
        let { content, backgroundUrl, category, title, componentIds } =
          res.data.data;
        this.bigdataForm = {
          id: id,
          content,
          backgroundUrl,
          category,
          title,
        };
        let option = JSON.parse(content);
        this.bigdataOption = Object.assign({ editSwitch: false }, option);
        let tasks = componentIds.map((id) => this.chartBackfill(id));
        Promise.all(tasks).then(this.initPreview);
      });
    }
    // 获取大屏分类列表
    categoryList({ size: 100000, current: 1 }).then((res) => {
      let list = res.data.data.records;
      let categoryList = list.filter((i) => !i.parentId);
      list.forEach((i) => {
        if (i.parentId) {
          let parent = categoryList.find((j) => j.id == i.parentId);
          if (!parent) return;
          if (!parent.children) {
            parent.children = [];
          }
          parent.children.push(i);
        }
      });
      this.categoryList = categoryList;
    });
  },
  mounted() {
    this.$bus.on("previewAll", this.previewAll);
    //   window.addEventListener("beforeunload", (e) => {
    //     this.beforeunloadHandler(e);
    //   });
    // },
    // destroyed() {
    //   window.removeEventListener("beforeunload", (e) => {
    //     this.beforeunloadHandler(e);
    //   });
  },
  methods: {
    // 组件初始化预览
    initPreview() {
      this.chartList.forEach((i) => {
        if (!this.$refs[i.key]) return;
        this.$refs[i.key][0].initPreview();
      });
    },
    getRefLineParams(params) {
      const { vLine, hLine } = params;
      this.vLine = vLine;
      this.hLine = hLine;
    },
    some() {
      console.log(JSON.parse(JSON.stringify(this.chartList)));
    },
    // 全部组件预览
    previewAll(list) {
      this.chartList.forEach((i) => {
        let has = list.find((j) =>
          j.chartList.find((k) => k.chartKey == i.key)
        );
        if (has) {
          if (!this.$refs[i.key]) return;
          this.$refs[i.key][0].preview(true, false, list);
        }
      });
    },
    getDataList() {
      // 获取数据集列表
      cubeCategoryList({ current: 1, size: 10000 }).then((res) => {
        let category = res.data.data.records;
        category.forEach((item) => {
          item.parent = category.find((i) => i.id == item.parentId);
        });
        let finalCategory = category.map((item) => {
          let value = item.id;
          let label = item.wsName;
          let parent = item.parent;
          while (parent) {
            label = parent.wsName + " / " + label;
            parent = parent.parent;
          }
          return { value, label };
        });
        cubeList({ current: 1, size: 100000 }).then((res) => {
          let list = res.data.data.records;
          this.cubeList = finalCategory
            .map((item) => {
              return {
                ...item,
                children: list
                  .filter((j) => j.workspaceId == item.value)
                  .map((k) => ({ label: k.cubeName, value: k.id })),
              };
            })
            .filter((i) => i.children.length);
        });
      });
      // 获取api列表
      dataapicategoryList().then((res) => {
        let category = res.data.data;
        dataapiList({ apiFormal: 1, apiType: 1 }).then((res) => {
          let list = res.data.data;
          this.apiList = category
            .map((i) => {
              return {
                label: i.categoryName,
                value: i.id,
                children: list
                  .filter((j) => j.categoryId == i.id)
                  .map((k) => ({ label: k.apiName, value: k.id })),
              };
            })
            .filter((i) => i.children.length);
        });
      });
    },
    beforeunloadHandler(e) {
      if (this.canRefresh) return;
      e = e || window.event;
      if (e) {
        e.returnValue = "您是否确认离开此页面-您输入的数据可能不会被保存";
      }
      return "您是否确认离开此页面-您输入的数据可能不会被保存";
    },
    onGoIndex() {
      window.open(this.$router.resolve({ path: "/" }).href, "_blank");
    },
    // 本页复制组件
    onChartCopynow() {
      let copyChart = JSON.parse(JSON.stringify(this.nowChart));
      delete copyChart.id;
      copyChart.key = util.getRandomStr(10);
      copyChart.site.x = 0;
      copyChart.site.y = 0;
      this.chartList.push(copyChart);
      this.nowChart = copyChart;
      this.$nextTick(this.onChartPreview);
      this.$message({ message: "组件复制成功", type: "success" });
    },
    // 跨屏复制组件
    onChartCopy() {
      let copyChart = JSON.parse(JSON.stringify(this.nowChart));
      delete copyChart.id;
      copyChart.key = util.getRandomStr(10);
      localStorage.setItem("copyChart", JSON.stringify(copyChart));
      localStorage.setItem("copyFlag", 1);
      this.$message({ message: "组件复制成功", type: "success" });
    },
    // 粘贴组件
    onChartPaste() {
      let flag = localStorage.getItem("copyFlag");
      if (parseInt(flag)) {
        let copyChart = JSON.parse(localStorage.getItem("copyChart"));
        copyChart.site.x = 0;
        copyChart.site.y = 0;
        this.chartList.push(copyChart);
        localStorage.setItem("copyFlag", 0);
        this.nowChart = copyChart;
        this.$nextTick(this.onChartPreview);
      } else {
        this.$message({ message: "请先选择组件进行复制", type: "warning" });
      }
    },
    // 打开背景右键菜单
    showBgMenu(event) {
      event.preventDefault();
      let x = event.clientX;
      let y = event.clientY;
      this.contextBgMenuData.axis = { x, y };
    },
    // 选择背景图
    handleOpenImg() {
      this.$refs.imglist.openImg(this.bigdataOption.bgImg, "background");
    },
    handleSetimg(img) {
      this.bigdataOption.bgImg = img;
    },
    // 组件配置回填
    chartBackfill(id) {
      return new Promise((resolve, reject) => {
        chartDetail({ id }).then((res) => {
          let {
            columnJson,
            filterJson,
            sortJson,
            limitVal,
            content,
            id,
            name,
            title,
            cubeDataId,
            useType,
            extJson,
          } = res.data.data;
          let { option, site, params, key } = JSON.parse(content);
          site.hiddened = site.hiddened || false;
          option.intervalSwitch = option.intervalSwitch || false;
          option.intervalTime = option.intervalTime || 5000;
          let chartList = this.chartLib.reduce(
            (r, i) => r.concat(i.charts),
            []
          );
          let chartSet = chartList.find((i) => i.name == name);
          // 组件构建
          let nowChart = {
            name,
            title: title || chartSet.title,
            option,
            site,
            id,
            select: false,
            key: key || util.getRandomStr(10),
            ext: JSON.parse(extJson || "{}"),
          };
          // 数据配置
          if (chartSet.dataconfig) {
            let { modalSet } = chartSet;
            nowChart.dataconfig = {
              dataType: useType,
              category: "",
              dataId: cubeDataId,
              limit: limitVal || 1000,
              params: params || [],
              zuanFlag: nowChart.ext.zuanFlag || false,
              zuan: nowChart.ext.zuanList || [],
              zuanLevel: 0,
              zuanStack: [],
            };
            nowChart.modalSet = modalSet;
            columnJson = JSON.parse(columnJson);
            columnJson.forEach((i) => {
              i.zuan = i.zuan || false;
              let ext = JSON.parse(i.extJson || "{}");
              i.extJson = Object.assign({}, defaultFieldExtJson, ext);
            });
            modalSet.forEach((set) => {
              nowChart.dataconfig[set.key] = columnJson.filter(
                (i) => i.type == set.key
              );
            });
            nowChart.dataconfig.filter = JSON.parse(filterJson).map((field) => {
              let {
                column,
                conditions,
                connectTime,
                connectType,
                asFilter,
                enumSource,
                enumId,
              } = field;
              let r = {
                conditions,
                connectTime,
                connectType,
                ...column,
                options: [],
                asFilter: asFilter === undefined ? true : asFilter,
                enumSource,
                enumId,
              };
              if (r.viewDataType == "DATETIME") {
                r.dateType = this.dateTypeMap[r.timeDataFormat];
                r.dateFormat = this.fieldDateFormats.find(
                  (i) => i.value == r.timeDataFormat
                ).label;
              }
              return r;
            });
            nowChart.dataconfig.sort = JSON.parse(sortJson).map((i) => {
              return {
                orderType: i.orderType,
                ...i.column,
              };
            });
          }
          // 样式配置
          if (chartSet.optionSet) {
            chartSet.optionSet.forEach((name) => {
              let set = this.styleLib.find((i) => i.name == name);
              if (!set) return;
              nowChart.option = Object.assign(
                {},
                JSON.parse(JSON.stringify(set.options)),
                nowChart.option
              );
            });
            nowChart.optionSet = JSON.parse(JSON.stringify(chartSet.optionSet));
          }
          this.chartList.push(nowChart);
          resolve();
        });
      });
    },
    // 当前组件预览
    onChartPreview() {
      this.$refs[this.nowChart.key][0].preview(true, false, [], true);
    },
    // 保存大屏背景图
    async saveBg() {
      let canvas = await this.$Screenshot(
        document.querySelector("#my-canvas"),
        { scale: 2 }
      );
      let file = this.dataURLtoFile(
        canvas.toDataURL("image/jpeg", 1.0),
        new Date().getTime() + ".jpg"
      );
      let formdata = new FormData();
      formdata.append("file", file);
      return uploadImg(formdata);
    },
    // 保存大屏，整理数据
    async onBigdataSave() {
      let { category, title } = this.bigdataForm;
      if (!category) {
        return this.$message({ message: "请选择大屏分类", type: "warning" });
      }
      if (!title) {
        return this.$message({ message: "请填写大屏名称", type: "warning" });
      }
      let componentList = this.chartList.map((chart) => {
        let contentObj = {};
        let customList = this.$refs[chart.key][0].beforeSave();
        if (customList && customList.length) {
          contentObj = customList.reduce(
            (r, i) => Object.assign(r, { [i.key]: i.value }),
            contentObj
          );
        }
        let { dataconfig, modalSet, option, site, name, id, title, key, ext } =
          chart;
        let params = (dataconfig && dataconfig.params) || [];
        let nowConfig = {
          component: {
            content: JSON.stringify({
              ...contentObj,
              option,
              site,
              params,
              key,
            }),
            name,
            title,
          },
        };
        if (modalSet) {
          nowConfig.component.limitVal = dataconfig.limit;
          nowConfig.component.useType = dataconfig.dataType;
          nowConfig.component.cubeDataId = dataconfig.dataId;
          let columnList = modalSet.reduce((r, s) => {
            return r.concat(
              dataconfig[s.key].map((i) => ({ ...i, type: s.key }))
            );
          }, []);
          columnList = util.filterFields(columnList, this.columnKeys);
          columnList.map((i) => {
            i.extJson = JSON.stringify(i.extJson || {});
          });
          let filterList = dataconfig.filter.map((filter) => {
            return {
              column: util.filterFields([filter], this.columnKeys)[0],
              connectTime: filter.connectTime,
              connectType: filter.connectType,
              conditions: filter.conditions,
              dateType: filter.dateType,
              dateFormat: filter.dateFormat,
              asFilter: filter.asFilter,
              enumSource: filter.enumSource,
              enumId: filter.enumId,
            };
          });
          let sortList = dataconfig.sort.map((sort) => {
            return {
              column: util.filterFields([sort], this.columnKeys)[0],
              orderType: sort.orderType,
            };
          });
          nowConfig.columnList = JSON.stringify(columnList);
          nowConfig.filterList = JSON.stringify(filterList);
          nowConfig.sortList = JSON.stringify(sortList);
          ext.zuanFlag = dataconfig.zuanFlag || false;
          ext.zuanList = dataconfig.zuan || [];
        } else {
          nowConfig.columnList = "";
          nowConfig.filterList = "";
          nowConfig.sortList = "";
        }
        if (id) {
          nowConfig.component.id = id;
        }
        nowConfig.component.extJson = JSON.stringify(ext);
        return nowConfig;
      });
      let visualData = {
        ...this.bigdataForm,
        content: JSON.stringify(this.bigdataOption),
      };
      if (this.bigdataId) {
        visualData.id = this.bigdataId;
      }
      let data = { componentList, visualData };
      let imgRes = await this.saveBg();
      data.visualData.backgroundUrl = imgRes.data.msg;
      bigdataSave(data).then((res) => {
        this.canRefresh = true;
        this.$confirm("保存成功，是否打开预览?", "提示", {
          confirmButtonText: "确定",
          cancelButtonText: "取消",
          type: "success",
        })
          .then(() => {
            let { category } = this.bigdataForm;
            let id = res.data.data;
            localStorage.setItem("bigdataPreviewFlag", 1);
            let routeUrl = this.$router.resolve({
              path: `/newbi/bigdata/preview/${category}/${id}`,
            });
            window.open(routeUrl.href, "_blank");
          })
          .catch(() => {})
          .finally(() => {
            if (this.editType == "add") {
              this.$router.replace("/newbi/bigdata/edit?id=" + res.data.data);
            } else {
              location.reload();
            }
          });
      });
    },
    dataURLtoFile(dataurl, filename) {
      let arr = dataurl.split(","),
        mime = arr[0].match(/:(.*?);/)[1],
        bstr = atob(arr[1]),
        n = bstr.length,
        u8arr = new Uint8Array(n);
      while (n--) {
        u8arr[n] = bstr.charCodeAt(n);
      }
      return new File([u8arr], filename, { type: mime });
    },
    toggleHigh(flag) {
      this.highRightPanel = flag;
    },
    // 删除组件
    onChartDel() {
      let id = this.nowChart.id;
      if (id) {
        this.$confirm("该组件已经保存过，确定删除?", "提示", {
          confirmButtonText: "确定",
          cancelButtonText: "取消",
          type: "warning",
        })
          .then(() => {
            chartDel({ ids: id }).then((res) => {
              this.$message({ type: "success", message: "删除成功!" });
              let index = this.chartList.findIndex((i) => i == this.nowChart);
              this.chartList.splice(index, 1);
              this.nowChart = null;
            });
          })
          .catch(() => {});
      } else {
        let index = this.chartList.findIndex((i) => i == this.nowChart);
        this.chartList.splice(index, 1);
        this.nowChart = null;
      }
    },
    // 打开右键菜单
    showMenu(event, chart) {
      this.nowChart = chart;
      event.preventDefault();
      var x = event.clientX;
      var y = event.clientY;
      this.contextMenuData.axis = { x, y };
    },
    // 选中某个组件时
    onSelectChart(chart) {
      this.chartList.forEach((i) => {
        this.$refs[i.key][0].onSelect("none");
        i.select = false;
      });
      this.nowChart = chart;
      chart.select = true;
      this.$refs[chart.key][0].onSelect("block");
    },
    // 取消选中组件，选中背景
    onSelectBg() {
      this.nowChart = null;
      this.chartList.forEach((i) => {
        this.$refs[i.key][0].onSelect("none");
        i.select = false;
      });
    },
    handleDragStart(e) {
      e.dataTransfer.setData("index", e.target.dataset.index);
    },
    handleDrop(e) {
      e.preventDefault();
      e.stopPropagation();
      const index = e.dataTransfer.getData("index");
      this.onAddChart(JSON.parse(index), e.layerX, e.layerY);
    },
    handleDragOver(e) {
      e.preventDefault();
      e.dataTransfer.dropEffect = "copy";
    },
    handleMouseup(e) {
      console.log(e);
    },
    // 添加一个组件
    onAddChart(chartSet, x = 0, y = 0) {
      let z = this.chartList.reduce((r, i) => Math.max(r, i.site.z), 0) + 1;
      let key = util.getRandomStr(10);
      let {
        name,
        title,
        width,
        height,
        option,
        dataconfig,
        modalSet,
        optionSet,
      } = chartSet;
      let newChart = {
        name,
        title,
        modalSet,
        option: JSON.parse(JSON.stringify(option)),
        site: {
          w: width || 300,
          h: height || 200,
          x,
          y,
          z,
          opacity: 100,
          bgColor: "rgba(255,255,255,0.5)",
          hiddened: false,
        },
        select: false,
        key,
        ext: {},
      };
      if (dataconfig) {
        newChart.dataconfig = {
          dataType: "",
          category: "",
          dataId: "",
          limit: 1000,
          zuanFlag: false,
          zuan: [],
          zuanLevel: 0,
          zuanStack: [],
        };
        if (this.defaultCube) {
          newChart.dataconfig.dataType = "CUBE";
          newChart.dataconfig.dataId = this.defaultCube;
        }
        modalSet.forEach((set) => {
          newChart.dataconfig[set.key] = [];
        });
        newChart.dataconfig.filter = [];
        newChart.dataconfig.sort = [];
        newChart.dataconfig.params = [];
      }
      if (optionSet) {
        optionSet.forEach((name) => {
          let set = this.styleLib.find((i) => i.name == name);
          if (!set) return;
          newChart.option = Object.assign(
            {},
            JSON.parse(JSON.stringify(set.options)),
            newChart.option
          );
        });
        newChart.optionSet = JSON.parse(JSON.stringify(optionSet));
      }
      newChart.intervalSwitch = false;
      newChart.option.intervalTime = 5000;
      this.chartList.push(newChart);
      this.nowChart = newChart;
      this.$nextTick(() => {
        this.onSelectChart(newChart);
        this.$refs[key][0].initPreview();
      });
      this.showRightPanel = true;
    },
    // 处理滚轮缩放面板
    handleWheel(e) {
      if (e.ctrlKey || e.metaKey) {
        e.preventDefault();
        if (e.deltaY > 0) {
          this.scale = Math.max(50, this.scale - 5);
        } else {
          this.scale = Math.min(200, this.scale + 5);
        }
      }
    },
  },
};
</script>
<style lang="scss">
  @import "./edit.scss";
</style>
