JavaScript场景应用:Canvas实战开发一个二维折线图插件

news2024/9/26 10:57:03

在这里插入图片描述

🏆作者简介,黑夜开发者,全栈领域新星创作者✌,阿里云社区专家博主,2023年6月csdn上海赛道top4。
🏆数年电商行业从业经验,历任核心研发工程师,项目技术负责人。
🏆本文已收录于专栏:100个JavaScript的小应用。
🎉欢迎 👍点赞✍评论⭐收藏

文章目录

  • 🚀一、插件介绍
  • 🚀二、关于Canvas的基础知识介绍
  • 🚀三、功能详细实现
    • 🔎2.1 HTML 结构(index.html)
    • 🔎2.2 实现Javascript主要绘图逻辑
      • 🍁2.2.1 JavaScript 文件
      • 🍁2.2.2 准备数据
      • 🍁2.2.3 绘制坐标系
      • 🍁2.2.4 需要绘制坐标系的线和标签
      • 🍁2.2.5 绘制折线
  • 🚀四、运行程序
  • 🚀五、总结


🚀一、插件介绍

折线图是一种常见的数据可视化方式,广泛应用于各种领域如金融、统计学、科学研究等。通过绘制连接数据点的线,我们可以清晰地观察数据的趋势和变化。在本篇教程中,我们将使用 JavaScript结合canvas元素和HTML来画出一个折线图。折线图将支持多条线的显示,并且可以根据配置的二维JSON数组进行灵活展示

本文将详细介绍如何使用JavaScript和HTML来绘制一个的折线图,以及如何进行配置以显示多条线。不过在开始写作之前,先来了解一下什么是canvas,它可以用来做什么事情。

阅读本文的时候如果您有一些基本的网页开发知识,会更好的理解本文的内容。

🚀二、关于Canvas的基础知识介绍

JavaScript Canvas是一种用于在网页上绘制图形的技术。它允许开发者使用JavaScript动态地在浏览器中绘制图像、文本和其他元素。

JavaScript Canvas提供了丰富的绘图API,包括绘制直线、矩形、圆形、路径、文本等基本图形元素,同时还支持图像的加载与绘制。开发者可以使用这些API来创建动画、游戏、数据可视化等各种交互式的网页应用。
在这里插入图片描述
Canvas的绘图过程是实时的,这意味着可以通过不断更新绘图来实现动态效果。开发者可以利用定时器和事件监听器来控制绘图的速度和响应用户的操作。

相比于其他绘图技术,JavaScript Canvas具有以下优点:

灵活性:可以通过JavaScript动态地修改绘图的属性和内容,实现复杂的交互效果。
跨平台:只需在支持HTML5的浏览器中运行,可以在多个设备和操作系统上使用。
高性能:Canvas使用硬件加速来提高绘图的性能,可以绘制大量图形元素而不影响网页的性能。
易用性:API简单易懂,学习曲线较低,并且有大量的文档和教程可供参考。

总之,JavaScript Canvas是一种功能强大、易于使用的网页绘图技术,为开发者提供了丰富的绘图功能,可用于创建各种精彩的交互式网页应用。

🚀三、功能详细实现

所有功能实现完成后,主要代码结构将融合在下面三个文件里面。下面我们来把整个过程走一遍。

在这里插入图片描述

🔎2.1 HTML 结构(index.html)

首先,我们需要创建一个包含 Canvas 元素的 HTML 结构。在 HTML 文件中添加以下代码:

<!DOCTYPE html>
<html>
<head>
	<meta charset="utf-8">
    <title>可配置的折线图</title>
</head>
<body>
    <canvas id="chart"></canvas>
    <script src="script.js"></script>
</body>
</html>

这段代码包含了一个带有 id 为 “chart” 的 Canvas 元素,并引入了一个 JavaScript 文件 “script.js”。

🔎2.2 实现Javascript主要绘图逻辑

🍁2.2.1 JavaScript 文件

