zoukankan      html  css  js  c++  java
  • 打造自己的图表控件1

    首先从最简单的折线图开始

    一个最简单的折线图有如下部分(这是从Excel截取的)

    X,Y坐标轴和折线图,所以可以把图表分成3个部分,左边,下边和中间。

    这里,构造两个对象,来组织这些部分。

    Chart 表示图表控件。

    ChartElement 表示控件中的内容。

    class Chart {
        constructor() {
            this.elements = []
        }
        add(element) {
            element.attach(this)
            this.elements.push(element)
        }
        remove(element) {
            element.detach(this)
            this.elements.remove(element)
        }
    }
    class ChartElement {
        constructor() {
            this.chart = null
        }
        attach(chart) {
            this.chart = chart
        }
        detach(chart) {
            this.chart = null
        }
    }

     但是有了这两个类,并不能画出来东西。所以还要构造出绘图的类CanvasDrawing和CanvasDrawingElement

    class CanvasDrawing {
        constructor(width, height) {
            var canvas = this.canvas = document.createElement("canvas")
            canvas.width = width
            canvas.height = height
            this.width = width
            this.height = height
            this.context = canvas.getContext("2d")
        }
        init(dom) {
            dom.appendChild(this.canvas);
        }
        renderChart(chart) {
            for (var element of chart.elements) {
                if (element instanceof CanvasDrawingElement) {
                    element.render(this.context, this.width, this.height)
                }
            }
        }
    }
    class CanvasDrawingElement extends ChartElement {
        constructor() {
            super()
        }
        render(context, width, height) {
    
        }
    }

    到这里,已经获取基本满足画东西的需求了。

    开始关键部分,画折线图。创建一个类,用来处理折线图 

    class SampleLineDrawing extends CanvasDrawingElement {
        constructor() {
            super()
            this.data = null //[ x1,y1,x2,y2 ]
        }
        render(context, width, height) {
            super.render(context, width, height)
            if (this.data != null) {
                context.save()
                context.strokeStyle = "#FF0000"
                context.beginPath()
                context.moveTo(this.data[0], this.data[1]);
                let length = this.data.length / 2
                for (let i = 1; i < length; i++) {
                    let x = this.data[2 * i]
                    let y = this.data[2 * i + 1]
                    context.lineTo(x, y)
                    console.log(x, y)
                }
                context.stroke();
                context.restore()
            }
        }
    }

    最后调用一下

    var width = 800
    var height = 600
    var chart = new Chart()
    var lineDrawing = new SampleLineDrawing()
    
    chart.add(lineDrawing)
    var chartDrawing = new CanvasDrawing(width, height)
    chartDrawing.init(document.body)
    function run() {
        requestAnimationFrame(run)
        lineDrawing.data = []
        for (var i = 0; i < width; i++) {
            lineDrawing.data.push(i)
            lineDrawing.data.push(Math.random() * (500 - 200) + 200)
        }
        chartDrawing.renderChart(chart)
    }
    run()

    本期到此结束,下期实现坐标系映射和视点设置。

  • 相关阅读:
    idea 插件之 SequenceDiagram
    idea 中添加mybatis的mapper文件模板
    springBoot 中 logback配置文件详解
    Mysql show processlist、show profiles 排查问题
    input 输入框效验
    Java基础之comparator和comparable的区别以及使用
    mysql sql使用记录
    mysql 优化之索引的使用
    IDEA 中常用快捷键的使用
    form表单中method的get和post区别
  • 原文地址:https://www.cnblogs.com/cuifeipeng/p/7661643.html
Copyright © 2011-2022 走看看