Node.js 艺术:用代码打印出绚丽多彩的控制台柱状图

简介: Node.js 艺术:用代码打印出绚丽多彩的控制台柱状图

说在前面

echarts图表我们见多了,有没有想过在控制台实现一个图标呢?本文将带您领略 Node.js 的魅力,教您如何使用 JavaScript 代码在控制台中一键绘制出令人惊叹的柱状图。我们将一起揭示背后的技巧,包括数据处理、格式化输出和绘图算法,让您轻松将数据转化为视觉艺术,并且为您的控制台应用增添一份独特的魅力。

效果展示

实现步骤

1、获取最大公约数

获取数据集合的最大公约数,并将数据集合中的每个元素都除以这个最大公约数,使得所有数据可以被放缩到一个较小的范围内。

function gcd(a, b) {
  if (b === 0) {
    return a;
  }
  return gcd(b, a % b);
}
function findGCD(numbers) {
  if (numbers.length === 0) {
    return null;
  }
  let result = numbers[0];
  for (let i = 1; i < numbers.length; i++) {
    result = gcd(result, numbers[i]);
    if (result === 1) {
      return 1;
    }
  }
  return result;
}

2、格式化数值

将每个数字格式化为固定位数的字符串,并居中对齐

function getShowNum(num, barWidth) {
  const numLen = (num + "").length;
  const dif = barWidth - numLen;
  const left = Math.floor(dif / 2);
  return " ".repeat(left) + num + " ".repeat(dif - left);
}

3、数据化简

将柱形图数据化简,所有数据除以他们的最大公约数,通过设置的maxHeight计算柱状图条形的高度缩放比例 scaleFactor。

let data = options.data;
  const { maxHeight, barSpacing = 2 } = options;
  const result = findGCD(data);
  data = data.map((item) => {
    return item / result;
  });
  const max = Math.max(...data);
  const barWidth = (max * result + "").length;
  const min = Math.min(...data);
  const scaleFactor = maxHeight / (max - min);

4、绘制柱状图

从 maxHeight 开始循环,逐行输出柱状图。对于每一行,先初始化 row 为一个竖线符号“|”和一个绿色 ANSI 转义码,用于表示柱状图条形的颜色。然后遍历数据集合中的每个元素,根据其大小和 scaleFactor 的结果,输出相应数量的空格或实心方块字符。

开头输出一个 | 作为y轴,最下方输出一行 作为x轴。

let maxLen = 0;
  for (let i = maxHeight + 3; i > 0; i--) {
    let row = "|   \x1B[32m";
    data.forEach((value) => {
      const scaledValue = Math.floor(value * scaleFactor);
      if (scaledValue === i) row += getShowNum(value * result, barWidth);
      else if (scaledValue >= i) {
        for (let j = 0; j < barWidth; j++) {
          row += "█";
        }
      } else {
        for (let j = 0; j < barWidth; j++) {
          row += " ";
        }
      }
      for (let j = 0; j < barSpacing; j++) {
        row += " ";
      }
    });
    maxLen = Math.max(maxLen, row.length);
    console.log(row + "\x1B[39m");
  }
  console.log(" ̄".repeat((maxLen / 3) * 2));

5、完整代码

const { findGCD } = require("../utils");
function getShowNum(num, barWidth) {
  const numLen = (num + "").length;
  const dif = barWidth - numLen;
  const left = Math.floor(dif / 2);
  return " ".repeat(left) + num + " ".repeat(dif - left);
}
function printBarChart(options) {
  let data = options.data;
  const { maxHeight, barSpacing = 2 } = options;
  const result = findGCD(data);
  data = data.map((item) => {
    return item / result;
  });
  const max = Math.max(...data);
  const barWidth = (max * result + "").length;
  const min = Math.min(...data);
  const scaleFactor = maxHeight / (max - min);
  let maxLen = 0;
  for (let i = maxHeight + 3; i > 0; i--) {
    let row = "|   \x1B[32m";
    data.forEach((value) => {
      const scaledValue = Math.floor(value * scaleFactor);
      if (scaledValue === i) row += getShowNum(value * result, barWidth);
      else if (scaledValue >= i) {
        for (let j = 0; j < barWidth; j++) {
          row += "█";
        }
      } else {
        for (let j = 0; j < barWidth; j++) {
          row += " ";
        }
      }
      for (let j = 0; j < barSpacing; j++) {
        row += " ";
      }
    });
    maxLen = Math.max(maxLen, row.length);
    console.log(row + "\x1B[39m");
  }
  console.log(" ̄".repeat((maxLen / 3) * 2));
}
// 使用示例
const options = {
  data: [3, 7, 2, 5, 8, 12],
  maxHeight: 10,
  barWidth: 2,
  barSpacing: 1,
};
printBarChart(options);

后续

目前只实现了一个简单的雏形样板,后续会考虑完善更多的功能和样式,并封装成一个插件,有兴趣的同学们可以提点建议和想法。

公众号

关注公众号『前端也能这么有趣』,获取更多有趣内容。

说在后面

🎉 这里是 JYeontu,现在是一名前端工程师,有空会刷刷算法题,平时喜欢打羽毛球 🏸 ,平时也喜欢写些东西,既为自己记录 📋,也希望可以对大家有那么一丢丢的帮助,写的不好望多多谅解 🙇,写错的地方望指出,定会认真改进 😊,偶尔也会在自己的公众号『前端也能这么有趣』发一些比较有趣的文章,有兴趣的也可以关注下。在此谢谢大家的支持,我们下文再见 🙌。