接下来,我们需要在 script.js 中编写代码来实现折线图的绘制逻辑。

首先,我们需要获取到 Canvas 元素并设置其宽度和高度。然后,我们需要定义一些全局变量,用于存储折线图的配置数据和绘制相关的参数。在script.js 文件中添加以下代码:

const canvas = document.getElementById("chart");
const ctx = canvas.getContext("2d");

canvas.width = 600;
canvas.height = 400;

let data = []; // 折线图的数据
let colors = ["#ff0000", "#00ff00", "#0000ff"]; // 折线的颜色
let lineWidth = 2; // 折线的宽度
let padding = 20; // 边距
let xAxisLabelHeight = 30; // x 轴标签的高度
let yAxisLabelWidth = 40; // y 轴标签的宽度

在这段代码中,我们使用 document.getElementById("chart") 获取到 Canvas 元素,并使用 canvas.getContext("2d") 获取到一个 CanvasRenderingContext2D 对象,用于绘制图形。

然后,我们设置了 Canvas 元素的宽度和高度为 600px 和 400px,并定义了一些全局变量,用于存储折线图的配置数据和绘制相关的参数。

🍁2.2.2 准备数据

接下来,我们需要准备一些数据供折线图使用。在script.js 文件中添加以下代码:

// 准备数据
data = [
    [{ x: 0, y: 1 }, { x: 1, y: 1 }, { x: 2, y: 0 }, { x: 3, y: 3 }, { x: 4, y: 5 }],
    [{ x: 0, y: 3 }, { x: 1, y: 2 }, { x: 2, y: 1 }, { x: 3, y: 10 }, { x: 4, y: 0 }],
];

这段代码定义了一个二维数组,每个子数组表示一条折线的数据。每个数据点都有 x 和 y 坐标,分别表示在水平和垂直方向上的位置。这个数据先放到这里,后面根据这个数据继续实现绘图逻辑。

🍁2.2.3 绘制坐标系

在绘制折线图之前,我们首先需要绘制坐标系。坐标系由 x 轴和 y 轴组成,可以帮助我们对数据进行定位和可视化。

首先,我们需要计算出 x 轴和 y 轴的长度,并确定 x 和 y 坐标轴的起点和终点坐标。在 script.js 文件中添加以下代码:

// 计算坐标系的长度和坐标
let xAxisLength = canvas.width - padding * 2 - yAxisLabelWidth;
let yAxisLength = canvas.height - padding * 2 - xAxisLabelHeight;

let xAxisStart = padding + yAxisLabelWidth;
let xAxisEnd = xAxisStart + xAxisLength;
let yAxisStart = canvas.height - padding - xAxisLabelHeight;
let yAxisEnd = yAxisStart - yAxisLength;

这段代码计算了 x 轴和 y 轴的长度,并确定了它们的起点和终点坐标。

🍁2.2.4 需要绘制坐标系的线和标签

接下来,我们需要绘制坐标系的线和标签。在 script.js 文件中添加以下代码:

// 绘制 x 轴线
ctx.beginPath();
ctx.moveTo(xAxisStart, yAxisStart);
ctx.lineTo(xAxisEnd, yAxisStart);
ctx.stroke();

// 绘制 y 轴线
ctx.beginPath();
ctx.moveTo(xAxisStart, yAxisStart);
ctx.lineTo(xAxisStart, yAxisEnd);
ctx.stroke();

// 绘制 x 轴标签
ctx.font = "12px Arial";
ctx.textAlign = "center";
ctx.fillText("X Axis", canvas.width / 2, canvas.height - padding / 2);

// 绘制 y 轴标签
ctx.save();
ctx.rotate(-Math.PI / 2);
ctx.font = "12px Arial";
ctx.textAlign = "center";
ctx.fillText("Y Axis", -canvas.height / 2, padding / 2);
ctx.restore();

