首页 > 其他分享 >EchartsLabel显示的细节处理

EchartsLabel显示的细节处理

时间:2023-01-30 17:22:41浏览次数:66  
标签:EchartsLabel 字符 const string 处理 text 细节 return font

0. 缘起

照理来说,春节过后的我现在应该还在快乐地摸鱼划水,但小测试猛地发来测试文档和示例,我对了一波之后对其中有个Echarts的label显示超过20截断有了些许冷汗泠泠的感觉。遂看了一波原本的代码,感慨下开山祖师爷细节处理的到位。

1. 柱状图数值显示的大致情况

xAxis

竖向

对于按照高度限制竖直文本高度的情况,需要按照 Math.floor(限制高度/行高),计算出限制字数

横向

全显示

其他方向

根据垂直高度及倾斜角,计算倾斜状态下的最大字符宽度

yAxis

y轴数值是什么就显示什么

2. 对xAxis的处理

xAxis配置中注意两个属性axisLabelnameTextStyle

    axisLabel: {
      //   interval: 0,
      show: config.showLabel,
      rotate: getRotate(config.labelRotate),
      formatter: getFormatter(config.labelRotate, aAxisHeight),
      rich: {
        text: {
          align: 'right',
          fontSize: LABEL_FONT_SIZE,
          lineHeight: LABEL_FONT_SIZE,
        },
        ellipsis: verticalEllipsis.style,
      },
    },
    nameTextStyle: {
      // 当显示label时,让name稍微下移,不然与label在同一行,容易混淆
      // 隐藏label时,让name上移,否则会超出视口
      lineHeight: config.showLabel ? 50 : 25,
    },

3. 关键函数

getFormatter

xAxislabel进行格式化,是入口函数

/**
 * get xAxis label formatter
 * */
const getFormatter = (rotate: XAxisLabelRotate, height: number) => {
  /**
   * echarts会根据xaxis label 高度动态的调整底部间距,我们需要做的
   * 是限制xaxis label 高度,不让其超过 “20个中文字符高度数值” 的高度
   *
   * 1. 默认遵从 从左到右原则
   *
   * 2. 对于竖直排列的文本,要这样展示i
   * -----------------------------
   *      乐
   *      盘
   *      游
   *
   *
   * */
  const formatter = (v: any) => {
    const text = String(v);

    // 竖直排列
    // 对于按照高度限制竖直文本高度的情况,只需要按照 Math.floor(限制高度/行高)
    // 计算出限制字数,然后对文本进行截取即可 (因为中英文字符高度相同)
    if (rotate === XAxisLabelRotate.Vertical) {
      const chartCount = Math.floor(height / LABEL_FONT_SIZE);

      return renderVerticalText({
        text,
        count: chartCount,
      });
    }

    // 水平
    if (rotate === XAxisLabelRotate.Horizontal) {
      return `{text|${text}}`;
    }

    // 其他角度
    // 根据垂直高度及倾斜角,计算倾斜状态下的最大字符宽度
    const stringWidth = height / Math.sin(Math.PI * (Math.abs(rotate) / 180));
    // 单个中文字符宽度
    const charWidth = textRuler.measureText('乐', {
      fontSize: `${LABEL_FONT_SIZE}px`,
    });
    // 计算最大字符数
    const chartCount = Math.floor(stringWidth / charWidth);
    // 截取字符
    const sub = subString(text, chartCount);
    return `{text|${sub}${sub !== text ? '...' : ''}}`;
  };

  return formatter;
};

renderVerticalText

将横向文本渲染成竖向的

/**
 * 将普通的字符串按照格式化成如下格式用于echarts渲染:
 *
 * "乐盘游"
 *  ↓↓↓↓↓↓
 * --------------
 *    乐
 *    盘
 *    游
 *
 * NOTE: 需要结合echarts rich属性使用
 *
 * 对于按照高度限制竖直文本高度的情况,只需要按照 Math.floor(限制高度/行高)
 * 计算出限制字数即可
 *
 * */
export default function renderVerticalText({ text, count }: Config): string {
  const shouldSlice = text.length > count;
  const subText = shouldSlice ? text.substring(0, count) : text;
  const verticalText = subText.split('').join('\n');

  if (shouldSlice) {
    return `{text|${verticalText}}\n{ellipsis|${verticalEllipsis.text}}`;
  }

  return `{text|${verticalText}}`;
}
export const verticalEllipsis = {
  text: '.\n.\n.',
  style: {
    lineHeight: 4,
    fontSize: 12,
  },
};

