React+Echarts实现数据排名+自动滚动+Y轴自定义toolTip文字提示

news2024/9/21 20:39:29

1、效果

2、环境准备

1、react18

2、antd 4+

 3、代码实现

原理:自动滚动通过创建定时器动态更新echar的dataZoom属性startValue、endValue,自定义tooltip通过监听echar的鼠标移入移出事件,判断tooltTip元素的显隐以及位置。

1、导入所需组件:在你的代码文件中导入所需的组件

import ReactECharts from 'echarts-for-react';

2、创建一个定时器,处理当前图表滚动至第几个数据,用于实现自动滚动

 // 开启定时器
  const initialScroll = (dataLen: number, myChart: any) => {
    const option = myChart.getOption();
    // 只有当大于10条数据的时候 才会看起来滚动
    let time = setInterval(() => {
      if (data.length <= 8) {
        return;
      }
      if (option?.dataZoom[0].endValue >= dataLen - 1) {
        option.dataZoom[0].endValue = 7;
        option.dataZoom[0].startValue = 0;
      } else {
        option.dataZoom[0].endValue = option.dataZoom[0].endValue + 1;
        option.dataZoom[0].startValue = option.dataZoom[0].startValue + 1;
      }
      myChart.setOption(option);
      myChart.setOption({
        dataZoom: [
          {
            type: 'slider',
            startValue: option.dataZoom[0].startValue,
            endValue: option.dataZoom[0].endValue,
          },
        ],
      });
    }, Number(rollTime));
    timer = time;
  };

3、在useEffect中添加自动滚动的定时器

  useEffect(() => {
    const myChart = chartRef?.current?.getEchartsInstance();
    let chartDom = chartRef.current?.getEchartsInstance()?.getDom();
    if (data.length > 8) {
      initialScroll(data.length, myChart);
      // 鼠标离开开启定时器
      chartDom?.addEventListener('mouseout', () => {
        if (timer) return;
        initialScroll(data.length, myChart);
      });
    }

    return () => {
      clearInterval(timer);
      timer = null;
    };
  }, [data]); // 检测数组内变量 如果为空 则监控全局

4、配置echars的属性,核心要配置dataZoom,控制数据从第几个开始展示,从第几个结束

export const getOption = (result) => {
  return {
    tooltip: {
      ...
      },
    },
    grid: {
      ...
    },
    xAxis: [
      {
      ...
      },
    ],
    yAxis: [
      {
        triggerEvent: true,
        data: result.map((item) => item.projectName),
        axisLabel: {
          ...
          formatter: (value) => {
            const valueNew =
              value.length > 4 ? `${value.slice(0, 4)}...` : value;
            const index = result.findIndex(
              (item) => item.projectName === value,
            );
            if (index < 3) {
              return `{icon${index + 1}|${index + 1}} {a|${valueNew}}`;
            } else {
              return `{icon0|${index + 1}} {a|${valueNew}}`;
            }
       }}
    ],
    dataZoom: [
      {
        yAxisIndex: [0, 1], // 这里是从X轴的0刻度开始
        show: false, // 是否显示滑动条,不影响使用
        type: 'slider', // 这个 dataZoom 组件是 slider 型 dataZoom 组件
        startValue: 0, // 从头开始。
        endValue: 7, // 展示到第几个。
      },
    ],
  };
};

4、echarts Y轴的title超出会显示省略,但是看不全体验不好,于是给Y轴加了一个自定义的tooltTip,翻看的echarts所有属性,纵向坐标系,Y轴没有相关属性定义tooltTip

  <ReactECharts
     ref={chartRef}
      option={getOption(data)}
      className={clsx(['h-full w-full'])}
      style={{ width: '100%', height: '100%' }}
    />
  <div className="axis-tip"> </div>

