vue3 3d餅圖

完整3D餅圖項目下載 https://download.csdn.net/download/weixin_54645059/91716476 只有一個vue文件 直接下滑到完整代碼就闊以

本文介紹了如何使用ECharts和ECharts-GL插件實現3D餅圖效果,并提出了數值顯示未解決的問題。主要包含以下內容:

安裝所需插件:yarn add echartsyarn add echarts-gl
提供了完整的Vue3組件代碼,包括3D餅圖的配置和渲染邏輯
核心功能:
1. 支持自定義餅圖高度和空心比例
2. 實現3D餅圖的參數曲面方程計算
3. 包含鼠標點擊和滑動特效
4. 圖例的選中狀態后 顯示完整的餅圖( selectedMode: true )
作者尚未研究明白如何在每個模塊直接顯示數值,并希望有解決方案的人能給予反饋。該實現通過計算數據百分比和構建3D曲面參數方程來渲染餅圖,但標簽顯示功能目前被注釋掉,需要進一步優化。

效果圖

![在這里插入圖片描述](https://i-blog.csdnimg.cn/direct/1b0314b006dd407fbb8b23f98ddd8bff.png

始終保持圓 isCircle.value = false

在這里插入圖片描述

isCircle.value = true

在這里插入圖片描述

安裝插件

yarn add echarts
yarn add echarts-gl

直接上完整代碼

<template><div class="container"><div class="chartsGl" id="charts"></div></div>
</template><script setup>
import * as echarts from "echarts";
import "echarts-gl";
import { nextTick, onMounted, ref } from "vue";
const pieHeight = ref(20); // 餅圖高度 0 自適應高度  其他值固定高度
const hollow = ref(0); // 空心的大小  0 實心  大于0 小于1 (空心的大小根據數據的大小來決定)onMounted(() => {init();
});
const optionData = ref([{ id: 0, name: "文案1", num: 50, itemStyle: { color: "#2196f3" } },{ id: 1, name: "文案2", num: 10, itemStyle: { color: "#0ce4d1" } },{ id: 2, name: "文案3", num: 20, itemStyle: { color: "#fbc02d" } },{ id: 3, name: "文案4", num: 30, itemStyle: { color: "#ff5252" } },{ id: 4, name: "文案5", num: 40, itemStyle: { color: "#ff9800" } },{ id: 5, name: "文案6", num: 100, itemStyle: { color: "#333" } },
]);const option = ref(null);
const init = () => {const total = optionData.value.reduce((sum, item) => sum + item.num, 0);// 計算每個項的百分比并添加到對象中optionData.value.forEach((item) => ((item.value = item.num), (item.bfb = ((item.value / total) * 100).toFixed(2) + "%")));//構建3d餅狀圖let myChart = echarts.init(document.getElementById("charts"));// 傳入數據生成 option ; getPie3D(數據,透明的空心占比(調節中間空心范圍的0就是普通餅1就很鏤空))option.value = getPie3D(optionData.value, hollow.value);//將配置項設置進去myChart.setOption(option.value);// 是否需要label指引線,如果要就添加一個透明的2d餅狀圖并調整角度使得labelLine和3d的餅狀圖對齊,并再次 setOption// option.value.series.push({//   name: "pie2d",//   type: "pie",//   // color: ["#fbc02d", "#2196f3", "#0ce4d1"],//   labelLine: {//     // length: 15, // 延長線第一段的長度//     // length2: 0, //延長線長度//     // maxSurfaceAngle: 80,//   },//   startAngle: -53, //起始角度,支持范圍[0, 360]。//   clockwise: false, //餅圖的扇區是否是順時針排布。上述這兩項配置主要是為了對齊3d的樣式//   radius: ["20%", "20%"],//   center: ["35%", "44%"],//   data: optionData.value,//   label: {//     alignTo: "edge",//     formatter: "{name|{b}}}",//     size: 30,//     // minMargin: 5,//     // edgeDistance: 10,//     // lineHeight: 15,//     rich: {//       time: {//         // fontSize: 10,//         color: "#999",//       },//     },//   },//   labelLine: {//     // show: true,//   },// });// myChart.setOption(option.value);//鼠標移動上去特效效果bindListen(myChart);
};
const getPie3D = (pieData, internalDiameterRatio) => {let series = [];let sumValue = 0;let startValue = 0;let endValue = 0;let legendData = [];let legendBfb = [];let k = 1 - internalDiameterRatio;// 為每一個餅圖數據,生成一個 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,},//設置餅圖在容器中的位置(目前沒發現啥用)// center: ["50%", "100%"],};//曲面的顏色、不透明度等樣式。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,也就是實現每一個扇形。legendData = [];legendBfb = [];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].pieData.value = pieHeight.value > 0 ? pieHeight.value : series[i].pieData.value;series[i].parametricEquation = getParametricEquation(series[i].pieData.startRatio, series[i].pieData.endRatio, false, false, k, series[i].pieData.value);startValue = endValue;let bfb = fomatFloat(series[i].pieData.value / sumValue, 4);legendData.push({name: series[i].name,value: bfb,});legendBfb.push({name: series[i].name,value: bfb,});}series = series.sort((a, b) => {return a.pieData.id - b.pieData.id;});//(第二個參數可以設置你這個環形的高低程度)let boxHeight = getHeight3D(series, 16); //通過傳參設定3d餅/環的高度// 準備待返回的配置項,把準備好的 legendData、series 傳入。let option = {color: ["#1C9FFD", "#0FF0FF", "#EBC542"],//圖例組件 //右側展示的文案legend: {selectedMode: true,data: legendData,//圖例列表的布局朝向。orient: "vertical",// right: 10,// top: 140,top: "middle",right: "5%",//圖例文字每項之間的間隔itemGap: 15,textStyle: {color: "#333",},show: true,icon: "rect",// 這個可以顯示百分比那種(可以根據你想要的來配置)formatter: function (param) {let item = optionData.value.filter((item) => item.name == param)[0];return `${item.name}: ${item.bfb}`;},},//移動上去提示的文本內容(我沒來得及改 你們可以根據需求改)tooltip: {formatter: (params) => {if (params.seriesName !== "mouseoutSeries" && params.seriesName !== "pie2d") {return (`名稱: ${params.seriesName}<br/>` + `值: ${optionData.value[params.seriesIndex].value}<br/>` + `百分比: ${optionData.value[params.seriesIndex].bfb}`);}},},itemStyle: {borderRadius: 5,},//這個可以變形xAxis3D: {min: -1,max: 1,},yAxis3D: {min: -1,max: 1,},zAxis3D: {min: -1,max: 1,},//此處是修改樣式的重點grid3D: {show: false,boxHeight: boxHeight, //圓環的高度//這是餅圖的位置top: "middle",left: "-15%",viewControl: {//3d效果可以放大、旋轉等,請自己去查看官方配置alpha: 34, //角度(這個很重要 調節角度的)distance: 300, //調整視角到主體的距離,類似調整zoom(這是整體大小)rotateSensitivity: true, //設置為0無法旋轉zoomSensitivity: 0, //設置為0無法縮放panSensitivity: 0, //設置為0無法平移autoRotate: false, //自動旋轉},},series: series,};return option;
};//獲取3d丙圖的最高扇區的高度
const getHeight3D = (series, height) => {if (pieHeight.value > 0) return pieHeight.value;series.sort((a, b) => {return b.pieData.value - a.pieData.value;});return (height * 35) / series[0].pieData.value;
};// 生成扇形的曲面參數方程,用于 series-surface.parametricEquation
const getParametricEquation = (startRatio, endRatio, isSelected, isHovered, k, h) => {// 計算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)let offsetX = isSelected ? Math.cos(midRadian) * 0.1 : 0;let offsetY = isSelected ? Math.sin(midRadian) * 0.1 : 0;// 計算高亮效果的放大比例(未高亮,則比例為 1)let hoverRate = isHovered ? 1.05 : 1;// 返回曲面參數方程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: 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;},};
};//這是一個自定義計算的方法
const fomatFloat = (num, n) => {var f = parseFloat(num);if (isNaN(f)) {return false;}f = Math.round(num * Math.pow(10, n)) / Math.pow(10, n); // n 冪var s = f.toString();var rs = s.indexOf(".");//判定如果是整數,增加小數點再補0if (rs < 0) {rs = s.length;s += ".";}while (s.length <= rs + n) {s += "0";}return s;
};
const bindListen = (myChart) => {let selectedIndex = "";let hoveredIndex = "";// 監聽點擊事件,實現選中效果(單選)myChart.on("click", function (params) {// 從 option.series 中讀取重新渲染扇形所需的參數,將是否選中取反。let isSelected = !option.value.series[params.seriesIndex].pieStatus.selected;let isHovered = option.value.series[params.seriesIndex].pieStatus.hovered;let k = option.value.series[params.seriesIndex].pieStatus.k;let startRatio = option.value.series[params.seriesIndex].pieData.startRatio;let endRatio = option.value.series[params.seriesIndex].pieData.endRatio;// 如果之前選中過其他扇形,將其取消選中(對 option 更新)if (selectedIndex !== "" && selectedIndex !== params.seriesIndex) {option.value.series[selectedIndex].parametricEquation = getParametricEquation(option.value.series[selectedIndex].pieData.startRatio,option.value.series[selectedIndex].pieData.endRatio,false,false,k,option.value.series[selectedIndex].pieData.value);option.value.series[selectedIndex].pieStatus.selected = false;}// 對當前點擊的扇形,執行選中/取消選中操作(對 option 更新)option.value.series[params.seriesIndex].parametricEquation = getParametricEquation(startRatio,endRatio,isSelected,isHovered,k,option.value.series[params.seriesIndex].pieData.value);option.value.series[params.seriesIndex].pieStatus.selected = isSelected;// 如果本次是選中操作,記錄上次選中的扇形對應的系列號 seriesIndexisSelected ? (selectedIndex = params.seriesIndex) : null;// 使用更新后的 option,渲染圖表myChart.setOption(option.value);});// 監聽 mouseover,近似實現高亮(放大)效果myChart.on("mouseover", function (params) {// 準備重新渲染扇形所需的參數let isSelected;let isHovered;let startRatio;let endRatio;let k;// 如果觸發 mouseover 的扇形當前已高亮,則不做操作if (hoveredIndex === params.seriesIndex) {return;// 否則進行高亮及必要的取消高亮操作} else {// 如果當前有高亮的扇形,取消其高亮狀態(對 option 更新)if (hoveredIndex !== "") {// 從 option.series 中讀取重新渲染扇形所需的參數,將是否高亮設置為 false。isSelected = option.value.series[hoveredIndex].pieStatus.selected;isHovered = false;startRatio = option.value.series[hoveredIndex].pieData.startRatio;endRatio = option.value.series[hoveredIndex].pieData.endRatio;k = option.value.series[hoveredIndex].pieStatus.k;// 對當前點擊的扇形,執行取消高亮操作(對 option 更新)option.value.series[hoveredIndex].parametricEquation = getParametricEquation(startRatio,endRatio,isSelected,isHovered,k,option.value.series[hoveredIndex].pieData.value);option.value.series[hoveredIndex].pieStatus.hovered = isHovered;// 將此前記錄的上次選中的扇形對應的系列號 seriesIndex 清空hoveredIndex = "";}// 如果觸發 mouseover 的扇形不是透明圓環,將其高亮(對 option 更新)if (params.seriesName !== "mouseoutSeries" && params.seriesName !== "pie2d") {// 從 option.series 中讀取重新渲染扇形所需的參數,將是否高亮設置為 true。isSelected = option.value.series[params.seriesIndex].pieStatus.selected;isHovered = true;startRatio = option.value.series[params.seriesIndex].pieData.startRatio;endRatio = option.value.series[params.seriesIndex].pieData.endRatio;k = option.value.series[params.seriesIndex].pieStatus.k;// 對當前點擊的扇形,執行高亮操作(對 option 更新)option.value.series[params.seriesIndex].parametricEquation = getParametricEquation(startRatio,endRatio,isSelected,isHovered,k,option.value.series[params.seriesIndex].pieData.value + 5);option.value.series[params.seriesIndex].pieStatus.hovered = isHovered;// 記錄上次高亮的扇形對應的系列號 seriesIndexhoveredIndex = params.seriesIndex;}// 使用更新后的 option,渲染圖表myChart.setOption(option.value);}});// 修正取消高亮失敗的 bugmyChart.on("globalout", function () {// 準備重新渲染扇形所需的參數let isSelected;let isHovered;let startRatio;let endRatio;let k;if (hoveredIndex !== "") {// 從 option.series 中讀取重新渲染扇形所需的參數,將是否高亮設置為 true。isSelected = option.value.series[hoveredIndex].pieStatus.selected;isHovered = false;k = option.value.series[hoveredIndex].pieStatus.k;startRatio = option.value.series[hoveredIndex].pieData.startRatio;endRatio = option.value.series[hoveredIndex].pieData.endRatio;// 對當前點擊的扇形,執行取消高亮操作(對 option 更新)option.value.series[hoveredIndex].parametricEquation = getParametricEquation(startRatio,endRatio,isSelected,isHovered,k,option.value.series[hoveredIndex].pieData.value);option.value.series[hoveredIndex].pieStatus.hovered = isHovered;// 將此前記錄的上次選中的扇形對應的系列號 seriesIndex 清空hoveredIndex = "";}// 使用更新后的 option,渲染圖表myChart.setOption(option.value);});myChart.on("legendselectchanged", function (event) {const { selected } = event; // 獲取當前所有圖例的選中狀態(key:圖例name,value:是否選中)const k = 1 - hollow.value; // 復用空心比例配置optionData.value.forEach((item) => (item.value = item.num));// 1. 篩選選中的原始數據(未選中則排除,選中為空時默認顯示全部)const selectedData = Object.keys(selected).length ? optionData.value.filter((item) => selected[item.name]) : [...optionData.value]; // 無選中時顯示全部// 2. 重新計算篩選后數據的總數值(用于計算扇形比例)const newSumValue = selectedData.reduce((sum, item) => sum + item.value, 0);if (newSumValue === 0) return; // 避免無數據時出錯// 3. 重置起始比例,遍歷選中數據計算新的startRatio/endRatiolet startValue = 0;const dataRatioMap = new Map(); // 存儲{圖例name: {startRatio, endRatio}}selectedData.forEach((item) => {const startRatio = startValue / newSumValue;const endRatio = (startValue + item.value) / newSumValue;dataRatioMap.set(item.name, { startRatio, endRatio });startValue += item.value;});// 4. 遍歷所有3D扇形系列,更新配置(顯示/隱藏、比例、3D形態)option.value.series.forEach((seriesItem) => {const seriesName = seriesItem.name;const isShow = selected[seriesName] ?? true; // 未選中項默認隱藏const pieData = optionData.value.find((item) => item.name === seriesName); // 關聯原始數據const ratioInfo = dataRatioMap.get(seriesName) || { startRatio: 0, endRatio: 0 }; // 未選中項比例置0// 4.1 更新扇形基礎信息(比例、高度)seriesItem.pieData = {...pieData,startRatio: ratioInfo.startRatio,endRatio: ratioInfo.endRatio,value: pieHeight.value > 0 ? pieHeight.value : pieData.value, // 復用高度配置};// 4.2 更新3D參數方程(核心:控制扇形的3D形態和位置)seriesItem.parametricEquation = getParametricEquation(ratioInfo.startRatio, // 新起始比例ratioInfo.endRatio, // 新結束比例seriesItem.pieStatus.selected, // 保留原點擊選中狀態seriesItem.pieStatus.hovered, // 保留原hover狀態k, // 空心比例seriesItem.pieData.value // 扇形高度);// 4.3 隱藏未選中的扇形(通過設置z軸范圍使其不可見)if (!isShow) {seriesItem.parametricEquation.z = () => -2; // 低于可視范圍(原配置z軸max=1)}});option.value.series[1].value = 100;// 5. 重渲染圖表,顯示完整3D餅圖myChart.setOption(option.value);});
};
</script>
<style scoped lang="scss">
//餅圖(外面的容器)
.container {width: 500px;height: 400px;background: #fff;
}
//餅圖的大小
.chartsGl {width: 500px;height: 400px;
}
</style>

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/94177.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/94177.shtml
英文地址,請注明出處:http://en.pswp.cn/web/94177.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

