<template>
  <div class="node-box" style="position:relative;" v-loading="graphLoading">
    <transition name="el-zoom-in-center">
      <div v-show="infoVisible" class="graph-info-box">
        <div class="graph-info-child">
          <div class="info-item" style="margin-bottom: 15px">
            <div class="info-item-title">
              <label>{{ comment }}</label>
              <!--<div class="add-attribute-box" style="float: right" @click="showAddGraphSpaceDialog({Name:''})">新建-->
              <!--</div>-->
              <!--<div class="add-attribute-box" style="float: right;margin-right: 10px" @click="removeGraphSpace()">-->
              <!--删除-->
              <!--</div>-->
            </div>
            <div class="info-item-content">
              <!--<el-select v-model="space" filterable placeholder="请选择" @change="handleSpaceChange">-->
              <!--<el-option v-for="item in spaceList"-->
              <!--:key="item.name"-->
              <!--:label="item.comment"-->
              <!--:value="item.name">-->
              <!--</el-option>-->
              <!--</el-select>-->
              <div style="margin-top: 20px;font-size: 14px;color: #606266">本体名称：{{ ontologyName }}</div>
            </div>
          </div>
          <el-tabs v-model="activeTab" class="el-tabs-item">
            <el-tab-pane label="概念" name="tag">
              <el-table
                  class="tab-table-item"
                  @row-click="modifyTag"
                  :data="tagList"
                  style="width: 100%">
                <el-table-column
                    prop="Name"
                    label="名称">
                  <template slot-scope="scope">
                    <div :style="scope.row.Name === activeSelectType ? 'color: #409EFF':''">
                      <label>{{ scope.row.comment }}</label>
                      <!--                      <label>({{ scope.row.count }})</label>-->
                    </div>
                  </template>
                </el-table-column>
              </el-table>
              <!--              <div class="add-attribute-box" @click="modifyTag({Name:''})">+新建TAG</div>-->
            </el-tab-pane>
            <el-tab-pane label="关系" name="edge" class="el-tabs-item">
              <el-table
                  class="tab-table-item"
                  @row-click="modifyEdge"
                  :data="edgeList"
                  style="width: 100%">
                <el-table-column
                    prop="Name"
                    label="名称">
                  <template slot-scope="scope">
                    <div :style="scope.row.Name === activeSelectType ? 'color: #409EFF':''">
                      <label>{{ scope.row.comment }}</label>
                      <!--                      <label>({{ scope.row.count }})</label>-->
                    </div>
                  </template>
                </el-table-column>
              </el-table>
              <!--              <div class="add-attribute-box" @click="modifyEdge({Name:''})">+新建EDGE</div>-->
            </el-tab-pane>

          </el-tabs>
        </div>
      </div>
    </transition>
    <transition name="el-zoom-in-center">
      <div v-show="propsInfoVisible" class="tree-graph-info">
        <div class="graph-info-child">
          <div v-show="tabModifyCmdType === 'tag'">
            <tag-modify ref="tagModify"></tag-modify>
          </div>
          <div v-show="tabModifyCmdType === 'edge'">
            <edge-type-modify ref="edgeTypeModify"></edge-type-modify>
          </div>
          <div v-show="tabModifyCmdType === 'nodeDetail'">
            <node-detail ref="nodeDetail"></node-detail>
          </div>
          <div v-show="tabModifyCmdType === 'edgeDetail'">
            <edge-detail ref="edgeDetail"></edge-detail>
          </div>
          <div v-show="tabModifyCmdType === 'edgeAdd'">
            <edge-add ref="edgeAdd"></edge-add>
          </div>
          <i class="el-icon-d-arrow-right" @click="propsInfoVisible = false;"></i>
        </div>
      </div>
    </transition>
    <!-- 为图谱准备一个具备大小（宽高）的Dom -->
    <div class="tree-container">
      <div class="icon-box">
        <div v-if="showFlag" style="display: inline-block;margin-right: 50px">
          <el-input placeholder="请输入关键词" v-model="keyword" style="width: 550px">
            <el-select v-model="searchTag" slot="prepend" placeholder="请选择概念" style="width: 150px" filterable>
              <el-option :label="item.comment" :value="item.Name" v-for="(item,index) in tagList"
                         v-if="index != 0"></el-option>
            </el-select>
            <el-button slot="append" icon="el-icon-search" @click="searchBtn()"></el-button>
          </el-input>
        </div>
        <div class="icon icon-search" @click="showFlag = !showFlag">
          <i title="搜索"></i>
        </div>
        <div class="icon icon-add" @click="showAddNodeDialog">
          <i title="新增类"></i>
        </div>
        <div title="新增关系" class="icon icon-arrow"
             @click="showAddEdgeDialog">
          <i title="新增关系"></i>
        </div>
        <div class="icon icon-save" @click="backGraph">
          <i title="返回"></i>
        </div>
        <!--<div title="按住shift点选两节点可新增关系" :class="['icon icon-arrow', createEdgeModelFlag ? 'active' : '']"-->
        <!--@click="changeCreateEdgeModel">-->
        <!--<i title="按住shift点选两节点可新增关系"></i>-->
        <!--</div>-->
        <!--        <div class="icon icon-remove" @click="removeNode">-->
        <!--          <i title="删除"></i>-->
        <!--        </div>-->
      </div>
      <div id="mountNode" style="width: 100%; height: 1000px"></div>
    </div>
    <graph-space-add ref="graphSpaceAdd"></graph-space-add>
  </div>
