Web端重叠路径可视化

news2024/11/19 22:32:19

近几年来,由于信息技术的发展,大数据成为了这个时代的代名词之一,“数据可视化”风靡一时。得益于HTML5提供的新标签“canvas”,Web端也能分“数据可视化”一杯羹。

随着越来越多的可视化方案和需求,需要解决问题也越来越多。当我们在Web端遇到重叠路径可视化渲染问题时,我们应该怎么做呢?

在这里插入图片描述

思路

按照数学的思路来说,对于上图所示的重叠路径渲染,我们应当计算出重叠的区域及重叠的次数,然后再分别进行渲染,就能得到上图。

但是,实践发现,在Web端这是一件极其复杂和困难的事情,我们不得不另寻他法。既然来硬的不行,就只能变通变通,另辟蹊径,做其他的尝试。

Canvas元素是一个位图,是基于像素的,在绘制图形时,当图形重叠时,其颜色通道会按照一定的规则进行叠加运算,如下图所示。

这就是我们的切入点,我们只需要根据叠加规则进行颜色再填充就能实现重叠路径的颜色区分渲染。

在这里插入图片描述

基于Canvas 2D

在Canvas2D 中,我们只需要设置填充颜色带透明度,绘制后获取ImageData,对ImageData进行修改,再重新渲染即可。

1.创建离屏canvas 设置透明度,进行渲染

const offscreenCanvas = new OffscreenCanvas(width, height); // 离屏canvas
const ctx = offscreenCanvas.getContext('2d');
ctx.fillStyle = 'rgba(0, 255, 0, 0.1)';
// 绘制内容

2.获取ImageData

const imageData = ctx.getImageData(0, 0, width, height); // 获取ImageData

3.通过imageData 计算遍数并改变颜色

const base = 0.1; // 上面第一步设置的填充颜色透明度
const data = imageData.data;
for(let i = 3; i < data.length; i++) {
const a = data[i];
const time = Math.log(1-a) / Math.log(1 - base); // 重叠次数
// 根据重叠次数更改颜色
}
return new ImageData(data, imageData.width, imageData.height);
// 返回imageData

4.再渲染上屏

ctx.putImageData(imageData, 0, 0); // 此处ctx为屏幕上canvas的上下文。

这样我们就可以使用Canvas2D API 在canvas 中绘制出重叠区域区分颜色的带状图。但是我们要注意一点,使用Path渲染时,一次渲染会被视为一个整体图案,透明度是不会叠加的。我们需要分批次渲染多边形,才能实现透明度叠加。

这种方法适合数据量不多且不存在高刷新的情况下,因为绘制数据、获取ImageData 及编辑ImageData需要占用很多的时间。

那还有没有更好的办法呢?Canvas2D 性能不满足的东西,就试着交给WebGL吧。

基于WebGL

WebGL是HTML5提供的基于canvas的像素栅格化的API,与canvas2D相比,它不再将绘制全交给CPU,而是由GPU进行图元绘制,在绘制性能上,有很大的提升。

原生WebGL使用相对比较复杂,在这里我们就使用Pixi.js进行搭建。

1.初始化

const app = new PIXI.Application({
width: 1920, height: 929,
antialias: true,    // default: false 反锯齿
transparent: true, // default: false 透明度
resolution: 1       // default: 1 分辨率
});
const container = new PIXI.Container();

2.设置滤镜,用于改变颜色

const fragment = `
arying vec2 vTextureCoord;
uniform sampler2D uSampler;
void main(void)
{
  vec4 currentColor = texture2D(uSampler, vTextureCoord);
  if(currentColor.a == 0.0) {
    gl_FragColor = vec4(0.0, 0.0, 0.0, 0.0);
  } else {
    highp float t = 1.0 - currentColor.a;
    highp float l = log(t);
    float temp = l / log(0.99);
    float f = fract(temp);
    int colorIndex = int(temp) - 1;
    if(f >= 0.5) {
       colorIndex += 1;
    }
// 大致的遍数 colorIndex;
// getColor 为你设置颜色的方法;
    gl_FragColor = getColor(colorIndex);
  }}
`
const filter = new PIXI.Filter(null, fragment);
app.stage.filters = [filter];

3.绘制内容

const line = new PIXI.Graphics();
line.lineStyle(60, 0x00FF00, 0.1);
line.moveTo(x, y);
line.lineTo(x1, y1);
.......
line.x = 0;
line.y = 0;
container.addChild(line);

在这里插入图片描述

这样就可以用WebGL区分颜色绘制出重叠路径了。

但是这只是个大概值,原因是因为精度的问题,随着重叠的次数的增加,误差会越来越大。