全球電商業財一體化趨勢加速,巨益科技助力品牌出海精細化運營

行業背景&#xff1a;跨境電商進入品牌化發展新階段隨著國內電商市場競爭日趨激烈&#xff0c;跨境電商已成為中國品牌尋求增長突破的重要賽道&#xff0c;在TikTok、Temu等平臺出海浪潮推動下&#xff0c;越來越多的中國品牌開始布局全球市場。然而&#xff0c;從單一市場的鋪…

【序列晉升】13 Spring Cloud Bus微服務架構中的消息總線

Spring Cloud Bus作為微服務架構中的關鍵組件&#xff0c;通過消息代理實現分布式系統中各節點的事件廣播與狀態同步&#xff0c;解決了傳統微服務架構中配置刷新效率低下、系統級事件傳播復雜等問題。它本質上是一個輕量級的事件總線&#xff0c;將Spring Boot Actuator的端點…

[激光原理與應用-314]:光學設計 - 光學系統設計與電子電路設計的相似或相同點

光學系統設計與電子電路設計雖分屬不同工程領域&#xff0c;但在設計理念、方法論和工程實踐中存在諸多相似或相同點。這些共性源于兩者均需解決復雜系統的優化問題&#xff0c;并遵循工程設計的通用規律。以下是具體分析&#xff1a;一、設計流程的相似性需求分析與規格定義光…