</template>

<script>
import request from '@/utils/request';
import {config} from '@/components/graph/config';
import G6 from '@antv/g6';
import tagModify from '@/components/dialog/TagModify';
import edgeTypeModify from '@/components/dialog/EdgeTypeModify';
import nodeDetail from '@/components/dialog/NodeDetail';
import edgeAdd from '@/components/dialog/EdgeAdd';
import edgeDetail from '@/components/dialog/EdgeDetail';
import {getFirstStringProperty} from '@/utils/common';
import graphSpaceAdd from '@/components/dialog/GraphSpaceAdd';

G6.registerBehavior('click-add-edge', {
  // Set the events and the corresponding responsing function for this behavior
  getEvents() {
    return {
      'node:click': 'onClick', // The event is canvas:click, the responsing function is onClick
      mousemove: 'onMousemove', // The event is mousemove, the responsing function is onMousemove
      'edge:click': 'onEdgeClick',
    };
  },
  // The responsing function for node:click defined in getEvents
  onClick(ev) {
    const self = this;
    const node = ev.item;
    const graph = self.graph;
    // The position where the mouse clicks
    const point = {x: ev.x, y: ev.y};
    const model = node.getModel();
    if (self.addingEdge && self.edge) {
      graph.updateItem(self.edge, {
        target: model.id,
      });
      // 打开编辑新建关系的信息弹窗
      vm.showAddEdgeDialog(self.edge._cfg.model);
      self.edge = null;
      self.addingEdge = false;
    } else {
      // Add anew edge, the end node is the current node user clicks
      self.edge = graph.addItem('edge', {
        source: model.id,
        target: model.id,
      });
      self.addingEdge = true;
    }
  },
  // The responsing function for mousemove defined in getEvents
  onMousemove(ev) {
    const self = this;
    // The current position the mouse clicks
    const point = {x: ev.x, y: ev.y};
    if (self.addingEdge && self.edge) {
      // Update the end node to the current node the mouse clicks
      self.graph.updateItem(self.edge, {
        target: point,
      });
    }
  },
  // The responsing function for edge:click defined in getEvents
  onEdgeClick(ev) {
    const self = this;
    const currentEdge = ev.item;
    if (self.addingEdge && self.edge === currentEdge) {
      self.graph.removeItem(self.edge);
      self.edge = null;
      self.addingEdge = false;
    }
  },
});