透明度是一个0-1的值,在默认情况下,透明度叠加时,是按照 (1 - (1 - 透明度)的重叠次数次方)的规律叠加。

这个值的差异会越来越小,渲染时又会丢失部分精度,这样就影响到了我们获取正确的重叠次数。

优化计算规则

我们知道了透明度叠加的问题,那有什么更好的办法吗?

我们还是离不开颜色,除了透明度外,还有单个颜色通道的叠加。

gl.enable(gl.BLEND);
gl.blendFunc(gl.ONE, gl.ONE);

当我们将WebGL混合像素算法的源混合因子和源目标合因子都指定为gl.ONE,单个颜色通道的颜色就会进行相加。我们指定颜色为 vec4(0.0, 1.0 / 255, 0, 1), 那么我们在着色器中可以这样写。

highp vec4 currentColor = texture2D(u_sampler, v_texCoord);
if(currentColor.g == 0.0) {
  gl_FragColor = u_backGround;
} else {
  // 颜色叠加 很准 最大限制255
  int colorIndex = int(currentColor.g * 255.0);
  gl_FragColor = getColor(colorIndex - 1);
}

这样绿色颜色通道就会随着叠加次数由0~1, 通过运算就能得到0~255的值, 就能保证在255次重叠下渲染的精确,至于更多次数,那就得另寻他法了。

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

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

相关文章

Java中接口的默认方法

为什么要使用默认方法 当我们把一个程序的接口写完后 用其他的类去实现&#xff0c;此时如果程序需要再添加一个抽象方法的时候我们只有两种选择 将抽象方法写在原本的接口中 但是这样写会导致其他所有改接口的实现类都需要实现这个抽象方法比较麻烦 写另一个接口 让需要的实…

Sqli-labs第一关到第四关

目录 一&#xff0c;了解PHP源代码 二&#xff0c;破解第一关 2.1在了解完源码之后&#xff0c;我们重点看一下 2.2破解这道题表中有几列 2.3查看表中哪一列有回显 2.4查询库&#xff0c;表&#xff0c;列信息 三&#xff0c;总结 前提&#xff1a; 之所以把1234关…

2024年5月5日 十二生肖 今日运势

小运播报&#xff1a;2024年5月5日&#xff0c;星期日&#xff0c;农历三月廿七 &#xff08;甲辰年己巳月己巳日&#xff09;&#xff0c;法定节假日。 红榜生肖&#xff1a;牛、猴、鸡 需要注意&#xff1a;鼠、虎、猪 喜神方位&#xff1a;东北方 财神方位&#xff1a;正…

eSIM IoT vs M2M vs Consumer

有任何关于GSMA\IOT\eSIM\RSP\业务应用场景相关的问题&#xff0c;欢迎W: xiangcunge59 一起讨论, 共同进步 (加的时候请注明: 来自CSDN-iot). 截至2023年5月&#xff0c;全球移动通信系统协会&#xff08;GSMA&#xff09;发布了三个关键的eSIM技术规范&#xff0c;这些规…

2000-2020年县域创业活跃度数据

2000-2020年县域创业活跃度数据 1、时间&#xff1a;2000-2020年 2、指标&#xff1a;地区名称、年份、行政区划代码、经度、纬度、所属城市、所属省份、年末总人口万人、户籍人口数万人、当年企业注册数目、县域创业活跃度1、县域创业活跃度2、县域创业活跃3 3、来源&#…

【前端项目——分页器】手写分页器实现(JS / React)

组件介绍 用了两种方式实现&#xff0c;注释详细~ 可能代码写的不够简洁&#xff0c;见谅&#x1f641; 1. 包含内容显示的分页器 网上看了很多实现&#xff0c;很多只有分页器部分&#xff0c;没和内容显示联动。 因此我增加了模拟content的显示&#xff0c;这里模拟了32条数…

JavaEE初阶Day 15:文件IO(1)

目录 Day 15&#xff1a;文件IO&#xff08;1&#xff09;IO文件1. 路径2. 文件的分类3. 使用Java针对文件系统进行操作3.1 属性3.2 构造方法3.3 方法 Day 15&#xff1a;文件IO&#xff08;1&#xff09; IO I&#xff1a;Input输入 O&#xff1a;Output输出 输入输出规则…

使用机器学习确定文本的编程语言

导入必要的库 norman Python 语句&#xff1a;import <span style"color:#000000"><span style"background-color:#fbedbb"><span style"color:#0000ff">import</span> pandas <span style"color:#0000ff&quo…

onedrive下載zip檔案有20G限制,如何解決

