使用 ECharts GL 实现交互式 3D 饼图:技术解析与实践
一、效果概览
本文基于 Vue 3 和 ECharts GL,实现了一个具有以下特性的 3D 饼图:
- 立体视觉效果:通过参数方程构建 3D 扇形与底座
- 动态交互:支持点击选中(位移效果)和悬停高亮(放大效果)
- 混合渲染:结合 3D 曲面与 2D 饼图标签
- 风格化设计:暗色背景搭配网格纹理,增强科技感
二、核心技术实现
1. 环境准备
import { ref, onMounted } from "vue";
import * as echarts from "echarts";
import "echarts-gl"; // 引入 3D 扩展
2. 参数方程生成器
核心函数 getParametricEquation
通过数学公式动态构建 3D 曲面:
function getParametricEquation(startRatio, endRatio, isSelected, isHovered, k, h) {// 计算弧度范围const startRadian = startRatio * Math.PI * 2;const endRadian = endRatio * Math.PI * 2;// 动态参数控制const offsetX = isSelected ? Math.cos(midRadian) * 0.1 : 0;const hoverRate = isHovered ? 1.5 : 1;return {u: { min: -Math.PI, max: Math.PI * 3 },v: { min: 0, max: Math.PI * 2 },x: (u, v) => offsetX + Math.cos(u) * (1 + Math.cos(v)*k) * hoverRate,y: (u, v) => offsetY + Math.sin(u) * (1 + Math.cos(v)*k) * hoverRate,z: (u, v) => (Math.sin(v) > 0 ? h*0.1 : -1)};
}
- u/v:定义曲面参数范围
- hoverRate:悬停时放大系数(1.5倍)
- offsetX/Y:选中时的位移偏移
3. 复合图表配置
通过 getPie3D
生成多层结构:
function getPie3D(pieData, internalDiameterRatio) {const series = [];// 生成数据扇形pieData.forEach(item => {series.push({type: "surface",parametric: true,itemStyle: { color: item.itemStyle.color },parametricEquation: getParametricEquation(...)});});// 添加红色底座series.push({parametricEquation: {x: (u, v) => Math.sin(v)*0.6*Math.sin(u),z: () => Math.cos(v) > 0 ? 0.8 : -0.2},itemStyle: { color: "#2c68ac" }});// 透明支撑环(用于鼠标事件)series.push({itemStyle: { opacity: 0 },parametricEquation: {...}});return { series, grid3D: {...}, tooltip: {...} };
}
- 底座设计:通过两个红色圆柱增强立体层次感
- 透明环:解决 3D 曲面鼠标事件穿透问题
4. 交互事件处理
// 点击选中
myChart.on("click", (params) => {const target = option.series[params.seriesIndex];target.parametricEquation = getParametricEquation(..., true); // 触发位移
});// 悬停高亮
myChart.on("mouseover", (params) => {option.series[params.seriesIndex].parametricEquation = getParametricEquation(..., hoverBarHeight); // 修改高度
});// 全局恢复
myChart.on("globalout", () => {series.forEach(item => item.parametricEquation.z = defaultBarHeight);
});
三、样式优化技巧
1. 背景网格
.chart-container::before {background-image: linear-gradient(#0e2a47 1px, transparent 1px),linear-gradient(90deg, #0e2a47 1px, transparent 1px);background-size: 20px 20px;
}
2. 标签融合
{type: "pie",label: {formatter: "{b}\n{@percent}%",position: "outside",opacity: 0 // 通过 2D 饼图实现标签},itemStyle: { opacity: 0 } // 隐藏 2D 图形
}
四、最佳实践建议
-
性能优化:
- 调整
u/v.step
值平衡渲染质量与性能 - 禁用非必要特效(如 postEffect)
- 调整
-
扩展方向:
- 增加
autoRotate
实现自动旋转 - 结合
dataset
实现动态数据更新
- 增加
-
调试技巧:
- 临时设置
wireframe: { show: true }
观察曲面结构 - 使用
viewControl
调整初始视角
- 临时设置
五、完整代码
<template><div class="chart-container"><div ref="chartRef" class="chart"></div></div>
</template><script setup>
import { ref, onMounted } from "vue";
import * as echarts from "echarts";
import "echarts-gl";const chartRef = ref(null);
// 默认柱状图高度
const defaultBarHeight = 30;
// 鼠标滑过高度
const hoverBarHeight = 40;onMounted(() => {const chartDom = chartRef.value;const myChart = echarts.init(chartDom);/*** 生成3D扇形的曲面参数方程* @param {number} startRatio - 起始比例 (0~1)* @param {number} endRatio - 结束比例 (0~1)* @param {boolean} isSelected - 是否选中状态* @param {boolean} isHovered - 是否悬停状态* @param {number} k - 辅助参数,控制扇形厚度* @param {number} h - 柱状图高度* @returns {Object} 曲面参数方程,包含u/v范围和x/y/z坐标函数*/function getParametricEquation(startRatio,endRatio,isSelected,isHovered,k,h) {// 计算中间比例和弧度值// 将比例(0~1)转换为弧度值(0~2π),用于三角函数计算let midRatio = (startRatio + endRatio) / 2;let startRadian = startRatio * Math.PI * 2; // 起始弧度let endRadian = endRatio * Math.PI * 2; // 结束弧度let midRadian = midRatio * Math.PI * 2; // 中间弧度// 如果只有一个扇形,则不实现选中效果。if (startRatio === 0 && endRatio === 1) {isSelected = false;}// 通过扇形内径/外径的值,换算出辅助参数 k(默认值 1/3)k = typeof k !== "undefined" ? k : 1 / 3;// 计算选中效果分别在 x/y 轴方向上的位移// 使用三角函数计算位移方向,0.1为位移幅度系数// 未选中状态位移为0,选中状态根据中间弧度计算位移方向let offsetX = isSelected ? Math.cos(midRadian) * 0.1 : 0;let offsetY = isSelected ? Math.sin(midRadian) * 0.1 : 0;// 计算高亮效果的放大比例// hoverRate=0.5表示悬停时放大50%,通过参数方程中的乘法实现let hoverRate = 0.5;// 返回曲面参数方程return {u: {min: -Math.PI,max: Math.PI * 3,step: Math.PI / 32,},v: {min: 0,max: Math.PI * 2,step: Math.PI / 20,},// x坐标函数:根据u/v参数计算曲面x坐标// 公式分解:// 1. Math.cos(u) - 基础圆形路径// 2. (1 + Math.cos(v) * k) - 控制扇形厚度// 3. hoverRate - 悬停放大系数// 4. offsetX - 选中位移x: function (u, v) {if (u < startRadian) {return (offsetX + Math.cos(startRadian) * (1 + Math.cos(v) * k) * hoverRate);}if (u > endRadian) {return (offsetX + Math.cos(endRadian) * (1 + Math.cos(v) * k) * hoverRate);}return offsetX + Math.cos(u) * (1 + Math.cos(v) * k) * hoverRate;},y: function (u, v) {if (u < startRadian) {return (offsetY + Math.sin(startRadian) * (1 + Math.cos(v) * k) * hoverRate);}if (u > endRadian) {return (offsetY + Math.sin(endRadian) * (1 + Math.cos(v) * k) * hoverRate);}return offsetY + Math.sin(u) * (1 + Math.cos(v) * k) * hoverRate;},z: function (u, v) {if (u < -Math.PI * 0.5) {return Math.sin(u);}if (u > Math.PI * 2.5) {return Math.sin(u) * h * 0.1;}return (Math.sin(v) > 0 ? 1 * h * 0.1 : -1) + 1;},};}/*** 生成3D饼图的完整配置项* @param {Array} pieData - 饼图数据数组* @param {number} internalDiameterRatio - 内径/外径比例* @returns {Object} ECharts配置项,包含series和legend等*/function getPie3D(pieData, internalDiameterRatio) {let series = [];let sumValue = 0;let startValue = 0;let endValue = 0;let legendData = [];let k =typeof internalDiameterRatio !== "undefined"? (1 - internalDiameterRatio) / (1 + internalDiameterRatio): 1 / 3;// 为每一个饼图数据,生成一个 series-surface 配置for (let i = 0; i < pieData.length; i++) {sumValue += pieData[i].value;let seriesItem = {name:typeof pieData[i].name === "undefined"? `series${i}`: pieData[i].name,type: "surface",parametric: true,wireframe: {show: false,},pieData: pieData[i],pieStatus: {selected: false,hovered: false,k: k,},};if (typeof pieData[i].itemStyle != "undefined") {let itemStyle = {};typeof pieData[i].itemStyle.color != "undefined"? (itemStyle.color = pieData[i].itemStyle.color): null;typeof pieData[i].itemStyle.opacity != "undefined"? (itemStyle.opacity = pieData[i].itemStyle.opacity): null;seriesItem.itemStyle = itemStyle;}series.push(seriesItem);}// 使用上一次遍历时,计算出的数据和 sumValue,调用 getParametricEquation 函数,// 向每个 series-surface 传入不同的参数方程 series-surface.parametricEquation,也就是实现每一个扇形。for (let i = 0; i < series.length; i++) {endValue = startValue + series[i].pieData.value;series[i].pieData.startRatio = startValue / sumValue;series[i].pieData.endRatio = endValue / sumValue;series[i].parametricEquation = getParametricEquation(series[i].pieData.startRatio,series[i].pieData.endRatio,false,false,k,defaultBarHeight);startValue = endValue;legendData.push(series[i].name);}// 添加两个红色圆柱底座series.push({name: "base1",type: "surface",parametric: true,silent: true,wireframe: {show: false,},itemStyle: {color: "#2c68ac",opacity: 1},parametricEquation: {u: {min: 0,max: Math.PI * 2,step: Math.PI / 40,},v: {min: 0,max: Math.PI,step: Math.PI / 40,},x: function (u, v) {return Math.sin(v) * 0.6 * Math.sin(u) + Math.sin(u) * 0.6;},y: function (u, v) {return Math.sin(v) * 0.6 * Math.cos(u) + Math.cos(u) * 0.6;},z: function (u, v) {return Math.cos(v) > 0 ? 0.8 : -0.2;},},});series.push({name: "base2",type: "surface",parametric: true,silent: true,wireframe: {show: false,},itemStyle: {color: "#1b4475",opacity: 1},parametricEquation: {u: {min: 0,max: Math.PI * 2,step: Math.PI / 40,},v: {min: 0,max: Math.PI,step: Math.PI / 40,},x: function (u, v) {return Math.sin(v) * 0.7 * Math.sin(u) + Math.sin(u) * 0.7;},y: function (u, v) {return Math.sin(v) * 0.7 * Math.cos(u) + Math.cos(u) * 0.7;},z: function (u, v) {return -1;},},});// 补充一个透明的圆环,用于支撑高亮功能的近似实现。series.push({name: "mouseoutSeries",type: "surface",parametric: true,wireframe: {show: false,},itemStyle: {opacity: 0,},parametricEquation: {u: {min: 0,max: Math.PI * 2,step: Math.PI / 20,},v: {min: 0,max: Math.PI,step: Math.PI / 20,},x: function (u, v) {return Math.sin(v) * Math.sin(u) + Math.sin(u);},y: function (u, v) {return Math.sin(v) * Math.cos(u) + Math.cos(u);},z: function (u, v) {return Math.cos(v) > 0 ? 0.1 : -0.1;},},});// 准备待返回的配置项,把准备好的 legendData、series 传入。let option = {//animation: false,legend: {data: legendData,orient: "vertical",right: "5%",top: "center",itemGap: 20,textStyle: {color: "#fff",fontSize: 14,// fontWeight: 'bold', // 增加字体加粗},},tooltip: {formatter: (params) => {if (params.seriesName !== "mouseoutSeries") {const value =option.series[params.seriesIndex]?.pieData?.value || "";return `${params.seriesName}<br/><span style="display:inline-block;margin-right:5px;border-radius:10px;width:10px;height:10px;background-color:${params.color};"></span>${value}`;}},},xAxis3D: {min: -1,max: 1,},yAxis3D: {min: -1,max: 1,},zAxis3D: {min: -1,max: 1,},grid3D: {show: false,boxHeight: 10,viewControl: {alpha: 45,distance: 250,rotateSensitivity: 0,zoomSensitivity: 0,panSensitivity: 0,autoRotate: false,},},series: series,};return option;}let data = [{value: 60,name: "通过",itemStyle: { color: "#82C3FF" },},{value: 6,name: "不通过",itemStyle: { color: "#FFB042" },},{value: 18,name: "待审核",itemStyle: { color: "#61D6E2" },},];// 传入数据生成 optionlet option = getPie3D(data, 0);// 监听鼠标事件,实现饼图选中效果(单选),近似实现高亮(放大)效果。let selectedIndex = "";let hoveredIndex = "";// 监听点击事件,实现选中效果(单选)// 原理:通过修改参数方程中的offsetX/Y实现扇形位移效果myChart.on("click", function (params) {// 目标对象const target = option.series[params.seriesIndex] || {};// 从 option.series 中读取重新渲染扇形所需的参数,将是否选中取反。let isSelected = !target?.pieStatus?.selected;let isHovered = target?.pieStatus?.hovered;let k = target?.pieStatus?.k;let startRatio = target?.pieData?.startRatio;let endRatio = target?.pieData?.endRatio;const pieData = option.series[selectedIndex]?.pieData || {};// 如果之前选中过其他扇形,将其取消选中(对 option 更新)if (selectedIndex !== "" && selectedIndex !== params.seriesIndex) {option.series[selectedIndex].parametricEquation = getParametricEquation(pieData.startRatio,pieData.endRatio,false,false,k,defaultBarHeight);option.series[selectedIndex].pieStatus.selected = false;}// 对当前点击的扇形,执行选中/取消选中操作(对 option 更新)option.series[params.seriesIndex].parametricEquation =getParametricEquation(startRatio,endRatio,isSelected,isHovered,k,defaultBarHeight);option.series[params.seriesIndex].pieStatus.selected = isSelected;// 如果本次是选中操作,记录上次选中的扇形对应的系列号 seriesIndexisSelected ? (selectedIndex = params.seriesIndex) : null;// 使用更新后的 option,渲染图表myChart.setOption(option);});// 监听 mouseover,近似实现高亮(放大)效果// 原理:通过修改参数方程中的hoverRate实现放大效果myChart.on("mouseover", function (params) {// 准备重新渲染扇形所需的参数let isSelected;let startRatio;let endRatio;let k;let isHoveredNew = false;// 如果触发 mouseover 的扇形当前已高亮,则不做操作if (hoveredIndex === params.seriesIndex) {return;// 否则进行高亮及必要的取消高亮操作} else {// 如果当前有高亮的扇形,取消其高亮状态(对 option 更新)if (hoveredIndex !== "") {const hoverTarget = option.series[hoveredIndex] || {};// 从 option.series 中读取重新渲染扇形所需的参数,将是否高亮设置为 false。isSelected = hoverTarget?.pieStatus?.selected;isHoveredNew = false;startRatio = hoverTarget?.pieData?.startRatio;endRatio = hoverTarget?.pieData?.endRatio;k = hoverTarget?.pieStatus.k;// 对当前点击的扇形,执行取消高亮操作(对 option 更新)option.series[hoveredIndex].parametricEquation = getParametricEquation(startRatio,endRatio,isSelected,isHoveredNew,k,defaultBarHeight);option.series[hoveredIndex].pieStatus.hovered = isHoveredNew;// 将此前记录的上次选中的扇形对应的系列号 seriesIndex 清空hoveredIndex = "";}// 如果触发 mouseover 的扇形不是透明圆环,将其高亮(对 option 更新)if (params.seriesName !== "mouseoutSeries") {const seriesSeries = option.series[params.seriesIndex] || {};// 从 option.series 中读取重新渲染扇形所需的参数,将是否高亮设置为 true。isSelected = seriesSeries?.pieStatus?.selected;isHoveredNew = true;startRatio = seriesSeries?.pieData?.startRatio;endRatio = seriesSeries?.pieData?.endRatio;k = seriesSeries?.pieStatus?.k;// 对当前点击的扇形,执行高亮操作(对 option 更新)option.series[params.seriesIndex].parametricEquation =getParametricEquation(startRatio,endRatio,isSelected,isHoveredNew,k,hoverBarHeight);if (option.series[params.seriesIndex]?.pieStatus) {option.series[params.seriesIndex].pieStatus.hovered = isHoveredNew;} else {option.series[params.seriesIndex].pieStatus = {hovered: isHoveredNew,};}// 记录上次高亮的扇形对应的系列号 seriesIndexhoveredIndex = params.seriesIndex;}// 使用更新后的 option,渲染图表myChart.setOption(option);}});// 修正取消高亮失败的 bugmyChart.on("globalout", function () {let isHoveredNew = false;let k;if (hoveredIndex !== "") {const curSeries = option.series[hoveredIndex] || {};// 从 option.series 中读取重新渲染扇形所需的参数,将是否高亮设置为 true。let isSelected = curSeries.pieStatus?.selected;k = curSeries?.pieStatus?.k;let startRatio = curSeries?.pieData?.startRatio;let endRatio = curSeries?.pieData?.endRatio;// 对当前点击的扇形,执行取消高亮操作(对 option 更新)option.series[hoveredIndex].parametricEquation = getParametricEquation(startRatio,endRatio,isSelected,isHoveredNew,k,defaultBarHeight);option.series[hoveredIndex].pieStatus.hovered = isHoveredNew;// 将此前记录的上次选中的扇形对应的系列号 seriesIndex 清空hoveredIndex = "";}// 使用更新后的 option,渲染图表myChart.setOption(option);});option.series.push({name: "pie2d",type: "pie",labelLine: {length: 40,length2: 120,lineStyle: {width: 2,},},label: {opacity: 1,show: true,position: "outside",fontSize: 16,itemStyle: {color: "#fff",fontSize: 14,fontWeight: "bold",fontFamily: "Arial, sans-serif",},textStyle: {color: "#fff",lineHeight: 30,rich: {top: {verticalAlign: "middle",padding: [0, 0, 0, 0],},bottom: {verticalAlign: "middle",padding: [0, 0, 0, 0],},},},formatter: (params) => {return `${params.name}\n${params.percent}%`;},},startAngle: -66, //起始角度,支持范围[0, 360]。clockwise: false, //饼图的扇区是否是顺时针排布。上述这两项配置主要是为了对齐3d的样式radius: ["40%", "36%"],// center: ['55%', '48%'], //指示线的位置data: data,itemStyle: {opacity: 0,},});myChart.setOption(option);// 组件卸载时清除事件监听return () => {window.removeEventListener("resize", resizeChart);myChart.dispose();};
});
</script><style scoped>
.chart-container {width: 100%;height: 100vh;background-color: #001529;display: flex;justify-content: center;align-items: center;position: relative;
}.chart {width: 800px;height: 600px;
}/* 添加网格背景 */
.chart-container::before {content: "";position: absolute;top: 0;left: 0;width: 100%;height: 100%;background-image: linear-gradient(#0e2a47 1px, transparent 1px),linear-gradient(90deg, #0e2a47 1px, transparent 1px);background-size: 20px 20px;opacity: 0.3;z-index: 0;
}.chart {z-index: 1;
}
</style>
通过本文方案,开发者可快速构建具有强交互性的 3D 数据可视化组件。关键点在于参数方程的灵活运用与事件系统的深度集成,这种模式可扩展至其他 3D 图表类型(如柱状图、散点图)的开发。
相关文章:
使用 ECharts GL 实现交互式 3D 饼图:技术解析与实践
一、效果概览 本文基于 Vue 3 和 ECharts GL,实现了一个具有以下特性的 3D 饼图: 立体视觉效果:通过参数方程构建 3D 扇形与底座动态交互:支持点击选中(位移效果)和悬停高亮(放大效果ÿ…...
allure生成测试报告(搭配Pytest、allure-pytest)
文章目录 前言allure简介allure安装软件下载安装配置环境变量安装成功验证 allure运行流程allure装饰器函数基本说明装饰器函数使用allure.attach 命令行运行利用allure-pytest生成中间结果json 查看测试报告总览页面每个tab页的说明类别页面测试套图表页面时间刻度功能页面包 …...
一场陟遐自迩的 SwiftUI + CoreData 性能优化之旅(下)
概述 自从 SwiftUI 诞生那天起,我们秃头码农们就仿佛打开了一个全新的撸码世界,再辅以 CoreData 框架的鼎力相助,打造一款持久存储支持的 App 就像探囊取物般的 Easy。 话虽如此,不过 CoreData 虽好,稍不留神也可能会…...
java的输入输出模板(ACM模式)
文章目录 1、前置准备2、普通输入输出API①、输入API②、输出API 3、快速输入输出API①、BufferedReader②、BufferedWriter 案例题目描述代码 面试有时候要acm模式,刷惯leetcode可能会手生不会acm模式,该文直接通过几个题来熟悉java的输入输出模板&…...
浏览器自动化与网络爬虫实战:工具对比与选型指南
浏览器自动化与网络爬虫实战:工具对比与选型指南 摘要 在当今数字化时代,浏览器自动化和网络爬虫技术已成为数据收集与测试的重要工具。本文深入剖析了多种主流浏览器自动化工具和爬虫框架的特点、优缺点及其适用场景,包括 Selenium、Puppe…...
“双非” “退伍” “材料” “学验证” 拿到Dream Offer
大家好,我是2024年路科验证V2X春季班的学员。在春季班的课上完后,觉得自己的基础大部分已经被路科给弥补了,但是很多课程中关于框架的搭建和一些细节还是不够扎实,有所欠缺,于是又重修了秋季班的课程。这两次课程给我的…...
python 上海新闻爬虫, 上观新闻 + 腾讯新闻
1. 起因, 目的: 继续爬上海新闻, 增加新闻来源。昨天写了: 东方网 澎湃新闻今天增加2个来源: 上观新闻 腾讯新闻此时有4个来源,我觉得已经差不多了。 2. 先看效果 3. 过程: 代码 1, 上观新闻 这里也有一个有趣的…...
【LUT技术专题】ECLUT代码解读
目录 原文概要 1. 训练 2. 转表 3. 测试 本文是对ECLUT技术的代码解读,原文解读请看ECLUT。 原文概要 ECLUT通过EC模块增大网络感受野,提升超分效果,实现SRLUT的改进,主要是2个创新点: 提出了一个扩展卷积&…...
Wsl2 网络模式介绍
每个模式说明参考下面连接 使用 WSL 访问网络应用程序 | Microsoft Learn...
项目高压生存指南:科学重构身体与认知系统的抗压算法
引言:压力重构的工程学思维 在项目管理的高压熔炉中,优秀从业者与普通执行者的核心差异不在于抗压能力的高低,而在于是否掌握压力管理的系统化算法。本文摒弃传统的鸡汤式减压建议,从人体工程学、神经科学和认知心理学角度&#…...
Java设计模式之工厂方法模式:从入门到精通
1. 工厂方法模式概述 1.1 定义与核心思想 工厂方法模式(Factory Method Pattern) **定义:**是一种创建型设计模式,它定义了一个用于创建对象的接口,但让子类决定实例化哪一个类。工厂方法使一个类的实例化延迟到其子类。 **核心思想:**工厂模式的核心思想是将对象的创建…...
生成自定义的androidjar文件具体操作
在Androidsdk目录下的platform找到对应的api的android源码包路径,如android-32拷贝里面的android.jar文件到目录,如 C:\Users\xxxxxxx\Desktop\android\new_android_jar,然后解压android.jar到目录new_android_jar下。在编译后的aosp源码中找…...
在一台CentOS服务器上开启多个MySQL服务
1. 创建目录 mkdir -p /data/mysql3307/{data,tmp,logs} # 赋权 chown -R mysql:mysql /data/mysql3307 chmod -R 750 /data/mysql3307 2.修改 /etc/my.cnf ,添加[mysqld3307]实例配置组 [mysqld3307] # MySQL服务的端口 port 3307 # 套接字文件存放路径 socket /…...
相机的方向和位置
如何更好的控制相机按照我们需要来更好的观察我们需要的地貌呢? 使用 // setview瞬间到达指定位置,视角//生成position是天安门的位置var position Cesium.Cartesian3.fromDegrees(116.397428,39.90923,100)viewer.camera.setView({//指定相机位置destination: position, 在…...
云原生架构下的微服务通信机制演进与实践
📝个人主页🌹:慌ZHANG-CSDN博客 🌹🌹期待您的关注 🌹🌹 一、引言:通信机制是微服务架构的基础 随着软件系统复杂度的提升,“单体架构 → 微服务架构 → 云原生架构”逐步成为企业数字化转型的演进主线。而在微服务架构中,“服务间通信机制”决定了系统的稳定性…...
Git标签删除脚本解析与实践:轻松管理本地与远程标签
Git 标签删除脚本解析与实践:轻松管理本地与远程标签 在 Git 版本控制系统中,标签常用于标记重要的版本节点,方便追溯和管理项目的不同阶段。随着项目的推进,一些旧标签可能不再需要,此时就需要对它们进行清理。本文将通过一个完整的脚本,详细介绍如何删除本地和远程的 …...
5G让媒体传播更快更智能——技术赋能内容新时代
5G让媒体传播更快更智能——技术赋能内容新时代 在5G时代,媒体传播已经不再是传统的“电视纸媒网站”模式,而是演变成超低延迟、高速传输、智能交互的全新生态。无论是直播、短视频、VR/AR内容还是AI驱动的个性化推荐,5G的高速连接能力都在让…...
数字IC前端学习笔记:锁存器的综合
相关阅读 数字IC前端专栏https://blog.csdn.net/weixin_45791458/category_12173698.html?spm1001.2014.3001.5482 锁存器是一种时序逻辑,与寄存器相比面积更小,但它的存在会使静态时序分析(STA)变得更加复杂,因此懂得什么样的设计会综合出…...
Spring Boot快速开发:从零开始搭建一个企业级应用
Spring Boot快速开发:从零开始搭建一个企业级应用 在当今的软件开发领域,Spring Boot已经成为构建企业级应用的首选框架之一。它不仅简化了Spring应用的初始搭建以及开发过程,还提供了许多开箱即用的功能,使得开发者能够快速地构…...
ATH12K驱动框架架构图
ATH12K驱动框架架构图 ATH12K驱动框架架构图(分层描述)I. 顶层架构II. 核心数据结构层次关系III. 主要模块详解1. 核心模块 (Core)2. 硬件抽象层 (HAL)3. 无线管理接口 (WMI)4. 主机目标通信 (HTC)5. 复制引擎 (CE)6. MAC层7. 数据路径 (DP)IV. 关键数据流路径1. 发送数据流 …...
数字信号处理|| 离散序列的基本运算
一、实验目的 (1)进一步了解离散时间序列时域的基本运算。 (2)了解MATLAB语言进行离散序列运算的常用函数,掌握离散序列运算程序的编写方法。 二、实验涉及的MATLAB子函数 (1)find 功能:寻找非零元素的索…...
集成管理工具Gitlab
GitLab 是一个功能强大的开源代码托管和协作平台,集成 GitLab 可以显著提升团队的开发效率。下面我将为你介绍如何集成 GitLab,包括安装配置和基本使用流程。 一、GitLab 安装与配置 GitLab 有多种安装方式,推荐使用官方 Omnibus 包安装&am…...
2025 年数维杯数学建模 C 题完整论文代码模型:清明时节雨纷纷,何处踏青不误春
《2025 年数维杯数学建模 C 题完整论文代码模型》 C题完整论文 一、问题重述 1.1 问题背景 2025 年第十届数维杯大学生数学建模挑战赛 C 题,将我们带入“清明时节雨纷纷,何处踏青不误春”的诗意情境。清明节,这个处于每年 4 月 4 日至 6 …...
2025数维杯数学建模C题完整限量论文:清明时节雨纷纷,何处踏青不误春?
2025数维杯数学建模C题完整限量论文:清明时节雨纷纷,何处踏青不误春? 清明节,在每年 4 月 4 日至 6 日之间,既是自然节气,也是我国重要 的传统节日,承载着中华民族千年的文化记忆与情感寄托。此…...
POSE识别 神经网络
Pose 识别模型介绍 Pose 识别是计算机视觉领域的一个重要研究方向,其目标是从图像或视频中检测出人体的关键点位置,从而估计出人体的姿态。这项技术在许多领域都有广泛的应用,如动作捕捉、人机交互、体育分析、安防监控等。 Pose 识别模型的…...
Missashe高数强化学习笔记(随时更新)
Missashe高数强化学习笔记 说明:这篇笔记用于博主对高数强化课所学进行记录和总结。由于部分内容写在博主的日记博客里,所以博主会不定期将其重新copy到本篇笔记里。 第一章 函数极限连续 第二章 一元函数微分学 第三章 一元函数积分学 第一节 不定…...
如何从极狐GitLab 容器镜像库中删除容器镜像?
极狐GitLab 是 GitLab 在中国的发行版,关于中文参考文档和资料有: 极狐GitLab 中文文档极狐GitLab 中文论坛极狐GitLab 官网 从容器镜像库中删除容器镜像 (BASIC ALL) 您可以从您的容器镜像库中删除容器镜像。 要基于特定标准自动删除容器镜像&#x…...
出现在‘{‘的段错误
今天在运行程序时,程序因段错误退出了,于是使用gdb调试。 部分输出如下: [New Thread 0x7fffc88be6c0 (LWP 47902)] [New Thread 0x7fffc80bd6c0 (LWP 47903)] [New Thread 0x7…...
【C++设计模式之Observer观察者模式】
Observer观察者模式 模式定义动机(Motivation)结构(Structure)应用场景一(气象站)实现步骤1.定义观察者接口2.定义被观察者(主题)接口3.实现具体被观察者对象(气象站)4.实现具体观察者(例如:显示屏)5.main.cpp中使用示例6.输出结果7. 关键点 …...
【软件测试】测试用例的概念与常见测试的模型
目录 一、测试用例的概念 1.1 什么是测试用例 1.2 编写测试用例的目的 1.3 用例设计的编写格式 二、模型 2.1 质量模型 2.2 测试模型 2.2.1 瀑布模型 2.2.2 螺旋模型 2.2.3 V 模型 2.2.4 W模型 2.2.5 增量、迭代模型 2.2.6 敏捷模型 2.2.6.1 敏捷宣言 2.2.6.2 Sc…...
OpenCV的 ccalib 模块用于自定义标定板的检测和处理类cv::ccalib::CustomPattern()----函数calibrate
操作系统:ubuntu22.04 OpenCV版本:OpenCV4.9 IDE:Visual Studio Code 编程语言:C11 算法描述 cv::ccalib::CustomPattern 是OpenCV的 ccalib 模块中的一个类,主要用于自定义标定板的检测和处理。这个模块提供了比传统的 calib3d…...
高效管理钉钉收款单数据集成到MySQL的技术方案
钉钉数据集成到MySQL的技术案例分享:dd-收款单-->mysql(鸿巢)收款单(其他收款) 在企业日常运营中,数据的高效管理和实时处理至关重要。本文将聚焦于一个具体的系统对接集成案例:如何将钉钉平…...
介质访问控制(MAC)
介质访问控制(MAC)详解 介质访问控制(Medium Access Control, MAC)是数据链路层的核心子层,负责解决多个设备共享同一通信介质时的冲突问题。它的核心目标是:在广播或多路访问网络中,确保数据有…...
在Mac M1/M2上使用Hugging Face Transformers进行中文文本分类(完整指南)
在Mac M1/M2上使用Hugging Face Transformers进行中文文本分类(完整指南) 前言 随着Apple Silicon芯片(M1/M2)的普及,越来越多的开发者希望在Mac上运行深度学习任务。本文将详细介绍如何在Mac M1/M2设备上使用Huggin…...
企业如何将钉钉付款单高效集成到金蝶云星空?
钉钉数据集成到金蝶云星空:修改下推的付款单③ 在企业信息化系统中,数据的高效流转和准确对接是实现业务流程自动化的关键。本文将分享一个实际案例,展示如何通过轻易云数据集成平台,将钉钉中的付款单数据无缝集成到金蝶云星空系…...
软件确认报告:审查功能、评估标准及推动软件稳定高效运行
软件确认报告的主要任务是严格审查软件的各项功能,以此为基础,为精确评估其是否满足标准提供依据,并推动软件实现稳定与高效的运行。具体来说,报告将从目的、背景、所依据的资料、采用的测试手段以及最终的测试成效等几个方面进行…...
Github 热点项目 Cursor开源代替,AI代理+可视化编程!支持本地部署的隐私友好型开发神器。
Void编辑器今天必须拥有姓名!作为总星数近1.5万的顶流开源工具,它用三大绝活圈粉无数:① 隐私党狂喜!所有AI对话直连模型商,你的代码数据绝不留在别人服务器;② 自带时光机功能,AI修改代码时自动…...
影像超分——从低清到高清的跨越密码
在数字时代,影像超分技术宛如魔法般存在,它能让老旧模糊的照片焕发新生但目前面临着高计算量、稳定性不足,压缩与量化误差影响大,退化模型的估计难度高等痛点与挑战,本文将围绕影像超分的工作技术原理、应用场景等展开…...
Vue项目---懒加载的应用
懒加载 介绍原理展示详细解析模版部分脚本部分数据和变量IntersectionObserver加载更多数据生命周期钩子 代码Mock数据前端代码 介绍 懒加载(Lazy Loading)是一种常见的前端优化技术,用于延迟加载页面上的资源(如图片、视频、组件…...
前端自学入门:HTML 基础详解与学习路线指引
在互联网的浪潮中,前端开发如同构建数字世界的基石,而 HTML 则是前端开发的 “入场券”。对于许多渴望踏入前端领域的初学者而言,HTML 入门是首要挑战。本指南将以清晰易懂的方式,带大家深入了解 HTML 基础,并梳理前端…...
机器学习 期末考试题
自测试卷1 一、选择题 1.下面关于数据分析说法正确的是( )。 A.数据分析是数学、统计学理论结合科学的统计分析方法 B.数据分析是一种数学分析方法 C.数据分析是统计学分析方法 D.数据分析是大数据分析方法 2.下面不是数据分析方法的是( )。 A.同比分析 B.环比分析…...
BP神经网络
一、BP 神经网络概述 BP(Back Propagation)神经网络是一种按照误差逆向传播算法训练的多层前馈神经网络,它是目前应用最广泛的神经网络模型之一。BP 神经网络由输入层、隐藏层和输出层组成,隐藏层可以有一层或多层。其学习过程由正…...
使用 NSSM 安装 Tomcat 11.0.6 为 Windows 服务
步骤 1:下载 NSSM 访问 NSSM 的官方网站:NSSM Download 下载适合您系统的版本(通常是 nssm-<version>-win64.zip 或 nssm-<version>-win32.zip)。 解压下载的文件。 步骤 2:将 NSSM 移动到 Tomcat 目录…...
拉西坦类促智药物的异同
吡拉西坦及其主要同类药物的深度研究报告 以下表格总结了本报告所讨论的主要拉西坦类药物的关键特性,以便进行直接比较。 表1:主要拉西坦类药物特性比较 特性 吡拉西坦 (Piracetam) 阿尼西坦 (Aniracetam) 奥拉西坦 (Oxiracetam) 普拉西坦 (Pramir…...
高级可视化图表分析实践——以《大侠立志传》武器系统为例
高级可视化图表分析实践——以《大侠立志传》武器系统为例 引言武器类型分布矩形树图结论 不同品质/类别武器的攻击力分布情况蜂群图分析结论 武器来源桑基图分析结论 武器附加属性词云图分析结论 不同品级武器装备熟练度要求/特质要求离散热力图结论品质与熟练度的正相关性品质…...
HT71663同步升压2.7V-13V输入10A聚能芯半导体禾润一级代理
在便携式设备飞速发展的今天,电源转换效率与产品尺寸始终是行业难以平衡的难题。但现在,HT71663 高功率全集成升压转换器强势登场,一举打破僵局,为便携式系统带来颠覆性的高效小尺寸解决方案! HT71663 的卓越性能&am…...
3D桌面可视化开发平台HOOPS Native Platform,如何实现3D系统快速开发与部署?
无论是制造、工程还是软件行业,高效的3D应用开发能力都直接影响着产品创新、客户体验和市场响应速度。HOOPS技术,凭借领先的技术实力和广泛的行业应用,正成为推动企业数字化转型、驱动业务增长的核心引擎。本文将深入解析HOOPS技术的优势&…...
DeepResearch深度搜索实现方法调研
DeepResearch深度搜索实现方法调研 Deep Research 有三个核心能力 能力一:自主规划解决问题的搜索路径(生成子问题,queries,检索)能力二:在探索路径时动态调整搜索方向(刘亦菲最好的一部电影是…...
使用Python删除PDF中多余或空白的页面
目录 为什么需要删除 PDF 中的多余或空白页面? 所需工具 环境准备 如何使用Python删除PDF中的多余页面 实现思路 详细实现步骤 实现代码 如何使用Python检测并删除PDF中的空白页 实现思路 详细实现步骤 实现代码 在处理 PDF 文件时,常常会遇到…...
什么是分布式光伏系统?屋顶分布式光伏如何并网?
政策窗口倒计时!分布式光伏如何破局而立? 2025年,中国分布式光伏行业迎来关键转折: ▸ "430"落幕——抢装潮收官,但考验才刚开始; ▸ "531"生死线——新增项目全面市场化交易启动&…...