var vm;
var graph;
var graphData;
var _ = require('lodash');
var nodeProps = {
  id: 'vid',
};
var edgeProps = {
  source: 'srcId',
  target: 'dstId',
}
export default {
  components: {
    'tag-modify': tagModify,
    'edge-type-modify': edgeTypeModify,
    'node-detail': nodeDetail,
    'edge-detail': edgeDetail,
    'graph-space-add': graphSpaceAdd,
    'edge-add': edgeAdd
  },
  data() {
    return {
      space: '', // 当前展示的图空间（实例）
      activeSelectType: 'All',
      spaceList: [], // 所有的图空间列表
      tagList: [], // 图空间的TAG列表
      edgeList: [], // 图空间的EDGE列表
      activeTab: 'tag',
      graphLoading: false,
      tabModifyCmdType: 'tag',
      createEdgeModelFlag: false,
      infoVisible: true, // 左侧信息栏显隐
      propsInfoVisible: false, // 右侧树形图谱
      selectObj: {
        type: '',
        value: {}
      },
      tagMap: {},
      edgeMap: {},
      ontologyName: "",
      showFlag: false,
      keyword: "",
      searchTag: "",
      ontologyId: "",
      comment: "",
      qo: {
        pageNo: "",
        name: ""
      }
    }
  },
  created() {
    vm = this;
  },
  mounted() {
    vm.qo = {
      pageNo: this.$route.query.pageNo,
      name: this.$route.query.name
    };
    vm.ontologyId = this.$route.query.ontologyId;
    vm.space = this.$route.query.space;
    vm.comment = this.$route.query.comment;
    vm.handleSpaceChange();
    // vm.querySpaceList();
    // vm.initGraph();
  },
  methods: {
    querySpaceList() { // 查询图空间列表，供快速选择切换
      request({
        url: '/nebula_operate/showspace',
        method: 'get',
        data: {}
      }).then(res => {
        vm.spaceList = res.data;
        if (res.data.length > 0) {
          vm.space = res.data[0].name;
          vm.handleSpaceChange();
        } else {
          vm.space = "";
          vm.tagMap = {};
          vm.edgeMap = {};
          vm.tagList = [];
          vm.edgeList = [];
          vm.ontologyName = "";
          vm.destroyGraph();
        }
      });
    },
    queryOntologyDetail() {
      var id = vm.ontologyId;
      // vm.spaceList.forEach(item => {
      //     if(item.name == vm.space){
      //         id = item.OntologyId;
      //     }
      // })

      if (id) {
        request({
          url: `/ontology/getone/` + id,
          method: 'post',
          data: {id: id}
        }).then(res => {
          vm.ontologyName = res.data.name;
        })
      }
    },
    handleSpaceChange() {
      vm.initGraph();
      vm.queryStatistics();
      vm.queryOntologyDetail();
    },
    queryStatistics() {
      request({
        url: `/nebula_operate/censusgraphbyspace/${vm.space}`,
        method: 'get',
        data: {}
      }).then(res => {
        let row = res.data;
        let tagMap = {};
        let edgeMap = {};
        row.forEach(item => {
          if (item.type === "Space") {
            if (item.name === "vertices") {
              tagMap['All'] = item.count;
            } else if (item.name === "edges") {
              edgeMap['All'] = item.count;
            }
          } else {
            if (item.type === "Tag") {
              tagMap[item.name] = item.count;
            } else if (item.type === "Edge") {
              edgeMap[item.name] = item.count;
            }
          }
        });
        vm.tagMap = tagMap;
        vm.edgeMap = edgeMap;
        vm.queryTagList();
        vm.queryEdgeList();
      });
    },
    queryTagList() { // 查询tag列表
      vm.propsInfoVisible = false;
      request({
        url: `/nebula_operate/showtag/${vm.space}`,
        method: 'get',
        data: {}
      }).then(res => {
        // res.data.unshift({
        //   Name: `All`,
        //   comment: '实体数'
        // });
        res.data.forEach(row => {
          row.count = vm.tagMap[row.Name] ? vm.tagMap[row.Name] : 0;
        });
        vm.tagList = res.data;
      });
    },
    queryEdgeList() {
      vm.propsInfoVisible = false;
      request({
        url: `/nebula_operate/showedge/${vm.space}`,
        method: 'get',
        data: {}
      }).then(res => {
        // res.data.unshift({
        //   Name: `All`,
        //   comment: '三元组数'
        // });
        res.data.forEach(row => {
          row.count = vm.edgeMap[row.Name] ? vm.edgeMap[row.Name] : 0;
        });
        vm.edgeList = res.data;
      });
    },
    modifyTag(row) {
      vm.tabModifyCmdType = 'tag';
      if (row.Name !== "All") {
        vm.propsInfoVisible = true;
        vm.$nextTick(() => {
          vm.$refs['tagModify'].updateValue(vm.space, row.Name);
        });
      } else {
        vm.propsInfoVisible = false;
      }
      // 更新图谱
      if (row.Name.length > 0) {
        vm.activeSelectType = row.Name;
        vm.querySpaceGraphData(row.Name, 'tag');
      }
    },
    modifyEdge(row) {
      vm.tabModifyCmdType = 'edge';
      if (row.Name !== "All") {
        vm.propsInfoVisible = true;
        vm.$nextTick(() => {
          vm.$refs['edgeTypeModify'].updateValue(vm.space, row.Name);
        });
      } else {
        vm.propsInfoVisible = false;
      }

      // 更新图谱
      if (row.Name.length > 0) {
        vm.activeSelectType = row.Name;
        vm.querySpaceGraphData(row.Name, 'edge');
      }
    },
    queryDetail(type, obj) { // type : node/edge
      vm.tabModifyCmdType = type + 'Detail';
      vm.propsInfoVisible = true;
      console.log(type);
      vm.$nextTick(() => {
        vm.$refs[type + 'Detail'].queryDetail(vm.space, obj);
      });
    },
    showAddGraphSpaceDialog() {
      vm.$refs['graphSpaceAdd'].openDialog();
    },
    removeGraphSpace() {
      this.$confirm('此操作将永久删除, 是否继续?', '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      }).then(() => {
        request({
          url: `/nebula_operate/dropspace/${vm.space}`,
          method: 'get',
          data: {}
        }).then(res => {
          vm.$message.success("删除成功");
          vm.querySpaceList();
        });
      });
    },
    querySpaceGraphData(typeName, type) { // 查询图空间内节点关系
      if (typeName == undefined) {
        vm.activeSelectType = "All";
        typeName = "All";
      }
      // vm.propsInfoVisible = false;
      vm.graphLoading = true;

      // 根据查询类型区分接口，分三种，固定edgeType，固定tag的和查询全部类型的
      if (typeName === 'All') {
        request({
          url: `/nebula_operate/findpathinspace/${vm.space}`,
          method: 'post',
          data: {}
        }).then(res => {
          vm.resolveGraphData(res);
        });
      } else {
        if (type === "tag") {
          request({
            url: `/nebula_operate/findnodes/${vm.space}`,
            method: 'post',
            data: {
              tag: typeName
            }
          }).then(res => {
            vm.resolveGraphData({data: {nodes: res.data, relations: []}});
          });
        } else if (type === "edge") {
          request({
            url: `/nebula_operate/findrelations/${vm.space}`,
            method: 'post',
            data: {
              edge: typeName
            }
          }).then(res => {
            vm.resolveGraphData(res);
          });
        }
      }

    },
    resolveGraphData(res) { //处理图谱数据，格式化
      if (res.data && res.data.nodes) {
        res.data.nodes.forEach(node => {
          Reflect.ownKeys(nodeProps).forEach(key => {
            node[key] = _.get(node, nodeProps[key], '');
          });

          if (node.properties) {
            // node.label = node.name = getFirstStringProperty(node.properties);
            node.label = node.name = node.vid;
          }

          if(node.labels === 'tag_1412011336') {
            node.style = {
              fill: '#8fe8e8'
            }
          }


        });
      }

      if (res.data && res.data.relations) {
        res.data.relations.forEach(edge => {
          Reflect.ownKeys(edgeProps).forEach(key => {
            edge[key] = _.get(edge, edgeProps[key], '');
          });
          if (edge.properties) {
            edge.label = edge.name = getFirstStringProperty(edge.properties);
          }

          // 是否指向自己
          edge.type = edge.srcId === edge.dstId ? 'loop' : '';
        });
      }

      graphData = {
        nodes: res.data && res.data.nodes ? res.data.nodes : [],
        edges: res.data && res.data.relations ? res.data.relations : []
      };
      // 读取数据
      graph.data(graphData);
      // 渲染图
      graph.render();
      vm.graphLoading = false;
    },
    initGraph() {
      this.destroyGraph();
      let mountNodeDom = document.getElementById("mountNode");
      let _width = mountNodeDom.clientWidth, _height = mountNodeDom.clientHeight;
      // 创建 G6 图实例
      if (graph == undefined || graph == null) {
        graph = new G6.Graph(config({width: _width, height: _height, id: 'mountNode'}));

        graph.on('aftercreateedge', (e) => {
          vm.showAddEdgeDialog(e.edge._cfg.model);
        });

        graph.on('canvas:click', (e) => {
          vm.selectObj = {
            type: '',
            value: {}
          };
          vm.clearStates();
        });

        graph.on('edge:click', function (e) { // 点击边事件
          let edge = e.item._cfg.model;
          if (!edge.name) {
            return;
          }
          vm.queryDetail('edge', {
            edgeType: edge.edgeName,
            srcVid: edge.srcId,
            dstVid: edge.dstId
          });
          graph.getEdges().forEach((edge) => {
            graph.clearItemStates(edge);
          });
          graph.getNodes().forEach((node) => {
            graph.clearItemStates(node);
          });
          graph.setItemState(e.item, 'yourStateName', true);

        });

        graph.on('node:click', (e) => {
          if (!event.shiftKey && !vm.createEdgeModelFlag) { // 按住shift属于新增关系，不需要触发点击节点事件
            let node = e.item._cfg.model;
            vm.queryDetail('node', {
              tag: node.labels,
              vid: node.vid,
            });
            vm.clearStates();
            graph.setItemState(e.item, 'yourStateName', true);
          }

        });
      }
      vm.querySpaceGraphData('All');
    },
    destroyGraph() {
      try {
        if (graph != undefined && graph != null) {
          graph.clear();
          graph = null;
          document.getElementById("mountNode").innerHTML = "";
        }
      } catch (err) {
        console.log(err);
      }
    },
    clearStates() { // 清空选中状态
      graph.getNodes().forEach((node) => {
        graph.clearItemStates(node);
      });
      graph.getEdges().forEach((edge) => {
        graph.clearItemStates(edge);
      });
    },
    changeCreateEdgeModel() { // 切换模式，默认和添加关系模式之间切换
      vm.createEdgeModelFlag = !vm.createEdgeModelFlag;
      if (vm.createEdgeModelFlag) {
        graph.setMode("addEdge");
      } else {
        graph.setMode("default");
      }
    },
    showAddEdgeDialog(edge) {
      vm.tabModifyCmdType = 'edgeDetail';
      vm.propsInfoVisible = true;
      vm.$nextTick(() => {
        vm.$refs['edgeDetail'].createItem(vm.space, edge.source, edge.target);
      });
    },
    showAddNodeDialog() {
      vm.tabModifyCmdType = 'nodeDetail';
      vm.propsInfoVisible = true;
      vm.$nextTick(() => {
        vm.$refs['nodeDetail'].createItem(vm.space);
      });
    },
    showAddEdgeDialog() {
      vm.tabModifyCmdType = 'edgeAdd';
      vm.propsInfoVisible = true;
      vm.$nextTick(() => {
        vm.$refs['edgeAdd'].createItem(vm.space);
      });
    },
    //搜索
    searchBtn() {
      if (!vm.searchTag) {
        vm.$message.warning("请选择概念");
        return false;
      }
      if (!vm.keyword) {
        vm.$message.warning("请输入关键字");
        return false;
      }
      vm.graphLoading = true;
      request({
        url: `/nebula_operate/findnodebykeyword/${vm.space}/${vm.searchTag}`,
        method: 'post',
        data: {keyword: vm.keyword}
      }).then(res => {
        if (res.data) {
          res.data.forEach(node => {
            Reflect.ownKeys(nodeProps).forEach(key => {
              node[key] = _.get(node, nodeProps[key], '');
            });

            if (node.properties) {
              node.label = node.name = getFirstStringProperty(node.properties);
            }
          });
        }

        graphData = {
          nodes: res.data ? res.data : [],
          edges: []
        };
        // 读取数据
        graph.data(graphData);
        // 渲染图
        graph.render();
        vm.graphLoading = false;
      });
    },
    findOnePathBySrcidAndDctid(srcId, dstId) {
      request({
        url: `/nebula_operate/findonepathbysrcidanddctid/${vm.space}/${srcId}/${dstId}`,
        method: 'get',
        data: {}
      }).then(res => {
        vm.resolveGraphData(res);
      });
    },
    findNodeById(tag, vid) {
      request({
        url: `/nebula_operate/findnodebyid/${vm.space}/${tag}/${vid}`,
        method: 'get',
        data: {}
      }).then(res => {
        if (res.data) {
          Reflect.ownKeys(nodeProps).forEach(key => {
            res.data[key] = _.get(res.data, nodeProps[key], '');
          });

          if (res.data.properties) {
            res.data.label = res.data.name = getFirstStringProperty(res.data.properties);
          }
        }

        graphData = {
          nodes: res.data ? [res.data] : [],
          edges: []
        };
        // 读取数据
        graph.data(graphData);
        // 渲染图
        graph.render();
        vm.graphLoading = false;
      });
    },
    backGraph() { // 返回
      vm.$router.push({path: "/graphSpaceManage", query: {pageNo: vm.qo.pageNo, name: vm.qo.name}})
    },
  }
}

