leader-line.min.js实现数据数据推送图

475 阅读3分钟

一、leader-line的用法

leaderLine不需要引入第三方库,用于连接两个dom,配置项丰富。(官网api)

cdn引入 <script src="https://cdn.jsdelivr.net/npm/leader-line@1.0.5/leader-line.min.js"></script>

NPM安装npm i leader-line import LeaderLine from leader-line

image.png


var startElement = document.getElementById('element-1'),
  endElement = document.getElementById('element-2');

// startElement起始元素,endElement结束元素 连接线的大小和颜色
new LeaderLine(startElement, endElement, {color: 'red', size: 8,path: "fluid",
startPlug: 'disc',endPlug: 'arrow',startPlugColor: "#4D88FF",startLabel:'文字介绍'});

//animations
new LeaderLine(
  LeaderLine.mouseHoverAnchor(startElement, 'draw', {
    animOptions: {
      duration: 3000,
      timing: [0.5, 0, 1, 0.42]
    }
  }),
  endElement
);

  • startElement起始元素
  • endElement结束元素
  • option线条设置项
    • color:"#000"线条颜色
    • size:3,线条粗细
    • dash:true(虚线)
    • endPlug:"arrow" 线尾类型
    • endPlugSize:1, 线尾尺寸
    • endPlugColor: '#000',线尾颜色
    • endSocket:"bottom", 线头的位置 top/left/right/bottom/auto
    • startPlug:"disc" 线头类型
    • startPlugSize:2,线头尺寸
    • startPlugColor:"#000" 线头颜色
    • startSocket:"bottom", 线头的位置 top/left/right/bottom/auto
    • path:"grid" 线的类型
    • outline:true,开启连接线边框
    • endPlugOutline/startPlugOutline:true,开启线尾/线头边框
    • endPlugOutlineColor/startPlugOutlineColor:"#000",线尾/线头边框颜色
    • endPlugOutlineSize/startPlugOutlineSize:1.5,线尾/线头边框大小
    • animations 连接动画 timing参数 ease/linear/ease-in/ease-out/ease-in-out
    • gradient{startColor:"#2e17c3",endColor:'#1df3f9'} 线条渐变色
    • dropShadow:true 线条阴影 dropShaw;dropShaw{dx:0,dy:3} dx/dy 阴影距离线条的位置
    • opacity:0.8 线条透明度

startPlug/endPlug 参数

startPlug/endPlug含义
disc圆形终端
square方形终端
arrow1箭头终端1
arrow2箭头终端2
arrow3箭头终端3
hand手型终端
crosshair十字标靶型终端
behind

path参数

path含义
straight直线
arc一般弧线
fluid流体曲线
magnet磁吸线
grid网格型折线

二、实现功能

image.png

        .dataPreview {
            width: 1000px;
            height: 400px;
            position: relative;
        }

        body .leader-line {
            pointer-events: unset !important;
        }

        .tooltip {
            position: absolute;
            font-size: 12px;
            text-align: left;
            background-color: white;
            border-radius: 3px;
            box-shadow: rgb(174, 174, 174) 0px 0px 10px;
            cursor: pointer;
            display: inline-block;
            padding: 10px;
            z-index: 1001;
            display: none;
        }

        .tooltip p {
            line-height: 1.5;
            color: #4D88FF;
        }

        .tooltip span {
            color: red;
            padding-left: 4px;
        }
  
<div class="dataPreview">
        <div id="id_1"></div>
    </div>
    <div class="tooltip">
        <p>推送接口名称:<span></span></p>
        <p>今日推送失败错误条数:<span>10</span></p>
    </div>
