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

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, // 展示到第几个。
      },
    ],
  };
};

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

JavaScript流程控制详解之顺序结构和选择结构

流程控制 流程控制&#xff0c;指的是控制程序按照怎样的顺序执行 在JavaScript中&#xff0c;共有3种流程控制方式 顺序结构选择结构循环结构 顺序结构 在JavaScript中&#xff0c;顺序结构是最基本的结构&#xff0c;所谓的顺序结构&#xff0c;指的是代码按照从上到下、…

数据结构之堆排序

对于几个元素的关键字序列{K1&#xff0c;K2&#xff0c;…&#xff0c;Kn}&#xff0c;当且仅当满足下列关系时称其为堆&#xff0c;其中 2i 和2i1应不大于n。 { K i ≤ K 2 i 1 K i ≤ K 2 i 或 { K i ≥ K 2 i 1 K i ≥ K 2 i {\huge \{}^{K_i≤K_{2i}} _{K_i≤K_{2i1}} …

《java 从入门到放弃》1.1 jdk 安装

1.jdk 是啥&#xff1f; jdk&#xff08;Java Development Kit&#xff09;&#xff0c;简单来说&#xff0c;就是java的开发工具。允许java 程序就是用它了。 jre &#xff0c;里面放的是java用的那些公用的包。 2.jdk下载 2.1 官网下载地址&#xff1a;Java Downloads | …

vue项目开发vscode配置

配置代码片段 步骤如下&#xff1a; 文件->首选项->配置用户代码片段新增全局代码片段起全局代码片段文件名“xxx.code-snippets” 这里以配置vue2初始代码片段为例&#xff0c;配置具体代码片段 {"name": "vue-sph","version": "…

07-使用Package、Crates、Modules管理项目

上一篇&#xff1a;06-枚举和模式匹配 当你编写大型程序时&#xff0c;组织代码将变得越来越重要。通过对相关功能进行分组并将具有不同功能的代码分开&#xff0c;您可以明确在哪里可以找到实现特定功能的代码&#xff0c;以及在哪里可以改变功能的工作方式。 到目前为止&…

2.6学习总结

2.6 1.蓝桥公园 2.路径 3.打印路径 4.【模板】Floyd Floyd算法&#xff1a; 是一种多源的最短路径算法&#xff0c;经过一次计算可以得到任意两个点之间的最短路径。 这种算法是基于动态规划的思想&#xff1a; m[i][j]表示从i到j这条边的距离&#xff0c;dp[k][i][j]表示从…

Docker的镜像和容器的区别

1 Docker镜像 假设Linux内核是第0层&#xff0c;那么无论怎么运行Docker&#xff0c;它都是运行于内核层之上的。这个Docker镜像&#xff0c;是一个只读的镜像&#xff0c;位于第1层&#xff0c;它不能被修改或不能保存状态。 一个Docker镜像可以构建于另一个Docker镜像之上&…

计算机网络——网络

计算机网络——网络 小程一言专栏链接: [link](http://t.csdnimg.cn/ZUTXU)前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家&#xff0c; [跳转到网站](https://www.captainbed.cn/qianqiu) 无线网络和移动网…

YOLOv8改进 | 基础篇 | 计算训练好权重文件对应的FPS、推理每张图片的平均时间(科研必备)

一、本文介绍 本文给大家带来的改进机制是利用我们训练好的权重文件计算FPS,同时打印每张图片所利用的平均时间,模型大小(以MB为单位),同时支持batch_size功能的选择,对于轻量化模型的读者来说,本文的内容对你一定有帮助,可以清晰帮你展示出模型速度性能的提升以及轻量…

2024PMP考试新考纲-近年PMP真题练一练和很详细解析(3)

今天华研荟继续为您分享和解析PMP真题&#xff0c;一方面让大家感受实际的PMP考试和出题形式&#xff0c;另一方面是通过较详细的解题思路和知识讲解帮助大家最后一个多月有效备考&#xff0c;一次性3A通过2024年PMP考试。 2024年PMP考试新考纲-近年真题随机练一练 (注&#x…

LeetCode 2641. 二叉树的堂兄弟节点 II:层序遍历并记下兄弟节点

【LetMeFly】2641.二叉树的堂兄弟节点 II&#xff1a;层序遍历并记下兄弟节点 力扣题目链接&#xff1a;https://leetcode.cn/problems/cousins-in-binary-tree-ii/ 给你一棵二叉树的根 root &#xff0c;请你将每个节点的值替换成该节点的所有 堂兄弟节点值的和 。 如果两个…

SparkJDBC读写数据库实战

默认的操作 代码val df = spark.read.format("jdbc").option("url", "jdbc:postgresql://localhost:5432/testdb").option("user", "username").option("password", "password").option("driver&q…

c#cad 创建-正方形(四)

运行环境 vs2022 c# cad2016 调试成功 一、程序说明 创建一个正方形&#xff0c;并将其添加到当前活动文档的模型空间中。 程序首先获取当前活动文档和数据库&#xff0c;并创建一个编辑器对象。 然后&#xff0c;使用事务开始创建正方形的操作。获取模型空间的块表记录&a…

【Java从入门到精通】Java对象和类

Java 对象和类 Java作为一种面向对象语言。支持以下基本概念&#xff1a; 多态继承封装抽象类对象实例方法重载 本节我们重点研究对象和类的概念。 对象&#xff1a;对象是类的一个实例&#xff08;对象不是找个女朋友&#xff09;&#xff0c;有状态和行为。例如&#xff0c…

显示器校准软件:BetterDisplay Pro for Mac v2.0.11激活版下载

BetterDisplay Pro是一款由waydabber开发的Mac平台上的显示器校准软件&#xff0c;可以帮助用户调整显示器的颜色和亮度&#xff0c;以获得更加真实、清晰和舒适的视觉体验。 软件下载&#xff1a; BetterDisplay Pro for Mac v2.0.11激活版下载 以下是BetterDisplay Pro的主要…

ABAP 标准状态栏GUI STATUS的快速创建

ABAP 标准状态栏GUI STATUS的快速创建 不用先创建GUI 状态 SE41

JVM内存泄漏问题分析处理实战

一、背景 文章开头&#xff0c;先分享一张大部分Java开发同学都记在心里的一张图。 没错&#xff0c;就是Spring Bean生命周期图。就因为这张图不熟悉&#xff0c;导致线上环境出现内存泄漏问题&#xff0c;系统频繁FullGC&#xff0c;服务无法响应。 1、第一次报错系统监控现…

vscode预览github上的markdown效果

需要安装的插件有&#xff1a; Github Markdown Preview Markdown Checkboxes Markdown Emoji Markdown footnotes Markdown Preview Github Styling Markdown Preview Mermaid Support Markdown yaml Preamble ctrlshiftv结合双页功能

澳福实例说明真实交易中止损单和限价单的区别

很多投资者不明白止损单和限价单的区别&#xff0c;今天澳福就举一个例子来说明真实交易中止损单和限价单的区别。 紫色椭圆显示了在欧元兑美元图表上的位置&#xff0c;在不稳定的增长之后&#xff0c;澳福 外汇看到了另一波修正&#xff0c;没有看涨的迹象。同时也发现从历史…

APIfox自动化编排场景(二)

测试流程控制条件 你可以在测试场景中新增流程控制条件&#xff08;循环、判断、等待、分组&#xff09;等。进一步满足了更复杂的测试场景/流程配置的使用&#xff0c;最终借助自动化测试功能解决复杂场景的测试工作。 分组​ 当测试流程中多个步骤存在相关联关系时&#xf…