function refreshDragedNodePosition(e) {
  const model = e.item.get('model');
  model.fx = e.x;
  model.fy = e.y;
}
</script>

<style>

.el-tabs-item {
  height: calc(100% - 200px);
}

.el-tabs-item .el-tabs__content {
  height: calc(100% - 50px);
}

.el-tabs-item .el-tabs__content .el-tab-pane {
  height: 100%;
}

.tab-table-item {
  height: 100%;
  overflow-y: auto;
}

.node-box {
  height: 100%;
}

.info-item-content .el-select {
  width: 100%;
}

.info-item {
  margin-bottom: 45px;
}

.info-item-title {
  border-bottom: 1px solid #ccc;
  padding-bottom: 15px;
  margin-bottom: 15px;
}

.info-item-title label {
  font-size: 18px;
  font-weight: bold;
  color: #2f2f2f;
}

.graph-name-box {
  position: absolute;
  top: 25px;
  left: 65px;
  width: 250px;
  font-size: 18px;
  font-weight: bold;
}


.form-title {
  font-size: 16px;
  margin: 15px 0;

}

.add-attribute-box {
  margin-top: 10px;
  color: #409EFF;
  cursor: pointer;
  text-align: right;
}

.graph-info-box, .tree-graph-info {
  position: absolute;
  top: 0;
  overflow: hidden;
  bottom: 0;
  background-color: #fff;
  padding: 15px;
  z-index: 999;
  border-right: 1px solid rgba(52, 100, 224, 0.15);
  box-shadow: 0px 2px 21px 0px rgba(52, 100, 224, 0.15);
}