于是在echarts同层节点添加一个toolTip节点,<div className="axis-tip"> </div> 就是ReactECharts的同层节点,通过监听echartsDom的鼠标移入移出控制toolTip的显示位置以及是否显示

  useEffect(() => {
    const myChart = chartRef?.current?.getEchartsInstance();
    let chartDom = chartRef.current?.getEchartsInstance()?.getDom();
    // 移入
    chartDom?.addEventListener('mouseover', () => {
      clearInterval(timer);
      timer = undefined;
      removeAxisTip();
    });
    // yAxis鼠标移入监听
    myChart?.on?.('mouseover', 'yAxis.category', function (e: any) {
      let axisTip: any = document.querySelector('.axis-tip');
      if (axisTip) {
        axisTip.innerText = e.value;
        axisTip.style.left = (Number(e?.event?.event?.screenX) || 0) + 'px';
        axisTip.style.top = (Number(e?.event?.event?.screenY) || 0) + 'px';
        axisTip.style.display = 'block';
      }
    });

    return () => {
      myChart?.off('mouseover', () => {});
      chartDom?.removeEventListener('mouseout', () => {});
      chartDom?.removeEventListener('mouseover', () => {});
      timer = null;
    };
  }, [data]); // 检测数组内变量 如果为空 则监控全局

 5、完整代码如下:

/**
 * 收集完成率排名 图表
 */
import clsx from 'clsx';
import ReactECharts from 'echarts-for-react';
import { useEffect, useRef } from 'react';
import '../index.less';
import { getOption } from './constants';

interface ProjectBarConfig {
  data: any;
  rollTime?: number;
}

const LineECharts = (props: ProjectBarConfig) => {
  const { rollTime = 5000, data } = props;

  const chartRef = useRef<ReactECharts>(null);
  let timer: any = null;

  // 开启定时器
  const initialScroll = (dataLen: number, myChart: any) => {
    const option = myChart.getOption();
    // 只有当大于10条数据的时候 才会看起来滚动
    let time = setInterval(() => {
      if (data.length <= 8) {
        return;
      }
      if (option?.dataZoom[0].endValue >= dataLen - 1) {
        option.dataZoom[0].endValue = 7;
        option.dataZoom[0].startValue = 0;
      } else {
        option.dataZoom[0].endValue = option.dataZoom[0].endValue + 1;
        option.dataZoom[0].startValue = option.dataZoom[0].startValue + 1;
      }
      myChart.setOption(option);
      myChart.setOption({
        dataZoom: [
          {
            type: 'slider',
            startValue: option.dataZoom[0].startValue,
            endValue: option.dataZoom[0].endValue,
          },
        ],
      });
    }, Number(rollTime));
    timer = time;
  };

  // 移除y轴tip
  const removeAxisTip = () => {
    let axisTip: any = document.querySelector('.axis-tip');
    if (axisTip) {
      axisTip.innerText = '';
      axisTip.style.display = 'none';
    }
  };

  useEffect(() => {
    const myChart = chartRef?.current?.getEchartsInstance();
    let chartDom = chartRef.current?.getEchartsInstance()?.getDom();
    if (data.length > 8) {
      initialScroll(data.length, myChart);
      // 鼠标离开开启定时器
      chartDom?.addEventListener('mouseout', () => {
        if (timer) return;
        initialScroll(data.length, myChart);
      });
    }
    // 移入
    chartDom?.addEventListener('mouseover', () => {
      clearInterval(timer);
      timer = undefined;
      removeAxisTip();
    });
    // yAxis鼠标移入监听
    myChart?.on?.('mouseover', 'yAxis.category', function (e: any) {
      let axisTip: any = document.querySelector('.axis-tip');
      if (axisTip) {
        axisTip.innerText = e.value;
        axisTip.style.left = (Number(e?.event?.event?.screenX) || 0) + 'px';
        axisTip.style.top = (Number(e?.event?.event?.screenY) || 0) + 'px';
        axisTip.style.display = 'block';
      }
    });

    // });

    return () => {
      clearInterval(timer);
      myChart?.off('mouseover', () => {});
      chartDom?.removeEventListener('mouseout', () => {});
      chartDom?.removeEventListener('mouseover', () => {});
      timer = null;
    };
  }, [data]); // 检测数组内变量 如果为空 则监控全局

  const heightRate = Math.min((data.length || 1) / 8, 1) * 100;

  return (
    <div
      className={clsx(['w-full h-full', 'flex flex-row'])}
      onMouseLeave={() => {
        removeAxisTip();
      }}
    >
      <div
        className={clsx(['flex-auto', 'h-full'])}
        style={{
          height: `${heightRate}%`,
          maxHeight: '100%',
          minHeight: '20%',
        }}
      >
        <ReactECharts
          ref={chartRef}
          option={getOption(data)}
          className={clsx(['h-full w-full'])}
          style={{ width: '100%', height: '100%' }}
        />
        <div className="axis-tip"> </div>
      </div>
    </div>
  );
};

