D3 二维图表的绘制系列(八)曲线图

D3形状(二):曲线工厂 给定一系列的点,d3.line除了可以将这些点转换为折线路径外,还可以利用曲线工厂,将这些点转换为各类曲线,并能调节这些曲线的参数,改变曲线的形态。 阅读详情

上一篇: 堆叠面积图 https://blog.youkuaiyun.com/zjw_python/article/details/98214359

下一篇: 基础饼图 https://blog.youkuaiyun.com/zjw_python/article/details/98201470

代码结构和初始化画布的Chart对象介绍,请先看 https://blog.youkuaiyun.com/zjw_python/article/details/98182540

本图完整的源码地址: https://github.com/zjw666/D3_demo/tree/master/src/lineChart/smoothLineChart

1 图表效果

在这里插入图片描述

2 数据

date,money
Mon,120
Tue,200
Wed,150
Thu,80
Fri,70
Sat,110
Sun,130

3 关键代码

导入数据为对象数组

d3.csv('./data.csv', function(d){
    return {
        date: d.date,
        money: +d.money
    };
}).then(function(data){
....

一些样式配置参数,与基础折线图类似

const config = {
        lineColor: chart._colors(0),
        margins: {top: 80, left: 80, bottom: 50, right: 80},
        textColor: 'black',
        gridColor: 'gray',
        ShowGridX: [],
        ShowGridY: [20, 40, 60, 80, 100, 120, 140, 160 ,180, 200, 220],
        title: '曲线图',
        pointSize: 5,
        pointColor: 'white',
        hoverColor: 'red',
        animateDuration: 1000
    }

尺度转换,具有X和Y轴

    /* ----------------------------尺度转换------------------------  */
    chart.scaleX = d3.scaleBand()
                    .domain(data.map((d) => d.date))
                    .range([0, chart.getBodyWidth()])
    
    chart.scaleY = d3.scaleLinear()
                    .domain([0, (Math.floor(d3.max(data, (d) => d.money)/10) + 1)*10])
                    .range([chart.getBodyHeight(), 0])

渲染线条,在基础折线图中,两点之间的连线为直线,为了达到画线的动画效果,直接对数据点进行线性插值,然后运用中间帧函数实现,曲线图的画线动画也是这个思路,不过区别在于由于两点之间的点是曲线,因此不能再直接应用线性插值,而是应该使用曲线插值。在D3中插值中,目前只支持B样条曲线的插值,而这种曲线插值并没有经过数据点,不满足我们的需求。三次样条曲线插值的方法有很多,例如有三次自然样条曲线、Hermite样条曲线、Cardinal样条曲线等介绍,我们这里运用Cardinal样条曲线插值法,计算曲线分段函数的系数。
在这里插入图片描述
插值算法参照这里修改

//对于给定点集points和张力tension, 进行cardinal样条曲线插值, 返回基于x坐标的插值函数
function cardinalSpline(points, tension){

    const controlPoints = addControlPoints(points);

    const pointsNum = controlPoints.length;
    
    if ( pointsNum < 4) return;

    const m =  getCardinalMatrix(tension);

    return function(x){

        //当x等于控制点的x值时,直接返回对应的控制点坐标
        if (x <= controlPoints[0].x) return [controlPoints[0].x, controlPoints[0].y]; 

        if (x >= controlPoints[pointsNum-1].x) return  [controlPoints[pointsNum-1].x, controlPoints[pointsNum-1].y];

        //遍历控制点,找到x所在区间对应的4个控制点,计算返回相应的插值点
        for (let i=1; i < pointsNum-2; i++){
            if (controlPoints[i].x < x && controlPoints[i+1].x > x){
                return [
                    compute(m, controlPoints[i-1].x, controlPoints[i].x, controlPoints[i+1].x, controlPoints[i+2].x, (x-controlPoints[i].x)/(controlPoints[i+1].x-controlPoints[i].x)),
                    compute(m, controlPoints[i-1].y, controlPoints[i].y, controlPoints[i+1].y, controlPoints[i+2].y, (x-controlPoints[i].x)/(controlPoints[i+1].x-controlPoints[i].x)),
                ]
            }else if (controlPoints[i+1].x === x){
                return [x, controlPoints[i+1].y];
            }
        }
    }

}

//返回m矩阵
function getCardinalMatrix(t){
    return [
        -t, 2-t, t-2, t,
        2*t, t-3, 3-2*t, -t,
        -t, 0, t, 0,
        0, 1, 0, 0
    ]
}

//计算x分量或y分量
function compute(m, p0, p1, p2, p3, u){
    const a = m[0]*p0 + m[1]*p1 + m[2]*p2 + m[3]*p3;
    const b = m[4]*p0 + m[5]*p1 + m[6]*p2 + m[7]*p3;
    const c = m[8]*p0 + m[9]*p1 + m[10]*p2 + m[11]*p3;
    const d = m[12]*p0 + m[13]*p1 + m[14]*p2 + m[15]*p3;

    return a*Math.pow(u,3) + b*Math.pow(u,2) + c*u + d; //三次曲线函数
}

//左右各增加两个虚拟的控制点,保证控制点数量大于等于4
function addControlPoints(points){
    const newPoints = []

    points.forEach((point) => {
        newPoints.push(point);
    })

    newPoints.unshift(points[0]);
    newPoints.push(points[points.length-1]);

    return newPoints;
}

export default cardinalSpline;

有了插值算法后,曲线图和基础折线图就几乎没有什么差别了

/* ----------------------------渲染线条------------------------  */
    chart.renderLines = function(){

        let lines = chart.body().selectAll('.line')
                    .data([data]);

            lines.enter()
                    .append('path')
                    .classed('line', true)
                .merge(lines)
                    .attr('fill', 'none')
                    .attr('stroke', config.lineColor)
                    .attr('transform', 'translate(' + chart.scaleX.bandwidth()/2 +',0)')
                    .transition().duration(config.animateDuration)
                    .attrTween('d', lineTween);
            
            lines.exit()
                    .remove();
            
            //中间帧函数
            function lineTween(){
                const generateLine = d3.line()
                                        .x((d) => d[0])
                                        .y((d) => d[1])
                                        .curve(d3.curveCardinal.tension(0.5));

                const inputPoints = data.map((d) => ({x: chart.scaleX(d.date), y: chart.scaleY(d.money)}));

                const interpolate = getInterpolate(inputPoints);    //根据输入点集获取对应的插值函数            
                
                const outputPonits = []

                return function(t){
                    outputPonits.push(interpolate(t));
                    return generateLine(outputPonits);
                }
            }

            //点插值
            function getInterpolate(points){

                const domain = d3.range(0, 1, 1/(points.length-1));
                domain.push(1);

                const carInterpolate = cardinalSpline(points, 0.5);

                const scaleTtoX = d3.scaleLinear()   //时间t与x坐标的对应关系
                                        .domain(domain)
                                        .range(points.map((item) => item.x));

                return function(t){
                    return carInterpolate(scaleTtoX(t));
                }

            }
    }

线画好后,就是添加数据圆点、坐标轴和文本标签等,一样的老套路

/* ----------------------------渲染点------------------------  */
    chart.renderPonits = function(){
        let ponits = chart.body().selectAll('.point')
                    .data(data);
            
            ponits.enter()
                    .append('circle')
                    .classed('point', true)
                .merge(ponits)
                    .attr('cx', (d) => chart.scaleX(d.date))
                    .attr('cy', (d) => chart.scaleY(d.money))
                    .attr('r', 0)
                    .attr('fill', config.pointColor)
                    .attr('stroke', config.lineColor)
                    .attr('transform', 'translate(' + chart.scaleX.bandwidth()/2 +',0)')
                    .transition().duration(config.animateDuration)
                    .attr('r', config.pointSize);
    }

    /* ----------------------------渲染坐标轴------------------------  */
    chart.renderX = function(){
        chart.svg().insert('g','.body')
                .attr('transform', 'translate(' + chart.bodyX() + ',' + (chart.bodyY() + chart.getBodyHeight()) + ')')
                .attr('class', 'xAxis')
                .call(d3.axisBottom(chart.scaleX));
    }

    chart.renderY = function(){
        chart.svg().insert('g','.body')
                .attr('transform', 'translate(' + chart.bodyX() + ',' + chart.bodyY() + ')')
                .attr('class', 'yAxis')
                .call(d3.axisLeft(chart.scaleY));
    }

    chart.renderAxis = function(){
        chart.renderX();
        chart.renderY();
    }

    /* ----------------------------渲染文本标签------------------------  */
    chart.renderText = function(){
        d3.select('.xAxis').append('text')
                            .attr('class', 'axisText')
                            .attr('x', chart.getBodyWidth())
                            .attr('y', 0)
                            .attr('fill', config.textColor)
                            .attr('dy', 30)
                            .text('日期');

        d3.select('.yAxis').append('text')
                            .attr('class', 'axisText')
                            .attr('x', 0)
                            .attr('y', 0)
                            .attr('fill', config.textColor)
                            .attr('transform', 'rotate(-90)')
                            .attr('dy', -40)
                            .attr('text-anchor','end')
                            .text('每日收入(元)');
    }

    /* ----------------------------渲染网格线------------------------  */
    chart.renderGrid = function(){
        d3.selectAll('.yAxis .tick')
            .each(function(d, i){
                if (config.ShowGridY.indexOf(d) > -1){
                    d3.select(this).append('line')
                        .attr('class','grid')
                        .attr('stroke', config.gridColor)
                        .attr('x1', 0)
                        .attr('y1', 0)
                        .attr('x2', chart.getBodyWidth())
                        .attr('y2', 0);
                }
            });

        d3.selectAll('.xAxis .tick')
            .each(function(d, i){
                if (config.ShowGridX.indexOf(d) > -1){
                    d3.select(this).append('line')
                        .attr('class','grid')
                        .attr('stroke', config.gridColor)
                        .attr('x1', 0)
                        .attr('y1', 0)
                        .attr('x2', 0)
                        .attr('y2', -chart.getBodyHeight());
                }
            });
    }

最后绑定鼠标交互事件

/* ----------------------------绑定鼠标交互事件------------------------  */
    chart.addMouseOn = function(){
        //防抖函数
        function debounce(fn, time){
            let timeId = null;
            return function(){
                const context = this;
                const event = d3.event;
                timeId && clearTimeout(timeId)
                timeId = setTimeout(function(){
                    d3.event = event;
                    fn.apply(context, arguments);
                }, time);
            }
        }

        d3.selectAll('.point')
            .on('mouseover', function(d){
                const e = d3.event;
                const position = d3.mouse(chart.svg().node());
                e.target.style.cursor = 'hand'

                d3.select(e.target)
                    .attr('fill', config.hoverColor);
                
                chart.svg()
                    .append('text')
                    .classed('tip', true)
                    .attr('x', position[0]+5)
                    .attr('y', position[1])
                    .attr('fill', config.textColor)
                    .text('收入:' + d.money);
            })
            .on('mouseleave', function(){
                const e = d3.event;
                
                d3.select(e.target)
                    .attr('fill', config.pointColor);
                    
                d3.select('.tip').remove();
            })
            .on('mousemove', debounce(function(){
                    const position = d3.mouse(chart.svg().node());
                    d3.select('.tip')
                    .attr('x', position[0]+5)
                    .attr('y', position[1]-5);
                }, 6)
            );
    }

大功告成!!!


如果觉得这篇文章帮助了您,请打赏一个小红包鼓励作者继续创作哦!!!

在这里插入图片描述

d3实现曲线面积图,柱状图,天气曲线 案例,web后端开发框架 面试题千万不要死记,一定要自己理解,用自己的方式表达出来,在这里预祝各位成功拿下自己心仪的offer。需要完整面试题的朋友可以点击蓝色字体免费获取里预祝各位成功拿下自己心仪的offer。需要完整面试题的朋友可以点击蓝色字体免费获取[外链图片转存中…(img-cSISvDNz-1712093107442)][外链图片转存中…(img-uanQLi89-1712093107443)][外链图片转存中…(img-2X1W9ZOp-1712093107443)] 阅读详情

相关推荐

D3 二维图表的绘制系列(一)介绍

1 介绍 D3 (或者叫 D3.js )是一个基于 web 标准的 JavaScript 可视化库. D3 可以借助 SVG, Canvas 以及HTML 将你的数据生动的展现出来. D3 结合了强大的可视化交互技术以及数据驱动 DOM 的技术,让你可以借助于现代浏览器的强大功能自由的对数据进行可视化 学习了d3一个多月,通过绘制一些简单的二维图表,总算入门了d3。强烈推荐《D3数据可视化实战...

zjw_python的博客 6万+

d3 曲线区域填充

本篇以一个简单的demo示范一下在d3中实现曲线的区域填充。 clip-path clip-path:创建一个只有元素的部分区域可以显示的剪切区域。显示clip-path内部的区域,而外部的区域不可见。 区域填充也主要以clip-path为基础来实现。 区域填充 1.1 先画一条曲线 <!DOCTYPE html> <html> <head> ...

weixin_30846599的博客 1015

D3 二维图表的绘制系列(七)堆叠面积图

上一篇: 基础折线图 https://blog.youkuaiyun.com/zjw_python/article/details/98210977 下一篇: 曲线图 https://blog.youkuaiyun.com/zjw_python/article/details/98201470 代码结构和初始化画布的Chart对象介绍,请先看 https://blog.youkuaiyun.com/zjw_python/articl...

zjw_python的博客 6066

d3 画曲线

准备工作创建画布、创建组之类的省略。 准备数据,并用比例尺扩大到整个画布(画布大小自己设置) let data = [1,3,4,5,5] let scale_x = d3.scaleLinear() .domain([0, data.length - 1]) .range([0, this.svgWidth]) let scale_y = d3.scaleLinear() .domain(...

romeo12334的博客 3483

D3 二维图表的绘制系列(二十三)旭日图

上一篇: 桑基图 https://blog.youkuaiyun.com/zjw_python/article/details/98492510 下一篇: 力导向图 https://blog.youkuaiyun.com/zjw_python/article/details/98201470 代码结构和初始化画布的Chart对象介绍,请先看 https://blog.youkuaiyun.com/zjw_python/article...

zjw_python的博客 3620

绘图软件Origin新手使用教程

*写在前面:本文为便于博主自己学习进行的摘录整理,由于经过实际软件操作验证,故投稿原创,主要来源为知乎* 绘图软件Origin使用教程一、新手绘制新图(1)创建新图1.新建图2.文字输入3.绘制箭头4.新建图表选择(2)绘图实例讲解1.创建工程2.将数据导入book3.创建空的graph,设置画布尺寸4.添加坐标系,设置坐标系的位置与尺寸5.添加图线6.设置坐标轴格式7.设置图的标题8.设置图线的格式9.设置并添加图例10.导出图片二、导入数据(1)支持导入的数据格式1.主要介绍2.导入数据3.数据格式转

Flora_Cao的博客 5万+

D3 二维图表的绘制系列(九)基础饼图

上一篇: 曲线图 https://blog.youkuaiyun.com/zjw_python/article/details/98478578 下一篇: 环形饼图 https://blog.youkuaiyun.com/zjw_python/article/details/98201470 代码结构和初始化画布的Chart对象介绍,请先看 https://blog.youkuaiyun.com/zjw_python/article...

zjw_python的博客 2585

Synopsys Sentaurus TCAD系列教程之-- Svisual《一》看图工具

Svisual作为独立的模块,可以实现Inspect对于节点.plt曲线的查看,也可以实现TecplotSV的.tdr看图功能,还可以进行自动化操作。1.1 打开:Sdevice模块下面运行完的节点(黄色), 方法一:右键–>Visualize–>Sentaurus Visual(Select File…), 跳转到sentaurus Visualization(左侧都是以.plt结尾的文件名),选择一个要查看的内容,点击ok. 方法二:双击运行完全的节点,跳转到Node xx Explorer,在左下角找

weixin_42104289的博客 1万+

用Matplotlib在PyQt5界面绘制动态曲线、柱形、二维、三维图(下)

文章目录前言循环的实现图形数据的更新曲线图的更新柱形图的更新二维图的更新三维图的更新 前言 上一篇介绍了如何在PyQt的界面上通过Matplotlib绘制静态的曲线图、柱形图、二维图和三维图。这一篇介绍一下如何通过数据更新实现这些图形的动态显示。 循环的实现 要实现图形或数据的动态更新,必然需要一个时间循环,在PyQt中一般通过QTimer来实现循环控制。QTimer的使用方式如下所示。 ...

weixin_43008870的博客 1万+

d3-morton-order:D3布局,使用连续的莫顿(Z阶)空间填充曲线可视化距离变量

d3-莫顿 D3布局使用连续的莫顿(Z阶)空间填充曲线可视化距离变量。 这是一个。 另请参阅 。 快速开始 import d3ZOrder from &#39;d3-morton&#39;; 或者 d3.zOrder = require(&#39;d3-morton&#39;); 甚至 [removed][removed] 然后 const myRange = { start: 4, length: 9 }; d3.zOrder() .order(2) .layout(myRange) API参考 方法 描述 默认 canvasWidth ([ number ]) 覆盖画布Z阶曲线整个域的方形画布每一侧的长度的吸气剂/设定剂。 1个 顺序([ int ]) Z阶曲线域的范围的吸气剂/设定剂,由4^order决定。 由于JS编号的上限为53位,

v4版本的D3js源码和Api已经齐全的demo

v4版本的D3js源码和Api已经齐全的demo,详细的api介绍和实例。以代码齐全;

Matlab读取EXCEL文本中的数据并绘制二维三维曲线图脚本

Matlab读取EXCEL文本中的数据并绘制二维三维曲线图需要将EXCEL保存为CSV格式,然后取数据成矩阵进行处理 转CSV的方式:pixhawk日志ulg格式转matlab数据csv格式 %1、导入文件 filename="D:\文件地址\abcd.csv"; %2、设置取值范围 %读取全部数据 % m=csvread(filename,1,0);%从第2行第0列开始扫描全部数据 %读取指定范围数据 start=1;%开始行 start1=0;%开始列 len=2356;%结束行 len2=6;%结束

落体偏东 6520

别再纠结高边低边了!用TI BQ76952设计两轮车BMS,手把手教你选对架构(附电路图)

本文深度解析基于TI BQ76952芯片的电动两轮车BMS设计策略,涵盖高边/低边驱动选择、四种基础架构的电流路径分析及选型决策矩阵。通过实战案例分享,帮助工程师优化BMS架构,提升系统可靠性和成本效益,特别适合电摩和共享单车应用场景。

weixin_42665255的博客 514

d3.js 旋转图形_MATLAB二维图形

7.2 二维图形MATLAB提供了众多的二维图形绘图函数,这些函数的分类[R.D.1]如图7-3所示。可以看出,MATLAB基本的二维图形包括线型(line)、条型(bar)、区域型(area)、方向矢量型(direction)、辐射型(radial)、散点型(scatter)等多种类型,图中已经将各个函数所能够绘制图形的基本样式做了小的缩略图。本节介绍常用二维绘图函数的使用。至于其...

weixin_39603050的博客 430

电机控制易混知识点1-基波频率/载波频率/采样频率

在电机控制学习工作中会接触到很多专业名词,其中基波频率,载波频率,采样频率是最常接触到的,特别对于电机控制小白开说,不容易理解,现对这几个概念做下总结归纳。

新能源电机控制工程师 | 聚焦实战问题,搭建互助平台 分享电机控制代码调试、现场故障排查、算法优化中的真实困惑;开放讨论电机基础知识以及工作中遇到难点等共性难题。拒绝单向输出,只做工程师的“技术树洞”与“解忧杂货铺”! 2191

Halcon棋盘格畸变矫正

通常我们使用的相机都是带有一定的畸变的,只是畸变的大小不同。对于我们常见的测量项目来说,对测量精度的要求很高,通常从相机镜头上进行优化,但是即使镜头优化或者成本原因,造成图像仍有一定的畸变时,我们就可是使用棋盘格标定板,进行畸变矫正。

m0_51559565的博客 3396

MATLAB曲线绘制

From:http://hi.baidu.com/fightiger/blog/item/b2c1831382bf52d9f7039eab.html   一。 二维数据曲线图 1.1 绘制 单根二维曲线 plot 函数的基本调用 格式为: plot(x,y)  其中x和y为长度相同的向量,分别用于存储x坐标 和y坐标数据。 例1-1 在0≤x≤2p区间内,绘制曲线

Rachel Zhang的专栏 1万+

MMdetection3D与MMdetection版本匹配全攻略:从安装到测试一步到位

本文详细解析了MMdetection3D与MMdetection版本匹配的关键问题,提供了从环境配置到测试验证的完整指南。针对常见的安装错误,文章强调了版本依赖链(PyTorch、MMCV、MMDetection、MMDetection3D)精确对齐的重要性,并给出了基于CUDA 11.3等环境的实战版本组合与避坑方案,帮助用户高效部署3D目标检测开发环境。

xgboost6farmer的博客 240

常用Matlab操作回顾(一)——作图

作图 1. 三维曲面图 x=linspace(a,b,n) y=linspace(c,d,n) % 注意n大小要一样 [X,Y]=meshgrid(x,y) % 生成区域内格点坐标 Z=f(X,Y) surf(X,Y,Z) xlabel('x') ylabel('y') zlabel('z') title('title') 2.三维曲线图 绘制三维线图plot3(X,Y,Z) 绘制网线...

Rosalind_Xu的博客 836

【安装文档】TRex流量分析仪保姆级安装指南--基于VMware虚拟机(ubantu18.04@Intel 82545EM

如果之前添加了网卡,这里就可以看见有3个网卡(没添加的现在再加也行),* Active *为Linux内核正在使用的网卡,另外两张是未启用的网卡(注:未启用的网卡在终端中使用ifconfig命令是查不到的,需要先使用ip addr找出网卡,再激活,此时网卡会变为* Active *状态。

lingshengxiyou的博客 2130

一起学习Avalonia(十三)

Avalonia 前面已经简单介绍了一下相关开发,有一个系统的了解。 到今天Avalonia已经基本成熟,但是扩展支持的还是不可能达到大企业的,我估计这也不可能。考虑了下,微软的MAUI框架可能会普及性更高,Avalonia也是我无意间知道的。 微软毕竟是会宣讲的全球。并且微软全球研发投入很大,全部专职开发,这种速度当然大。但是MAUI根据计划,可能还要很长时间,而且是社区支持Linux,估计时间更久。这不能适应现在的国产化开发。 预计一段时间还是需要Avalonia作为优先。当前Avalonia使

jinyuttt的专栏 4086

matlab曲线绘制

From:http://hi.baidu.com/fightiger/blog/item/b2c1831382bf52d9f7039eab.html   一。 二维数据曲线图 1.1 绘制 单根二维曲线 plot 函数的基本调用 格式为: plot(x,y)  其中x和y为长度相同的向量,分别用于存储x坐标 和y坐标数据。 例1-1 在0≤x≤2p区间内,绘制曲线

Poem~ 1595

STM32F407上优化CAN总线通信(500kbps速率,多终端系统)需要从硬件设计、软件配置和实时性能三个方面进行综合优化

STM32F407上优化CAN总线通信(500kbps速率,多终端系统)需要从硬件设计、软件配置和实时性能三个方面进行综合优化

a_zxswer的博客 381

python动态爱心曲线_用Matplotlib在PyQt5界面绘制动态曲线、柱形、二维、三维图(下)...

前言上一篇介绍了如何在PyQt的界面上通过Matplotlib绘制静态的曲线图、柱形图、二维图和三维图。这一篇介绍一下如何通过数据更新实现这些图形的动态显示。循环的实现要实现图形或数据的动态更新,必然需要一个时间循环,在PyQt中一般通过QTimer来实现循环控制。QTimer的使用方式如下所示。def __init__(self,parent=None):super(ImgDisp,self)....

weixin_39744230的博客 393

手把手教你学Simulink--单相逆变器模糊逻辑控制策略仿真

本文介绍了在Simulink中设计单相逆变器模糊逻辑控制策略的完整流程。主要包括:1)构建单相逆变器模型;2)使用FuzzyLogicToolbox设计模糊控制器,定义输入输出变量和模糊规则;3)将控制器集成到Simulink模型;4)添加干扰源和示波器;5)配置仿真参数并分析结果。该方法利用模糊控制处理非线性系统的优势,可实现输出电压的精确跟踪,具有良好的鲁棒性。文中提供了详细的步骤说明和示例代码,强调准确设计隶属函数和规则库对控制性能的关键作用。该仿真设计为电力电子控制系统的开发提供了有效支持。

MHD0815的博客 200

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

matlab如何理解绘柱状图,matlab如何绘制柱状图

3.2 特殊图形和坐标的绘制 3.2.1 特殊图形绘制在MATLAB 7.3的 Workspace窗口中,如果选 择了Workspace窗口中的某 个内存变量,单击工具栏 中的绘制列数据曲线......3.2 特殊图形和坐标的绘制 3.2.1 特殊图形绘制在MATLAB 7.3的 Workspace窗口中,如果选 择了Workspace窗口中的某 个内存变量,单击工具栏 中的绘制列数据曲线.......

weixin_30792221的博客 843

温度PID控制PLC程序

温度PID稳定控制程序,适用于欧姆龙PLC,对其他PLC也具有很大参考价值

上一篇: D3 二维图表的绘制系列(七)堆叠面积图
下一篇: D3 二维图表的绘制系列(九)基础饼图
PAT-python-zjw
博客等级 码龄10年 381粉丝 408原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值