canvas 曲线图 双数值轴 山峰图

2023-11-11 09:36
文章标签 canvas 数值 曲线图 山峰

本文主要是介绍canvas 曲线图 双数值轴 山峰图,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

下面的代码本人亲自撰写,原生不易啊。

<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title>
</head><body><canvas id="myCanvas" width="400" height="300"></canvas>
</body><script>class MyCanvas {static dom = null;static ctx = null;static canvasWidth = 0;static canvasHeight = 0;static config = null;static valx = 0;static valy = 0;static xlist = [];static ylist = [];static lenTrue = 0;init(dom) {MyCanvas.dom = domMyCanvas.ctx = MyCanvas.dom.getContext('2d');MyCanvas.canvasWidth = MyCanvas.ctx.canvas.width;MyCanvas.canvasHeight = MyCanvas.ctx.canvas.height;}// 配置参数setOption(config) {MyCanvas.ctx.clearRect(0, 0, MyCanvas.dom.width, MyCanvas.dom.height);MyCanvas.config = configMyCanvas.xlist = config.series.data.map(e => e[0]);MyCanvas.ylist = config.series.data.map(e => e[1]);MyCanvas.valx = MyCanvas.x1valjpx()MyCanvas.valy = MyCanvas.y1valjpx()MyCanvas.ctx.lineWidth = 1;MyCanvas.xGraduate()MyCanvas.xDashedLine()MyCanvas.yGraduate()MyCanvas.yDashedLine()MyCanvas.curve()}static getRandomColor() {let color = `hsl(${Random(0, 360)},${Random(50, 100)}%,${Random(20, 60)}%)`function Random(min, max) {return Math.round(Math.random() * (max - min)) + min;}return color}// 绘制曲线static curve() {const left = MyCanvas.config.grid.leftconst curvature = MyCanvas.config.series.curvature// xhb:曲线两个落点都是y轴最大的px值const xhb = MyCanvas.canvasHeight - 20MyCanvas.ctx.beginPath();MyCanvas.ctx.setLineDash([]);MyCanvas.ylist.forEach((e, i) => {MyCanvas.ctx.strokeStyle = MyCanvas.getRandomColor();MyCanvas.ctx.lineWidth = 3;// xy是控制点的xy坐标const x = MyCanvas.xlist[i] * MyCanvas.valx + leftconst y = e * MyCanvas.valy * 2const line = new Path2D();line.name = MyCanvas.config.series.data[i][2]line.moveTo(x - curvature, xhb);line.quadraticCurveTo(x, xhb - y, x + curvature, xhb);MyCanvas.ctx.stroke(line);MyCanvas.dom.addEventListener("mousemove", (event) => {const isPointInPath = MyCanvas.ctx.isPointInStroke(line, event.offsetX, event.offsetY);if (isPointInPath) {// 曲线被悬浮console.log(line);}});})}// 求x轴每一份值对应了多少实际px值static x1valjpx() {const max = Math.max(...MyCanvas.xlist)const interval = MyCanvas.config.xAxis.intervalconst curvature = MyCanvas.config.series.curvature// 总间隔数const len = Math.ceil(max / interval)// 总值数const valz = len * intervalconst left = MyCanvas.config.grid.leftconst right = MyCanvas.config.grid.rightconst xw = MyCanvas.canvasWidth - left - right// 求出每一份x值对应的图表里面的x轴px数值const valx = xw / valzconst maxql = max * valx + curvatureif (maxql > xw) {// 说明最大x将会超出可画范围,需要增加竖线let lenTrue = lenlet maxqlTrue = maxqllet valxTrue = valxwhile (maxqlTrue > xw) {lenTrue++// 总值数const valz = lenTrue * interval// 求出每一份x值对应的图表里面的y轴px数值valxTrue = xw / valzmaxqlTrue = max * valxTrue + curvature}MyCanvas.lenTrue = lenTruereturn valxTrue}return valx}// 求y轴每一份值对应了多少实际px值static y1valjpx() {const max = Math.max(...MyCanvas.ylist)const interval = MyCanvas.config.yAxis.intervalconst curvature = MyCanvas.config.series.curvature// 总间隔数const len = Math.ceil(max / interval)// 总值数const valz = len * intervalconst top = MyCanvas.config.grid.topconst bottom = MyCanvas.config.grid.bottomconst xh = MyCanvas.canvasHeight - top - bottom// 求出每一份y值对应的图表里面的y轴px数值return xh / valz}// 绘制x轴刻度值,从左到右画static xGraduate() {const grid = MyCanvas.config.gridconst xAxis = MyCanvas.config.xAxisconst gridLen = Object.keys(grid).lengthconst curvature = MyCanvas.config.series.curvatureMyCanvas.ctx.beginPath();MyCanvas.ctx.strokeStyle = '#000';MyCanvas.ctx.textAlign = "center";MyCanvas.ctx.textBaseline = "top";MyCanvas.ctx.font = "14px Arial";if (gridLen) {const left = MyCanvas.config.grid.leftconst right = MyCanvas.config.grid.rightconst top = MyCanvas.config.grid.topconst bottom = MyCanvas.config.grid.bottomconst interval = MyCanvas.config.xAxis.intervallet len = 0if (MyCanvas.lenTrue) {len = MyCanvas.lenTrue} else {const max = Math.max(...MyCanvas.lxList)len = Math.ceil(max / interval)}const xw = MyCanvas.canvasWidth - left - rightconst jg = xw / lenfor (let i = 0; i < len + 1; i++) {if (i) {MyCanvas.ctx.fillText(interval * i, left + (jg * i), MyCanvas.canvasHeight - bottom + xAxis.kdjl)}}}}// 绘制x刻度虚线,从右到左画static xDashedLine() {const grid = MyCanvas.config.gridconst gridLen = Object.keys(grid).lengthconst curvature = MyCanvas.config.series.curvatureMyCanvas.ctx.beginPath();MyCanvas.ctx.strokeStyle = MyCanvas.config.xAxis.dashedColor;MyCanvas.ctx.setLineDash([3, 2]);if (gridLen) {const left = MyCanvas.config.grid.leftconst right = MyCanvas.config.grid.rightconst top = MyCanvas.config.grid.topconst bottom = MyCanvas.config.grid.bottomconst interval = MyCanvas.config.xAxis.intervallet len = 0if (MyCanvas.lenTrue) {len = MyCanvas.lenTrue} else {const max = Math.max(...MyCanvas.lxList)len = Math.ceil(max / interval)}// x方向可画范围pxconst xw = MyCanvas.canvasWidth - left - rightconst jg = xw / lenfor (let i = 0; i < len + 1; i++) {MyCanvas.ctx.moveTo(MyCanvas.canvasWidth - right - (jg * i), MyCanvas.canvasHeight - bottom);MyCanvas.ctx.lineTo(MyCanvas.canvasWidth - right - (jg * i), top);}}MyCanvas.ctx.stroke();}// 绘制y刻度虚线,从下到上画static yDashedLine() {const grid = MyCanvas.config.gridconst gridLen = Object.keys(grid).lengthMyCanvas.ctx.beginPath();MyCanvas.ctx.strokeStyle = MyCanvas.config.yAxis.dashedColor;MyCanvas.ctx.setLineDash([3, 2]);if (gridLen) {const left = MyCanvas.config.grid.leftconst right = MyCanvas.config.grid.rightconst top = MyCanvas.config.grid.topconst bottom = MyCanvas.config.grid.bottomconst max = Math.max(...MyCanvas.ylist)const interval = MyCanvas.config.yAxis.intervalconst len = Math.ceil(max / interval)const xh = MyCanvas.canvasHeight - top - bottomconst jg = xh / lenfor (let i = 0; i < len + 1; i++) {MyCanvas.ctx.moveTo(left, MyCanvas.canvasHeight - bottom - (jg * i));MyCanvas.ctx.lineTo(MyCanvas.canvasWidth - right, MyCanvas.canvasHeight - bottom - (jg * i));}}MyCanvas.ctx.stroke();}// 绘制y刻度值,从下到上画static yGraduate() {const grid = MyCanvas.config.gridconst yAxis = MyCanvas.config.yAxisconst gridLen = Object.keys(grid).lengthMyCanvas.ctx.beginPath();MyCanvas.ctx.strokeStyle = '#000';MyCanvas.ctx.textAlign = "right";MyCanvas.ctx.textBaseline = "middle";MyCanvas.ctx.font = "14px Arial";if (gridLen) {const left = MyCanvas.config.grid.leftconst right = MyCanvas.config.grid.rightconst top = MyCanvas.config.grid.topconst bottom = MyCanvas.config.grid.bottomconst max = Math.max(...MyCanvas.ylist)const interval = MyCanvas.config.yAxis.intervalconst len = Math.ceil(max / interval)const xh = MyCanvas.canvasHeight - top - bottomconst jg = xh / lenfor (let i = 0; i < len + 1; i++) {if (i == 0) {MyCanvas.ctx.fillText(0, left - yAxis.kdjl, MyCanvas.canvasHeight - bottom)} else {MyCanvas.ctx.fillText(interval * i, left - yAxis.kdjl, MyCanvas.canvasHeight - bottom - (jg * i))}}}}}const myCanvas = document.querySelector('#myCanvas');const canvas = new MyCanvas()canvas.init(myCanvas)canvas.setOption({grid: {top: 20,right: 20,bottom: 20,left: 40,},yAxis: {dashedColor: '#000',kdjl: 8, // 刻度与轴线距离interval: 5, // 每条虚线间隔(单位不是px,而是数值,对应刻度值距离值)},xAxis: {dashedColor: '#000',kdjl: 8, // 刻度与轴线距离interval: 5, // 每条虚线间隔(单位不是px,而是数值,对应刻度值距离值)},series: {curvature: 20,// 曲线曲率单位pxdata: [[10, 20, '信号1'], [8, 23, '信号2'], [15, 30, '信号3'], [25, 10, '信号4'], [44, 58, '信号5']]}})
</script></html>

 

这篇关于canvas 曲线图 双数值轴 山峰图的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/389135

相关文章

交换两个变量数值的3种方法

前言:交换两个数值可不是"a = b,b = a"。这样做的话,a先等于了b的值;当“b = a”后,因为此时a已经等于b的值了,这个语句就相当于执行了b = b。最终的数值关系就成了a == b,b == b。 下面教给大家3种交换变量数值的方法: 目录 1. 中介法 2. 消和法 3. 异或法 4. 总结 1. 中介法 中介法(又称 临时变量法 或 酱油法),其中心

OpenGL/GLUT实践:流体模拟——数值解法求解Navier-Stokes方程模拟二维流体(电子科技大学信软图形与动画Ⅱ实验)

源码见GitHub:A-UESTCer-s-Code 文章目录 1 实现效果2 实现过程2.1 流体模拟实现2.1.1 网格结构2.1.2 数据结构2.1.3 程序结构1) 更新速度场2) 更新密度值 2.1.4 实现效果 2.2 颜色设置2.2.1 颜色绘制2.2.2 颜色交互2.2.3 实现效果 2.3 障碍设置2.3.1 障碍定义2.3.2 障碍边界条件判定2.3.3 障碍实现2.3.