export default LineECharts;

 echar属性配置:

const ranKIconList = [
  'data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyOCIgaGVpZ2h0PSIyMCIgdmlld0JveD0iMCAwIDI4IDIwIiBmaWxsPSJub25lIj4NCiAgPHBhdGggZD0iTTAgMEgyMEwyOCAxMC41TDIwIDIwSDBWMFoiIGZpbGw9InVybCgjcGFpbnQwX2xpbmVhcl8yNDIxM183MDA4KSIvPg0KICA8ZGVmcz4NCiAgICA8bGluZWFyR3JhZGllbnQgaWQ9InBhaW50MF9saW5lYXJfMjQyMTNfNzAwOCIgeDE9IjE0IiB5MT0iMCIgeDI9IjE0IiB5Mj0iMjAiIGdyYWRpZW50VW5pdHM9InVzZXJTcGFjZU9uVXNlIj4NCiAgICAgIDxzdG9wIHN0b3AtY29sb3I9IiNGRkQxMkUiLz4NCiAgICAgIDxzdG9wIG9mZnNldD0iMSIgc3RvcC1jb2xvcj0iI0ZGQjgwMCIvPg0KICAgIDwvbGluZWFyR3JhZGllbnQ+DQogIDwvZGVmcz4NCjwvc3ZnPg==',
  'data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyOCIgaGVpZ2h0PSIyMSIgdmlld0JveD0iMCAwIDI4IDIxIiBmaWxsPSJub25lIj4NCiAgPHBhdGggZD0iTTAgMC4yODU2NDVIMjBMMjggMTAuNzg1NkwyMCAyMC4yODU2SDBWMC4yODU2NDVaIiBmaWxsPSJ1cmwoI3BhaW50MF9saW5lYXJfMjQyMTNfNzAxMSkiLz4NCiAgPGRlZnM+DQogICAgPGxpbmVhckdyYWRpZW50IGlkPSJwYWludDBfbGluZWFyXzI0MjEzXzcwMTEiIHgxPSIxNCIgeTE9IjAuMjg1NjQ1IiB4Mj0iMTQiIHkyPSIyMC4yODU2IiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSI+DQogICAgICA8c3RvcCBzdG9wLWNvbG9yPSIjQThDRkYwIi8+DQogICAgICA8c3RvcCBvZmZzZXQ9IjEiIHN0b3AtY29sb3I9IiM4N0I4RTEiLz4NCiAgICA8L2xpbmVhckdyYWRpZW50Pg0KICA8L2RlZnM+DQo8L3N2Zz4=',
  'data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyOCIgaGVpZ2h0PSIyMSIgdmlld0JveD0iMCAwIDI4IDIxIiBmaWxsPSJub25lIj4NCiAgPHBhdGggZD0iTTAgMC41NzEyODlIMjBMMjggMTEuMDcxM0wyMCAyMC41NzEzSDBWMC41NzEyODlaIiBmaWxsPSJ1cmwoI3BhaW50MF9saW5lYXJfMjQyMTNfNzAxNCkiLz4NCiAgPGRlZnM+DQogICAgPGxpbmVhckdyYWRpZW50IGlkPSJwYWludDBfbGluZWFyXzI0MjEzXzcwMTQiIHgxPSIxNCIgeTE9IjAuNTcxMjg5IiB4Mj0iMTQiIHkyPSIyMC41NzEzIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSI+DQogICAgICA8c3RvcCBzdG9wLWNvbG9yPSIjRkFDNjgxIi8+DQogICAgICA8c3RvcCBvZmZzZXQ9IjEiIHN0b3AtY29sb3I9IiNGNTkzMzgiLz4NCiAgICA8L2xpbmVhckdyYWRpZW50Pg0KICA8L2RlZnM+DQo8L3N2Zz4=',
  'data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyOCIgaGVpZ2h0PSIyMSIgdmlld0JveD0iMCAwIDI4IDIxIiBmaWxsPSJub25lIj4NCiAgPHBhdGggZD0iTTAgMC44NTY5MzRIMjBMMjggMTEuMzU2OUwyMCAyMC44NTY5SDBWMC44NTY5MzRaIiBmaWxsPSJ1cmwoI3BhaW50MF9saW5lYXJfMjQyMTNfNzAxNykiLz4NCiAgPGRlZnM+DQogICAgPGxpbmVhckdyYWRpZW50IGlkPSJwYWludDBfbGluZWFyXzI0MjEzXzcwMTciIHgxPSIxNCIgeTE9IjAuODU2OTM0IiB4Mj0iMTQiIHkyPSIyMC44NTY5IiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSI+DQogICAgICA8c3RvcCBzdG9wLWNvbG9yPSIjMEM0MjdDIi8+DQogICAgICA8c3RvcCBvZmZzZXQ9IjEiIHN0b3AtY29sb3I9IiMwODM1NjYiLz4NCiAgICA8L2xpbmVhckdyYWRpZW50Pg0KICA8L2RlZnM+DQo8L3N2Zz4=',
];
// 配置调色板
export const colorPalette = [
  ['#2EF2FF', '#2EB3FF'],
  ['#FFD12E', '#FFB82E'],
  ['#8EED15', '#00CF61'],
  ['#CFCFCF', '#999'],
  ['#FF7D54', '#FF2E2E'],
  ['#00F3E5', '#00D4D6'],
].map(([startColor, endColor]) => ({
  type: 'linear',
  x: 0,
  y: 0,
  x2: 0,
  y2: 1,
  colorStops: [
    {
      offset: 0,
      color: startColor, // 0% 处的颜色
    },
    {
      offset: 1,
      color: endColor, // 100% 处的颜色
    },
  ],
  global: false, // 缺省为 false
}));