Linux學習:信號的保存

目錄1. 進程的異常終止與core dump標志位1.1 進程終止的方式1.2 core方案的作用與使用方式2. 信號的保存2.1 信號的阻塞2.2 操作系統中的sigset_t信號集類型2.3 進程PCB中修改block表的系統調用接口2.4 信號阻塞的相關問題驗證1. 進程的異常終止與core dump標志位 1.1 進程終止…

數據分析編程第二步: 最簡單的數據分析嘗試

2.1 數據介紹有某公司的銷售數據表 sales.csv 如下:第一行是標題&#xff0c;解釋每一列存了什么東西。第二行開始每一行是一條數據&#xff0c;對應一個訂單。這種數據有個專業的術語&#xff0c;叫結構化數據。這是現代數據處理中最常見的數據類型。整個表格的數據統稱為一個…

UDP報文的數據結構

主要內容參照https://doc.embedfire.com/net/lwip/zh/latest/doc/chapter14/chapter14.html#id6&#xff0c;整理出來自用。 1. UDP 報文首部結構體&#xff08;udp_hdr&#xff09; 為清晰定義 UDP 報文首部的各個字段&#xff0c;LwIP 設計了udp_hdr結構體&#xff0c;其包含…

圖論與最短路學習筆記

圖論與最短路在數學建模中的應用 一、圖論模型圖 G(V,E)G(V,E)G(V,E) VVV&#xff1a;頂點集合EEE&#xff1a;邊集合每條邊 (u,v)(u,v)(u,v) 賦予權值 w(u,v)w(u,v)w(u,v)&#xff0c;可用 鄰接矩陣 或 鄰接表 表示。二、最短路問題的數學形式 目標&#xff1a;尋找從源點 sss…