这段代码使用 ctx.beginPath() 开始一个新的路径,并使用 ctx.moveTo(x, y)ctx.lineTo(x, y) 绘制出 x 轴线和 y 轴线。然后,我们使用 ctx.stroke() 来绘制路径。

接下来,我们使用 ctx.fontctx.textAlignctx.fillText(text, x, y) 来绘制 x 轴和 y 轴的标签。为了方便显示,我们将 y 轴的标签旋转了 -90 度。

🍁2.2.5 绘制折线

现在,我们已经准备好了坐标系,接下来就是绘制折线了。

首先,我们需要计算每个数据点在坐标系中的实际位置。在 “script.js” 文件中添加以下代码:

// 计算每个数据点在坐标系中的实际位置
let scaleX = xAxisLength / (data[0].length - 1);
let scaleY = yAxisLength / Math.max(...data.flat().map((point) => point.y));

let scaledData = data.map((line) =>
	line.map(({ x, y }) => ({
		x: xAxisStart + x * scaleX,
		y: yAxisStart - y * scaleY,
	}))
);

这段代码首先计算了 x 轴和 y 轴的缩放比例,以便将数据点的坐标值映射到坐标系中的实际位置。

接着,我们使用 data.flat() 将二维数组转换为一维数组,并使用 Math.max(...array) 找到数组中的最大值。然后,我们对每个数据点进行缩放计算,并将计算结果保存到 scaledData 中。

接下来,我们可以开始绘制折线了。在 “script.js” 文件中添加以下代码:

// 绘制折线
scaledData.forEach((line, index) => {
	ctx.beginPath();
	line.forEach(({ x, y }, i) => {
		if (i === 0) {
			ctx.moveTo(x, y);
		} else {
			ctx.lineTo(x, y);
		}
	});
	ctx.strokeStyle = colors[index % colors.length];
	ctx.lineWidth = lineWidth;
	ctx.stroke();
});

这段代码使用 scaledData.forEach() 遍历每条折线的数据,在遍历过程中,使用 ctx.beginPath() 开始新的路径,并使用 ctx.moveTo(x, y)ctx.lineTo(x, y) 绘制折线的每个点。

然后,我们根据折线的索引选择对应的颜色和线宽,并使用 ctx.strokeStylectx.lineWidth 来设置样式。最后,我们使用 ctx.stroke() 绘制路径。

🚀四、运行程序

现在,我们已经完成了折线图的绘制逻辑。接下来,我们需要在浏览器中运行这个程序,并查看结果。打开文件夹,进入到存放 HTML 文件和 JavaScript 文件的目录,双击index.html,即可在Chrome中查看效果,如下图所示。你将会看到一个显示了两条折线的折线图。
在这里插入图片描述

🚀五、总结

在本教程中,我们学习了如何使用JavascriptHTML绘制一个支持多条线的折线图。我们使用二维JSON数组来灵活配置数据进行绘图操作。通过遵循以上步骤和代码逻辑,你可以根据自己的需求绘制出不同的折线图,并对其进行进一步的定制和样式设置。

在实际应用中,你可以根据需要修改绘图区域的大小、线条的颜色和样式,甚至添加坐标轴和图例等功能。这种灵活性使得使用JavascriptHTML绘制折线图成为一种非常强大和实用的方法。希望本教程能为你提供一个良好的起点,使你能够深入学习和探索折线图的制作。

在这里插入图片描述

完整源码可以通过页面顶部下载或者撩我,后面将会分享更多的实战经验,我们下次见。

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

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

相关文章

MySQL概述与体系结构

文章目录 一、MySQL概述1.1 MySQL与redis的区别1.2 数据处理分类1.3 SQL1.4 数据类型 二、数据库设计三范式2.1 范式一2.2 范式二2.3 范式三2.4 反范式 三、MySQL体系结构3.1 结构组成3.2 连接池 四、sql语句执行过程4.1 select语句4.2 CRUD执行过程 一、MySQL概述 1.1 MySQL与…