export const getOption = (result) => {
  return {
    //   color: '2379FF',
    //   backgroundColor: '#000416',
    color: colorPalette,
    tooltip: {
      show: true,
      trigger: 'axis',
      padding: [8, 15],
      backgroundColor: 'rgba(1, 15, 29, 80%)',
      fontWeight: 700,
      borderColor: 'rgba(46, 179, 255, 50%)',
      textStyle: {
        color: 'rgba(255, 255, 255, 1)',
      },
    },
    legend: {
      show: false,
    },
    grid: {
      left: '100',
      right: '52',
      top: '0',
      bottom: '4',
    },
    xAxis: [
      {
        splitLine: {
          show: false,
        },
        type: 'value',
        show: false,
        axisLine: {
          show: false,
        },
      },
    ],
    yAxis: [
      {
        triggerEvent: true,
        splitLine: {
          show: false,
        },
        axisLine: {
          show: false,
        },
        // type: 'category',
        axisTick: {
          show: false,
        },
        inverse: true,
        // offset: 10,
        data: result.map((item) => item.projectName),
        axisLabel: {
          color: '#fff',
          fontSize: 12,
          // marginLeft: 12,
          overflow: 'truncate',
          ellipsis: '...',
          margin: 110,
          align: 'left',
          formatter: (value) => {
            const valueNew =
              value.length > 4 ? `${value.slice(0, 4)}...` : value;
            const index = result.findIndex(
              (item) => item.projectName === value,
            );
            if (index < 3) {
              return `{icon${index + 1}|${index + 1}} {a|${valueNew}}`;
            } else {
              return `{icon0|${index + 1}} {a|${valueNew}}`;
            }
          },
          rich: {
            icon0: {
              width: 28,
              height: 18,
              fontSize: 12,
              align: 'center',
              verticalAlign: 'middle',
              color: '#fff',
              padding: [3, 4], //[上, 右, 下, 左]
              fontWeight: 400,
              backgroundColor: {
                image: ranKIconList[3],
              },
            },
            icon1: {
              width: 28,
              height: 18,
              fontSize: 12,
              align: 'center',
              verticalAlign: 'middle',
              padding: [3, 4], //[上, 右, 下, 左]
              backgroundColor: {
                image: ranKIconList[0],
              },
            },
            icon2: {
              fontSize: 12,
              align: 'center',
              verticalAlign: 'middle',
              padding: [3, 4], //[上, 右, 下, 左]
              width: 28,
              height: 18,
              backgroundColor: {
                // image: bg,
                image: ranKIconList[1],
              },
            },
            icon3: {
              width: 28,
              height: 18,
              fontSize: 12,
              verticalAlign: 'middle',
              padding: [3, 4], //[上, 右, 下, 左]
              align: 'center',
              backgroundColor: {
                image: ranKIconList[2],
              },
            },
            a: {
              fontSize: '12px',
              color: '#B8D3F1',
              align: 'center',
            },

            z: {
              width: 6,
              height: 6,
            },
          },
        },
      },
    ],
    series: [
      {
        type: 'bar',
        label: {
          show: true,
          position: 'right',
          // distance: 0,
          textStyle: {
            fontSize: 12,
            color: '#2EB3FF', // 值文字颜色
          },
          formatter: (value) => {
            return `{a|${value?.data}%}`;
          },
          rich: {
            a: {
              fontSize: 12,
              fontWeight: 500,
              color: '#2EB3FF', // 值文字颜色
              fontStyle: 'normal',
              fontFamily: 'Arial',
              padding: [0, 8, 0, 8], //[上, 右, 下, 左]
            },
            b: {
              fontSize: 14,
            },
          },
        },
        itemStyle: {
          normal: {
            fontWeight: 400,
            // color: function(params) {
            //   return barShadowColor[params.dataIndex]
            // },
            opacity: 0.8,
          },
        },
        barWidth: 8,
        data: result.map((item) => item.value),
        // barGap:2,
        z: 2,
      },

      {
        name: '背景',
        type: 'bar',
        tooltip: { show: false },
        barWidth: 12,
        barHeight: 20,
        barGap: '-100%',
        // z: -1
      },
    ],
    dataZoom: [
      {
        yAxisIndex: [0, 1], // 这里是从X轴的0刻度开始
        show: false, // 是否显示滑动条,不影响使用
        type: 'slider', // 这个 dataZoom 组件是 slider 型 dataZoom 组件
        startValue: 0, // 从头开始。
        endValue: 7, // 展示到第几个。
      },
    ],
  };
};

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1437200.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