第九節 Spring 基于構造函數的依賴注入

當容器調用帶有一組參數的類構造函數時&#xff0c;基于構造函數的 DI 就完成了&#xff0c;其中每個參數代表一個對其他類的依賴。接下來&#xff0c;我們將通過示例來理解 Spring 基于構造函數的依賴注入。示例&#xff1a;下面的例子顯示了一個類 TextEditor&#xff0c;只能…

【數據庫】PostgreSQL詳解:企業級關系型數據庫

文章目錄什么是PostgreSQL&#xff1f;核心特性1. 標準兼容性2. 擴展性3. 高級功能4. 可靠性數據類型1. 基本數據類型2. 高級數據類型基本操作1. 數據庫操作2. 表操作3. 數據操作高級查詢1. 連接查詢2. 子查詢3. 窗口函數JSON操作1. JSON數據類型2. JSON查詢3. JSON索引全文搜索…

FFMPEG相關解密,打水印,合并,推流,

1&#xff1a;ffmepg進行打水印解密 前提ffmepg安裝利用靜態版就可以這個什么都有&#xff0c;不用再配置其他信息&#xff1a;&#xff08;這個利用ffmpeg終端命令是沒問題的&#xff0c;但是如果要是再C中調用ffmpeg庫那么還需要從新編譯安裝下&#xff09; 各個版本 Inde…