.graph-info-box {
  left: 0;
  width: 230px;
}

.tree-graph-info {
  right: 0;
  width: 500px;
}

.graph-info-child {
  width: 100%;
  height: 100%;
  position: relative;
}

.graph-info-child .el-table__header-wrapper {
  display: none;
}

.el-icon-d-arrow-left, .el-icon-d-arrow-right, .el-icon-d-arrow-right2 {
  position: absolute;
  top: 50%;
  margin-top: -10px;
  font-size: 20px;
  cursor: pointer;
  z-index: 1000;
}

.el-icon-d-arrow-left {
  right: 0px;
}

.el-icon-d-arrow-right {
  left: 0px;
}

.info-line-item {
  margin-bottom: 35px;
}

.info-title {
  font-size: 16px;
  font-weight: 600;
  margin-bottom: 12px;
}

.info-content > div {
  margin-bottom: 5px;
  line-height: 20px;
}

ol, ul {
  list-style: none;
  margin: 0;
  padding: 0;
}

.menu {
  /*这个样式不写，右键弹框会一直显示在画布的左下角*/
  position: absolute;
  background: white;
  border-radius: 5px;
  border: 1px solid #f2f4f7;
  left: -99999px;
  top: -999999px;
}

.menu div {
  list-style: none;
  padding: 5px 10px;
  color: black;
  border-bottom: 1px dashed #ffffff;
  font-size: 14px;
  cursor: pointer;
}