目录
相关文章
|
10月前
|
JavaScript 前端开发 安全
【逆向】Python 调用 JS 代码实战:使用 pyexecjs 与 Node.js 无缝衔接
本文介绍了如何使用 Python 的轻量级库 `pyexecjs` 调用 JavaScript 代码,并结合 Node.js 实现完整的执行流程。内容涵盖环境搭建、基本使用、常见问题解决方案及爬虫逆向分析中的实战技巧,帮助开发者在 Python 中高效处理 JS 逻辑。
|
JavaScript 前端开发 算法
流量分发代码实战|学会用JS控制用户访问路径
流量分发工具(Traffic Distributor),又称跳转器或负载均衡器,可通过JavaScript按预设规则将用户随机引导至不同网站,适用于SEO优化、广告投放、A/B测试等场景。本文分享一段不到百行的JS代码,实现智能、隐蔽的流量控制,并附完整示例与算法解析。
401 1
|
存储 JavaScript 前端开发
在NodeJS中使用npm包进行JS代码的混淆加密
总的来说,使用“javascript-obfuscator”包可以帮助我们在Node.js中轻松地混淆JavaScript代码。通过合理的配置,我们可以使混淆后的代码更难以理解,从而提高代码的保密性。
1450 9
|
人工智能 程序员 UED
【01】完成新年倒计时页面-蛇年新年快乐倒计时领取礼物放烟花html代码优雅草科技央千澈写采用html5+div+CSS+JavaScript-优雅草卓伊凡-做一条关于新年的代码分享给你们-为了C站的分拼一下子
【01】完成新年倒计时页面-蛇年新年快乐倒计时领取礼物放烟花html代码优雅草科技央千澈写采用html5+div+CSS+JavaScript-优雅草卓伊凡-做一条关于新年的代码分享给你们-为了C站的分拼一下子
987 21
【01】完成新年倒计时页面-蛇年新年快乐倒计时领取礼物放烟花html代码优雅草科技央千澈写采用html5+div+CSS+JavaScript-优雅草卓伊凡-做一条关于新年的代码分享给你们-为了C站的分拼一下子
|
前端开发 JavaScript
【Javascript系列】Terser除了压缩代码之外,还有优化代码的功能
Terser 是一款广泛应用于前端开发的 JavaScript 解析器和压缩工具,常被视为 Uglify-es 的替代品。它不仅能高效压缩代码体积,还能优化代码逻辑,提升可靠性。例如,在调试中发现,Terser 压缩后的代码对删除功能确认框逻辑进行了优化。常用参数包括 `compress`(启用压缩)、`mangle`(变量名混淆)和 `output`(输出配置)。更多高级用法可参考官方文档。
1090 11
|
前端开发 JavaScript
【02】v1.0.1更新增加倒计时完成后的放烟花页面-优化播放器-优化结构目录-蛇年新年快乐倒计时领取礼物放烟花html代码优雅草科技央千澈写采用html5+div+CSS+JavaScript-优雅草卓伊凡-做一条关于新年的代码分享给你们-为了C站的分拼一下子
【02】v1.0.1更新增加倒计时完成后的放烟花页面-优化播放器-优化结构目录-蛇年新年快乐倒计时领取礼物放烟花html代码优雅草科技央千澈写采用html5+div+CSS+JavaScript-优雅草卓伊凡-做一条关于新年的代码分享给你们-为了C站的分拼一下子
891 14
【02】v1.0.1更新增加倒计时完成后的放烟花页面-优化播放器-优化结构目录-蛇年新年快乐倒计时领取礼物放烟花html代码优雅草科技央千澈写采用html5+div+CSS+JavaScript-优雅草卓伊凡-做一条关于新年的代码分享给你们-为了C站的分拼一下子
|
JavaScript
JS代码的一些常用优化写法
JS代码的一些常用优化写法
236 0
|
JavaScript 前端开发 算法
JavaScript 中通过Array.sort() 实现多字段排序、排序稳定性、随机排序洗牌算法、优化排序性能,JS中排序算法的使用详解(附实际应用代码)
Array.sort() 是一个功能强大的方法,通过自定义的比较函数,可以处理各种复杂的排序逻辑。无论是简单的数字排序,还是多字段、嵌套对象、分组排序等高级应用,Array.sort() 都能胜任。同时,通过性能优化技巧(如映射排序)和结合其他数组方法(如 reduce),Array.sort() 可以用来实现高效的数据处理逻辑。 只有锻炼思维才能可持续地解决问题,只有思维才是真正值得学习和分享的核心要素。如果这篇博客能给您带来一点帮助,麻烦您点个赞支持一下,还可以收藏起来以备不时之需,有疑问和错误欢迎在评论区指出~
|
JavaScript 前端开发 API
JavaScript中通过array.map()实现数据转换、创建派生数组、异步数据流处理、复杂API请求、DOM操作、搜索和过滤等,array.map()的使用详解(附实际应用代码)
array.map()可以用来数据转换、创建派生数组、应用函数、链式调用、异步数据流处理、复杂API请求梳理、提供DOM操作、用来搜索和过滤等,比for好用太多了,主要是写法简单,并且非常直观,并且能提升代码的可读性,也就提升了Long Term代码的可维护性。 只有锻炼思维才能可持续地解决问题,只有思维才是真正值得学习和分享的核心要素。如果这篇博客能给您带来一点帮助,麻烦您点个赞支持一下,还可以收藏起来以备不时之需,有疑问和错误欢迎在评论区指出~
|
人工智能 数据可视化 机器人
【通义灵码】三句话生成P5.js粒子特效代码,人人都可以做交互式数字艺术
我发掘出的通义灵码AI程序员新玩法:三句话生成P5.js粒子特效代码,人人都可以做交互式数字艺术
688 6