阿里云游戏服务器租用价格表,2024最新报价

阿里云游戏服务器租用价格表&#xff1a;4核16G服务器26元1个月、146元半年&#xff0c;游戏专业服务器8核32G配置90元一个月、271元3个月&#xff0c;阿里云服务器网aliyunfuwuqi.com分享阿里云游戏专用服务器详细配置和精准报价&#xff1a; 阿里云游戏服务器租用价格表 阿…

C语言之随心所欲打印三角形,金字塔,菱形(倒金字塔)

个人主页&#xff08;找往期文章包括但不限于本期文章中不懂的知识点&#xff09;&#xff1a; 我要学编程(ಥ_ಥ)-CSDN博客 目录 三角形 金字塔 倒金字塔 菱形 三角形 题目&#xff1a;根据输入的行数打印对应的三角形。&#xff08;用 * 号打印&#xff09; #includ…

亚信安慧AntDB构建繁荣生态的数据库管理系统

亚信安慧AntDB是一款数据库管理系统&#xff0c;它采用全球影响力大、社区繁荣、开放度高、生态增长迅速的PG内核。这款系统具有卓越的性能和稳定性&#xff0c;在全球范围内备受用户青睐。与此同时&#xff0c;AntDB的社区也是充满活力的&#xff0c;用户可以在社区中交流经验…