MySql知識梳理之DML語句

注意: 插入數據時&#xff0c;指定的字段順序需要與值的順序是一一對應的。 字符串和日期型數據應該包含在引號中。 插入的數據大小&#xff0c;應該在字段的規定范圍內注意:修改語句的條件可以有&#xff0c;也可以沒有&#xff0c;如果沒有條件&#xff0c;則會修改整張表的所…

GaussDB GaussDB 數據庫架構師修煉(十八)SQL引擎-SQL執行流程

1 SQL執行流程查詢解析&#xff1a;詞法分析、語法分析、 語義分析 查詢重寫&#xff1a;視圖和規則展開、基于規則的查詢優化 計劃生成&#xff1a;路徑搜索和枚舉、選出最優執行計劃 查詢執行&#xff1a;基于優化器生成的物理執行計劃對數據進行獲取和計算2 解析器和優化器S…

grpc 1.45.2 在ubuntu中的編譯

要在 Ubuntu 上編譯 gRPC 1.45.2&#xff0c;需要按照以下步驟操作。以下指南基于 gRPC 官方文檔和相關資源&#xff0c;確保環境配置正確并成功編譯。請確保你有管理員權限&#xff08;sudo&#xff09;以安裝依賴項和執行相關命令。 1. 準備環境 確保你的 Ubuntu 系統已安裝…

