<template>
  <div
    style="height:100%; position: relative; font-size: 16px;"
    v-loading="loading"
    class="d-flex align-center justify-center"
  >
    <MEmpty v-if="empty"></MEmpty>
    <relation-graph
      v-show="!empty"
      ref="graphRef"
      :options="graphOptions"
      :on-node-click="onNodeClick"
      :on-line-click="onLineClick"
    >
    </relation-graph>

  </div>
</template>

<script>
import RelationGraph from 'relation-graph'
import MEmpty from '@/components/Common/empty'
const defaultNodeColor = 'rgba(238, 178, 94, 1)'
const NODES_SIZE = {
  width: 30,
  height: 30
}
// }
export default {
  name: 'details-graph',
  components: { RelationGraph, MEmpty },
  props: {
    graphData: {
      type: Object,
      default: () => ({})
    }
  },
  data () {
    return {
      menu: {
        x: 0,
        y: 0,
        show: false,
        items: [
          { title: '查看', handle: this.handleView }
        ],
        activeId: +this.$route.params.id,
        item: {}
      },
      empty: true,
      loading: false,
      graphOptions: {
        // defaultJunctionPoint: 'lr',
        // 这里可以参考"Graph 图谱"中的参数进行设置 https://www.relation-graph.com/#/docs/graph
        debug: false, // 是否开始调试模式，调试模式下会在控制台打印额外的日志信息
        showDebugPanel: false, // 是否显示调试按钮，通过此按钮可以打印配置、数据等
        backgroundImage: '', // 图谱水印url,如：https://ssl.relation-graph.com/images/relatioon-graph-canvas-bg.png
        downloadImageFileName: '', // 下载图片时，图片的名称
        disableZoom: false, // 是否禁用图谱的缩放功能
        disableDragNode: false, // 是否禁用图谱中节点的拖动
        moveToCenterWhenRefresh: true, // 当图谱刷新后（调用setJsonData或refresh方法都会触发），让图谱根据节点居中（图片会默认将根节点作为中心展示，此选项会根据节点分布寻找中心）
        zoomToFitWhenRefresh: true, // 当图谱刷新后（调用setJsonData或refresh方法都会触发），是否让图谱缩放到适合可见区域大小，此选项不适用于fixed和force布局
        useAnimationWhenRefresh: true, // 当图谱刷新后（调用setJsonData或refresh方法都会触发），使用动画让图居中、缩放
        useAnimationWhenExpanded: true,
        defaultFocusRootNode: true, // 默认为根节点添加一个被选中的样式
        disableNodeClickEffect: false, // 是否禁用节点默认的点击效果（选中、闪烁）
        disableLineClickEffect: false, // 是否禁用线条默认的点击效果（选中、闪烁）
        allowShowZoomMenu: true, // 是否在右侧菜单栏显示放大缩小的按钮，此设置和disableZoom不冲突
        allowAutoLayoutIfSupport: true, // 是否在工具栏中显示【自动布局】按钮（只有在布局支持且此选项为true时才会显示的按钮）
        allowShowRefreshButton: true, // 是否在工具栏中显示【刷新】按钮
        allowShowDownloadButton: true, // 是否在工具栏中显示【下载图片】按钮
        backgroundImageNoRepeat: false, // 只在右下角显示水印，不重复显示水印
        allowSwitchLineShape: true, // 是否在工具栏中显示切换线条形状的按钮
        allowSwitchJunctionPoint: true, // 是否在工具栏中显示切换连接点位置的按钮
        isMoveByParentNode: false, // 是否在拖动节点后让子节点跟随
        defaultExpandHolderPosition: 'hide', // 默认的节点展开/关闭按钮位置（left/top/right/bottom/hide）
        defaultNodeColor, // 默认的节点背景颜色
        checkedLineColor: '#FD8B37', // 当线条被选中时的颜色
        defaultNodeFontColor: '#ffffff', // 默认的节点文字颜色
        defaultNodeBorderColor: '#90EE90', // 默认的节点边框颜色
        defaultNodeBorderWidth: 0, // 默认的节点边框粗细（像素）
        defaultLineColor: '#cccccc', // 默认的线条颜色
        defaultLineWidth: 2, // 默认的线条粗细（像素）
        defaultLineShape: 2, // 默认的线条样式（1:直线/2:样式2/3:样式3/4:折线/5:样式5/6:样式6）使用示例
        defaultNodeShape: 0, // 默认的节点形状，0:圆形；1:矩形
        defaultShowLineLabel: true, // 默认是否显示连线文字，v2版本此选项已无效，主要是这个选项没什么用
        hideNodeContentByZoom: true, // 是否根据缩放比例隐藏节点内容
        // disableDragCanvas: false,
        // lineUseTextPath: false,
        defaultLineMarker: { // 默认的线条箭头样式，示例参考：配置工具中的选项：连线箭头样式
          markerWidth: 24,
          markerHeight: 24,
          refX: 6,
          refY: 6,
          data: 'M2,2 L10,6 L2,10 L6,6 L2,2'
        },
        layouts: [
          {
            label: '自动布局',
            layoutName: 'center', // 布局方式（tree树状布局/center中心布局/force自动布局）
            from: 'left',
            maxLayoutTimes: 20,
            layoutClassName: 'seeks-layout-force',
            useLayoutStyleOptions: false,
            defaultNodeColor: '#FFC5A6',
            defaultNodeFontColor: '#000000',
            defaultNodeBorderColor: '#efefef',
            defaultNodeBorderWidth: 1,
            defaultLineColor: '#FD8B37',
            defaultLineWidth: 1,
            defaultShowLineLabel: true,
            defaultLineMarker: {
              markerWidth: 12,
              markerHeight: 12,
              refX: 6,
              refY: 6,
              data: 'M2,2 L10,6 L2,10 L6,6 L2,2'
            }
          }
        ]
      },
      config: {
        BusinessDomain: {
          color: '#9FA8DA',
          title: '业务域',
          className: 'sourceNode',
          ...NODES_SIZE
        },
        DataSource: {
          color: '#4CAF50',
          title: '数据源',
          className: 'modelNode',
          ...NODES_SIZE
        },
        DataFlow: {
          color: '#FF9800',
          title: '数据流程',
          className: 'dataFlowNode',
          ...NODES_SIZE
        },
        data_standard: { // 标准
          color: '#009688',
          title: '数据标准',
          className: 'standardNode',
          ...NODES_SIZE
        },
        DataLabel: { // 标签
          color: '#9C27B0',
          title: '数据标签',
          className: 'labelNode',
          ...NODES_SIZE
        },
        DataMeta: { // 元数据
          color: defaultNodeColor,
          title: '元数据',
          className: '',
          ...NODES_SIZE
        }
      }
    }
  },
  computed: {
    legend () {
      return Object.values(this.config)
    }
  },
  mounted () {
    this.init()
  },
  methods: {
    handleContextmenu (v, node) {
      const { left, top } = this.$refs.graphRef.$el.getBoundingClientRect()
      this.menu.x = v.clientX - left
      this.menu.y = v.clientY - top
      this.menu.item = node
      this.menu.show = true
    },
    handleView () {
      this.init(() => {
        this.menu.activeId = +this.menu.item.id
      })
    },
    async init (successCallback = () => {}) {
      // 清空再渲染
      this.loading = true
      this.empty = false
      try {
        this.graphOptions.downloadImageFileName = this.graphData.rootId ?? ''

        this.graphData.nodes.forEach(ele => {
          // if (!this.config[ele.node_type]) {
          //   return
          // }
          ele.text = ele.name_zh || ele.name_en
          ele.data = { ...ele }
          // Object.assign(ele, this.config[ele.node_type])
        })

        this.$nextTick(() => {
          this.$refs.graphRef.setOptions(this.graphOptions, async (graphInstance) => {
            if (!this.$refs.graphRef || !this.$refs.graphRef.setJsonData) {
              return
            }
            this.$refs.graphRef.setJsonData(this.graphData, async (_graphInstance) => {
              await _graphInstance.setZoom(75)
              successCallback()
              this.loading = false
            })
          })
        })
      } catch (error) {
        this.empty = true
        this.$snackbar.error(error)
      }
    },
    onNodeClick (nodeObject, $event) {
      console.log('onNodeClick:', nodeObject)
    },
    onLineClick (lineObject, $event) {
      console.log('onLineClick:', lineObject)
    }
  }
}
</script>

<style lang="scss" scoped>
ul{
  list-style: none;
}
.legend {
  pointer-events: none;
  width: 100%;
  user-select: none;
  -moz-user-select: none;
  -webkit-user-select: none;
  -ms-user-select: none;
  position: absolute;
  top: 0;
  z-index: 10;
  color: #666;
  .rounded-circle {
    width: 24px;
    height: 24px;
  }
}
.pointerEvents {
  pointer-events: auto;
}
::v-deep .rel-node-checked {
  box-shadow: unset !important;
}
.node-active {
  box-shadow: 0 0 0px 6px #f3f900 !important;
  // background: #000 !important;
  // border: 2px solid #000;
}
.node-text {
  color: #000;
  font-size: 16px;
  position: absolute;
  height:25px;
  transform: translate(-50%, 0);
  line-height: 25px;
  left: 50%;
  margin-top:5px;
  text-align: center;
}

::v-deep .rel-toolbar {
  background-color: #f39930;
  color: #ffffff;
  .c-current-zoom {
    color: #ffffff;
  }
}
</style>