.menu div:hover {
  color: #659bc5;
  background: #f3f6fa;
}

.menu div:last-child {
  border-bottom: none;
}

ul#menuBox li {
  cursor: pointer;
  margin: 5px 0;
}

ul#menuBox li:hover {
  color: #1c63e0;
}

.tree-container {
  position: relative;
  padding-left: 300px;
}

.tips-box {
  position: absolute;
  top: 25px;
  left: 50%;
  width: 300px;
  margin-left: -150px;
  font-size: 16px;
}

div.icon-box {
  position: absolute;
  top: 25px;
  right: 75px;
}

div.icon {
  display: inline-block;
  cursor: pointer;
  padding: 15px;
  background-color: #fff;
  border-radius: 40px;
  margin-left: 15px;
}

div.icon i {
  width: 25px;
  height: 25px;
  margin: auto;
  display: inline-block;
}


div.icon-add i {
  background: url("../../assets/image/icon/bg-add.png") no-repeat center/contain;
}


div.icon-remove i {
  background: url("../../assets/image/icon/changyonggoupiaorenshanchu.png") no-repeat center/contain;
}


div.icon-save i {
  background: url("../../assets/image/icon/fanhui.png") no-repeat center/contain;
}

div.icon-arrow i {
  background: url("../../assets/image/icon/arrowTop-fill.png") no-repeat center/contain;
}


div.icon-tree i {
  background: url("../../assets/image/icon/shuxingicon.png") no-repeat center/contain;
}

div.icon-search i {
  background: url("../../assets/image/icon/search.png") no-repeat center/contain;
}

div.icon-arrow.active i {
  background: url("../../assets/image/icon/arrowTop-fill-active.png") no-repeat center/contain;
}

div.icon-arrow.active {
  box-shadow: 0px 0px 6px #979797;
}


</style>
