Canvas 绘制折线统计图

我们只要不是要去用 canvas 做游戏,能做到 让 数据 可视图形化 即可,下面是 canvas 绘制折线统计图的练习

<canvas width="600" height="400" id="cas" style='border: 1px solid black;'></canvas>
<script>
    var cas = document.getElementById( 'cas' );
    var ctx = cas.getContext( '2d' );   // 获取绘图对象

    /*---- 绘制坐标系 ----*/
    // 坐标系在 canvas 中的 padding
    var padding = 30;
    // 坐标系原点
    var x0 = padding,   // 在正方向 padding
        y0 = cas.height - padding; // 左下角 高度-padding
    // 箭头高宽
    var arrowHeight = 20,   // 箭头高度
        arrowWidth = 10;    // 箭头宽度
    // 坐标系最大 x,坐标系最大 y
    var maxX = cas.width - padding * 2 - arrowHeight,
        maxY = cas.height - padding * 2 - arrowHeight;

    // 绘制 坐标系 两个轴
    ctx.moveTo( x0, y0 ); // 从 原点开始
    ctx.lineTo( x0 + maxX + arrowHeight, y0 );  // 绘制 x 轴
    ctx.moveTo( x0, y0 ); // 从 原点开始
    ctx.lineTo( x0, y0 - maxY - arrowHeight ); // 绘制 y 轴 由于 方向是反的,所以要加 负号
    ctx.stroke();    // 连点成线,绘制路径

    // 绘制 坐标系 箭头
    ctx.beginPath();
    // 绘制 x 轴 箭头
    ctx.moveTo( x0 + maxX + arrowHeight, y0 ); // x 轴右顶点开始
    ctx.lineTo( x0 + maxX, y0 - arrowWidth / 2 ); // 箭头上半边线, 由于是反的,上半边是减
    ctx.lineTo( x0 + maxX + arrowHeight / 2, y0 ); // 回 一半
    ctx.lineTo( x0 + maxX, y0 + arrowWidth / 2 ); // 箭头下半边线顶点
    ctx.closePath(); // 闭合路径 绘制出下半边线
    // 绘制 y 轴 箭头
    ctx.moveTo( x0, padding ); // y 轴 上顶点开始
    ctx.lineTo( x0 - arrowWidth / 2, padding + arrowHeight ); // 箭头左半边
    ctx.lineTo( x0, padding + arrowHeight / 2 ); // 回一半
    ctx.lineTo( x0 + arrowWidth / 2, padding + arrowHeight ); // 箭头右半边 顶点
    ctx.closePath(); // 闭合路径 绘制出右半边线
    ctx.fill(); // 填充路径

    /*-----  绘制坐标系点 ------*/
    var data1 = [ [ 10, 20 ], [ 15, 13 ], [ 17, 30 ], [ 30, 10 ], [ 20, 15 ] ];
    var data3 = []; // 用于存储计算之后的坐标
    // 排序
    // 由于 要进行 连线,所以要先进行排序, 这里冒泡一下
    var flag = true; // 定义 flag 看 有没有 排完
    for ( var i = 0; i < data1.length - 1; i++ ) {  // 排 length - 1 趟
        for( var j = 0; j < data1.length - 1 - i; j++ ) { // 每 排完一趟,每趟 就少排一次
            if ( data1[ j ][ 0 ] > data1[ j + 1][ 0 ] ) {   // 如果 大于,那就换
                var t = data1[ j ];
                data1[ j ] = data1[ j + 1 ];
                data1[ j + 1 ] = t;
                flag = false;  // 交换了 说明没排好
            }
        }
        if ( flag ) break; // 一趟下来,没进行交换,说明已经排好,退出
        flag = true; // 否则没排完,置为 ture
    }

    // 计算出最大值,和比例
    var dataMaxX = Math.max.apply( null, data1.map( function( v ) { return v[ 0 ]; } ) );
    var dataMaxY = Math.max.apply( null, data1.map( function( v ) { return v[ 1 ]; } ) );

    // 使用循环绘制点
    ctx.beginPath();
    ctx.fillStyle = 'blue'; // 设置画笔颜色

    for( var i = 0; i < data1.length; i++ ) {
        // 每个是 点边长 为 8 的矩形
        var tmpX = data1[ i ][ 0 ]; // 基准点 x 坐标
        var tmpY = data1[ i ][ 1 ]; // 基准点 y 坐标
        // 按比例 缩放
        tmpX = tmpX * maxX / dataMaxX;
        tmpY = tmpY * maxY / dataMaxY;
        // 转换坐标基准,以 x0 y0 为基准
        tmpX = tmpX + x0;
        tmpY = y0 - tmpY;

        data3.push( [ tmpX, tmpY ] ); // 将计算好的坐标点存放到数组中

        // 绘制点
        ctx.moveTo( tmpX - 4, tmpY - 4 );
        ctx.lineTo( tmpX + 4, tmpY - 4 );
        ctx.lineTo( tmpX + 4, tmpY + 4 );
        ctx.lineTo( tmpX - 4, tmpY + 4 );
        ctx.closePath();
    }
    ctx.fill(); // 绘制出四个点

    /*---- 连线 -----*/
    ctx.beginPath(); // 开启路径
    ctx.strokeStyle = 'blue'; // 换个颜色
    data3.forEach( function( v, i ) {
        ctx [ [ 'moveTo', 'lineTo' ][ i==0?0:1 ] ]( v[ 0 ], v[ 1 ] );
    });
    ctx.stroke(); // 绘制