Java设计模式大全:23种常见的设计模式详解(三)

本系列文章简介&#xff1a; 设计模式是在软件开发过程中&#xff0c;经过实践和总结得到的一套解决特定问题的可复用的模板。它是一种在特定情境中经过验证的经验和技巧的集合&#xff0c;可以帮助开发人员设计出高效、可维护、可扩展和可复用的软件系统。设计模式提供了一种在…

Springboot项目报文加密(AES、RSA、Filter动态加密)

Springboot项目报文加密(AES、RSA、Filter动态加密) 一、痛点1.1、初版报文加密二、前期准备2.1、AES加密2.2、RSA加密2.3、国密算法概述2.4、国密SM22.5、国密SM32.6、国密SM42.7、JAVA中的拦截器、过滤器2.8、请求过滤器2.9、响应过滤器2.10、登录验证码2.11、BCrypt非对称…

【力扣 51】N 皇后(回溯+剪枝+深度优先搜索)

按照国际象棋的规则&#xff0c;皇后可以攻击与之处在同一行或同一列或同一斜线上的棋子。 n 皇后问题 研究的是如何将 n 个皇后放置在 nn 的棋盘上&#xff0c;并且使皇后彼此之间不能相互攻击。 给你一个整数 n &#xff0c;返回所有不同的 n 皇后问题 的解决方案。 每一种…

C++ 11/14/17 智能指针

1. 简介 为了更加容易&#xff08;更加安全&#xff09;的使用动态内存&#xff0c;引入了智能指针的概念。智能指针的行为类似常规指针&#xff0c;重要的区别是它负责自动释放所指向的对象。 标准库提供的两种智能指针的区别在于管理底层指针的方法不同&#xff1a;shared_p…

【MATLAB】使用随机森林在回归预测任务中进行特征选择(深度学习的数据集处理)

1.随机森林在神经网络的应用 当使用随机森林进行特征选择时&#xff0c;算法能够为每个特征提供一个重要性得分&#xff0c;从而帮助识别对目标变量预测最具影响力的特征。这有助于简化模型并提高其泛化能力&#xff0c;减少过拟合的风险&#xff0c;并且可以加快模型训练和推理…

时间序列特有的交叉验证方法GroupTimeSeriesSplit

一、前言 对于时间序列的任务的交叉验证&#xff0c;很核心的问题在于数据是否leak&#xff0c;因为较其他数据最为不同的是时间信息&#xff0c;有先后的发生顺序。 如果用简单的打散数据顺序&#xff0c;之后抽取&#xff0c;进行交叉验证肯定是违反这个时间顺序的规则的&…

有趣的CSS - 多彩变化的按钮

目录 整体效果核心代码html 代码css 部分代码 完整代码如下html 页面css 样式页面渲染效果 整体效果 这个按钮效果主要使用 :hover 、:active 伪选择器以及 animation 、transition 属性来让背景色循环快速移动形成视觉效果。 核心代码部分&#xff0c;简要说明了写法思路&…

shell脚本基础语法(.sh ./ sh bash source shell)