复现沙箱逃逸漏洞

什么是沙箱(sandbox) 在计算机安全性方面&#xff0c;沙箱&#xff08;沙盒、sanbox&#xff09;是分离运行程序的安全机制&#xff0c;提供一个隔离环境以运行程序。通常情况下&#xff0c;在沙箱环境下运行的程序访问计算机资源会受到限制或者禁止&#xff0c;资源包括内存、…

小白到运维工程师自学之路 第六十四集 (dockerfile构建tomcat、mysql、lnmp、redis镜像)

一、tomcat&#xff08;更换jdk&#xff09; mkdir tomcat cd tomcat/ tar xf jdk-8u191-linux-x64.tar.gz tar xf apache-tomcat-8.5.40.tar.gzvim Dockerfile FROM centos:7 MAINTAINER Crushlinux <syh163.com> ADD jdk1.8.0_191 /usr/local/java ENV JAVA_HOME /us…

使用Canvas裁剪图片

使用Canvas裁剪图片 概述 在Web开发中&#xff0c;我们经常需要对图片进行裁剪&#xff0c;以满足不同尺寸需求或者实现图片的局部展示。本篇博客将带您深入了解如何使用Canvas技术来实现图片的裁剪功能。我们将通过一个实例来演示如何利用Canvas绘制图片&#xff0c;并通过蒙…

二叉树的相关题目

目录 1、根据二叉树创建字符串 2、二叉树的层序遍历 3、二叉树的最近公共祖先 4、搜索二叉树与双向链表 5、从前序与中序遍历序列构造二叉树 6、 从中序与后序遍历序列构造二叉树 7、二叉树的前序遍历&#xff08;非递归实现&#xff09; 8、二叉树的中序遍历&#xff08…

宋浩高等数学笔记(十)重积分

本章更新第10章重积分&#xff0c;关于三重积分的应用部分暂时略过&#xff0c;本部分在考察的时候不会很难&#xff0c;困难在于对重积分本质的理解&#xff0c;以及极坐标下相关公式的计算。类比普通的定积分&#xff0c;如果对一个宽度不均匀的函数&#xff0c;求积分分后相…

工厂模式详解与应用场景

摘要&#xff1a; 工厂模式是一种常见的设计模式&#xff0c;它可以帮助我们在面向对象的程序设计中更好地组织和管理对象的创建过程。本文将详细介绍工厂模式的概念、三种常见的工厂模式应用场景&#xff0c;并提供高质量的C代码示例&#xff0c;旨在帮助初学者更好地理解和应…

【Spring Boot系列】-Spring Boot过滤器Filter

【Spring Boot系列】-Spring Boot过滤器Filter 文章目录 【Spring Boot系列】-Spring Boot过滤器Filter一、概述二、Filter&#xff08;过滤器&#xff09;数据流程三、Spring Boot 过滤器生命周期四、使用注解方式实现过滤器(WebFilter)4.1. 在springboot 启动类添加该注解Ser…

JAVA大神必备,IDEA自带的JVM监控神器

前言 开发阶段实时监测&#xff0c;自己的JVM信息&#xff0c;实时可视化 Hotspot JVM 垃圾回收监控工具, 支持查看本地和远程JVM进程, 支持G1 and ZGC算法。 插件安装 在线安装 IntelliJ IDEA 可通过在线安装的方式&#xff0c;安装插件 JDK VisualGC&#xff0c;安装步骤: …

过程:从虚拟机上添加 git 并成功提交到 GitLab 的全过程

Ⅰ、准备工作&#xff1a; 1、Git 查看&#xff1a; 其一、命令&#xff1a;git --version // 此时就能在虚拟机环境下看到 git 的版本为: git version 2.41.0 其二、如何在虚拟机上安装 git &#xff1a; A、命令 &#xff1a; sudo apt-get install git B、然后再输入虚…

JavaScript |(三)内建对象 | 数组 | string对象 | 尚硅谷JavaScript基础实战