subString

截取指定宽度字符

/**
 * 截取 **指定数量中文字符宽度** 的字符串,超过的部分舍弃
 *
 * */
export default function subString(str: string, len: number): string {
  if (str.length < len) {
    return str;
  }

  // 按照实际长度进行截取
  const subStr = str.substring(0, len);
  // 在截取后的字符串中查找,属于ascii编码的字符,因为这些字符宽度只有中文一半
  // (其他半角字符基本不会出现,所以不做考虑)
  const enChars = subStr.match(/[\u20-\u7f]/g);

  // 如果ascii编码的字符数量大于1个,则实际截取的字符串长度会比预想的
  // 长度小很多,所以需要补齐
  if (enChars && enChars.length > 1) {
    const restLen = Math.floor(enChars.length / 2);

    return subStr + subString(str.substring(len), restLen);
  }

  return subStr;
}

4. 倾斜时的类:

倾斜时还有一些细节处理,看了真感觉叹为观止。

先算单个字符,再算最大字符数,最后截取这一部分显示

textRulerInstance.ts

import createTextRuler from './textRuler';

export default createTextRuler();

textRuler.ts

import { setCSSFont, CSSFont } from './cssFont';

/**
 * 创建一个测量字符绘制像素宽度的尺子

标签:EchartsLabel,字符,const,string,处理,text,细节,return,font
From: https://www.cnblogs.com/lepanyou/p/17076708.html

相关文章

  • 多个线程下处理事务
     springboot项目都是声明式事务,在多个线程事务处理时,需要我们使用手动事务管理器@ResourceprivatePlatformTransactionManagerplatformTransactionManager;......
  • 在selenium中如何处理多窗口?
    这个多窗口之间跳转处理,在实际selenium自动化测试经常遇到。点击一个链接,这个链接会在一个新的tab打开,然后接下来要查找元素在新tab打开的页面,需要先将driver切换至window,......
  • 你是如何处理iframe里面元素定位的?
    有时候我们写的元素定位表达式没有问题,但是脚本还是提示nosuchelement,那么我们就需要考虑 这个元素是否在iframe中。通过f12查看元素HTML中是否有iframe标签,如果有iframe......
  • windwos 系统打补丁后重启不了处理方案
    如果可以进入WinRE这个修复的高级选项,选择安全模式,是否可以进入,卸载最近安装的补丁,再重启看一下。如果无法进入安全模式的话,那么选择cmd模式,使用下方命令。这通常会回退pe......
  • 验证码的几种处理方式
     针对验证码有如下方法:1>在产品没有上线前,需要找开发先给web验证码留后门,也就是将验证码验证先注释掉2>让开发给web验证码留一个万用验证码,只要输入给定的验证码,就可以......
  • WPF-控件的平移、旋转、镜像缩放、倾斜处理
    代码:<PathMargin="0"Width="14"Height="14"Stretch="Fill"Fill="#40568d"Data="M344576v-192L56624l288240v-192h240a3843840100-768H152v96h432a2882880......
  • Fitter-细节-过滤器拦截方式配置 Fitter-细节-过滤器链(多个过滤器)
    Fitter-细节-过滤器拦截方式配置  拦截方式配置:资源被访问的方式注解配置:设置dispatcherTypes属性1.REQUEST:默认值。浏览器直接请求资源......
  • 处理Navicat到期的办法
    次方法是无限续杯法,可无限使用14天Navicat。1.删除注册表win+R输入regedit分别粘贴如下两条语句HKEY_CURRENT_USER\Software\PremiumSoft\Data 删除全部Date文件夹......
  • 谷歌邮箱无法显示使用 Base64 处理的图片的解决方法
    前言有时候图片会使用Base64编码来处理,然后再传到前端img标签的src属性里展示,这里记录遇到的一个问题,就是使用谷歌邮箱来打开图片,使用了Base64编码处理的图片是展......
  • 【KAWAKO】audiotsm-使用python对音频进行变速不变调处理
    目录安装库导入相关库定义reader定义writer定义WSLOA算法,并运行官方手册源码安装库pipinstallaudiotsm导入相关库importaudiotsmimportaudiotsm.io.wavimpo......