vue + d3.js(v6) 绘制【树状图/思维导图】

<template>
    <div class="d3Chart"></div>
</template>
<script>
    import * as d3 from 'd3';

    export default {
        mounted() {
            // 源数据
            let data = {
                "name": "中国",
                "children":
                    [
                        {
                            "name": "浙江",
                            "children":
                                [
                                    {"name": "杭州"},
                                    {"name": "宁波"},
                                    {"name": "温州"},
                                    {"name": "绍兴"}
                                ]
                        },
                        {
                            "name": "广西",
                            "children":
                                [
                                    {
                                        "name": "桂林",
                                        "children":
                                            [
                                                {"name": "秀峰区"},
                                                {"name": "叠彩区"},
                                                {"name": "象山区"},
                                                {"name": "七星区"}
                                            ]
                                    },
                                    {"name": "南宁"},
                                    {"name": "柳州"},
                                    {"name": "防城港"}
                                ]
                        },
                        {
                            "name": "黑龙江",
                            "children":
                                [
                                    {"name": "哈尔滨"},
                                    {"name": "齐齐哈尔"},
                                    {"name": "牡丹江"},
                                    {"name": "大庆"}
                                ]
                        },
                        {
                            "name": "新疆",
                            "children":
                                [
                                    {"name": "乌鲁木齐"},
                                    {"name": "克拉玛依"},
                                    {"name": "吐鲁番"},
                                    {"name": "哈密"}
                                ]
                        }
                    ]
            }
            // 画布的参数
            let mapWidth = 600;
            let mapHeight = 600;
            let mapPadding = 20
            // 定义画布—— 外边距 10px
            let svgMap = d3.select(".d3Chart").append('svg').attr("width", mapWidth).attr("height", mapHeight).style("margin", "10px")
            // 定义树状图画布
            let treeMap = svgMap.append("g").attr("transform", "translate(" + mapPadding + "," + mapPadding + ")");
            // 将源数据转换为可以生成树状图的数据(有节点 nodes 和连线 links )
            let treeData = d3.tree()
            // 设置树状图的尺寸
                .size([mapWidth - 3 * mapPadding, mapHeight - 6 * mapPadding])
                // 设置树状图节点之间的间隔
                .separation(function (a, b) {
                    return (a.parent == b.parent ? 1 : 2) / a.depth;
                })(
                    // 创建层级布局,对源数据进行数据转换
                    d3.hierarchy(data).sum(function (d) {
                        return d.value;
                    })
                )
            // 贝塞尔曲线生成器
            let Bézier_curve_generator = d3.linkHorizontal()
                .x(function (d) {
                    return d.y;
                })
                .y(function (d) {
                    return d.x;
                });
            //绘制边
            treeMap.selectAll("path")
            // 节点的关系 links
                .data(treeData.links())
                .enter()
                .append("path")
                .attr("d", function (d) {
                    // 根据name值的长度调整连线的起点
                    var start = {x: d.source.x, y: d.source.y + d.source.data.name.length * 16 + 12};
                    var end = {x: d.target.x, y: d.target.y};
                    return Bézier_curve_generator({source: start, target: end});
                })
                .attr("fill", "none")
                .attr("stroke", "blue")
                .attr("stroke-width", 1);
            // 创建分组——节点+文字
            let groups = treeMap.selectAll("g")
            // 节点 nodes
                .data(treeData.descendants())
                .enter()
                .append("g")
                .attr("transform", function (d) {
                    var cx = d.x;
                    var cy = d.y;
                    return "translate(" + cy + "," + cx + ")";
                });
            //绘制节点
            groups.append("circle")
                .attr("r", 2)
                .attr("fill", "white")
                .attr("stroke", "red")
                .attr("stroke-width", 1);
            //绘制文字
            groups.append("text")
                .attr("x", function (d) {
                    return 8
                })
                .attr("y", -5)
                .attr("dy", 10)
                .text(function (d) {
                    return d.data.name;
                })
        }
    }
</script>
<style scoped>
</style>

猜你喜欢

转载自blog.csdn.net/weixin_41192489/article/details/112988335