canvas绘制经典折线图(一)

最终效果图如下:

实现步骤如下:注-引用了jQuery

HTML代码

<!doctype html>
<html lang="en">
 <head>
  <meta charset="UTF-8">
  <meta name="Generator" content="EditPlus®">
  <meta name="Author" content="">
  <meta name="Keywords" content="">
  <meta name="Description" content="">
  <title>canvas绘制折线图</title>
  <script src="scripts/jquery-1.11.3.js"></script>
  <script src="scripts/recordPaint.js"></script>
  <style>
    
  </style>
 </head>
 <script>
    $(function(){
         /*
             * 定义绘制折线图的关键数据(12个月的消费记录-金额)
             * 封装函数专门用于绘制折线图
               recordPaint(Elem,Data)方法
               * Elem - 表示<canvas>元素
               * Data - 表示关键数据
          */
         var datas = [1200,2000,3000,500,200,800,1800,2200,2600,1000,600,300];
         recordPaint($("#recordCvs")[0],datas);
    });
 </script>
 <body>
    <div id="recordContent">
        <canvas id="recordCvs" width="600" height="400"></canvas>
    </div>
 </body>
</html>

JS代码:即HTML中引用的外部JS文件<script src="scripts/recordPaint.js"></script>

/**
 * Created by walker on 2015/11/26.
 * 定义recordPaint()方法
 */
function recordPaint(Elem,Data){
    // 1. 创建画布对象
    var context = Elem.getContext('2d');
    // 2. 获取画布的宽度和高度
    const WIDTH = Elem.width;
    const HEIGHT = Elem.height;
    // 3. 定义坐标轴相对画布的内边距
    var padding = 20;//初始化内边距
    var paddingLeft = 60;//至少大于绘制文字的宽度
    var paddingBottom = 30;//至少大于绘制文字的高度
    // 4. 定义绘制坐标轴的关键点的坐标值
    var axisY = {// y轴的起点坐标值
        x : paddingLeft,
        y : padding
    };
    var origin = {// 原点坐标值(x轴与y轴相交点)
        x : paddingLeft,
        y : HEIGHT - paddingBottom
    };
    var axisX = {
        x : WIDTH - padding,
        y : HEIGHT - paddingBottom
    };
    // 5. 绘制坐标轴
    context.beginPath();
    context.moveTo(axisY.x,axisY.y);
    context.lineTo(origin.x,origin.y);
    context.lineTo(axisX.x,axisX.y);
    context.stroke();
    // 6. 绘制坐标轴的箭头
    context.beginPath();
    context.moveTo(axisY.x-5,axisY.y 10);
    context.lineTo(axisY.x,axisY.y);
    context.lineTo(axisY.x 5,axisY.y 10);
    context.stroke();

    context.beginPath();
    context.moveTo(axisX.x-10,axisX.y-5);
    context.lineTo(axisX.x,axisX.y);
    context.lineTo(axisX.x-10,axisX.y 5);
    context.stroke();

    // 定义折点的x轴值
    var pointsX = [];

    // 7. 绘制坐标轴的刻度(x轴的月份和y轴的金额)
    // x轴的月份
    var month = {
        x : paddingLeft,
        y : HEIGHT - paddingBottom
    }
    // 设置字体
    context.font = "14px 微软雅黑";
    // 设置垂直对齐
    context.textBaseline = "top";
    for(var i=1;i<=12;i  ){
        pointsX[pointsX.length] = month.x;
        // 绘制月份信息
        context.fillText(i "月",month.x,month.y);
        // 改变每次绘制的x坐标轴的值
        month.x  = (axisX.x - origin.x)/12;
    }

    // 绘制y轴的金额
    // 从众多的关键金额中,取到最高金额
    /*
    var datas = [];
    for(index in Data){
        datas[datas.length] = Data[index];
    }
    function sortNumber(a,b){
        return a - b;
    }
    var max = datas.sort(sortNumber)[datas.length-1];
    */
    var max = Math.max.apply(Math,Data);

    var moneyY = (origin.y - axisY.y)/(max/500 1);

    // 定义绘制的坐标值
    var money = {
        x : axisY.x - 5,
        y : axisY.y   moneyY,
        jin : max
    }
    // 设置水品对齐
    context.textAlign = "right";
    // 遍历"最高值/间隔"次
    for(var i=0;i<max/500;i  ){
        // 绘制金额
        context.fillText(money.jin "元",money.x,money.y);
        // y轴向下移动(增加)
        money.y  = moneyY;
        // 金额每次减500
        money.jin -= 500;
    }

    /*
      绘制折线
      * 12个折点的x轴值,对应12个月文字的x轴值
      * 折点的y轴值等于原点的y轴值-折点到原点的距离
        * 折点到原点的距离 = (3000点的y到原点的y的长度)*当前金额/3000
     */
    context.beginPath();
    for(var i=0;i<Data.length;i  ){
        // 获取折点的x和y值
        var pointY = origin.y - (origin.y - (axisY.y   moneyY))*Data[i]/max;
        var pointX = pointsX[i];
        // 绘制折线
        if(i == 0){
            context.textAlign = "left";
            //context.textBaseline = "bottom";
            context.moveTo(pointX,pointY);
        }else{
            context.textAlign = "center";
            context.textBaseline = "bottom";
            context.lineTo(pointX,pointY);
        }
        // 绘制折点的金额
        context.fillText(Data[i],pointX,pointY);
    }
    context.stroke();
    // 绘制12个折点的圆
    for(var i=0;i<Data.length;i  ){
        // 获取折点的x和y值
        var pointY = origin.y - (origin.y - (axisY.y   moneyY))*Data[i]/max;
        var pointX = pointsX[i];
        // 绘制圆
        context.fillStyle = "red";
        context.beginPath();
        context.arc(pointX,pointY,3,0,Math.PI*2);
        context.fill();
    }

}

  总结:每个拐点的坐标值要清晰


