开发案例:使用 canvas 实现图表系列之折线图

HTML5——Canvas图表插件 chart 常规版本的Chart.js和 Chart.min.js,附带chart.js库的同时还带着颜色解析器。如果你想使用这个版本并且在你的图表中使用时间轴,你需要在安装Chart.js之前安装上Moment.js。而另一个版本Chart.bundle.js 和Chart.bundle.min.js早就包含了Moment.js。chart.js是简单而灵活的javascript图表插件,底层封装了canvas,而且是复合目前主流的响应式。以下使用的是chart.js的2.0版本。chart.js目前有两种版本。 阅读详情

一、功能结构

实现一个公共组件的时候,首先分析一下大概的实现结构以及开发思路,方便我们少走弯路,也可以使组件更加容易拓展,维护性更强。然后我会把功能逐个拆开来讲,这样大家才能学习到更详细的内容。下面简单阐述下折线图组件的功能结构:

以上是基础的功能结构框架,包含一些比较简单的基础功能,后续还有点击触发、动画等功能也会规划进去。这一期我们先实现上面这些基础的功能,后续再慢慢拓展。

二、公共属性

1.  一个组件肯定会有一些公共的属性作为动态参数,便于组件之间的信息传递,我们分别讲解一下五个公共属性的作用:画布的宽度(cWidth)和高度(cHeight),这个是最基本的。但是我这里控制是非必传,默认值都是 100%就可以了。

2.  画布的内部留白间距(cSpace)。主要是用来控制内容区与画布外框的距离,避免绘画的内容被截掉。

3.  字体大小(fontSize)。主要是来控制整个绘画内容的字体大小,全局性,避免每个小功能都需要传字体大小。

4.  字体颜色(color)。与字体大小的功能一致。

5.  图表数据(data)。用来存储图表内容的数组,其中 name 与 value 是必传的。

以下是具体的代码:

 // 图表数据的特征接口
interface interface_data {
  name: string | number;
  value: string | number;
  [key: string]: any;
}


// 图表的特征接口
interface interface_option {
  cWidth?: string | number,
  cHeight?: string | number,
  fontSize?: string | number,
  color?: string,
  cSpace?: number,
  data?: interface_data[]
}


// option 默认值
const def_option: interface_option = {
  cWidth: '100%',
  cHeight: '100%',
  fontSize: 10,
  color: '#333',
  cSpace: 20,
  data: []
}


@Component
export struct McLineChart {
  private settings: RenderingContextSettings = new RenderingContextSettings(true)
  private context: CanvasRenderingContext2D = new CanvasRenderingContext2D(this.settings)
  @State options: interface_option = {}
  aboutToAppear() {
    this.options = Object.assign({}, def_option, this.options)
  }
  build() {
    Canvas(this.context)
      .width(this.options.cWidth)
      .height(this.options.cHeight)
      .onReady(() => {
        
      })
  }
}

三、绘画坐标轴

绘画图表内容区部分,首先是绘画坐标轴,坐标轴分为 X 轴跟 Y 轴,我们要先开始画 Y 轴,原因是:y 轴上要显示文本标签,如果一开始没有得到文本标签对应的宽度最大值,那么 Y 轴跟 X 轴的起点坐标就会有偏差,会导致绘画全部错位,下图是完整的坐标轴的效果。

1.绘画 Y 轴

Y 轴整体是由轴线、分割线、刻度线、文本标签四个部分组成的,四个部分都有先后关系,而且包含一定的算法逻辑,下面简单用一个概念图进行讲解。

首先用 500*500 的矩形作为我们这次的画布,我们可以在图上看到 Y 轴整体包含了文本标签、Y 轴线、分割线、刻度线四个部分。而 canvas 绘画基本都是通过坐标来定位的,Y 轴整体的四个部分的起点与结束坐标都互相有关系,甚至需要把内部间距、分割间距、y 轴线高度、文本最大的宽度四个属性计算在内。以上是概念与思路,接下来我们逐一讲解代码:

1、计算得到文本最长宽度(maxNameW ),我们可以从图中看到,不论是 y 轴线、刻度线还是分割线的起点坐标都是需要内容间距、文本标签、文本标签与分割线间隔相加计算得到,而为了保持对齐,所以我们需要计算出文本最长宽度。而 y 轴的文本一般都是数据(data)对应的数值,所以我们需要得到传入数据(data)中的最大值。然后讲最大值分割成五等分。以下就是计算获取最大文本宽度的代码,部分逻辑我也会写在代码上:

build() {
    Canvas(this.context)
      .width(this.options.cWidth)
      .height(this.options.cHeight)
      .backgroundColor(this.options.backgroundColor)
      .onReady(() => {
        const values: number[] = this.options.data.map((item) => Number(item.value || 0))
        const maxValue = Math.max(...values)
        let maxNameW = 0
        let cSpiltNum = 5 // 分割等分
        let cSpiltVal = maxValue / cSpiltNum // 计算分割间距
        for(var i = 0; i <= this.options.data.length; i++){
          // 用最大值除于分割等分得到每一个文本的间隔值,而每一次遍历用间隔值乘于i就能得到每个刻度对应的数值了,计算得到得知需要保留整数且转成字符串
          const text = (cSpiltVal * i).toFixed(0)
          const textWidth = this.context.measureText(text).width; // 获取文字的长度
          maxNameW = textWidth > maxNameW ? textWidth : maxNameW // 每次进行最大值的匹配
        }
      })
}

2、绘画文本标签,我们可以从图中看到文本标签的 x 坐标只跟内部间距有关,而且我们从上面代码就已经得到每个刻度的分割间距了,从而可以得到每个文本的 y 轴。

.onReady(() => {
   ....
   for(var i = 0; i <= this.options.data.length; i++){
     ...
     // 绘画文本标签
     this.context.fillText(text, this.options.cSpace, cSpiltVal * (this.options.data.length - i) + this.options.cSpace , 0);
   }
})

3、绘画刻度线。我们可以从概念图得到,刻度线的起点 x 坐标算法是:内部间距(cSpace)加最长文本宽度(maxNameW )加上文本与刻度线的间距,起点 y 坐标则跟文本一样,通过分割间距与下角标的关系得到每个刻度的 y 坐标;而终点 x 坐标则是刻度线的长度,终点 y 坐标则跟起点的 y 坐标一样,我设置默认长度是 5,这样就能得到我们的刻度线了。代码如下:

.onReady(() => {
  ....
  const length = this.options.data.length
  for(var i = 0; i <= length; i++){
    ...
  }
  // 上面是获取最长文本宽度的代码
  // 画线的方法
  function drawLine(x, y, X, Y){
    this.context.beginPath();
    this.context.moveTo(x, y);
    this.context.lineTo(X, Y);
    this.context.stroke();
    this.context.closePath();
  }
  for(var i = 0; i <= length; i++){
    const item = this.options.data[i]
    // 绘画文本标签
    ctx.fillText(text, this.options.cSpace,  cSpiltVal * (this.data.length - i) + this.options.cSpace, 0);
    // 内部间距+文本长度
    const scaleX = this.options.cSpace + maxNameW
    // 通过数据最大值算出等分间隔,从而计算出每一个的终点坐标
    const scaleY = cSpiltVal * (length - i) + this.options.cSpace
    // 这里的5就是我设置文本跟刻度线的间隔与刻度线的长度
    drawLine(scaleX, scaleY, scaleX + 5 + 5, scaleY);
  }
})

4、绘画 y 轴线。继续分析概览图,从图中我们可以得到:y 轴线的起点 x 坐标的算法是:内部间距(cSpace)加最长文本宽度(maxNameW )加上文本与刻度线的间距以及刻度线长度,起点 y 坐标则是内部上间距;而终点 x 坐标与起点 x 坐标相同,终点 y 坐标算法是:画布高度减去上下两边的内部间距。通过以上计算关系就能绘画出 y 轴线了。代码如下:

.onReady(() => {  ...  // 上面是绘画其他组成部分代码   const startX = this.options.cSpace + maxNameW + 5 + 5   const startY = this.options.cSpace   const endX = startX   const endY = this.context.height - (this.options.cSpace * 2)   drawLine(startX, startY, endX, endY); // 绘画y轴})

5、绘画分割线。其实从图中可以看出分割线与刻度线差不多,起点 x 坐标算法是:在刻度线起点 x 坐标基础上加刻度线长度;起点 y 轴与刻度线相同。而终点的 x 坐标算法:画布宽度减去起点 x 坐标;终点的 y 坐标与起点的 y 坐标相同。具体代码如下:

.onReady(() => {
  ....
  // 上面是获取最长文本宽度的代码
  for(var i = 0; i <= length; i++){
    const item = this.options.data[i]
    // 绘画文本标签跟刻度
    ...
    // 绘画分割线
    const splitX = scaleX + 5 + 5
    const splitY = scaleY
    drawLine(splitX, splitY, this.context.width - splitX - this.options.cSpace, splitY);
  }
})

2.绘画 X 轴

绘画完 Y 轴之后,我们接着绘画 X 轴, X 轴与 Y 轴绘画逻辑一致,只是方向不同而已。具体的算法就不一一详解,可以参考一下概念图。

而与绘画 Y 轴不一致的在于:

1.  最长对象不一样。Y 轴最长是文本宽度;而 X 轴需要获取的最长是文本高度。

2.  间隔分割数不一样。Y 轴是自定义的分割数;而 X 轴分割线是实际数据的长度。

3.  分割间距长度算法不一样。Y 轴算法是用数据最大值处于自定义的分割数;而 X 轴算法是用画布宽度减去(左右两边的内部间隙以及 Y 轴宽度(文本最长宽度加上刻度线宽度)),再除去数据的长度,得到每个间隔的长度。

除了上面三点需要注意的,其他的就是调换一下计算的位置。X 轴整体的代码如下:

.onReady(() => {
  const cSpace = this.options.cSpace
  // 上面是绘制y轴的代码
  ....
  // 绘制x轴
  // 获取每个分割线的间距:this.context.width - 20为x轴的长度
  let xSplitSpacing = parseInt(String((this.context.width - cSpace * 2 - maxNameW) / this.options.data.length))
  let x = 0;
  for(var i = 0; i <= this.options.data.length; i++){
    // 绘画分割线
    x = xSplitSpacing * (i + 1) // 计算每个数值的x坐标值
    this.drawLine(x + cSpace + maxNameW, this.context.height - cSpace, x + cSpace + maxNameW, cSpace);
    // 绘制刻度
    this.drawLine(x + cSpace + maxNameW, this.context.height - cSpace, x + cSpace + maxNameW, this.context.height - cSpace);
    // 绘制文字刻度标签
    const text = this.options.data[i].name
    const textWidth = this.context.measureText(text).width; // 获取文字的长度
    // 这里文本的x坐标需要减去本身文本宽度的一半,这样才能居中显示, y坐标这是画布高度减去内部间距即可
    this.context.fillText(text, x + cSpace + maxNameW - textWidth / 2, this.context.height - cSpace, 0);
  }
this.context.save();
  this.context.rotate(-Math.PI/2);
  this.context.restore();
})

四、绘画折线区

绘画完坐标轴之后,就可以来绘画折线区的内容了。也是整个画布重点的部分。折线区分为三个部分:绘画折线、绘画标点、绘画文本。

1.绘画折线

从上面的图可以看出折线直接就是把实际数据的数值转成 x 跟 y 坐标,再通过连线连接起来。而每一个转折点的 x 坐标算法跟 x 轴的刻度或者文本是一样的,而 y 坐标是实际数值通过一定算法转成我们需要的高度。x 坐标我们已经获取了,只要是攻克我们的 y 坐标即可。可以通过图来观察一下在画布中与实际数据的关系:

首先 Y 轴的高度代表的是实际数据的最大值,这个我们绘画 Y 轴的时候就得到的结果,那我们则可以算出 Y 轴高度与实际数据的缩放倍数(scale),而折线的的每个 y 坐标对应的也是实际数值,需要把实际数值转换成画布中高度,那么就用实际数值乘与刚刚得到的缩放倍数(scale)就能得到转化后的高度了。

虽然我们已经得到每个转折点缩放后的高度,但是如果要跟 Y 轴坐标一一对应的 y 坐标的画,还需要用画布的高度减去下边内部高度加 x 轴高度,再减去缩放后的实际高度。这样算出来的才是我们想要的 y 坐标值,大概算法关系已经知道了,以下是最终代码:

.onReady(() => {
  ...
  // 上面是绘制x轴跟y轴的代码
  // 绘画折线
  const ySacle = (this.context.height - cSpace *2) / maxValue // 计算出y轴与实际最大值的缩放倍数
  //连线
  this.context.beginPath();
  for(var i=0; i< this.options.data.length; i++){
    const dotVal = String(this.options.data[i].value);
    const x = xSplitSpacing * (i + 1) + cSpace + maxNameW // 计算每个数值的x坐标值
    const y = this.context.height - cSpace - parseInt(dotVal * ySacle); // 画布的高度减去下边内部高度加x轴高度,再减去缩放后的实际高度
    if(i==0){
      // 第一个作为起点
      this.context.moveTo( x, y );
    }else{
      this.context.lineTo( x, y );
    }
  }
  ctx.stroke();
})

2.绘画标点、文本标签

画完折线我们基本能得到很多东西,比如折线上每个转折点的 x 跟 y 坐标值。这样对我们绘画标点与文本标签就很方便了:

.onReady(() => {
  ...
  // 上面是绘制x轴跟y轴的代码
  // 绘画折线
  const ySacle = (this.context.height - cSpace *2) / maxValue // 计算出y轴与实际最大值的缩放倍数
  this.context.beginPath();
  for(var i=0; i< this.options.data.length; i++){
    // 绘画折线代码
    ...
    // 绘制标点
    drawArc(x, y);
    // 绘制文本标签
    const textWidth = this.context.measureText(dotVal).width; // 获取文字的长度
    const textHeight = this.context.measureText(dotVal).height; // 获取文字的长度
    this.context.fillText(dotVal, x - textWidth / 2, y - textHeight / 2); // 文字
  }


  function drawArc( x, y ){
    this.context.beginPath();
    this.context.arc( x, y, 3, 0, Math.PI*2 );
    this.context.fill();
    this.context.closePath();
  }
  this.context.stroke();
})

最终效果如下:

五、总结

以上是本次技术分析,希望能对大家有所启发,也祝愿各位开发者能开发出理想的效果,后续我们会把 chart 相关系列的组件封装到组件库发布到市场上,这样可以直接开箱即用了。敬请期待吧,后续还有很多技术的分享,不要错过!

HTML5画布canvas实战(1)--折线图 画布基本教程 画布基础知识和绘制 Canvas MDN 唠唠叨叨 canvas 是 HTML5 新增的元素,可用于通过使用JavaScript中的脚本来绘制图形。例如,它可以用于绘制图形,制作照片,创建动画,甚至可以进行实时视频处理或渲染。 HTML结构 <style> canvas { border: 1px solid #000;... 阅读详情

相关推荐

前端 - canvas标签画折线图

首先在HTML里新增一个canvas标签<canvas id="canvas" width="500px" height="300px" style="border:1px solid black;float:left;"></canvas> 然后JS部分 //获取折线图 function getPolygonalChart(){ var canvas = documen...

sos_nice的博客 644

Canvas之绘制折线图

一、 绘制网格 绘制网格 网格的大小 网格的条数,横线条数,竖线条数,画布高度 网格的条数我们根据画布的大小来对网格大小进行相除,取整 &amp;lt;script&amp;gt; var myCanvas = document.querySelector('canvas'); var ctx = myCanvas.getContext('2d'); /*1.绘制网格*/ /...

Welkin_qing的博客 5116

鸿蒙实战开发:使用canvas实现图表系列之折线图

实现一个公共组件的时候,首先分析一下大概的实现结构以及开发思路,方便我们少走弯路,也可以使组件更加容易拓展,维护性更强。然后我会把功能逐个拆开来讲,这样大家才能学习到更详细的内容。下面简单阐述下折线图组件的功能结构:

liuhaojiabin的博客 1080

学习 canvas (二) 绘制图表

创建一个新页面 新建一个barchart.html文件: <!DOCTYPE html> <html lang="en"> <body> <canvas width="500" height="500" id="canvas"></canvas> <script type="text/javascript"></script> </body> </html> Canvas元素

小小的前端 1849

HarmonyOS 实战开发-使用canvas实现图表系列之折线图

实现一个公共组件的时候,首先分析一下大概的实现结构以及开发思路,方便我们少走弯路,也可以使组件更加容易拓展,维护性更强。然后我会把功能逐个拆开来讲,这样大家才能学习到更详细的内容。下面简单阐述下折线图组件的功能结构:

m0_71524094的博客 2203

canvas绘图折线图表

canvas折线图绘制插件

xiaoxiaoshuai__的博客 629

【Unity笔记】Unity图表插件推荐与使用指南:轻松实现可视化图表(Unity绘制折线图/柱状图/饼图)

本文整理自近期在 Unity 中实现折线图、波形图等图表可视化功能的调研与开发实践,聚焦图表库选型、使用方式与扩展技巧,目标为在 Unity 项目中实现功能完整、性能稳定的图形展示方案,供有类似需求的开发者参考。

一个XR(AR|VR|MR)程序猿的博客(EQ-雪梨蛋花汤) 2243

SYSUI-自定义图表折线图代码-非svg和canvas

本示例将介绍使用SYUSI框架扩展的一个折线图图表功能模块,数据展示非svg和canvas模式,而是传统的html结构,以操作DOM处理。 //引入SYSUI框架 <script type="text/javascript" src="../js/SYSUI/SYSUI.js"></script>//本地地址 用户可以自己去下载 下载地址:下载SYSUI.JS var sys=new Global.SYSUI({ Module:"#themeModule",//声明的元素对象

weixin_43962384的博客 1076

鸿蒙NEXT开发浅进阶到精通04:基于 Canvas 实现 XY 轴折线图单例

使用Canvas画折线图就简单三步一看就会,第一步画折线图区域容器,第二步画横轴纵轴坐标点,第三步一根一根的画线

m0_72778152的博客 2424

掌握JavaScript Canvas API:创建动态折线图

Canvas元素是HTML5规范中的一部分,它提供了一个通过JavaScript进行绘图的位图区域。开发者可以通过Canvas API直接在网页中绘制图形、处理图片、甚至是动画。由于其高度的灵活性和强大的渲染能力,Canvas广泛应用于数据可视化、游戏开发、多媒体展示等众多领域。虽然第三方库提供了很多便利,但在某些情况下,我们可能需要开发自定义的可视化组件来满足特定的业务需求。通过封装自定义组件,我们可以提供更好的用户体验和更高效的代码复用。// 示例JavaScript代码:自定义组件封装。

weixin_35750747的博客 960

基于HTML5 Canvas的JavaScript图表库实战(支持雷达图、饼图、折线图、曲线图、柱状图)

htmltable {th, td {th {pre {简介:JavaScript图表库是Web数据可视化的核心工具,结合HTML5 Canvas可实现高性能、高自定义的图形绘制。本文介绍基于Canvas的多种图表实现原理,涵盖雷达图、饼图、折线图、曲线图和柱状图,利用arc()、lineTo()、bezierCurveTo()、rect()等绘图方法完成动态渲染,并通过fillStyle、strokeStyle、文本标签等增强视觉效果。

weixin_33814090的博客 1262

canvas动态绘制折线图

公司的实践课题vue项目,用折线图展示近六个月的收入和支出,以前看到图表,第一个想到的就是从echarts官网调用,但这次导师建议我们用canvas去画,然后去封装,这样可以加大课题难度,同时理解底层的东西。 demo运行效果如图所示: 先分析折线图 主要包括画线、画圆、绘制文字三部分,分别使用canvas提供的以下方法 画线:moveTo() lineTo() 画圆:arc(...

qq_36135258的博客 3291

雪亮工程视频联网技术详解:视综平台主流接入方式与协议分析

随着雪亮工程建设的深入,视频资源的汇聚与共享成为核心需求。本文简要剖析了雪亮视综平台下的视频联网接入技术,重点讲解了主流接入方式的区别与选型,并深入探讨了平台内部及跨平台的视频资源共享机制(含级联与推送模式),旨在为安防开发人员和系统集成商提供清晰的架构思路与技术参考。

lsz152590的博客 718

9款基于HTML5/SVG/Canvas的折线图表应用

利用HTML5制作精美而实用的折线图表比较简单,因为我们除了可以利用HTML/CSS/Javascript外,还可以使用功能强大的SVG和Canvas动画特性,今天我们就来分享9款基于HTML5/SVG/Canvas的折线图表应用。1、华丽的HTML5图表 可展示实时数据HTML5在图表应用中也十分广泛,比起以前的网页图表,HTML5图表制作更便捷,功能更强大。这款HTML5图表插件外观十分华丽和...

yanyiping992的博客 703

LLVM 编译器学习笔记之三十六-- 指令调度Instruction scheduling

1、参考Instruction scheduling in LLVM - 知乎,在中后端均存在指令调度 指令调度模型 2、在llvm12->llvm14 中Machine Instruction Scheduler有个patch增强了load/store指令的合并,也就是指令调度不仅仅只是改变指令的顺序,该优化类似gcc中的store-merge优化 .....................................................................

~ 飞 扬 的 天 空 ~ 5688

网络基础(二):数制转换与分类编址的IPv4地址

本文介绍数制转换、IP地址、分类编址的IPv4地址,希望对你有帮助!

十七拾的博客 1055

带着canvas去流浪系列之二 绘制折线图

【摘要】 用canvasAPI实现echarts简易图表 示例代码托管在:http://www.github.com/dashnowords/blogs 一. 任务说明 使用原生canvasAPI绘制折线图。(柱状图截图来自于百度Echarts官方示例库【查看示例链接】。 二. 重点提示 一般折线图是比较好实现的,只需要调用最基本的moveTo()和lineTo( )方法来绘制即可。平滑...

华为云官方博客 2341

AI图像去噪实战:5种最新深度学习模型在超声图像处理中的效果对比(附代码)

本文对比了2022至2024年间五种前沿深度学习模型在超声图像去噪领域的实战效果,包括FDDL-Net、MG-CNFNet、Dual-TranSpeckle、可控去噪模型及Wave-Mamba。文章深入剖析了各模型的核心创新与架构,并提供了可运行的代码片段,旨在帮助医学影像算法工程师根据不同的性能、速度与临床需求,选择最合适的AI图像去噪解决方案。

1a2s3d4f5g的博客 915

Android自定义组件系列【9】——Canvas绘制折线图

有时候我们在项目中会遇到使用折线图等图形,Android的开源项目中为我们提供了很多插件,但是很多时候我们需要根据具体项目自定义这些图表,这一篇文章我们一起来看看如何在Android中使用Canvas绘制折线图。先看看绘制的效果:实现原理很简单,我就直接给出代码:package com.example.testcanvasdraw; import java.util.ArrayList; imp

水寒 1万+

ISO13849功能安全从入门到精通(3):安全功能及其对降低风险的贡献4

例如,如果机器必须在有限速度下运行时进行设置,那么在低加速度值下进行设置时,参数P1将是正确的选择:随着危险缓慢出现并给予足够的运动自由,操作员将能够移出危险区域。例如,在无故障的条件下,在操作者的手的方向移动的滚子不能陷住它。在所有其他情况下,F1是正确的选择,前提是危险暴露的持续时间不超过机器总操作时间的1/20。需求来源于必要的风险降低。由于这些考虑而降低的PLr在任何情况下都不得低于通过比较方式考虑的机器的PLr,因为并不能从事故发生率低和严重程度低得出实施的安全功能提供的安全水平高于要求。

wdconan001的博客 834

Anomalib库安装以及使用

Anomalib是一个专注于异常检测的深度学习库。它的目标是收集最新的异常检测算法,并提供用于在公共和私有数据集上进行基准测试的工具。该库提供了一系列已实现的异常检测算法,这些算法在最近的文献中有所描述。此外,Anomalib还提供了一套工具,方便开发人员开发和实现自定义模型。该库特别注重基于图像的异常检测,旨在识别数据集中的异常图像或图像中的异常像素区域。通过使用Anomalib,用户可以快速构建和评估各种异常检测算法,以满足其特定需求。

mingo_敏 5198

canvas图表(2) - 折线图

原文地址:canvas图表(2) - 折线图 话说这天气一冷啊, 就患懒癌, 就不想码代码, 就想着在床上舒舒服服看视频. 那顺便就看blender视频, 学习下3D建模, 如果学会了建3D模型, 那...

qq_29069777的博客 285

运放实现阶梯波发生器-总结报告

实验目的: 学习、理解、掌握方波电路、限幅电路积分累加电路、反馈电路 课程条件: 电脑仿真软件Multisim 原理框图和实验思路: 方波电路通过微分电路可以形成正负脉冲,在通过限幅电路后变为单脉冲,最后在积分电路中形成阶梯波。微分电路存在的意义就是为了防止方波频率过大,从而导致在经过限幅电路的方波,在一个周期内将电容的电充满,这样就不会产生阶梯波。如果方波的频率比较小,可以近似认为是正负脉冲,这样就可以跳过微分电路。 ...............

0 1万+

HTML Canvas 绘制实时动态折线图

本文使用HTML的Canvas元素绘制实时动态折线图。 参考于这篇博客HTML5 Canvas动画折线图 可动态添加节点 自定义Start、Stop按钮和画板canvas <button id="start" style="text-align:center;">Start</button> <button id="stop" style="text-align:center;">Stop</button> <canvas id=...

qq_41672428的博客 5866

【大模型+知识图谱】大模型与知识图谱融合:技术演进、实践应用与未来挑战

大模型与知识图谱的融合不是简单拼接,而是认知智能的范式重构。当符号主义的精确性与连接主义的泛化能力深度交织,我们正站在通向可信AGI的关键路口。正如OpenKG技术委员会王昊奋教授所言:“2025年将是图模协同从技术探索走向规模落地的分水岭”。参考文献OpenKG 2024年度报告(同济大学王昊奋)大型语言模型与知识图谱协同研究综述(海豚实验室,2024)知识图谱与大模型结合方法概述(黄巍,2023)图模互补:知识图谱与大模型融合综述(优快云,2024)

知识靠谱的博客 1092

jdk-8u144-linux-x64.tar.gz.

该资源为搭建Linux系统Java环境用,资源的后缀为tar.gz格式的压缩包

上一篇: HarmonyOS:NativeWindow 开发指导
下一篇: HarmonyOS:使用 MindSpore Lite 引擎进行模型推理
「已注销」
博客等级 码龄5年 1045粉丝 297原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

「已注销」

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值