<script src="jquery-3.3.1.min.js"></script>
<script src="leader-line.min.js"></script>
<script>
    let dataset = {
        nodes: [
            {
                id: 0, label: "开课信息表", left: 26, top: 66, bg: "#4D88FF"
            },
            { id: 1, label: "教学班学生表", shape: "rect", left: 202, top: 66 },
            { id: 2, label: "按课程维度查询表", shape: "rect", left: 381, top: 66, bg: "#4D88FF" },
            { id: 3, label: "按学生维度查询表", shape: "rect", left: 568, top: 66, bg: "#4D88FF" },
            { id: 4, label: "正考管理表", shape: "rect", left: 202, top: 180 },
            { id: 5, label: "补考管理表", shape: "rect", left: 381, top: 180 },
            { id: 6, label: "重修管理表", shape: "rect", left: 568, top: 180 },
            { id: 7, label: "清考管理表", shape: "rect", left: 752, top: 180 },
            { id: 8, label: "成绩结果数据表", shape: "rect", left: 483, top: 335 }
        ],
        edges: [
            { source: 0, target: 1, isDataLine: false },
            { source: 1, target: 2, isDataLine: false },
            { source: 2, target: 3, isDataLine: false },
            { source: 1, target: 4, isDataLine: false, straightLine: true },
            { source: 4, target: 5, isDataLine: false },
            { source: 5, target: 6, isDataLine: false },
            { source: 6, target: 7, isDataLine: false },
            { source: 4, target: 8, label: "/api/credit/manage/score/result", errorCount: 10, isDataLine: true, hasErrorData: true },
            { source: 5, target: 8, label: "/api/manage/score/create", errorCount: 16, isDataLine: true, hasErrorData: true },
            { source: 6, target: 8, isDataLine: true, hasErrorData: false },
            { source: 7, target: 8, isDataLine: true, hasErrorData: false },
        ]
    }
    let divStr = ""
    dataset.nodes.map(item => {
        if (item.bg) {
            divStr += `<div id="id_${item.id}" style="position:absolute;left:${item.left}px;
        top:${item.top}px;padding:0 10px;height:44px;border:1px solid #4D88FF; color:#4D88FF;background:${item.bg};color:#fff;
        text-align:center;line-height:44px;border:1px solid ##4D88FF;border-radius:6px">${item.label}</div>`
        } else {
            divStr += `<div id="id_${item.id}" style="position:absolute;left:${item.left}px;
        top:${item.top}px;padding:0 10px;height:44px;border:1px solid #4D88FF; color:#4D88FF;
        text-align:center;line-height:44px;border:1px solid ##4D88FF;border-radius:6px">${item.label}</div>`
        }


    })
    $(".dataPreview").html(divStr);
    dataset.edges.map(item => {
        let line = new LeaderLine(document.getElementById(`id_${item.source}`), document.getElementById(`id_${item.target}`), {
            startPlug: 'disc',
            endPlug: 'arrow',
            color: "#4D88FF",
            // startLabel: LeaderLine.pathLabel(item.label),
            // endLabel: LeaderLine.pathLabel(item.label),
            // middleLabel: LeaderLine.captionLabel(item.label),
            startPlugColor: "#4D88FF",
            path: "fluid",
            size: 2,
           
        });
        if (item.hasErrorData) {
            line.setOptions({ color: "#FF0000", startPlugColor: "#FF0000", dash: true })
        }
        if (item.straightLine) {
            line.setOptions({ path: 'straight' })
        }
        if (item.isDataLine) {
            line.setOptions({ startSocket: 'bottom', endSocket: 'top' });
        }
    })
    $("#leader-line-10-line-path").parents('svg').css({ "z-index": 10 })
    $(".leader-line").mouseenter(function () {
        let id = $(this).find('defs').children().first().attr('id');
        // 匹配数字正则
        id = id.match(/\d+/)[0];
        console.log(id);
        if (id && dataset.edges[id - 1].label) {
            $(".tooltip p:first-child span").text(dataset.edges[id - 1].label)
            $(".tooltip p:last-child span").text(dataset.edges[id - 1].errorCount);
            let x = parseInt($(this).css("left")) + parseInt($(this).css("width")) / 4;
            let y = parseInt($(this).css("top")) + parseInt($(this).css("height")) / 2;
            console.log(x, y);
            $(".tooltip").css({ left: x, top: y }).show()
        }
    }).mouseleave(function () {
        console.log(11);
        $(".tooltip").hide()
    })
</script>