</script>

最终绘制出来的结果:
这里写图片描述

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
要实现这个需求,你需要掌握以下几个步骤: 1. 读取csv文件 2. 解析每行数据,提取出点赞数和日期信息 3. 按照月份对点赞数进行统计 4. 使用matplotlib库绘制折线图 5. 将绘制好的图表嵌入到网页中 下面我们一步一步来实现。 首先,读取csv文件可以使用Python内置的csv库。假设你的csv文件长这样: ``` 日期,点赞数 2021-01-01,10 2021-01-02,8 2021-02-01,12 2021-02-03,7 2021-03-04,15 ``` 你可以用以下代码读取: ```python import csv with open('data.csv') as f: reader = csv.DictReader(f) rows = list(reader) ``` 这里使用了`csv.DictReader`,它可以将csv文件的每一行解析成一个字典,字典的键是文件第一行中的列名。 接下来,我们需要解析每行数据,提取出点赞数和日期信息。假设你的csv文件中日期的格式是`YYYY-MM-DD`,那么可以使用Python内置的datetime库来处理日期时间。以下是代码: ```python from datetime import datetime likes_by_month = {} for row in rows: date_str = row['日期'] like_count = int(row['点赞数']) date = datetime.strptime(date_str, '%Y-%m-%d') month = date.strftime('%Y-%m') if month not in likes_by_month: likes_by_month[month] = [] likes_by_month[month].append(like_count) ``` 这里使用了一个字典`likes_by_month`,它的键是每个月份的字符串,值是一个列表,列表中存储了这个月份内的所有点赞数。注意,这里假设每个月份内的点赞数是可以累加的。 接下来,我们需要对每个月份内的点赞数进行统计。这里我们可以使用Python内置的statistics库,具体来说是使用statistics.mean函数计算每个月份的平均点赞数。以下是代码: ```python from statistics import mean month_list = [] like_mean_list = [] for month, like_list in likes_by_month.items(): month_list.append(month) like_mean_list.append(mean(like_list)) ``` 这里我们将每个月份的字符串和它的平均点赞数分别存储在了两个列表`month_list`和`like_mean_list`中。 现在我们有了每个月份的平均点赞数,接下来就可以使用matplotlib库绘制折线图了。以下是代码: ```python import matplotlib.pyplot as plt plt.plot(month_list, like_mean_list) plt.xlabel('Month') plt.ylabel('Likes') plt.title('Monthly Likes') plt.show() ``` 这里我们使用了`plt.plot`函数来绘制折线图,`plt.xlabel`和`plt.ylabel`用于设置x轴和y轴的标签,`plt.title`用于设置图表标题,`plt.show`用于显示图表。 最后,我们需要将绘制好的图表嵌入到网页中。这里我们可以使用Matplotlib的webagg后端,它可以将图表嵌入到Flask或Django等web框架中。以下是代码: ```python from flask import Flask from matplotlib.backends.backend_webagg import FigureCanvasWebAgg as FigureCanvas app = Flask(__name__) @app.route('/likes') def likes(): fig, ax = plt.subplots() ax.plot(month_list, like_mean_list) ax.set_xlabel('Month') ax.set_ylabel('Likes') ax.set_title('Monthly Likes') canvas = FigureCanvas(fig) return canvas.print_figure(format='svg') if __name__ == '__main__': app.run(debug=True) ``` 这里我们使用了Flask框架,定义了一个路由`/likes`,当用户访问这个路由时,会返回一个SVG格式的图表。注意,这里我们使用了`FigureCanvasWebAgg`来创建图表画布,它可以将图表渲染为SVG格式。 以上就是实现统计csv文件每个月的点赞数字段并绘制折线图在网页上的全部步骤。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值