一般來說&#xff0c;OneDrive網頁版對文件下載大小的限制如下圖所示&#xff0c;更多資訊&#xff0c;請您參考這篇文章&#xff1a;OneDrive 和 SharePoint 中的限制 - Microsoft Support 因此我們推薦您使用OneDrive同步用戶端來同步到本地電腦&#xff0c;您也可以選擇只同…

【实验】使用docker-compose编排lnmp(dockerfile) 完成Wordpress 部署

环境准备 docker&#xff1a;192.168.67.30 虚拟机&#xff1a;4核4G 关闭防火墙 systemctl stop firewalld systemctl disable firewalld setenforce 0 安装docker 直接点击【复制】粘贴到xshell中即可&#xff0c; 执行过程中若出现睡眠(sleep)通过 kill -9 pid号 &#x…

库存管理系统开源啦

软件介绍 ModernWMS是一个针对小型物流仓储供应链流程的开源库存管理系统。该系统的开发初衷是为了满足中小型企业在有限IT预算下对仓储管理的需求。通过总结多年ERP系统研发经验&#xff0c;项目团队开发了这套适用于中小型企业的系统&#xff0c;以帮助那些有特定需求的用户。…

vector的使用

1.构造函数 void test_vector1() {vector<int> v; //无参的构造函数vector<int> v2(10, 0);//n个value构造&#xff0c;初始化为10个0vector<int> v3(v2.begin(), v2.end());//迭代器区间初始化,可以用其他容器的区间初始化vector<int> v4(v3); //拷贝…

【 书生·浦语大模型实战营】作业(六):Lagent AgentLego 智能体应用搭建

【 书生浦语大模型实战营】作业&#xff08;六&#xff09;&#xff1a;Lagent & AgentLego 智能体应用搭建 &#x1f389;AI学习星球推荐&#xff1a; GoAI的学习社区 知识星球是一个致力于提供《机器学习 | 深度学习 | CV | NLP | 大模型 | 多模态 | AIGC 》各个最新AI方…

jupyter notebook 设置密码报错ModuleNotFoundError: No module named ‘notebook.auth‘

jupyter notebook 设置密码报错ModuleNotFoundError: No module named ‘notebook.auth‘ 原因是notebook新版本没有notebook.auth 直接输入以下命令即可设置密码 jupyter notebook password

链表的带环问题 链表的深度拷贝

1.1. 链表是否带环 代码很简单&#xff0c;最主要就是如何证明 首先判断链表是否带环&#xff0c;可以定义两个指针&#xff0c;一个快指针一个慢指针。快指针走两步&#xff0c;慢指针走一步一定会相遇吗&#xff1f;有没有可能会超过&#xff1f;假设进环的时候fast和slow的…

87、动态规划-最长地址子序列

思路&#xff1a; 使用递归来理解题目&#xff0c;然后在看如何优化&#xff0c;假设我当前使用元素那么最长是多少&#xff0c;如果不使用当前元素最长是多少&#xff0c;然后取最大值。 代码如下&#xff1a; //算出最长递增子序列的长度public static int lengthOfLIS02(…

【机器学习】集成方法---Boosting之AdaBoost

一、Boosting的介绍 1.1 集成学习的概念 1.1.1集成学习的定义 集成学习是一种通过组合多个学习器来完成学习任务的机器学习方法。它通过将多个单一模型&#xff08;也称为“基学习器”或“弱学习器”&#xff09;的输出结果进行集成&#xff0c;以获得比单一模型更好的泛化性…

批量美化图片,轻松实现多张图片描边,让图片瞬间焕发新生!

图片已成为我们日常生活中不可或缺的一部分。无论是社交媒体上的个人分享&#xff0c;还是商业宣传中的产品展示&#xff0c;高质量、精美的图片都扮演着至关重要的角色。然而&#xff0c;对于许多人来说&#xff0c;图片处理仍然是一个令人头疼的问题。现在&#xff0c;我们为…

激动,五四青年节,拿下YashanDB认证YCP

&#x1f4e2;&#x1f4e2;&#x1f4e2;&#x1f4e3;&#x1f4e3;&#x1f4e3; 作者&#xff1a;IT邦德 中国DBA联盟(ACDU)成员&#xff0c;10余年DBA工作经验&#xff0c; Oracle、PostgreSQL ACE CSDN博客专家及B站知名UP主&#xff0c;全网粉丝10万 擅长主流Oracle、My…

SpringTask定时任务

SpringBoot项目定时任务 首先在启动类引入注解EnableScheduling然后在方法中加注解Scheduled(cron“”)cron表达式 生成cron https://www.pppet.net/