影响画布微信小程序canvas及skyline和webview用户界面布局的关键流程

影响微信小程序画布canvas及skyline和webview用户界面布局的关键流程 目录 影响微信小程序画布canvas及skyline和webview用户界面布局的关键流程 一、微信小程序canvas开发流程 1.1、官方指南 1.2、客制化开发 第一步:在 WXML 中添加 canvas 组件 第二步:获取 Canvas 对象和渲染上下文 第三步 画布#ID选择器执行回调——

鸿蒙图表MPChart自定义样式(五)左y轴显示数值,右y轴显示百分比

左y轴数值不变,右y轴改成百分比,需要通过自定义RightAxisFormatter实现IAxisValueFormatter接口,将右y轴的数值改成百分比文本,RightAxisFormatter类如下: class RightAxisFormatter implements IAxisValueFormatter {maxNumber: number = 0;constructor(ma

(转)mysql按字段排序 按照字段的数值大小排序,而非 ascii码排序

参考:http://www.cnblogs.com/codefly-sun/p/5898738.html     如果是varchar类型, 排序后是这样的: 就是对mysql数值字符串类型进行排序,在默认情况下使用order by 字段名称 desc/asc 进行排序的时候,mysql进行的排序规则是按照ASCII码进行排序的,并不会自动的识别出这些数据是数值   ,百度了一下,

Android canvas save restore saveLayer的异同点

一、基础操作 drawText、drawRect、drawColor等 对于这些基础操作,相信每一个安卓开发者都能说上个一二点出来,这些就不多做介绍,api 工程师必备技能之一。 在进阶之前,先回答这个问题:    问:canvas既然大家都理解为画布,那如果先在画布上绘制了某些内容,然后再canvas.rotate旋转了画布,为什么这些已经绘制在画布上的内容不会跟随着旋转?    答:由此可

牛客《剑指Offer》 -- 数值的整数次方

题目描述 给定一个double类型的浮点数base和int类型的整数exponent。求base的exponent次方。 思路 特别注意负数的情况,出现负数,将其转化为正数然后求倒数。 class Solution {public:double Power(double base, int exponent) {double total = 1;bool flag = false

自定义View-Canvas

转载自:https://www.jianshu.com/p/f69873371763 Android Canvas 方法总结 简介 在自定义 View的时候,我们经常需要绘制一些自己想要的效果。 这里就需要使用Canvas对象。 下面将Canvas对象常用方法做个笔记,方便记忆。 对Canvas进行操作 对Canvas的一系列操作,是指对Canvas进行旋转、平移、缩放等操作。 这些操作可以

canvas-实现放大镜效果

canvas-实现放大镜效果 目录 文章目录 前言推荐阅读代码展示结果展示 前言 本文为canvas实现放大镜逻辑简单,适合作为基础项目练手 推荐阅读 《H5 canvas核心技术》 代码展示 <!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><meta http-equiv="X-UA-Comp

canvas-原生js实现时钟绘图效果

canvas-原生js实现时钟绘图效果 目录 文章目录 前言代码效果查看 前言 本文为canvas实现时钟效果可直接复制使用 代码 <!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta n