uniapp 端开发 echarts 树结构图

news/2024/9/19 3:21:39/ 标签: uni-app, 前端

实现效果 : 

1. 在uniapp 中写echarts 树结构图需要使用  
 

<script module="echarts" lang="renderjs">

否则会无法显示echarts 图形 

rebderjs 代码  引入了 /static/echarts.min.js
是在 ECharts 在线构建 定制你的echarts

<template><view><view class="echarts" :prop="option" :change:prop="echarts.update"></view></view>
</template><script>export default {name: 'Echarts',props: {option: {type: Object,required: true}},methods: {// echarts 点击跳转的onViewClick(options) {console.log("已进入");console.log(options);if (null !== options.test?.lawId && undefined !== options.test?.lawId) {uni.navigateTo({url: ' ', // 替换为你的详情页面路径和查询参数fail: function(res) {console.error('页面跳转失败:', res);}});} else {console.log(options);}}}}
</script><script module="echarts" lang="renderjs">import _ from 'lodash';export default {data() {return {chart: null,options: "",fontSize: 12,symbolSize: 7,paddingH: 8,paddingW: 4,height: 20,width: 300,width2: 80,startTime: null, // 用于记录开始时间debouncedResize: _.debounce(this.resize, 500), // 防抖动处理elesCounts: 0,loading: true}},mounted() {if (typeof window.echarts === 'object') {this.init();} else {// 动态引入类库const script = document.createElement('script')// script.src = './static/echarts.min.js'script.src = './static/echarts/echarts1.min.js'script.onload = this.initdocument.head.appendChild(script);//这两行代码解决在小程序中echarts点击失效问题}},methods: {/*** 初始化echarts*/init() {echarts.env.touchEventsSupported = true;echarts.env.wxa = false;echarts.env.canvasSupported = false;echarts.env.svgSupported = true;echarts.env.domSupported = true;//渲染前this.loading = true;this.chart = echarts.init(this.$el, {renderer: 'canvas'});if (this.loading) {this.chart.showLoading('default', {text: '数据加载中...',color: '#333',textColor: '#666',maskColor: 'rgba(255, 255, 255, 0)',zlevel: 0});}// 延迟执行以确保图表渲染完成setTimeout(() => {this.chart.hideLoading();}, 1000); this.update(this.option);// 监听图表渲染完成事件},getLeftNodeChildren(zoom, children) {this.symbolSize = Math.min(7, this.symbolSize * zoom);return children.map(child => ({...child,label: {...child.label,fontSize: Math.max(2, Math.min(12, this.fontSize * zoom)),padding: [Math.min(4, this.paddingW * zoom), Math.min(8, this.paddingH * zoom)],height: this.height,width: this.width},symbolSize: this.symbolSize,children: child.children ? this.getLeftNodeChildren(zoom, child.children) : [],}));},/*** 监测数据更新* @param {Object} option*/update(option) {if (this.chart) {// 因App端,回调函数无法从renderjs外传递,故在此自定义设置相关回调函数if (option) {this.options = option// tooltipif (option.tooltip) {console.log(option.tooltip.position);// 判断是否设置tooltip的位置if (option.tooltip.positionStatus) {option.tooltip.position = this.tooltipPosition()}// 判断是否格式化tooltipif (option.tooltip.formatterStatus) {option.tooltip.formatter = this.tooltipFormatter(option.tooltip.formatterUnit, option.tooltip.formatFloat2, option.tooltip.formatThousands)}}// 设置新的optionthis.chart.setOption(option, option.notMerge);// 确保在初始化后禁用触摸事件支持if (typeof this.chart === 'object') {this.chart.getZr().handler.touchEventsSupported = false;this.chart.getZr().handler.wxa = false;}// 添加条件语句来确保属性已经存在if (this.chart._chartsViews && this.chart._chartsViews[0] && this.chart._chartsViews[0]._data) {let elesArr = Array.from(new Set(this.chart._chartsViews[0]._data._graphicEls));this.elesCounts = elesArr.length;console.log(elesArr.length);if (elesArr.length >= 130) {option.series[0].top = '-600px';option.series[0].left = '-600px';console.log(88888);// console.log(111111);this.chart.resize({width: 1200,height: 5000});} else {this.resize(); // 使用防抖动的 resize'}}// this.chart.resize({// 	width: 800,// 	height: 400// });this.chart.off("click")//跳转前先解绑,防止重复跳转this.chart.off('click');//	使用 ECharts 内部点击事件this.chart.on("click", params => {console.log(params.data);// 判断点击的是否是树图的节点if (params.componentType === 'series' && params.seriesType === 'tree') {// 阻止事件冒泡params.event.event.stopPropagation();// 处理点击事件console.log('Tree节点被点击,数据为:', params.data);}this.$ownerInstance.callMethod('onViewClick', {test: params.data})});this.chart.on('treeroam', this.handleTreeRoam);}}},// 使用 _.throttle 包装 handleTreeRoam 函数,确保其每300毫秒最多执行一次handleTreeRoam: _.throttle(function(res) {const opt = this.options;const zoom = res.zoom || 1;console.log(zoom);if (zoom == 1) {this.chart.setOption(this.options);return;}console.log(zoom);// 更新字体大小const fontSize = Math.max(2, Math.min(12, this.fontSize * zoom));this.fontSize = fontSize;const padding = [Math.min(4, this.paddingW * zoom), Math.min(8, this.paddingH * zoom)];this.paddingW = padding[0];this.paddingH = padding[1];const heights = Math.min(30, this.height * zoom);this.height = heights;const widths = Math.min(300, this.width * zoom);this.width = widths;const widths2 = Math.min(80, this.width2 * zoom);this.width2 = widths2;const newOption = {...opt,series: [{...opt.series[0],label: {...opt.series[0].label,fontSize: fontSize,padding: padding,},leaves: {...opt.series[0].leaves,label: {...opt.series[0].leaves.label,fontSize: fontSize,padding: padding,},},data: opt.series[0].data.map(node1 => ({...node1,label: {...node1.label,fontSize: fontSize,padding: padding,height: heights,},symbolSize: this.symbolSize,children: node1.children.map(node2 => ({...node2,label: {...node2.label,fontSize: fontSize,padding: padding,height: heights,width: widths2},symbolSize: this.symbolSize,children: this.getLeftNodeChildren(zoom, node2.children),})),})),}],};this.options = newOption;// this.chart.setOption(this.options, true);if (zoom != 1) {if (this.elesCounts > 130) {const opt = this.options.series[0].data[0];const height = opt.label.height;console.log(height);if (opt.label.height < 20 && opt.label.height >= 10) {this.chart.resize({width: 900,height: 3800});} else {this.chart.resize({width: 450,height: 2500});}} else {this.resize();}this.chart.setOption(this.options, true);}}, 1000), // 300 毫秒节流// 使用 _.debounce 包装 setOption 函数,确保其在 300 毫秒后执行resizeDebounce: _.debounce(function() {if (this.chart) {this.resize();}}, 300), // 300 毫秒防抖// 使用 _.debounce 包装 setOption 函数,确保其在 300 毫秒后执行debouncedSetOption: _.debounce(function() {if (this.chart) {console.log(99999);}}, 300), // 300 毫秒防抖resize() {const opt = this.options.series[0].data[0];let elesArr = Array.from(new Set(this.chart._chartsViews[0]._data._graphicEls));let dep = this.chart._chartsViews[0]._data.tree.root.height; // 获取树高let layer_height = 10; // 层级之间的高度let layer_width = 25; // 兄弟节点之间的距离const height = opt.label.height;const elesCount = elesArr.length;// dep 是节点深度   elesCount 是节点的数量  这里根据节点深度和数量进行设置// 根据自己需求完善 if (dep == 4) {if (elesCount < 10) {// 调整高度和宽度逻辑if (opt.label.height == 30) {layer_height = 130;layer_width = 120;} else if (opt.label.height < 25 && opt.label.height >= 20) {layer_height = 130;layer_width = 110;} else if (opt.label.height < 20 && opt.label.height >= 15) {layer_height = 130;layer_width = 100;} else if (opt.label.height < 15 && opt.label.height >= 10) {layer_height = 130;layer_width = 80;} else if (opt.label.height < 10 && opt.label.height > 5) {layer_height = 130;layer_width = 70;} else {layer_height = 130;layer_width = 70;}console.log('opt is 4 and elesCount is less than 10');} let newHeight = layer_height * elesArr.length;let currentWidth = layer_width * (elesArr.length - 1) || layer_width;let newWidth = Math.max(currentWidth, layer_width);console.log(newWidth);console.log(newHeight);// 保持图表中心在可视区域this.chart.resize({width: newWidth,height: newHeight});},/*** 设置tooltip的位置,防止超出画布*/tooltipPosition() {return (point, params, dom, rect, size) => {//其中point为当前鼠标的位置,size中有两个属性:viewSize和contentSize,分别为外层div和tooltip提示框的大小let x = point[0]let y = point[1]let viewWidth = size.viewSize[0]let viewHeight = size.viewSize[1]let boxWidth = size.contentSize[0]let boxHeight = size.contentSize[1]let posX = 0 //x坐标位置let posY = 0 //y坐标位置if (x < boxWidth) { //左边放不开posX = 5} else { //左边放的下posX = x - boxWidth}if (y < boxHeight) { //上边放不开posY = 5} else { //上边放得下posY = y - boxHeight}return [posX, posY]}},}}
</script><style lang="scss" scoped>.echarts {width: 100vh;height: 100vh;}.p-line-charts-out {height: 100%;width: 100%;.p-line-charts {width: 100% !important;height: calc(100% - 25px) !important;}}
</style>

echarts 展示页面 :  基本代码调试一下就可以了

<view ref="echartsContainer"><echarts ref="echarts" :option="option"  style="height: 100vh; width: 100vw;"></echarts>
<script >import echarts from '@/pages/userCenter/business.vue';convertToTreeData(data) {return {tooltip: {trigger: 'item',triggerOn: 'mousemove',},series: [{type: 'tree',scaleLimit: {min: 0.5,max: 2},data: [data],top: '5%',left: '3%',bottom: '5%',right: '10%',initialTreeDepth: -1,roam: true,zoom: 1,symbolSize: 1,label: {fontSize: 9,position: 'right',show: true,borderRadius: 5,borderWidth: 1,verticalAlign: 'middle',align: 'center',color: '#fff'},leaves: {label: {position: 'right',verticalAlign: 'middle',align: 'left',fontSize: 12, // 初始字体大小padding: [4, 8], // 初始内边距},},lineStyle: {color: '#ccc',width: 1.5,type: 'solid'},emphasis: {disabled: true,focus: 'ancestor'},// 当节点大于100 时 关闭动画containLabel: true,}]};},</script>


http://www.ppmy.cn/news/1527505.html

相关文章

GBase8c主备版500升级步骤

# 升级方式区别 就地升级&#xff1a;升级期间需停止业务进行&#xff0c;一次性升级所有节点。 灰度升级&#xff1a;灰度升级支持全业务操作&#xff0c;也是一次性升级所有节点。 指定节点升级&#xff1a;基于灰度升级&#xff0c;支持升级指定节点&#xff0c;支持部分…

【Transformer深入学习】之一:Sinusoidal位置编码的精妙

看苏神的文章提到&#xff1a;Transformer原论文使用Sinusoidal位置编码&#xff0c;作为位置编码的一个显式解&#xff0c;Google 在原论文中对它的描述寥寥无几&#xff0c;只是简单提及了它可以表达相对位置信息&#xff0c;并未提及这个编码的合理性。 看了几篇文章&#x…

python定时任务,定时爬取水质和天气

定时爬取水质和天气 代码 代码 from apscheduler.schedulers.background import BackgroundScheduler import requests import datetimeurlweather "http://localhost:8000/CrwalingViewWeather" # 天气接口 urlwater "http://localhost:8000/CrwalingViewW…

【LeetCode】每日一题 2024_9_15 与车相交的点(差分)

前言 每天和你一起刷 LeetCode 每日一题~ LeetCode 启动&#xff01; 今天的题目曾经的我做过了 . . . 又是复习的一天 题目&#xff1a;与车相交的点 代码与解题思路 func numberOfPoints(nums [][]int) (ans int) { diff : [102]int{}for _, p : range nums {diff[p[0]]d…

Redhat 7,8系(复刻系列) 一键部署Oracle21c-xe rpm

Oracle21c-xe前言 无论您是开发人员、DBA、数据科学家、教育工作者,还是仅仅对数据库感兴趣,Oracle Database Express Edition (XE) 都是理想的入门方式。它是全球企业可依赖的强大的 Oracle Database,提供简单的下载、易于使用和功能齐全的体验。您可以在任何环境中使用该…

快手手撕 力扣2487 从链表中移除节点 单调栈 递归

Problem: 2487. 从链表中移除节点 &#x1f468;‍&#x1f3eb; 参考题解 &#x1f496; 递归解法 /*** Definition for singly-linked list.* public class ListNode {* int val;* ListNode next;* ListNode() {}* ListNode(int val) { this.val val; }* …

Qt中QGraphicsView窗口大小与视图大小的关系

在Qt框架中&#xff0c;QGraphicsView窗口和视图的大小之间存在一定的关系。为了更好地理解这种关系&#xff0c;我们可以从以下几个方面来阐述&#xff1a; 1. 窗口大小 定义&#xff1a;窗口大小指的是QGraphicsView部件在屏幕上占据的矩形区域的大小。它由宽度和高度两个维…

get_property --Cmakelist之中

get_property 是 CMake 中用于获取目标、目录、变量或文件等属性的命令。它可以提取某个特定属性的值&#xff0c;以便在构建脚本的其他地方使用。 语法 get_property(<variable> <TYPE> <name> PROPERTY <property-name> [SET | DEFINED | BRIEF_DO…

Spring Boot-API网关问题

****### Spring Boot API 网关问题分析与解决方案 在微服务架构中&#xff0c;API 网关扮演着非常重要的角色。它位于客户端和微服务之间&#xff0c;充当所有外部请求的入口&#xff0c;负责请求的路由、聚合、鉴权、限流等功能。Spring Boot 提供了多种方式实现 API 网关&am…

记录工作中遇到的问题(持续更新~)

跨域问题 2024-09-15 【前提】&#xff1a;前端配置了nignx转发&#xff0c;后端设置了跨域拦截&#xff0c;对http://xxxx做了允许跨域。但是访问http://xxx被拦截了&#xff0c;返回403 Forbidden。同样的配置放在另外一套部署的环境上就完全没问题&#xff0c;http://xxx可…

828华为云征文|华为Flexus云服务器搭建OnlyOffice私有化在线办公套件

一、引言 在当今数字化办公的时代&#xff0c;在线办公套件的需求日益增长。华为Flexus云服务器凭借其强大的性能和稳定性&#xff0c;为搭建OnlyOffice私有化在线办公套件提供了理想的平台。在2024年9月14日这个充满探索精神的日子里&#xff0c;我们开启利用华为Flexus云服务…

Python实现一个简单的爬虫程序(爬取图片)

目录 1、安装爬虫Scrapy 2、新建爬虫项目 3、配置爬虫 4、编写爬虫代码,爬取百度图片 5、运行爬虫程序 使用爬虫需要遵守相关法律和规范! 1、安装爬虫Scrapy 编程环境是Anaconda,其安装和使用见我之前的文章,这里就不赘述了。 首先安装爬虫Scrapy,为了加快下载速度…

边缘计算网关:连接中心计算与边缘设备的重要桥梁-天拓四方

一、边缘计算网关&#xff1a;重新定义信息高速公路的“路标” 边缘计算网关&#xff0c;作为边缘计算生态系统中的核心组件&#xff0c;不仅承载着数据传输的功能&#xff0c;更是智能信息处理的关键节点。它通过分布式计算架构&#xff0c;将数据处理任务前置到网络边缘&…

[Linux#49][UDP] 2w字详解 | socketaddr | 常用API | 实操:实现简易Udp传输

目录 套接字地址结构&#xff08;sockaddr&#xff09; 1.Socket API 2.sockaddr结构 3. sockaddr、sockaddr_in 和 sockaddr_un 的关系 sockaddr 结构体 sockaddr_in 结构体&#xff08;IPv4 套接字地址&#xff09; sockaddr_un 结构体&#xff08;Unix域套接字地址&a…

oracle表的类型

表是数据库最基本的逻辑结构&#xff0c;一切数据都存放在表中&#xff0c;其它数据库对象(索引、视图、同义词等)都是为了更方便的操作表中的数据。Oracle数据库是由若干个表组成&#xff0c;每个表由列和行组成。 数据库表的类型按照存储结构划分&#xff1a; (1)普通表&…

镀金引线---

一、沉金和镀金 沉金和镀金都是常见的PCB金手指处理方式&#xff0c;它们各有优劣势&#xff0c;选择哪种方式取决于具体的应用需求和预算。 沉金&#xff08;ENIG&#xff09;是一种常用的金手指处理方式&#xff0c;它通过在金手指表面沉积一层金层来提高接触性能和耐腐蚀性…

[Unity Demo]从零开始制作空洞骑士Hollow Knight第二集:通过InControl插件实现绑定玩家输入以及制作小骑士移动空闲动画

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、通过InControl插件实现绑定玩家输入二、制作小骑士移动和空闲动画 1.制作动画2.玩家移动和翻转图像3.状态机思想实现动画切换总结 前言 好久没来CSDN看看&…

Gitlab 中几种不同的认证机制(Access Tokens,SSH Keys,Deploy Tokens,Deploy Keys)

前言 公司主要使用 Go 语言做项目&#xff0c;有一些 Gitlab 私有仓库需要引用&#xff0c;在做 CI 时&#xff0c;要自行配置权限以获取代码。 最近发现各个项目组在做 CI 遇到仓库权限问题时的解决方式不尽相同&#xff0c;有用 Project Token 的&#xff0c;有用 Deploy K…

css总结(记录一下...)

文字 语法说明word-wrapword-wrap:normal| break-word normal:使用浏览器默认的换行 break-word:允许在单词内换行 text-overflow clip:修剪文本 ellipsis:显示省略符号来代表被修剪的文本 text-shadow可向文本应用的阴影。能够规定水平阴影、垂直阴影、模糊距离&#xff0c;以…

CCS811二氧化碳传感器详解(STM32)

目录 一、介绍 二、传感器原理 1.原理图 2.引脚描述 3.工作原理介绍 三、程序设计 main.c文件 ccs811.h文件 ccs811.c文件 四、实验效果 五、资料获取 项目分享 一、介绍 CCS811模块是一种气体传感器&#xff0c;可以测量环境中TVOC(总挥发性有机物质)浓度和eCO2…