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()

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

  • 相关阅读:
    【笔记】求数据前n个主成分以及对高维数据映射为低维数据
    使用sklearn中的fetch_mldata的错误情况以及可能可行的解决方法
    【笔记】求数据的对应主成分PCA(第一主成分)
    【笔记】主成分分析法PCA的原理及计算
    【笔记】如何确定梯度计算的准确性以及调试梯度下降法
    【笔记】随机梯度下降法
    【笔记】线性回归中的梯度下降法(实现以及向量化并进行数据归一化)
    AttributeError: module 'numpy' has no attribute 'num'
    灵雀云CTO陈恺:从“鸿沟理论”看云原生,哪些技术能够跨越鸿沟?
    容器云在证券行业的探索与实践
  • 原文地址:https://www.cnblogs.com/cuifeipeng/p/7661643.html
Copyright © 2011-2022 走看看