D3.js

javascript 复制代码
  d3是用于数据可视化 可用于处理数据、创建图表、实现动画效果和交互功能

应用场景:

  • 数据可视:将复杂的数据以图表的形式展示出来,便于用户理解和分析。
  • 交互式图:支持事件处理和动画效果,提升用户体验。
  • 仪表盘和报:广泛应用于仪表盘、报告等场景,帮助用户实时监控和分析数据。
  • 地理可视:提供丰富的地理投影功能,用于创建地图和地理可视

d3官网

d3

绘制三角形

javascript 复制代码
<template>
  <svg ref="svgRef" width="200" height="200"></svg>
</template>
 
<script setup>
import { onMounted, ref } from 'vue';
import * as d3 from 'd3';
 
const svgRef = ref(null);
 
onMounted(() => {
  const svg = d3.select(svgRef.value);
 
  // 创建三角形的路径
  const trianglePath = "M100 0 L200 200 L0 200 Z";
 
  // 绘制三角形
  svg.append('path')
    .attr('d', trianglePath)
    .attr('fill', 'steelblue');
});
</script>
 
<style>
/* 样式可以根据需要添加,这里仅为了展示三角形 */
svg {
  border: 1px solid #000;
}
</style>

绘制圆

javascript 复制代码
   <template>
  <div ref="d3Container"></div>
</template>
 
<script setup>
import { onMounted, ref } from 'vue';
import * as d3 from 'd3';
 
const d3Container = ref(null);
 
onMounted(() => {
  const svg = d3.select(d3Container.value).append('svg').attr('width', 200).attr('height', 200);
  const circle = svg.append('circle').attr('cx', 100).attr('cy', 100).attr('r', 50).style('fill', 'blue');
});
</script>
 
<style>
/* 可以添加一些样式 */
</style>

绘制不同值以柱状图形显示

javascript 复制代码
<template>
  <div ref="d3Container"></div>
</template>
 
<script setup>
import { onMounted, ref } from 'vue';
import * as d3 from 'd3';
 
const d3Container = ref(null);
 
onMounted(() => {
  const dataset = [12, 31, 20, 17, 25, 18, 15];
  const svg = d3.select(d3Container.value).append('svg').attr('width', 500).attr('height', 100);
  svg.selectAll('rect')
    .data(dataset)
    .join('rect')
    .attr('x', (d, i) => i * 70)
    .attr('y', d => 100 - d)
    .attr('width', 60)
    .attr('height', d => d)
    .attr('fill', 'blue');
});
</script>
 
<style>
/* 样式内容 */
</style>

d3+dagre-d3 画流程图

javascript 复制代码
npm install --save d3 dagre-d3 
javascript 复制代码
<template>
  <div style="border: 1px solid #ccc; padding: 20px; width: 600px">
    <svg class="dagre" width="600" height="600">
      <g class="container"></g>
    </svg>
    <div ref="tooltip" class="tooltip">
      <div>节点ID:{{currentNode.id}}</div>
      <div>节点名称:{{currentNode.nodeName}}</div>
    </div>
  </div>
</template>
 
