uniapp 树节点l-echart tree

echarts 图表 👑👑👑👑👑

一个基于 JavaScript 的开源可视化图表库 查看更多 站点1 | 查看更多 站点2

基于 echarts 做了兼容处理,更多示例请访问 uni示例 站点1 | uni示例 站点2 | 官方示例

Q群:1046793420

平台兼容

H5 微信小程序 支付宝小程序 百度小程序 头条小程序 QQ 小程序 App

安装

  • 第一步、在uniapp 插件市场 找到 百度图表 导入
  • 第二步、安装 echarts 或者直接使用插件内的echarts.min文件
pnpm add echarts
 -or-
npm install echarts

注意

  • 🔔 必须使用hbuilderx 3.4.8-alpha及以上
  • 🔔 echarts 5.3.0及以上
  • 🔔 如果是 cli 项目需要主动 import 插件
import LEchart from '@/uni_modules/lime-echart/components/l-echart/l-echart.vue';
export default {
    components: {LEchart}
}
// 如果你使用 npm 安装了 echarts
import * as echarts from 'echarts'


// 方式三:按需引入
// 按需引入 开始
import * as echarts from 'echarts/core';
import {LineChart, BarChart} from 'echarts/charts';
import {TitleComponent,TooltipComponent,GridComponent, DatasetComponent, TransformComponent, LegendComponent } from 'echarts/components';
// 标签自动布局,全局过渡动画等特性
import {LabelLayout,UniversalTransition} from 'echarts/features';
// 引入 Canvas 渲染器,注意引入 CanvasRenderer 是必须的一步
import {CanvasRenderer} from 'echarts/renderers';

// 按需引入 注册必须的组件
echarts.use([
    LegendComponent,
    TitleComponent,
    TooltipComponent,
    GridComponent,
    DatasetComponent,
    TransformComponent,
    LineChart,
    BarChart,
    LabelLayout,
    UniversalTransition,
    CanvasRenderer
]);
//-------------按需引入结束------------------------

完整示例

1716452212913.png

1716452190896.png

echarts官网文档
https://echarts.apache.org/zh/api.html#events.treeroam

<template>
    <view class="content">
        <view style="top: 50px;color: blueviolet;position: fixed;z-index: 999;">
            <view @tap="tapFX()" style="display: flex;">
                朝向:<button> {{chaoxiang()["name"]}}</button>
            </view>
            <view style="display: flex;">
                缩放:<button @click="tapZoom(+0.5)">+</button>
                <button @click="tapZoom(-0.5)">-</button>
            </view>
        </view>

        <view class="mui-content" style="margin-top: 16px;height: 100vh;width: 100vw;">
            <l-echart ref="chart" style="width: 100%;height:100%;" @finished="init"></l-echart>

        </view>

    </view>
</template>

