Sankey.vue 2.03 KB
<template>
  <div ref="containerRef" class='canvas-wrapper'>

  </div>
</template>

<script lang="ts" setup name="topbar">
import { ref, watch } from 'vue';
import * as echarts from "echarts";

const props = defineProps({
  treeData: {
    type: Array<any>,
    default: [
      {
        source: 'a',
        target: 'a1',
        value: 5
      },
      {
        source: 'a',
        target: 'a2',
        value: 3
      },
      {
        source: 'b',
        target: 'b1',
        value: 8
      },
      {
        source: 'a',
        target: 'b1',
        value: 3
      },
      {
        source: 'b1',
        target: 'a1',
        value: 1
      },
      {
        source: 'b1',
        target: 'c',
        value: 2
      }
    ]
  },
  names: {
    type: Array<any>,
    default: [
      {
        name: 'a'
      },
      {
        name: 'b'
      },
      {
        name: 'a1'
      },
      {
        name: 'a2'
      },
      {
        name: 'b1'
      },
      {
        name: 'c'
      }
    ]
  }
})

watch(() => props.treeData, (val) => {
  setChartsOption();
})

const sankeyInstance: any = ref();

const containerRef = ref();

const setChartsOption = () => {
  let option = {
    tooltip: {
      trigger: 'item'
    },
    series: [
      {
        type: 'sankey',
        top: 80,
        bottom: 40,
        left: 50,
        right: 50,
        data: props.names,
        links: props.treeData,
        lineStyle: {
          color: 'source',
          curveness: 0.5
        },
      }
    ]
  }
  sankeyInstance.value.setOption(option);
  sankeyInstance.value.resize();
}

const resizeObserver = ref();

const observeResize = () => {
  resizeObserver.value = new ResizeObserver(() => {
    sankeyInstance.value?.resize();
  });
  resizeObserver.value.observe(containerRef.value);
}

onMounted(() => {
  nextTick(() => {
    sankeyInstance.value = echarts.init(containerRef.value);
    setChartsOption();
    observeResize();
  })
})

</script>

<style lang="scss" scoped>
.canvas-wrapper {
  width: 100%;
  height: 100%;
  position: relative;
}
</style>