lesson45:Linux基礎入門指南:從內核到實踐操作全解析

目錄 一、Linux簡介與核心概念 1.1 Linux的起源與發展 1.2 內核與發行版的關系 二、Linux內核版本解析 2.1 內核版本命名規則 2.2 2025年主流內核版本 三、主流Linux發行版對比 3.1 桌面用戶首選 Ubuntu 24.04 LTS Linux Mint 22 3.2 技術愛好者之選 Fedora 41 Ar…

PCL點云庫入門(第24講)——PCL庫點云特征之NARF特征描述 Normal Aligned Radial Feature(NARF)

一、算法原理 1、NARF 特征概述 NARF(Normal Aligned Radial Feature)是 2011 年由 Bastian Steder 等人在論文 《Point Feature Extraction on 3D Range Scans Taking into Account Object Boundaries》中提出的一種 稀疏局部 3D 特征描述子。 核心目標是提取具有“邊界意…

使用 eventpp 構建跨 RT-Thread 與 ARM-Linux 的輕量級 Active Object(AO)事件驅動框架

0. 引言 本文展示一個實踐路徑&#xff1a;以輕量級 C 事件庫 eventpp 為核心&#xff0c;設計并實現一個面向嵌入式的、可移植的 Active Object&#xff08;AO&#xff09;事件驅動架構。該架構滿足以下目標&#xff1a; 跨平臺兼容&#xff1a;單套代碼在 RT-Thread&#xff…

【python實用小腳本-193】Python全能PDF小助手:剪切/合并/旋轉/加密一條龍——再也不用開會員

Python全能PDF小助手&#xff1a;剪切/合并/旋轉/加密一條龍——再也不用開會員 PDF編輯, 本地處理, 零會員費, 多功能腳本, 瑞士軍刀 故事開場&#xff1a;一把瑞士軍刀救了周五下班的你 周五 17:55&#xff0c;老板甩來一堆 PDF&#xff1a; “把第 3、7 頁刪掉”“再和合同合…

Ubuntu根分區擴容

目錄 1.先查看/dev/sda 整塊磁盤設備的分區占用情況&#xff1a; 2.在VMware中編輯虛擬機&#xff1a; 3.進入虛擬機&#xff0c;進入disk應用程序&#xff1a; 4.擴容文件系統 5.最后通過df-h lsblk或通過可視化GParted進行驗證。 1.先查看/dev/sda 整塊磁盤設備的分區占…

智慧城市SaaS平臺/市政設施運行監測系統之空氣質量監測系統、VOC氣體監測系統、污水水質監測系統及環衛車輛定位調度系統架構內容

1. 空氣質量監測系統1) 監測點管理 a) 監測點基本信息 支持記錄空氣質量監測點的名稱、位置、類型、設備配置等信息。 b) 監測點分布地圖 支持通過GIS地圖展示監測點的分布情況&#xff0c;支持地圖查詢和導航。 2) 空氣質量監測 a) 實時數據采集 支持實時采集空氣質量數據&…

PiscCode迅速集成YOLO-Pose 實現姿態關鍵點軌跡跟蹤應用

在計算機視覺領域&#xff0c;人體姿態檢測與軌跡跟蹤是很多應用場景的核心技術&#xff0c;例如運動分析、行為識別、智能監控等。本文將介紹如何在 PiscCode 平臺上&#xff0c;利用 YOLO-Pose 模型進行姿態估計&#xff0c;并實現多人關鍵點軌跡跟蹤。 一、什么是 PiscCode …