React - LineChart组件编写(用于查看每日流水图表)
一、简单版本
- LineChart.tsx
// src/component/LineChart/LineChart.tsx
import React, {useEffect,useRef,useImperativeHandle,forwardRef,useMemo,useCallback,
} from 'react';
import * as echarts from 'echarts/core';
import type { ComposeOption } from 'echarts/core';
import type { LineSeriesOption } from 'echarts/charts';
import type {GridComponentOption,TooltipComponentOption,LegendComponentOption,
} from 'echarts/components';
import { SVGRenderer } from 'echarts/renderers';
import ResizeObserver from 'resize-observer-polyfill';
import classNames from 'classnames';
import { numberWithCommas } from '@/utils/numberWithCommas';
import './LineChart.css';// 注册必要组件
const { LineChart: ELineChart } = require('echarts/charts');
const {GridComponent,TooltipComponent,LegendComponent,
} = require('echarts/components');echarts.use([ELineChart,GridComponent,TooltipComponent,LegendComponent,SVGRenderer,
]);type ECOption = ComposeOption<| LineSeriesOption| GridComponentOption| TooltipComponentOption| LegendComponentOption
>;export interface IChartData {date: string;value: number | string;
}interface ExtraDataItem {data: IChartData[];rgbColor: number[];colorPrefix?: string;labelPrefix?: string;
}interface LineChartProps {data: IChartData[];extraData?: ExtraDataItem[];rgbColor?: number[];xAxisName?: string;yAxisName?: string;valueUnit?: string;isEmptyTipsVisible?: boolean;labelPrefix?: string;colorPrefix?: string;labelProcessor?: (data: IChartData) => string;renderTooltip?: (params: any) => string;name?: string;isOriginX?: boolean;height?: string;yAxisTextAlign?: 'left' | 'center' | 'right';
}export interface LineChartHandle {showLoading: () => void;hideLoading: () => void;getInstance: () => echarts.ECharts | null;
}const LineChart = forwardRef<LineChartHandle, LineChartProps>(({data,extraData = [],rgbColor = [255, 150, 0],xAxisName = '日期',yAxisName = '流水金额(元)',valueUnit = '元',isEmptyTipsVisible = false,labelPrefix,colorPrefix,labelProcessor,renderTooltip,name = 'tmp',isOriginX = false,height = '200px',yAxisTextAlign = 'center',
}, ref) => {const chartRef = useRef<HTMLDivElement>(null);const chartInstance = useRef<echarts.ECharts | null>(null);const observerRef = useRef<ResizeObserver | null>(null);// 修改后的x轴数据处理逻辑const xAxisData = useMemo(() => {const dataSources = [data, ...extraData.map(item => item.data)];const validData = dataSources.find(d => d?.length) || [];return validData.map((item: IChartData) =>(isOriginX? item.date: item.date.split('-')[2]), // 直接取日期部分(第三个分割项));}, [data, extraData, isOriginX]);// 修改系列配置保留完整数据对象const createSeries = useCallback((color: number[],seriesData: IChartData[],seriesName?: string,): LineSeriesOption => ({name: seriesName || 'tmp',data: seriesData, // 保留完整数据对象type: 'line',encode: {x: 'date', // 指定x轴字段y: 'value', // 指定y轴字段},// 其他保持不变的配置...smooth: true,symbol: 'circle',symbolSize: 8,areaStyle: {color: {type: 'linear',x: 0,y: 0,x2: 0,y2: 1,colorStops: [{ offset: 0, color: `rgba(${color.join(',')},0.7)` },{ offset: 1, color: `rgba(${color.join(',')},0)` },],},},itemStyle: {color: `rgb(${color.join(',')})`,borderColor: 'white',borderWidth: 2,},}), []);// 获取图表配置const getOptions = useCallback((): ECOption => {const yAxisCache: Record<string, boolean> = {};return {grid: {// left: 40,left: 60, // 增加左侧间距right: 30,bottom: 60, // 足够空间防止裁剪top: 40,},xAxis: {name: `{offset|${xAxisName}}`,nameLocation: 'end',nameGap: 5,nameTextStyle: {rich: {offset: {lineHeight: 24, // 增加行高实现下移padding: [8, 0, 0, 0], // 调整上边距align: 'center',color: '#999',fontSize: 12,},},},data: xAxisData,axisLine: {lineStyle: { width: 1, color: '#D5D9E0' },},axisLabel: { color: '#999' },axisTick: { alignWithLabel: true },axisPointer: {show: true,type: 'line',lineStyle: {type: 'dashed',color: `rgb(${rgbColor.join(',')})`,},},},yAxis: {name: yAxisName,nameTextStyle: {color: '#999',fontSize: 12,padding: [0, 0, 0, 0],align: yAxisTextAlign,},type: 'value',splitLine: {lineStyle: {color: '#E6E9F0',type: 'dashed',},},axisLine: { show: false },axisLabel: {color: '#999',margin: 0,interval: 1, // ✅ 正确间隔控制formatter: (value: number) => { // ✅ 移除index参数let result = String(value);if (value >= 1e8) result = `${(value / 1e8).toFixed(1)}亿`;else if (value >= 1e7) result = `${(value / 1e7).toFixed(1)}kw`;else if (value >= 1e4) result = `${(value / 1e4).toFixed(1)}w`;return `${result}${valueUnit}`; // ✅ 直接返回结果}},axisTick: { show: false },},// 在图表配置中修改tooltip配置项tooltip: {trigger: 'axis',backgroundColor: 'rgba(17,18,18,0.7)', // 加深背景色textStyle: {color: '#fff', // 明确设置字体颜色fontSize: 12,lineHeight: 17, // 增加行高},// 修改tooltip formatter部分formatter: (params: any) => {if (renderTooltip) return renderTooltip(params);const firstParam = params?.[0];if (!firstParam) return '';// 安全访问数据const dataIndex = firstParam.dataIndex;const dateValue = firstParam.data?.date || '';// 正确解析日期格式const [year, month, day] = dateValue.split('-');const partial = isOriginX? [dateValue]: [`${month}月${day}日`]; // 直接使用分割后的月日// 处理主数据if (data?.length && data[dataIndex]) {const currentData = data[dataIndex];// 带2位小数(银行金额常用格式)const moneyFormat = new Intl.NumberFormat('zh-CN', {style: 'decimal',});const value = labelProcessor?.(currentData) || moneyFormat.format(Number(currentData.value));partial.push(`${colorPrefix ? `<div class="color-dot" style="background:${colorPrefix}"></div>` : ''}${labelPrefix || ''} ${value} ${valueUnit}`,);}// 处理额外数据extraData?.forEach(item => {if (item.data[dataIndex]) {const currentValue = item.data[dataIndex].value;const value = numberWithCommas(Number(currentValue));partial.push(`${item.colorPrefix ? `<div class="color-dot" style="background:${item.colorPrefix}"></div>` : ''}${item.labelPrefix || ''} ${value} ${valueUnit}`,);}});return partial.join('</br>');},padding: [8, 18, 8, 18],},series: [...(extraData?.map(item =>createSeries(item.rgbColor, item.data, item.labelPrefix),) || []),createSeries(rgbColor, data, name),],};}, [xAxisData, rgbColor, extraData, data, name, isOriginX, xAxisName, yAxisName, yAxisTextAlign, valueUnit, renderTooltip, labelProcessor, colorPrefix, labelPrefix, createSeries]);// 初始化图表useEffect(() => {if (!chartRef.current) return;chartInstance.current = echarts.init(chartRef.current, null, {renderer: 'svg',});chartInstance.current.setOption(getOptions());// 响应式处理const resizeHandler = () => chartInstance.current?.resize();observerRef.current = new ResizeObserver(() => resizeHandler());observerRef.current.observe(chartRef.current);return () => {observerRef.current?.disconnect();chartInstance.current?.dispose();};}, [getOptions]);// 更新图表useEffect(() => {chartInstance.current?.setOption(getOptions());}, [getOptions]);// 暴露组件方法useImperativeHandle(ref, () => ({showLoading: () => {chartInstance.current?.showLoading({text: '',color: '#FF9600',});},hideLoading: () => chartInstance.current?.hideLoading(),getInstance: () => chartInstance.current,}));return (<div className="line-chart" style={{ height }}><div ref={chartRef} className="chart" /><div className={classNames('empty-tips', { 'empty-tips--visible': isEmptyTipsVisible })}>暂无数据, 本月活跃大神的数据将在当月2号6时以后更新.</div></div>);
});export default LineChart;
- LineChart.css
/* src/components/LineChart/LineChart.css */
.line-chart {width: 100%;position: relative;/* 添加最小高度防止内容塌陷 */min-height: 120px;
}.chart {width: 100%;height: 100%;/* 修复图表可能出现的模糊问题 */transform: translateZ(0);
}.empty-tips {/* 优化空状态样式 */position: absolute;width: 80%;max-width: 280px;padding: 16px;left: 50%;top: 50%;transform: translate(-50%, -50%);background: rgba(0, 0, 0, 0.65);border-radius: 8px;color: #fff;font-size: 14px;text-align: center;line-height: 1.5;opacity: 0;transition: opacity 0.3s;pointer-events: none;
}.empty-tips--visible {opacity: 1;/* 添加轻微动画 */animation: fade-in 0.3s ease;
}/* 新增tooltip容器样式 */
.echarts-tooltip {box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15) !important;border-radius: 8px !important;backdrop-filter: blur(4px);
}.color-dot {/* 优化颜色点显示 */width: 10px;height: 10px;border-radius: 50%;margin-right: 6px;box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);/* 修复对齐问题 */display: inline-flex;vertical-align: baseline;
}@keyframes fade-in {from { opacity: 0; transform: translate(-50%, -45%); }to { opacity: 1; transform: translate(-50%, -50%); }
}
-
DashboardPage.tsx
// src/pages/Dashboard/index.tsx
import React, { useRef } from 'react';
import LineChart, {IChartData, LineChartHandle} from '@/component/LineChart';const DashboardPage = () => {const chartRef = useRef<LineChartHandle>(null);// 示例数据const data: IChartData[] = [{ date: '2024-05-01', value: 12345670 },{ date: '2024-05-02', value: 2345678 },{ date: '2024-05-03', value: 3456789 },{ date: '2024-05-04', value: 0 },];const extraData = [{data: [{ date: '2024-05-01', value: 5000000 },{ date: '2024-05-02', value: 600000 },{ date: '2024-05-03', value: 700000 },{ date: '2024-05-04', value: 0 },],rgbColor: [100, 200, 255],colorPrefix: '#64c8ff',labelPrefix: '辅助流水',},];return (<div style={{ padding: 24 }}><h2>数据看板</h2><div style={{ marginTop: 20, height: '500px' }}><LineChartref={chartRef}data={data}extraData={extraData}rgbColor={[255, 150, 0]}height="100%"xAxisName="日期"yAxisName="流水金额(元)"valueUnit="元"colorPrefix="#FF9600"labelPrefix="主要流水"/></div></div>);
};export default DashboardPage;
二、优化版本,价格interval
- LineChart.tsx
// src/components/LineChart/LineChart.tsx
import React, {useEffect,useRef,useImperativeHandle,forwardRef,useMemo,useCallback,
} from 'react';
import * as echarts from 'echarts/core';
import type { ComposeOption } from 'echarts/core';
import type { LineSeriesOption } from 'echarts/charts';
import type {GridComponentOption,TooltipComponentOption,LegendComponentOption,
} from 'echarts/components';
import { SVGRenderer } from 'echarts/renderers';
import ResizeObserver from 'resize-observer-polyfill';
import classNames from 'classnames';
import { numberWithCommas } from '@/utils/numberWithCommas';
import './LineChart.css';// 注册必要组件
const { LineChart: ELineChart } = require('echarts/charts');
const {GridComponent,TooltipComponent,LegendComponent,
} = require('echarts/components');echarts.use([ELineChart,GridComponent,TooltipComponent,LegendComponent,SVGRenderer,
]);type ECOption = ComposeOption<| LineSeriesOption| GridComponentOption| TooltipComponentOption| LegendComponentOption
>;export interface IChartData {date: string;value: number | string;
}interface ExtraDataItem {data: IChartData[];rgbColor: number[];colorPrefix?: string;labelPrefix?: string;
}interface LineChartProps {data: IChartData[];extraData?: ExtraDataItem[];rgbColor?: number[];xAxisName?: string;yAxisName?: string;valueUnit?: string;isEmptyTipsVisible?: boolean;labelPrefix?: string;colorPrefix?: string;labelProcessor?: (data: IChartData) => string;renderTooltip?: (params: any) => string;name?: string;isOriginX?: boolean;height?: string;yAxisTextAlign?: 'left' | 'center' | 'right';interval?: number; // 日期间隔步长,例如:2就代表每隔一天 (01,03,05,...)
}export interface LineChartHandle {showLoading: () => void;hideLoading: () => void;getInstance: () => echarts.ECharts | null;
}const LineChart = forwardRef<LineChartHandle, LineChartProps>(({data,extraData = [],rgbColor = [255, 150, 0],xAxisName = '日期',yAxisName = '流水金额(元)',valueUnit = '元',isEmptyTipsVisible = false,labelPrefix,colorPrefix,labelProcessor,renderTooltip,name = 'tmp',isOriginX = false,height = '200px',yAxisTextAlign = 'center',interval = 1,
}, ref) => {const chartRef = useRef<HTMLDivElement>(null);const chartInstance = useRef<echarts.ECharts | null>(null);const observerRef = useRef<ResizeObserver | null>(null);// 修改后的x轴数据处理逻辑const xAxisData = useMemo(() => {const dataSources = [data, ...extraData.map(item => item.data)];const validData = dataSources.find(d => d?.length) || [];return validData.map((item: IChartData) =>(isOriginX? item.date: item.date.split('-')[2]), // 直接取日期部分(第三个分割项));}, [data, extraData, isOriginX]);// 修改系列配置保留完整数据对象const createSeries = useCallback((color: number[],seriesData: IChartData[],seriesName?: string,): LineSeriesOption => ({name: seriesName || 'tmp',data: seriesData, // 保留完整数据对象type: 'line',encode: {x: 'date', // 指定x轴字段y: 'value', // 指定y轴字段},// 其他保持不变的配置...smooth: true,symbol: 'circle',symbolSize: 8,areaStyle: {color: {type: 'linear',x: 0,y: 0,x2: 0,y2: 1,colorStops: [{ offset: 0, color: `rgba(${color.join(',')},0.7)` },{ offset: 1, color: `rgba(${color.join(',')},0)` },],},},itemStyle: {color: `rgb(${color.join(',')})`,borderColor: 'white',borderWidth: 2,},}), []);// 获取图表配置const getOptions = useCallback((): ECOption => {const yAxisCache: Record<string, boolean> = {};return {grid: {// left: 40,left: 60, // 增加左侧间距right: 30,bottom: 60, // 足够空间防止裁剪top: 40,},xAxis: {name: `{offset|${xAxisName}}`,nameLocation: 'end',nameGap: 5,nameTextStyle: {rich: {offset: {lineHeight: 24, // 增加行高实现下移padding: [8, 0, 0, 0], // 调整上边距align: 'center',color: '#999',fontSize: 12,},},},data: xAxisData,axisLine: {lineStyle: { width: 1, color: '#D5D9E0' },},axisLabel: {interval: 0, // 显示所有标签color: '#999',formatter: (value: string, index: number) => {return index % interval === 0 ? value : ''; // 不满足间隔时返回空},},axisTick: { alignWithLabel: true },axisPointer: {show: true,type: 'line',lineStyle: {type: 'dashed',color: `rgb(${rgbColor.join(',')})`,},},},yAxis: {name: yAxisName,nameTextStyle: {color: '#999',fontSize: 12,padding: [0, 0, 0, 0],align: yAxisTextAlign,},type: 'value',splitLine: {lineStyle: {color: '#E6E9F0',type: 'dashed',},},axisLine: { show: false },axisLabel: {color: '#999',margin: 0,interval: 1, // ✅ 正确间隔控制formatter: (value: number) => { // ✅ 移除index参数let result = String(value);if (value >= 1e8) result = `${(value / 1e8).toFixed(1)}亿`;else if (value >= 1e7) result = `${(value / 1e7).toFixed(1)}kw`;else if (value >= 1e4) result = `${(value / 1e4).toFixed(1)}w`;return `${result}${valueUnit}`; // ✅ 直接返回结果},},axisTick: { show: false },},// 在图表配置中修改tooltip配置项tooltip: {trigger: 'axis',backgroundColor: 'rgba(17,18,18,0.7)', // 加深背景色textStyle: {color: '#fff', // 明确设置字体颜色fontSize: 12,lineHeight: 17, // 增加行高},// 修改tooltip formatter部分formatter: (params: any) => {if (renderTooltip) return renderTooltip(params);const firstParam = params?.[0];if (!firstParam) return '';// 安全访问数据const dataIndex = firstParam.dataIndex;const dateValue = firstParam.data?.date || '';// 正确解析日期格式const [year, month, day] = dateValue.split('-');const partial = isOriginX? [dateValue]: [`${month}月${day}日`]; // 直接使用分割后的月日// 处理主数据if (data?.length && data[dataIndex]) {const currentData = data[dataIndex];// 带2位小数(银行金额常用格式)const moneyFormat = new Intl.NumberFormat('zh-CN', {style: 'decimal',});const value = labelProcessor?.(currentData) || moneyFormat.format(Number(currentData.value));partial.push(`${colorPrefix ? `<div class="color-dot" style="background:${colorPrefix}"></div>` : ''}${labelPrefix || ''} ${value} ${valueUnit}`,);}// 处理额外数据extraData?.forEach(item => {if (item.data[dataIndex]) {const currentValue = item.data[dataIndex].value;const value = numberWithCommas(Number(currentValue));partial.push(`${item.colorPrefix ? `<div class="color-dot" style="background:${item.colorPrefix}"></div>` : ''}${item.labelPrefix || ''} ${value} ${valueUnit}`,);}});return partial.join('</br>');},padding: [8, 18, 8, 18],},series: [...(extraData?.map(item =>createSeries(item.rgbColor, item.data, item.labelPrefix),) || []),createSeries(rgbColor, data, name),],};}, [xAxisData, rgbColor, extraData, data, name, isOriginX, xAxisName, yAxisName, yAxisTextAlign, valueUnit, renderTooltip, labelProcessor, colorPrefix, labelPrefix, createSeries]);// 初始化图表useEffect(() => {if (!chartRef.current) return;chartInstance.current = echarts.init(chartRef.current, null, {renderer: 'svg',});chartInstance.current.setOption(getOptions());// 响应式处理const resizeHandler = () => chartInstance.current?.resize();observerRef.current = new ResizeObserver(() => resizeHandler());observerRef.current.observe(chartRef.current);return () => {observerRef.current?.disconnect();chartInstance.current?.dispose();};}, [getOptions]);// 更新图表useEffect(() => {chartInstance.current?.setOption(getOptions());}, [getOptions]);// 暴露组件方法useImperativeHandle(ref, () => ({showLoading: () => {chartInstance.current?.showLoading({text: '',color: '#FF9600',});},hideLoading: () => chartInstance.current?.hideLoading(),getInstance: () => chartInstance.current,}));return (<div className="line-chart" style={{ height }}><div ref={chartRef} className="chart" /><div className={classNames('empty-tips', { 'empty-tips--visible': isEmptyTipsVisible })}>暂无数据, 本月活跃大神的数据将在当月2号6时以后更新.</div></div>);
});export default LineChart;
- LineChart.css
/* src/components/LineChart/LineChart.css */
.line-chart {width: 100%;position: relative;/* 添加最小高度防止内容塌陷 */min-height: 120px;
}.chart {width: 100%;height: 100%;/* 修复图表可能出现的模糊问题 */transform: translateZ(0);
}.empty-tips {/* 优化空状态样式 */position: absolute;width: 80%;max-width: 280px;padding: 16px;left: 50%;top: 50%;transform: translate(-50%, -50%);background: rgba(0, 0, 0, 0.65);border-radius: 8px;color: #fff;font-size: 14px;text-align: center;line-height: 1.5;opacity: 0;transition: opacity 0.3s;pointer-events: none;
}.empty-tips--visible {opacity: 1;/* 添加轻微动画 */animation: fade-in 0.3s ease;
}/* 新增tooltip容器样式 */
.echarts-tooltip {box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15) !important;border-radius: 8px !important;backdrop-filter: blur(4px);
}.color-dot {/* 优化颜色点显示 */width: 10px;height: 10px;border-radius: 50%;margin-right: 6px;box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);/* 修复对齐问题 */display: inline-flex;vertical-align: baseline;
}@keyframes fade-in {from { opacity: 0; transform: translate(-50%, -45%); }to { opacity: 1; transform: translate(-50%, -50%); }
}
- DashboardPage.tsx
import React, { useRef } from 'react';
import LineChart, {IChartData, LineChartHandle} from '@/component/LineChart';const DashboardPage = () => {const chartRef = useRef<LineChartHandle>(null);// 生成完整5月份数据(31天)const generateMonthlyData = () => {const daysInMonth = 31;const baseValue = 10000000; // 基础值1千万const data: IChartData[] = [];const extra: IChartData[] = [];// 带波动的数据生成函数const generateDataPoint = (day: number, isExtra = false) => {// 基础波动(-20% ~ +20%)let fluctuation = 1 + (Math.random() * 0.4 - 0.2);// 周末效应(周六周日减少15%)const date = new Date(2024, 4, day);if ([0, 6].includes(date.getDay())) {fluctuation *= 0.85;}// 月末促销(最后三天增加40%)if (day > 28) fluctuation *= 1.4;// 额外数据波动较小(-15% ~ +15%)if (isExtra) {fluctuation = 1 + (Math.random() * 0.3 - 0.15);return baseValue * 0.4 * fluctuation; // 主数据的40%左右}return baseValue * fluctuation;};for (let day = 1; day <= daysInMonth; day++) {const dateString = new Date(2024, 4, day).toLocaleDateString('zh-CN', {year: 'numeric',month: '2-digit',day: '2-digit',}).replace(/\//g, '-');data.push({date: dateString,value: Math.round(generateDataPoint(day)),});extra.push({date: dateString,value: Math.round(generateDataPoint(day, true)),});}return { data, extra };};const { data, extra } = generateMonthlyData();const extraData = [{data: extra,rgbColor: [100, 200, 255],colorPrefix: '#64c8ff',labelPrefix: '辅助流水',},];return (<div style={{ padding: 24 }}><h2>数据看板</h2><div style={{ marginTop: 20, height: '500px' }}><LineChartref={chartRef}data={data}extraData={extraData}rgbColor={[255, 150, 0]}height="100%"xAxisName="日期"yAxisName="流水金额(元)"valueUnit="元"colorPrefix="#FF9600"labelPrefix="主要流水"interval={2}/></div></div>);
};export default DashboardPage;
相关文章:
React - LineChart组件编写(用于查看每日流水图表)
一、简单版本 LineChart.tsx // src/component/LineChart/LineChart.tsx import React, {useEffect,useRef,useImperativeHandle,forwardRef,useMemo,useCallback, } from react; import * as echarts from echarts/core; import type { ComposeOption } from echarts/core; …...
什么情况下需要使用二级指针
当你需要一个函数修改另一个函数中的指针变量时(改变指针变量的指向),你必须传递该指针的地址,也就是"指向指针的指针"。这是C语言中实现"引用传递"效果的标准方式。 函数A中声明了一个结构体指针变量mys&am…...
动态规划(8.下降路径最小和(medium))
题目链接:931. 下降路径最小和 - 力扣(LeetCode) 解法: 关于这⼀类题,由于我们做过类似的,因此「状态表示」以及「状态转移」是比较容易分析出来的。 比较难的地方可能就是对于「边界条件」的处理。 1. 状…...
自动插入分号机制
📜 JS 自动分号插入(ASI)机制详解 自动分号插入(Automatic Semicolon Insertion)是 JavaScript 中一个独特而重要的特性,它影响着代码的解析和执行方式。 🌟 核心概念速览 ASI 引擎自动补充分号 当 JavaScript 解析器遇到特定语法情况时&a…...
C语言贪吃蛇实现
When the night gets dark,remember that the Sun is also a star. 当夜幕降临时,请记住太阳也是一颗星星。 ————《去月球海滩篇》 目录 文章目录 一、《贪吃蛇》游戏介绍 二、WIN32部分接口简单介绍 2.1 控制台窗口大小设置 2.2 命令行窗口的名称的变更 2…...
基于数据挖掘的网络入侵检测关键技术研究
标题:基于数据挖掘的网络入侵检测关键技术研究 内容:1.摘要 随着互联网的迅速发展,网络安全问题日益严峻,网络入侵行为对个人、企业和国家的信息安全构成了巨大威胁。本文的目的是研究基于数据挖掘的网络入侵检测关键技术,以提高网络入侵检测…...
git上传大文件到远程仓库中
git 上传大文件报错 上传大文件文件到远程仓库上面,出现错误(gitee-100M,github-50M) remote: error: File: f422c55c723a183a1944cbec840c0171042c8251 135 MB, exceeds 100.00 MB. 意思是单个文件超过100M导致上传失败。 安装LFS curl…...
计算机网络基础之三种交换技术及其性能分析
一. 交换技术基础 1. 三种交换技术 电路交换:用于电话网络报文交换:用于电报网络分组交换:用于现代计算机网络 2. 人类历史上的通信网络 #mermaid-svg-AeGvrkUbCkicFOIo {font-family:"trebuchet ms",verdana,arial,sans-serif;…...
ANYmal Parkour: Learning Agile Navigation for Quadrupedal Robots
ANYmal Parkour: Learning Agile Navigation for Quadrupedal Robots 研究动机解决方案技术路线感知模块运动模块导航模块补充 实验结果 ANYmal Parkour: Learning Agile Navigation for Quadrupedal Robots 研究动机 行走控制器不能依赖于稳定和周期性的步态,而必…...
【AI学习笔记】AI造神时代的潘式理论与智能进化
背景前摇: 周会分享选题,决定选择这篇华为蓝军部长潘少钦先生所著的文章,原题目为《AI如此强大,我是否要改行?》。选择这篇文章的理由是,其不仅有充实扎实的AI基础知识作为铺垫,更具有独特鲜明…...
CVE-2021-45232未授权接口练习笔记
CVE-2021-45232 是 Apache APISIX Dashboard 中的一个严重权限漏洞,类似于攻击者无需密码即可拿到整个网关系统的“万能钥匙”。攻击者利用此漏洞,可直接操控网关流量转发规则,甚至远程执行代码,引发服务器沦陷。 默认账户密码导致…...
远场分量(平面波角谱)与倏逝波
远场分量(平面波角谱)与倏逝波的详细解释 在光学和电磁学中,远场分量(平面波角谱)和倏逝波是描述光场传播特性的两个核心概念,尤其在衍射理论、近场光学和超分辨成像中至关重要。以下是它们的物理意义、数…...
修改Flutter工程中Android项目minSdkVersion配置
Flutter项目开发过程中,根据模板自动生成.android项目,其中app>build.gradle中minSdkVersion的值是19,但是依赖了一个三方库,它的Android sdk 最小版本只支持到21,运行报错如下: 我们可以手动修改.andro…...
后端返回了 xlsx 文件流,前端怎么下载处理
当后端返回一个 .xlsx 文件流时,前端可以通过 JavaScript 处理这个文件流并触发浏览器下载。 实现步骤 发送请求获取文件流: 使用 fetch 或 axios 等工具向后端发送请求,确保响应类型设置为 blob(二进制数据流)。 创建…...
js中async+await+promise的用法及常见问题总结
文章目录 概况asyncawaitPromise总结常见问题 概况 在ts/js中,async 和 await 是用于简化异步操作的关键字,一般与Promise联用(不理解Promise可以看一下这篇《JS中Promise用法(简要说明)》)。它们的核心作…...
单纯形法之大M法
1. 问题背景与标准化 在求解某些线性规划问题时,往往难以直接找到初始的基本可行解。特别是当约束中存在等式或 “≥” 类型的不等式时,我们需要引入人工变量来构造一个初始可行解。 考虑如下标准形式问题(假设为最大化问题)&am…...
一个数组分为两个sum相等的数组
vector,问是否可以拆成两部分,使其两部分的总和相同,用代码写一下 #include <iostream> #include <vector>using namespace std;bool canPartition(vector<int>& nums) {int sum 0;for (int num : nums) {sum num;…...
Socket如何实现客户端和服务器间的通信
使用Socket实现客户端和服务器间的通信 Socket是一种网络编程接口,广泛用于实现客户端和服务器之间的通信。在网络应用程序中,Socket提供了一种简单而强大的机制来建立和管理网络连接。本文将详细介绍如何使用Python的Socket模块来实现基本的客户端和服…...
崖山数据库(YashanDB)部署全流程详解
文章目录 引言 第1部分:环境准备 服务器要求 初始环境调整 第2部分:yasboot工具介绍 yasboot核心功能 yasboot进程架构 第3部分:YashanDB安装步骤 创建安装用户 目录规划 命令行安装流程 步骤1:生成配置文件 步骤2&a…...
07_JavaScript函数作用域_递归
目录 一、作用域(重点) 二、变量的使用规则 (重点) 2.1 访问规则 2.2 赋值规则 三、递归函数 (难点) 了解 四、对象 4.1 对象的创建 一、作用域(重点) 什么是作用域 ? 作用…...
基于大模型预测的初治菌阳肺结核诊疗方案研究报告
目录 一、引言 1.1 研究背景与意义 1.2 研究目的 二、初治菌阳肺结核概述 2.1 疾病定义与病理机制 2.2 流行病学特征 2.3 传统诊疗方法与局限性 三、大模型在初治菌阳肺结核预测中的应用原理 3.1 大模型技术简介 3.2 数据收集与预处理 3.3 模型构建与训练 3.4 模型…...
C# Modbus TCP/IP学习记录
Modbus协议中,角色分为主站(Mater)、从站(Slave);数据类型分为线圈(Coil)、离散输入(Input)、保持寄存器(HoldingRegister)、输入寄存…...
斜线、短横、空格,三种分隔日期的优雅解析(Python | DeepSeek)
标准日期解析操作,str.replace链式如灵蛇蜿蜒,三元表达式像空灵仙家妙法。 笔记模板由python脚本于2025-03-25 22:32:24创建,本篇笔记适合三元表达式、字符串操作修习的coder翻阅。 【学习的细节是欢悦的历程】 博客的核心价值:在…...
Skynet 中 snlua 服务启动整体流程分析
前言: 在 Skynet 中,Lua 扮演了极其重要的角色。Skynet 大多数业务逻辑都跑在一个个 Lua 服务里,而能够将 Lua 环境嵌入到 Skynet 框架下,并与 Skynet 消息调度机制完美结合,正是 snlua 服务所承担的核心功能。 本文将…...
RWA代币化崛起中的香港机遇:数字金融新枢纽的破局之道
引言:全球资产代币化浪潮中的香港坐标 在2025年全球金融数字化重构的关键节点,RWA(现实世界资产代币化)市场以年均740%的增速重塑价值流动规则。香港凭借独特的政策创新、跨境枢纽优势及庞大的资产储备,正从传统金融中…...
Docker Compose介绍
基本概念 Docker-Compose是Docker官方的开源项目,负责实现对docker容器集群的快速编排。 可以这么理解,docker compose是docker提出的一个工具软件,可以管理多个docker容器组成一个应用,只需要编写一个YAML格式的配置文件docker…...
【LeetCode 题解】算法:15.三数之和
一、问题描述 在 LeetCode 上有这样一道经典的算法题,题目要求给定一个整数数组 nums,找出所有不重复的三元组 [nums[i], nums[j], nums[k]],需要满足以下两个条件: 三个元素的索引互不相同,即 i ! j,i ! …...
springboot使用阿里限流框架-sentinel
当前项目源码 控制台下载 启动bin中的看板服务:账号密码:sentinel/sentinel 官方文档地址 项目引入依赖 <!-- sentinel注解支持 --> <dependency><groupId>com.alibaba.csp</groupId><artifactId>sentinel-annotation-aspectj<…...
Ubuntu20.04系统安装IsaacSim4.5与IsaacLab环境
Introduction 今天用自己的Ubuntu20.04系统安装最新更新的IsaacSim 4.5 与 最新版的IsaacLab遇到了问题,且这个问题组里师兄之前也遇到了,我的解决方法是从头来过,所及记录一下。 IsaacSim现在支持pip安装,但是Ubuntu20.04的pip…...
【大模型】数字人 EchoMimicV2 的环境配置和使用
一、EchoMimicV2的简单介绍 EchoMimicV2是EchoMimicV1的升级版本,旨在通过音频驱动生成更加自然和流畅的半身人类动画。它能够让用户仅通过简单的音频输入,生成与声音内容相匹配的动画效果,使虚拟人物看起来更加生动。 作者:由蚂蚁…...
导入 Excel 规则批量修改或删除 PDF 文档内容
需要对 PDF 文档内容进行修改的时候,通常我们会需要借助一些专业的工具来帮我们完成。那我们如果需要修改的 PDF 文档较多的时候,有什么方法可以帮我们实现批量操作呢?今天这篇文章就给大家介绍一下当我们需要批量修改多个 PDF 文档的时候&am…...
2.Excel :快速填充和拆分重组
一 案例1:快速填充 电子邮件中包含每个人的人名,现在要提取电子邮件中的姓名到名字列。 方法1:将 Nancy 复制到单元格后,邮件会高亮,然后输入A的时候系统就会知道提取名字了。 补充:如果第三个位置输入错误…...
python tkinter 开发蓍草占卜系统
1. 项目概述 1.1 简介 蓍草占卜是中国传统的占卜方法,用于演算六十四卦。本系统通过现代编程技术,将传统的蓍草占卜方法数字化,提供一个准确、便捷的占卜工具。 蓍草占卜,作为中国古代的一种传统占卜方法,承载着深厚…...
综合小实验之电视机
综合小实验1 一、实验拓扑图 二、实验要求 按照图示配置IP地址;按照图示区域划分配置对应的动态路由协议;在R7上配置dhcp服务器,能够让pc可以获取IP地址;将所有环回⼝宣告进ospf中,将环回⼝7宣告进rip中,…...
全排列|| 分发饼干 摆动序列
1.给定一个可包含重复数字的序列 nums ,按任意顺序 返回所有不重复的全排列。 示例 1: 输入:nums [1,1,2] 输出: [[1,1,2], [1,2,1], [2,1,1]] 示例 2: 输入:nums [1,2,3] 输出:[[1,2,3…...
【开源宝藏】用 JavaScript 手写一个丝滑的打字机动画效果
你当前项目实现了一个非常丝滑的 打字机文字效果动画,使用的是自定义的 typical.js 脚本。下面我将给出一份逐步拆解的中文教程,帮你或其他初学者快速上手并自定义这个打字效果。 ✨ 最终效果 打开页面后,中央会逐字显示: Hello…...
推荐1款简洁、小巧的实用收音机软件,支持手机和电脑
聊一聊 没想到现在还有人喜欢听广播。 我一直以为听广播必须要用那种小广播机才可以。 原来手机或电脑上也是可以的。 今天给大家分享一款可以在电脑和手机上听广播的软件。 软件介绍 龙卷风收音机 电台广播收音机分电脑和手机两个版本。 电脑端无需安装,下载…...
64. MfgTool烧写工具详解
一、MfgTool工具简介 1、mfgtool是NXP官方做的向I.MX系列烧写系统的软件,运行在windows下。可以烧写uboot.imx、zImage、dtb,rootfs。通过USB烧写。 Mfgtool里面默认存放了NXP官方开发板的系统文件, 2、基本原理 向开发板烧系统分两部分&am…...
3、孪生网络/连体网络(Siamese Network)
目的: 用Siamese Network (孪生网络) 解决Few-shot learning (小样本学习)。 Siamese Network并不是Meta Learning最好的方法, 但是通过学习Siamese Network,非常有助于理解其他Meta Learning算法。 这里介绍了两种方法:Siamese Network (孪生网络)、Trplet Loss Siam…...
前端学习笔记--CSS
HTMLCSSJavaScript 》 结构 表现 交互 如何学习 1.CSS是什么 2.CSS怎么用? 3.CSS选择器(重点,难点) 4.美化网页(文字,阴影,超链接,列表,渐变。。。) 5…...
开个坑记录一下树莓派4B部署yolo的一些问题
问题一:操作系统与内核信息 这个问题困扰了我一天半,下载的时候显示的信息是aar64的系统,但是这并无意味着一个问题,那就是你的操作系统是64位的。需要采用如下的指令查看: getconf LONG_BIT 我在树莓派得出来的操作…...
1.1 结构体与类对象在List中使用区别
一、问题的起源如下的代码是错误的,无法编译通过 struct Point {public int X;public int Y; }List<Point> points new List<Point> { new Point { X 1, Y 2 } }; points[0].X 10; // 编译错误!无法修改副本的字段 二、原因分析 在C#中&…...
详细说明windows系统函数::SetUnhandledExceptionFilter(ExceptionFilter)
::SetUnhandledExceptionFilter(ExceptionFilter); 是 Windows 编程中用于设置顶层未处理异常过滤器的关键 API 调用。它属于 Windows 结构化异常处理(SEH, Structured Exception Handling)机制的一部分,主要用于捕获那些未被程序内部处理的异…...
力扣刷题39. 组合总和
39. 组合总和 - 力扣(LeetCode) 需要定义一个index变量用来记录访问数组的下标,每次递归进行传参,在搜索过程中,因为为了避免重复数据,而且允许一个元素的重复出现,传入index时传入当前遍历的i…...
正弦函数的连续傅里叶变换正弦序列的DTFT
正弦序列 时域 x [ n ] sin ( ω 0 n ) x[n] \sin(\omega_0 n) x[n]sin(ω0n)频域 X ( e j ω ) j π 2 [ δ ( ω − ω 0 ) − δ ( ω ω 0 ) ] X({\rm e}^{{\rm j}\omega}) \frac{{\rm j}\pi}{2} \left[ \delta(\omega - \omega_0) - \delta(\omega \omega_0…...
winstart.wsf 病毒清理大作战
0x00 背景 发现感染了winstart.wsf 病毒如何清理。 0x01 现象 遍历Users下每个目录以及C:\和C:\Windows\Temp 2个目录写入病毒文件。 C:\Users\Administrator\AppData\Local\Temp\winstart.wsf C:\Users\Administrator\AppData\Roaming\Microsoft\Windows\Start Menu\Program…...
leetcode 20.有效括号
20. 有效的括号 - 力扣(LeetCode) class Solution:def isValid(self, s: str) -> bool:stack []for i in s :if i in ((,{,[ ):stack.append(i)elif i in () ):# 这种情况是 栈弹出元素为空时候 ,右半部分的括号多出来一些 比如&#x…...
Leetcode刷题笔记1 图论part07
卡码网 53 寻宝 prim算法 prim算法核心就是三步,称为prim三部曲: 第一步,选距离生成树最近节点第二步,最近节点加入生成树第三步,更新非生成树节点到生成树的距离(即更新minDist数组) def p…...
unittest自动化测试实战
🍅 点击文末小卡片,免费获取软件测试全套资料,资料在手,涨薪更快 为什么要学习unittest 按照测试阶段来划分,可以将测试分为单元测试、集成测试、系统测试和验收测试。单元测试是指对软件中的最小可测试单元在与程…...
flask,示例及解释
1) from flask import Flask, render_templateapp Flask(__name__)app.route(/) def index():return render_template(m1index.html)app.route(/get_type) def get_type():return ["语文", "数学"]if __name__ __main__:app.run(host0.0.0.0…...