Linux 之 Shell 脚本基础语法 0. 学习一门语言的顺序 1. Shell 编程概述 1.1 Shell 名词解释 在 Linux 操作系统中&#xff0c;Shell 是一个命令行解释器&#xff0c;它为用户提供了一个与操作系统内核交互的界面。用户可以通过 Shell 输入命令&#xff0c;然后 Shell 将这些…

Redis -- zset有序集合

聪明在于勤奋&#xff0c;天才在于积累。 目录 zset 有序集合 zset相关命令 zadd zcard zcount zrange zrevrange zrangebyscore zpopmax bzpopmax zpopmin bzpopmin zrank zscore zrem zRemRangeByRank zRemRangeByScore zincrby 集合间操作 zinte…

mac电脑快捷指令实现拼图

mac访达&#xff0c;搜索输入‘快捷指令’&#xff0c;找到‘快捷指令’&#xff0c; 点击快捷指令&#xff0c;进入快捷指令中心&#xff0c;搜索‘拼图’ &#xff0c;选中‘照片拼图’&#xff0c; 点击‘添加快捷指令’&#xff0c; 在‘所有快捷键指令’中可以看到添加的快…

Unity C#进阶案例 “泛型编程”

文章目录 泛型基础示例1&#xff1a;泛型类与方法示例2&#xff1a;泛型方法示例3&#xff1a;泛型约束示例4&#xff1a;泛型委托与事件示例5&#xff1a;泛型单例模式&#xff08;Unity&#xff09; 在Unity中&#xff0c;C#的泛型编程是一种强大的工具&#xff0c;它允许你编…

对网络流水印的调查

文章信息 论文题目&#xff1a;Network Flow Watermarking: A Survey 期刊&#xff08;会议&#xff09;&#xff1a; IEEE Communications Surveys & Tutorials 时间&#xff1a;2016 级别&#xff1a;中科院1区 文章链接&#xff1a;https://ieeexplore.ieee.org/stamp/…

JCTC | 利用几何深度学习对蛋白质-配体结合pose进行等变灵活建模

Overview 该论文解决了药物开发中蛋白质-配体复合结构灵活建模的挑战。作者提出了一种名为FlexPose的新型深度学习框架&#xff0c;它可以直接对复杂结构进行建模&#xff0c;而不需要传统的采样和评分策略。 该模型结合了标量-向量双特征表示和 SE(3)等变网络设计来处理动态结…

AI数字人训练数据集汇总

唇读&#xff08;Lip Reading&#xff09;&#xff0c;也称视觉语音识别&#xff08;Visual Speech Recognition&#xff09;&#xff0c;通过说话者口 型变化信息推断其所说的内容&#xff0c;旨在利用视觉信道信息补充听觉信道信息&#xff0c;在现实生活中有重要应用。例如&…

SpringCloud-创建多模块项目

在微服务架构中&#xff0c;项目的组织结构对于代码的维护和团队的协作至关重要。Spring Cloud作为一个强大的微服务框架&#xff0c;提供了丰富的功能和组件&#xff0c;同时也支持多模块项目的创建&#xff0c;使得代码结构更加清晰、易于管理。本文将介绍如何使用 Spring Cl…

【教程】Linux使用git自动备份和使用支持文件恢复的rm命令

转载请注明出处&#xff1a;小锋学长生活大爆炸[xfxuezhang.cn] 背景介绍 首先非常不幸地告诉你&#xff1a;Linux 系统的标准 rm 命令不支持文件恢复功能。一旦使用 rm 删除了文件或目录&#xff0c;它们就会从文件系统中永久删除&#xff0c;除非你使用专门的文件恢复工具尝试…

华视 CVR-100UC 身份证读取 html二次开发模板

python读卡&#xff1a;python读卡 最近小唐应要求要开发一个前端的身份证读卡界面&#xff0c;结果华视CVR-100UC 的读取界面是在是有点&#xff0c;而且怎么调试连官方最基本的启动程序都执行不了。CertReader.ocx 已成功&#xff0c;后面在问询一系列前辈之后&#xff0c;大…