<script>
    import LEchart from '@/uni_modules/lime-echart/components/l-echart/l-echart.vue';
    import * as echartsLime from '@/uni_modules/lime-echart/static/echarts.min'
    //  颜色设定 不同颜色寓意不同权重
    var fatherColor = 'green';
    var midColor = 'rgb(193, 92, 31)';
    var smallColor = 'rgb(247, 203, 174)';
    export default {
        components: {
            LEchart
        },
        data() {
            return {
                // 模拟节点数据
                swyyQ: {
                    "id": 100,
                    "name": "新能源汽车",
                    // 展示的内容
                    label: {
                        // 修改 position 和 distance 的值试试
                        // 支持:'left', 'right', 'top', 'bottom', 'inside', 'insideTop', 'insideLeft', 'insideRight', 'insideBottom', 'insideTopLeft', 'insideTopRight', 'insideBottomLeft', 'insideBottomRight'
                        position: 'top',
                        distance: 10,

                        show: true,
                        formatter: ['富文本'].join('\n'),
                        backgroundColor: '#eee',
                        borderColor: '#555',
                        borderWidth: 1,
                        borderRadius: 5,
                        padding: 5,
                        fontSize: 15,
                        shadowBlur: 3,
                        shadowColor: '#888',
                        shadowOffsetX: 0,
                        shadowOffsetY: 3,
                        textBorderColor: '#000',
                        textBorderWidth: 3,
                        color: '#000'
                    },
                    itemStyle: {
                        color: midColor
                    },
                    "children": [{
                            "id": 101,
                            "name": "大型企业",
                            itemStyle: {
                                color: fatherColor
                            },

                        },
                        {
                            "id": 102,
                            "name": "中型企业",
                            itemStyle: {
                                color: midColor
                            },

                        },
                        {
                            "id": 103,
                            "name": "小型企业",
                            itemStyle: {
                                color: smallColor
                            },

                        },
                        {
                            "id": 104,
                            "name": "其他规模企业",
                            itemStyle: {
                                color: fatherColor
                            },
                        }
                    ]
                },
                // 缩放比例
                zoom: 1,
                orient: [{
                    name: "左右",
                    value: 'LR'
                }, {
                    name: "上下",
                    value: 'TB'
                }], // 布局 上下 'TB'(从上到下)或 'LR'(从左到右)
                // orient: 'TB', //上下布局
                chaoxiangIdx: 1,
                showCeng: 3,
                option: {},
            }
        },

        mounted() {
            // this.setCengNum()
        },

        methods: {
            setCengNum() {
                // this.option
                console.log(this.option.series)
                // this.showCeng=
            },
            chartOnClick(params) {
                var that = this
                console.log([params.dataIndex, params.data, params.seriesType, params.dataType, params
                    .componentType
                ])
                console.log(params)
                // params 包含了点击事件的相关信息,如被点击的系列(series)、数据点(data)等
                // console.log(chart.getModel().getComponent('series'));
                if (params.componentType === 'markPoint') {
                    // 点击到了 markPoint 上
                    if (params.seriesIndex === 5) {
                        // 点击到了 index 为 5 的 series 的 markPoint 上。
                    }
                } else if (params.componentType === 'series') {
                    // 有节点添加
                    if (params.data.children) {
                        params.data.children.push({
                            ...this.swyyQ
                        })
                    } else {
                        // 没节点创建
                        params.data.children = [{
                            ...this.swyyQ
                        }]
                    }
                    // 这是全部节点的数据
                    var data = that.chart.getModel().getComponent('series').option.data
                    var option = that.option
                    option.series[0].data = data
                    that.option = option
                    console.log(that.option)
                    that.setData()
                    if ([params.seriesType, ] === 'graph') {
                        if (params.dataType === 'edge') {
                            // 点击到了 graph 的 edge(边)上。
                        } else {
                            // 点击到了 graph 的 node(节点)上。
                        }
                    }
                }
            },
            setData() {
                var chart = this.chart
                // 为 chart 实例添加点击事件的监听
                chart.on('click', this.chartOnClick);
                chart.setOption(this.option)
                // 监听鼠标滚轮事件来放大缩小树图
                chart.on('mousewheel', function(event) {
                    // 获取 dataZoom 组件的索引
                    var dataZoomIndex = chart.getOption().dataZoom[0].id;
                    // 判断鼠标滚动的方向
                    if (event.deltaY > 0) {
                        // 放大
                        chart.dispatchAction({
                            type: 'dataZoom',
                            dataZoomId: dataZoomIndex,
                            zoomLock: 1,
                            delta: 0.1
                        });
                    } else {
                        // 缩小
                        chart.dispatchAction({
                            type: 'dataZoom',
                            dataZoomId: dataZoomIndex,
                            zoomLock: 1,
                            delta: -0.1
                        });
                    }
                });
                this.setCengNum()
            },
            /**
             * 遍历数节点
             */
            nodesStutes(nodes) {
                if (nodes.childList && nodes.childList.length) {
                    for (let i = 0; i < nodes.childList.length; i++) {
                        if (nodes.childList[i].relationType === 2) {
                            // 修改连线颜色
                            nodes.childList[i].lineStyle = {
                                color: '#6DD400'
                            }
                        } else if (nodes.childList[i].relationType === 1) {
                            nodes.childList[i].lineStyle = {
                                color: '#0780ED'
                            }
                        }
                        nodesStutes(nodes.childList[i])
                    }
                }
            },
            // 展开指定节点的函数
            expandNode(nodeId, level) {
                var myChart = this.chart
                // 递归展开节点
                function expand(nodes, level) {
                    nodes.forEach(function(node) {
                        if (node.id === nodeId) {
                            node.collapsed = false; // 将节点设置为展开状态
                        } else if (node.children && level > 0) {
                            expand(node.children, level - 1);
                        }
                    });
                }
                expand([treeData], level); // 调用递归函数,从根节点开始,并指定递归的层级

                // 更新echarts配置
                myChart.setOption({
                    series: [{
                        data: [treeData]
                    }]
                });
            },
            // 缩放比例
            tapZoom(v) {
                console.log(v)
                var zoom = this.zoom + v
                if (zoom < 0) {
                    this.zoom = 0.1
                }
                this.zoom = zoom
                // console.log(this.zoom)
                this.init()
            },
            // 朝向切換
            tapFX() {
                // console.log(this.chaoxiangIdx)
                if (this.chaoxiangIdx == 1) {
                    this.chaoxiangIdx = 0
                } else {
                    this.chaoxiangIdx = 1
                }
                this.init()
            },
            chaoxiang() {
                return this.orient[this.chaoxiangIdx]
            },
            formatter(params) {
                let newName = ''
                let len = params.data.name.length
                let strLen = 4 //一行显示几个字
                if (this.chaoxiangIdx) {
                    strLen = 1
                }
                let rowNum = Math.ceil(len / strLen)
                if (len > strLen) {
                    for (let p = 0; p < rowNum; p++) {
                        let tempStr = ''
                        let start = p * strLen
                        let end = start + strLen
                        if (p == rowNum - 1) {
                            tempStr = params.data.name.substring(start, len)
                        } else {
                            tempStr = params.data.name.substring(start, end) + '\n'
                        }
                        newName += tempStr
                    }
                } else {
                    newName = params.data.name
                }
                let n = newName
                if (n.length > 16) {
                    n = n.slice(0, 16) + '...'
                }
                let str = `{name|${n}}`
                return str
            },
            async init() {
                // 函数用于计算节点的子节点数量
                function getNodeCount(node) {
                    if (!node || !node.children) {
                        return 0;
                    }
                    return node.children.reduce((count, child) => {
                        return count + 1 + getNodeCount(child);
                    }, 0);
                }
                //  颜色设定 不同颜色寓意不同权重
                var fatherColor = 'green';
                var midColor = 'rgb(193, 92, 31)';
                var smallColor = 'rgb(247, 203, 174)';

                // 新能源汽车
                let swyyQ = this.swyyQ

                // 新材料行业
                let xclkQ = {
                    id: 11,
                    "name": "生物与新医药",
                    itemStyle: {
                        color: fatherColor
                    },
                    "children": [{
                            "id": 12,
                            symbol: 'image://http://localhost:8080/static/logo.png', //节点图片
                            "name": "大型企业",
                            itemStyle: {
                                color: fatherColor
                            },
                            "children": [swyyQ]

                        },
                        {
                            "id": 13,
                            "name": "中型企业",
                            itemStyle: {
                                color: midColor
                            },

                        },
                        {
                            "id": 14,
                            "name": "小型企业",
                            itemStyle: {
                                color: smallColor
                            },

                        },
                        {
                            "id": 15,
                            "name": "其他规模企业",
                            itemStyle: {
                                color: fatherColor
                            },
                        }
                    ]
                };

                let data = {
                    "id": 10,
                    "name": "行业分类",
                    itemStyle: {
                        color: fatherColor
                    },
                    "children": [swyyQ, xclkQ]

                }
                // 获取网页宽度 设置树形条目实体宽高度
                let width = 360;
                let widthSize = 0.039 * width;
                if (widthSize > 36) {
                    widthSize = 36;
                }
                let heightSize = widthSize * 2.6;

                this.option = {
                    // 鼠标缩放
                    dataZoom: [{
                        type: 'slider', // 这里设置为slider类型
                        start: 0, // 左边在最左边
                        end: 100 // 右边在最右边,表示初始显示100%
                    }],
                    // // 开启点击 触发提示
                    // tooltip: {
                    //  trigger: 'item',
                    //  triggerOn: 'mousemove'
                    // },
                    //

                    series: [{
                        // 缩放比例
                        zoom: this.zoom,
                        type: 'tree',
                        data: [data],
                        left: '15px',
                        right: '15px',
                        top: '15px',
                        bottom: '15px',
                        symbol: 'square',//节点色块
                        // symbol: 'image://http://localhost:8080/static/logo.png', //节点图片
                        // 节点尺寸
                        symbolSize: [widthSize, heightSize],
                        // 默认展开层级
                        initialTreeDepth: this.showCeng,
                         // 自定义显示内容
                        // 设置标签文字横向 或纵向显示
                        label: {
                            rotate: 0, // 文字旋转90度
                            position: 'left', // 文字位置调整到左侧
                            verticalAlign: 'middle', // 垂直居中
                            align: 'right', // 右对齐
                            fontSize: 16, // 字体大小
                            // 内容格式化
                            formatter: this.formatter,
                            rich: {
                                name: {
                                    fontSize: 14
                                },
                                current: {
                                    fontSize: 12,
                                    padding: 0,
                                    color: '#07CA42',
                                    fontWeight: 600,
                                    backgroundColor: '#E5F7EA',
                                    borderRadius: 2
                                },
                                main: {
                                    color: '#0780ED',
                                    fontSize: 12,
                                    padding: 0,
                                    fontWeight: 600,
                                    backgroundColor: '#E6F2FD',
                                    borderRadius: 2
                                }
                            }
                        },
                        labelLayout: {
                            dy: -20,
                            verticalAlign: 'top'
                        },
                        lineStyle: {
                            // 树图边的样式
                            // color: 'rgba(0,0,0,.35)', // 树图边的颜色
                            width: 1, // 树图边的宽度
                            // curveness: 1, // 树图边的曲度
                            shadowColor: 'rgba(0, 0, 0, 0.5)' // 阴影颜色
                            // shadowBlur: 10 // 图形阴影的模糊大小
                        },
                        blur: {
                            // 淡出状态的相关配置,开启emphasis.focus后有效
                            itemStyle: {}, // 节点的样式
                            lineStyle: {}, // 树图边的样式
                            label: {} // 淡出标签的文本样式
                        },
                        leaves: {
                            // 叶子节点的特殊配置
                            // label: {
                            //  // 叶子节点的文本标签样式
                            //  distance: 0,
                            //  position: 'bottom',
                            //  verticalAlign: 'middle'
                            // },
                            // itemStyle: {}, // 叶子节点的样式
                            // emphasis: {}, // 叶子节点高亮状态的配置
                            // blur: {}, // 叶子节点淡出状态的配置
                            // select: {} // 叶子节点选中状态的配置
                        },
                        animation: true, // 是否开启动画
                        expandAndCollapse: true, // 子树折叠和展开的交互,默认打开
                        animationDuration: 550, // 初始动画的时长
                        animationEasing: 'linear', // 初始动画的缓动效果
                        animationDelay: 0, // 初始动画的延迟
                        animationDurationUpdate: 750, // 数据更新动画的时长
                        animationEasingUpdate: 'cubicInOut', // 数据更新动画的缓动效果
                        animationDelayUpdate: 0, // 数据更新动画的延迟

                        nodePadding: 30, //结点间距 (发现没用)
                        layerPadding: 10, //连接线长度 (发现没用)
                        roam: true, // 开启缩放拖拽
                        scrollbarSize: 10, // 设置滚动条大小
                        scrollbarThumbColor: 'rgba(169, 169, 169, 0.3)', // 设置滚动条颜色
                        // 添加 layout 和 orient 配置
                        // 开启自适应
                        autoLayout: true,
                        // layout: 'orthogonal', // 直角布局
                        orient: this.chaoxiang().value || 'LR', // 布局 上下 'TB'(从上到下)或 'LR'(从左到右)
                        // orient: 'TB', //上下布局
                    }]
                };
                // chart 图表实例不能存在data里
                this.chart = await this.$refs.chart.init(echartsLime, null, {
                    renderer: 'canvas'
                });
                // 为窗口的大小变化绑定事件监听器
                // window.addEventListener('resize', () => {
                //  console.log(111)
                //  this.chart.resize();
                // });
                this.setData()
            }

        }

    }
</script>

<style>
</style>
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 214,377评论 6 496
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,390评论 3 389
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 159,967评论 0 349
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,344评论 1 288
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,441评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,492评论 1 292
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,497评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,274评论 0 269
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,732评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,008评论 2 328
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,184评论 1 342
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,837评论 4 337
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,520评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,156评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,407评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,056评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,074评论 2 352

推荐阅读更多精彩内容