<script>
  import dagreD3 from 'dagre-d3';
  import * as d3 from 'd3';
 
  export default {
    name: 'dagre',
    props: {
      tableList: {
        type: Array,
        default: []
      }
    },
    data() {
      return {
        currentNode: {
          id: null,
          nodeName: '',
        },
        // nodes: [],
        edges: [],
        indexObj: {},
        nodes: [
          {id: 0,nodeName: "A",shape: "rect"},
          {id: 1,nodeName: "B",shape: "diamond"},
          {id: 2,nodeName: "C",shape: "rect"},
          {id: 3,nodeName: "D",shape: "rect"},
          {id: 4,nodeName: "E",shape: "rect"},
          {id: 5,nodeName: "F",shape: "rect"}
        ],
        edges: [
          {start: 0,end: 1,label: "哈哈"},
          {start: 1,end: 2,label: ""},
          {start: 1,end: 3,label: ""},
          {start: 2,end: 4,label: ""},
          {start: 3,end: 5,label: ""},
          {start: 4,end: 5,label: ""}
        ],
      };
    },
    mounted() {
      // 把表格的数据转成节点和线条
      this.changeData();
      // this.draw();
    },
    methods: {
      async changeData() {
        // 给每个节点设置对应的编号
        this.tableList.map((v, i) => {
          this.indexObj[v.name] = i;
        });
        await this.tableList.map(async (v, i) => {
          // 点
          this.nodes.push({
            id: i,
            nodeName: v.name,
            shape: "rect"
          });
          // 线
          let arr = await this.getLine(v);
          this.edges = this.edges.concat(arr);
        });
        this.draw();
      },
      getLine(node) {
        let brr = [];
        if (node.pre.length) {
          if (node.pre.length === 1) {
            brr.push({
              start: this.indexObj[node.pre[0]],
              end: this.indexObj[node.name],
              label: ""
            });
          } else {
            node.pre.map(v => {
              brr.push({
                start: this.indexObj[v],
                end: this.indexObj[node.name],
                label: ""
              });
            });
          }
        }
        return brr;
      },
      // 绘制简单的流程图
      draw() {
        // 创建 Graph 对象
        const g = new dagreD3.graphlib.Graph().setGraph({
          rankdir: 'LR', // 流程图从下向上显示,默认'TB',可取值'TB'、'BT'、'LR'、'RL'
        }).setDefaultEdgeLabel(function () {
          return {};
        });
 
        // Graph添加节点
        this.nodes.forEach(node => {
          g.setNode(node.id, {
            id: node.id,
            label: node.nodeName,
            shape: node
            .shape, //节点形状,可以设置rect(长方形),circle,ellipse(椭圆),diamond(菱形) 四种形状,还可以使用render.shapes()自定义形状
            style: 'fill:#fff;stroke:#70baff', //节点样式,可设置节点的颜色填充、节点边框 fill:#61b2e4;stroke:#fff
            labelStyle: 'fill: #000;font-weight:bold', //节点标签样式, 可设置节点标签的文本样式(颜色、粗细、大小)fill: #fff;font-weight:bold
            rx: 5, // 设置圆角
            ry: 5, // 设置圆角
            paddingBottom: 15,
            paddingLeft: 20,
            paddingRight: 20,
            paddingTop: 15,
          });
        });
 
        // Graph添加节点之间的连线
        if (this.nodes.length > 1) {
          this.edges.forEach(edge => {
            g.setEdge(edge.start, edge.end, {
              label: edge.label, //边标签
              style: 'stroke: #70baff; fill: none; stroke-width: 2px', // 连线样式
              arrowheadStyle: 'fill: #70baff;stroke: #70baff;', //箭头样式,可以设置箭头颜色
              arrowhead: 'normal', //箭头形状,可以设置 normal,vee,undirected 三种样式,默认为 normal
            })
          });
        }
 
        // 获取要绘制流程图的绘图容器
        const container = d3.select('svg.dagre').select('g.container');
 
        // 创建渲染器
        const render = new dagreD3.render();
        // 在绘图容器上运行渲染器绘制流程图
        render(container, g);
 
        // 拖拽缩放
        const svg = d3.select('svg.dagre');
        let zoom = d3.zoom().scaleExtent([0.5, 2]).on('zoom', current => {
          container.attr('transform', current.transform);
        });
        svg.call(zoom);
 
        // 鼠标悬停显示隐藏tooltip
        const that = this;
        const tooltipBox = that.$refs.tooltip;
        container.on('mouseover', e => {
          if (e.target.nodeName === "rect") {
            that.currentNode = that.nodes.filter(item => item.id === Number(e.target.__data__))[0];
            tooltipBox.style.display = 'block';
            tooltipBox.style.top = e.clientY + 20 + 'px';
            tooltipBox.style.left = e.clientX + 'px';
            // 点击某个节点,修改节点样式,再次点击恢复原来的样式
            //  if(e.target.style.fill === "rgb(97, 178, 228)") { e.target.style = "fill:#877ee1;stroke:#fff"; } 
            //  else { e.target.style = "fill:#61b2e4;stroke:#fff";  }
          }
        }).on('mouseout', function () {
          tooltipBox.style.display = 'none';
        })
      },
    },
  };
 
</script>
 
<style scoped>
  .tooltip {
    position: absolute;
    font-size: 12px;
    background-color: white;
    border-radius: 3px;
    box-shadow: rgb(174, 174, 174) 0px 0px 10px;
    cursor: pointer;
    display: none;
    padding: 10px;
  }
 
  .tooltip>div {
    padding: 10px;
  }
 
</style>
相关推荐
Pro_er12 小时前
Vue3 性能优化十大技巧:打造高性能应用的终极指南
vue·前端开发
Pro_er1 天前
Vue3响应式编程三剑客:计算属性、方法与侦听器深度实战指南
vue·前端开发
鑫~阳2 天前
Vue2是如何利用Object.defineProperty实现数据的双向绑定?
前端·vue.js·vue
寰宇软件2 天前
PHP房屋出租出售高效预约系统小程序源码
前端·小程序·uni-app·vue·php
爱学习的小王!2 天前
nvm安装、管理node多版本以及配置环境变量【保姆级教程】
经验分享·笔记·node.js·vue
程序员小续3 天前
Excel 表格和 Node.js 实现数据转换工具
前端·javascript·react.js·前端框架·vue·excel·reactjs
胖头鱼不吃鱼-3 天前
开源低代码平台与 Vue.js
开源·vue
零凌林3 天前
WEB前端将指定DOM生成图片并下载最佳实践(html2canvas)
前端·vue·html2canvas·blob·图片下载·dom转图片
Pro_er3 天前
Vue3 数据响应式原理与高效数据操作全解析
vue·前端开发
寰宇软件3 天前
PHP培训机构教务管理系统小程序源码
小程序·uni-app·vue·php