Highcharts自由绘图,根据数据动态描绘结构图/流程图

前言:

Highcharts自由绘图官网看到demo,明白了是svg矢量图形。

然后就想,根据数据动态画图,这画图又不是html的div一大堆标签无脑堆,折行啥的还得计算。。。

一番折腾,写了下,但是已知么有解决的问题就是字符串过多折行的问题,个人觉得有点麻烦,所以只写了个demo。

废话不多说,放代码。(ps:可直接复制粘贴,如有不对之处,望指出,共同进步)

确实觉得有点麻烦,可以看我另一篇用js写的,点我跳转

html部分:

<!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport"
          content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <script src="https://cdn.hcharts.cn/highcharts/highcharts.js"></script>
</head>
<body>
<div id="container" style="width: 800px; margin: 0 auto"></div>
</body>
</html>

js部分:

<script>
    let data = {
        root: [
            {title: '根节点1', color: 'red'},
            {title: '根节点2', color: 'yellow'},
            {title: '根节点3', color: 'skyblue'},
        ],
        child: [
            {title: '节点', color: '#ccc'},
        ],
        child2: [
            {title: '子节点1'},
            {title: '子节点2阿诗丹顿'},
            {title: '子节点3'},
            {title: '子节点4'},
            {title: '子节点5'},
            {title: '子节点6'},
            {title: '子节点7'},
            {title: '子节点8'},
        ]
    };
    console.log("数据源", data);
    let myChart = Highcharts.chart('container', {
        chart: {
            backgroundColor: 'white',//背景颜色
            events: {
                click: function (e) {//点击事件
                    //console.log(e);
                    //console.log(e.target.getAttribute('data'));
                    if (e.target.getAttribute('data') || e.target.innerHTML) {//兼容处理
                        alert(e.target.getAttribute('data') || e.target.innerHTML)
                    }
                },
                load: function () {
                    const X = 5;//开始画图的位置
                    const Y = 40;//矩形高度&&刻度尺   (控制高度)
                    let startX;
                    let startY = Y;
                    //开始画图
                    drawPicture('container', this.renderer, data.root);
                    drawPicture('container', this.renderer, data.child);
                    drawPicture('container', this.renderer, data.child2, true);

                    /**
                     * 画图
                     * @param domName   id名称
                     * @param renderer  highchart自带的属性
                     * @param data  源数据
                     * @param isEnd 画图是否结束 true=>是|false=>否
                     */
                    function drawPicture(domName, renderer, data, isEnd) {
                        let container = document.getElementById(domName);
                        let containerW = container.clientWidth;
                        let d = 1;//初始行数
                        //数据渲染
                        for (let i in data) {
                            //console.log(data[i].title);
                            let num = data.length;
                            let w = (containerW - 4 * 10) / 4;//宽度
                            num = num > 4 ? 4 : num;
                            switch (num) {
                                case 1:
                                    startX = w * 1.5 + 15;//如果只有一个子代,默认居中
                                    break;
                                case 2:
                                    startX = (w + 10) * (Number(i) + 1);//如果只有两个子代,默认居中
                                    break;
                                case 3:
                                    startX = (w / 2 + 10) + (w + 10) * (Number(i));//如果只有两个子代,默认居中
                                    break;
                                default:
                                    break;
                            }
                            let c = Math.ceil((Number(i) + 1) / num); //第几排
                            if (d !== c) {//判断是否换行
                                d = c;
                                startX = X
                            }
                            //console.log(c);
                            setRect(renderer, {
                                x: startX,
                                y: (c === 1) ? (startY + 10) : (startY + 10 * c + Y * (c - 1)),
                                w: w,
                                h: Y,
                                attr: {
                                    data: data[i].title,
                                    fill: data[i].color ? data[i].color : 'pink'
                                }
                            });

                            setTitle(renderer, {
                                title: data[i].title,
                                x: startX,
                                y: (c === 1) ? (startY + 10) : (startY + 10 * c + Y * (c - 1)),
                                attr: {
                                    data: data[i].title,
                                }
                            });
                            startX += w + 10;
                        }
                        startY += 10 * (d + 1) + Y * d;//该层循环完的高度

                        if (!isEnd) {
                            //箭头
                            setArrow(renderer, {
                                w: containerW / 2,
                                distance: startY,
                                h: Y * 2
                            });
                            startY += 80;
                            startX = X;//startX复位
                        } else {
                            container.style.height = startY + "px";
                        }
                    }
                }
            }
        },
        title: {
            text: '×××图',
            style: {
                color: 'black'
            }
        },
        credits: {
            enabled: false
        }
    });

    myChart.reflow();//高度

    //描绘title
    function setTitle(renderer, opt) {
        renderer.label(opt.title, opt.x, opt.y)
            .attr(opt.attr)
            .css({
                fontSize: '16px',
                color: 'black',
                width: opt.x + 'px',
                height: opt.y + 'px',
                lineHeight: opt.y + 'px',
                minHeight: opt.y + 'px',
                textAlign: 'center'
            }).add();
    }

    //描绘矩形
    function setRect(renderer, opt) {
        let defaultOpt = {
            fill: 'pink',
            stroke: 'black',
            'stroke-width': 1
        };
        let newObj = Object.assign(defaultOpt, opt.attr);
        renderer.rect(opt.x, opt.y, opt.w, opt.h, 5).attr(newObj).add();
    }

    //描绘箭头
    //arrowW,arrowH均为起点
    function setArrow(renderer, opt) {
        let arrowW = opt.w;
        let arrowD = opt.distance;
        let arrowH = opt.h;
        let arrow = ['M', arrowW, arrowD, 'L', arrowW, arrowD + arrowH, 'L', (arrowW - 10), arrowD + (arrowH - 10), 'M', arrowW, arrowD + arrowH, 'L', (arrowW + 10), arrowD + (arrowH - 10)];
        renderer.path(arrow)
            .attr({
                'stroke-width': 2,
                stroke: opt.color || "red"
            }).add();
    }

</script>

效果图:

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值