更多专业前端知识,请上 【猿2048】www.mk2048.com
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
要在 Android 上绘制折线图,可以使用 Canvas 和 Paint 类来实现。 首先,你需要创建一个自定义 View 组件,并在其 onDraw() 方法中实现绘图逻辑。在绘制折线图时,你需要先计算出每个数据点的坐标,然后使用 Path 类绘制连接这些点的线条。 下面是一个简单的示例代码,实现了一个基本的折线图绘制: ```java public class LineChartView extends View { private List<Float> mData = new ArrayList<>(); public LineChartView(Context context) { super(context); } public LineChartView(Context context, AttributeSet attrs) { super(context, attrs); } public LineChartView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); } public void setData(List<Float> data) { mData = data; invalidate(); // 通知 View 进行重新绘制 } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); // 设置画笔颜色和样式 Paint paint = new Paint(); paint.setColor(Color.BLUE); paint.setStyle(Paint.Style.STROKE); paint.setStrokeWidth(5); // 计算每个数据点的坐标 int width = getWidth(); int height = getHeight(); float xInterval = width / (mData.size() - 1); float yInterval = height / Collections.max(mData); Path path = new Path(); for (int i = 0; i < mData.size(); i++) { float x = i * xInterval; float y = height - mData.get(i) * yInterval; if (i == 0) { path.moveTo(x, y); } else { path.lineTo(x, y); } } // 绘制折线图 canvas.drawPath(path, paint); } } ``` 在 Activity 中,你可以通过调用 setData() 方法来设置折线图的数据,并将自定义 View 组件添加到布局中: ```java List<Float> data = new ArrayList<>(); data.add(10f); data.add(20f); data.add(50f); data.add(30f); data.add(40f); LineChartView lineChartView = new LineChartView(this); lineChartView.setData(data); LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams( LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.MATCH_PARENT); linearLayout.addView(lineChartView, layoutParams); ``` 上述代码会在 LinearLayout 中添加一个折线图,其中数据为 [10, 20, 50, 30, 40]。你可以根据自己的需求来修改上述代码,实现更加复杂的折线图绘制

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值