学习来源&#xff1a;尚硅谷JavaScript基础&实战丨JS入门到精通全套完整版 文章目录 &#x1f4da;数组&#x1f407;数组介绍⭐️数组&#xff08;Array&#xff09;⭐️基本操作⭐️数组的字面量 &#x1f407;数组中的常用方法⭐️push()⭐️pop()⭐️unshift()⭐️shif…

微信小程序wx.getlocation接口权限申请总结

先附上申请通过截图 插播内容&#xff1a;可代开通&#xff0c;保证通过。wx.getLocation接口&#xff08;获取当前的地址位置&#xff09; qq&#xff1a; 308205428 如何申请 当申请微信小程序的wx.getLocation接口权限时&#xff0c;你可以…

yolov8-制作数据集,数据集格式转换(yolo格式-voc格式)附完整代码

yolo训练时可使用的数据集格式为yolo格式以及voc格式&#xff0c; voc格式的数据集在训练时需要先转换为yolo格式&#xff0c;然后根据自己的数据集的位置更改yaml配置文件的文件路径即可。基于目前对Yolo系列训练模型的讲解已经很全面&#xff0c;所以本文主要讲解yolo数据集与…

记录 FreeRTOS 信号量 的简单用法

FreeRTOS 信号量 最简单的应用场景是 两个任务间的同步 &#xff0c;这里以 二值信号量 Binary Semaphore为例 用法 &#xff1a; 1&#xff0c;定义与 创建 /* Definitions for myBinarySem01 */ osSemaphoreId_t myBinarySem01Handle; const osSemaphoreAttr_t myBinarySe…

c++类与对象详解

c类与对象详解 对象类方法自定义类型类的特性this类的六个默认成员函数static成员友元内部类 对象 在C中&#xff0c;对象是类的实例。定义对象的语法为&#xff1a; <class_name> object_name;其中&#xff0c;class_name 是定义类时指定的类名&#xff0c;object_nam…

二分查找【Java算法】

文章目录 1. 概念2. 思路3. 代码实现 1. 概念 二分查找又叫折半查找&#xff0c;要求待查找的序列有序&#xff0c;每次取中间位置的值与待查关键字比较&#xff0c;如果待查关键字比中间位置的值小&#xff0c;则在前半部分循环这个查找的过程&#xff0c;反之&#xff0c;在后…

7_分类算法—逻辑回归

文章目录 逻辑回归&#xff1a;1 Logistic回归&#xff08;二分类问题&#xff09;1.1 sigmoid函数1.2 Logistic回归及似然函数&#xff08;求解&#xff09;1.3 θ参数求解1.4 Logistic回归损失函数1.5 LogisticRegression总结 2 Softmax回归&#xff08;多分类问题&#xff0…

单元测试之 - Review一个微服务的单元测试

这里以github上一个microservice的demo代码为例&#xff0c;来看看如何为一个完整的服务编写单元测试。具体代码如下所示&#xff0c;我们重点查看一下catalog和customer&#xff0c;order中的单元测试有哪些。 首先来看catalog服务的单元测试,这个服务下面主要编写了CatalogWe…

时序数据异常检测算法

引言 异常检测的场景很多&#xff0c;例如&#xff1a;硬件的故障检测、流量的异常点的检测等场景。针对时间序列类数据的异常检测算法也有很多&#xff0c;业界比较流行的比如普通的统计学习方法–3σ原则和箱线图识别数据离群点&#xff0c;它利用检测点偏移量来检测出异常。…

Michael.W基于Foundry精读Openzeppelin第19期——EnumerableSet.sol

Michael.W基于Foundry精读Openzeppelin第19期——EnumerableSet.sol 0. 版本0.1 EnumerableSet.sol 1. 目标合约2. 代码精读2.1 结构体Set2.1.1 _contains(Set storage set, bytes32 value) && _length(Set storage set) && _at(Set storage set, uint256 inde…