• 数据可视化前端技术选型


    数据可视化解决方案:

    在这里插入图片描述

    SKia 是Chrome和Android的底层2D绘图渲染,采用c++编程

    OpenGL 是2D、3D图形渲染库,可以绘制简单2D到复杂的3D图形,OpenGL常用于CAD、VR、数据可视化和游戏等众多领域

    Chrome 使用Skia作为绘图引擎,向上层开放了canvas、svg、WebGL、HTML等绘图能力

    Canvas入门

    Canvas是h5的新特性,它允许我们使用canvas元素在网页上通过JavaScript绘制图像
    入门案例:绘制点、矩形、直线和圆形

    <!DOCTYPE html>
    <html lang="en">
    
    <head>
        <meta charset="UTF-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>canvas练习</title>
    </head>
    
    <body>
        <canvas id="canvas" width="800" height="800"></canvas>
        <script>
        	// 为了让vscode能够提示canvas的api
            /** @type {HTMLCanvasElement} */
            const canvas = document.getElementById('canvas');
    
            // 绘制正方形
            const ctx = canvas.getContext('2d'); // 获取canvas对象
            ctx.fillStyle = 'red'; // 填充色
            ctx.fillRect(0, 0, 50, 50); // 绘制正方形
    
            // 绘制线段
            ctx.beginPath()
            ctx.lineWidth = 1; // 线条宽度
            ctx.strokeStyle = 'blue'; // 线条颜色
            ctx.moveTo(100, 100); // 起点 (相当于画布)
            ctx.lineTo(250, 75); // 终点
            ctx.lineTo(350, 85);  // 可使用lineTo绘制多条线段
            ctx.stroke(); // 绘制线段
    
            // 绘制圆形
            ctx.beginPath()
            ctx.lineWidth = 1;
            ctx.strokeStyle = 'green';
            ctx.fillStyle = 'red';
            ctx.arc(200, 200, 50, 0, 2 * Math.PI); // x, y轴坐标, 半径,起始角度,结束角度
            ctx.stroke();
            ctx.fill()
    
            // 绘制点
            ctx.beginPath()
            ctx.lineWidth = 1; // 线条宽度
            ctx.strokeStyle = 'red'; // 线条颜色
            ctx.moveTo(300, 300); // 起点 (相当于画布)
            ctx.lineTo(301, 301); // 终点
            ctx.stroke(); // 绘制线段
        </script>
    </body>
    </html>
    

    Svg入门

    Svg是一种基于XML的图像文件格式,英文全称是Scalable Vector Graphics,即可缩放的矢量图。在放大的情况下canvas会失真,svg不会。

    <!DOCTYPE html>
    <html lang="en">
    
    <head>
        <meta charset="UTF-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>svg 练习</title>
    </head>
    
    <body>
        <svg width="800" height="800">
            // 绘制矩形
            <rect width="50" height="50" style="fill:red; stroke-width:1px; stroke:aqua" />
            // 绘制线段
            // x1 y1 起点坐标 x2 y2 终点坐标
            <line x1="100" y1="100" x2="250" y2="75" style="stroke: blue; stroke-width: 1px;" />
            <line x1="250" y1="75" x2="300" y2="85" style="stroke:red ; stroke-width: 1px;" />
    
            // 绘制圆形 cx cy 中心坐标, r 半径
            <circle cx="200" cy="200" r="50" stroke="green" stroke-width="2" fill="red" />
            
            // 绘制点
            <line x1="300" y1="300" x2="301" y2="301" style="stroke: blue; stroke-width: 1px;" />
        </svg>
    </body>
    
    </html>
    

    WebGL

    WebGL(Web Graphics Library)是一种3D绘图协议,WebGL可以作为HTML5 canvas提供硬件3D加速渲染,这样的Web开发人员就可以借助系统显卡来在浏览器里更流畅地展示3D场景和模型了,还能创建复杂的导航和数据视觉化。

    ZRender 入门

    ZRender是二维绘图引擎,他提供canvas,svg,vml等多种渲染方式。ZRender也是Echarts的渲染器。

    <!DOCTYPE html>
    <html lang="en">
    
    <head>
        <meta charset="UTF-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>ZRender练习</title>
        <script src="https://cdn.jsdelivr.net/npm/zrender@4.3.0/dist/zrender.js"></script>
    </head>
    
    <body>
        <div id="content" style="width: 800px; height: 800px;"></div>
        <script>
            const zr = zrender.init(document.getElementById('content'));
            // 矩形
            const rect = new zrender.Rect({
                shape: {
                    x: 0,
                    y: 0,
                    width: 50,
                    height: 50
                },
                style: {
                    fill: 'red',
                    lineWidth: 0
                }
            })
            zr.add(rect);
            // 圆形
            const circle = new zrender.Circle({
                shape: {
                    cx: 200,
                    cy: 300,
                    r: 40
                },
                style: {
                    fill: 'red',
                    stroke: '#F00'
                }
            });
            zr.add(circle);
    
            // 线段
            const line = new zrender.Polyline({
                shape: {
                    // 连线的点
                    points: [
                        [100, 100],
                        [200, 75],
                        [300, 85]
                    ]
                },
                style: {
                    stroke: 'red',
                    lineWidth: 1
                }
            });
            zr.add(line);
    
             // 点
             const point = new zrender.Polyline({
                shape: {
                    // 连线的点
                    points: [
                        [300, 300],
                        [301, 301],
                    ]
                },
                style: {
                    stroke: 'red',
                    lineWidth: 1
                }
            });
            zr.add(point);
        </script>
    </body>
    
    </html>
    

    D3 入门

    D3(Data-Driven Docment)是一个JavaScript图形库,基于Canvas、 Svg和HTML

    <!DOCTYPE html>
    <html lang="en">
    
    <head>
        <meta charset="UTF-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>d3练习</title>
        <script src="https://d3js.org/d3.v5.js"></script>
    </head>
    
    <body>
        <p>vue</p>
        <p>react</p>
        <p>angular</p>
        <button id="datum">datum</button>
        <button id="data">data</button>
        <script>
            const body = d3.select('body');
            const p = body.selectAll('p');
            function doDatum() {
                const str = 'text'
                p.datum(str);
                p.text(function (d, i) {
                    console.log(d, i);
                    return `${d}-${i}`
                })
            }
            function doData() {
                const dataset = ['vue', 'react', 'angular']
                p.data(dataset).text(function (d, i) {
                    console.log(d, i)
                    return `${d}-${i}`
                })
            }
            const datum = document.getElementById('datum').addEventListener('click', function () {
                doDatum();
            });
            const data = document.getElementById('data').addEventListener('click', function () {
                doData();
            });
        </script>
    </body>
    
    </html>
    

    three.js

    three.js 是一种基于WebGL的JavaScript 3D图形库

    <!DOCTYPE html>
    <html lang="en">
    
    <head>
        <meta charset="UTF-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>three练习</title>
        <script src="https://threejs.org/build/three.js"></script>
    </head>
    
    <body>
        <script>
            var camera, scene, renderer
            var geometry, material, mesh
            init();
            animate();
            function init() {
                camera = new THREE.PerspectiveCamera(70, window.innerWidth / window.innerHeight); // 角度
                camera.position.z = 1;
                scene = new THREE.Scene();
                geometry = new THREE.BoxGeometry(0.2, 0.2, 0.2); //背景
                material = new THREE.MeshNormalMaterial();
                mesh = new THREE.Mesh(geometry, material);
                scene.add(mesh);
                renderer = new THREE.WebGLRenderer({ antialias: true });
                renderer.setSize(window.innerWidth, window.innerHeight);
                document.body.appendChild(renderer.domElement)
            }
            function animate() {
                requestAnimationFrame(animate);
                mesh.rotation.x += 0.01;
                mesh.rotation.y += 0.02;
                renderer.render(scene, camera)
            }
        </script>
    </body>
    
    </html>
    

    Canvas 图片压缩

    <!DOCTYPE html>
    <html lang="en">
    
    <head>
        <meta charset="UTF-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Document</title>
    </head>
    
    <body>
        <input type="file" id="upload">
        <script>
            const ACCEPT = ['image/jpg', 'image/png', 'image/jpeg'];
            const MAXSIZE = 3 * 1024 * 1024;
            const MAXSIZE_STR = '3MB';
            const upload = document.getElementById('upload');
            function convertImageToBase64(file, callback) {
                let reader = new FileReader();
                reader.addEventListener('load', (e) => {
                    console.log(reader.result)
                    const base64Image = e.target.result;
                    callback && callback(base64Image);
                    reader = null;
                })
                reader.readAsDataURL(file);
            }
    
            function compress(base64Image, callback) {
                console.log(base64Image);
                let maxW = 1024;
                let maxH = 1024;
                // 创图对象,设定高宽,进行压缩,设置分辨率,进行输出
                const image = new Image();
                image.addEventListener('load', (e) => {
                    let ratio;
                    let needCompress = false; // 是否需要压缩
                    if (maxW < image.naturalWidth) {
                        needCompress = true;
                        ratio = image.naturalWidth / 1024;
                        maxH = image.naturalHeight / ratio;
                    } // 经过处理后。图片的实际尺寸为1024 * 640
                    if (maxH < image.naturalHeight) {
                        needCompress = true;
                        ratio = image.naturalHeight / 1024;
                        maxW = image.naturalWidth / ratio;
                    }
                    // 不需要压缩
                    if (!needCompress) {
                        maxH = image.naturalHeight;
                        maxW = image.naturalWidth;
                    }
                    const canvas = document.createElement('canvas');
                    canvas.setAttribute('id', '__compress__');
                    canvas.width = maxW;
                    canvas.height = maxH;
                    canvas.style.visibility = 'visible';
                    document.body.appendChild(canvas);
    
                    const ctx = canvas.getContext('2d');
                    ctx.clearRect(0, 0, maxW, maxH);
                    ctx.drawImage(image, 0, 0, maxW, maxH);
                    // 设置精细度
                    const compressImage = canvas.toDataURL('image/jpeg', 0.9);
                    callback && callback(compressImage);
                    // const _image = new Image();
                    // _image.src = compressImage;
                    // document.body.appendChild(_image);
                    canvas.remove();
    
                })
                image.src = base64Image;
                document.body.appendChild(image);
    
            }
    
            function uploadToServer(compressImage) {
                console.log(compressImage);
            }
    
            upload.addEventListener('change', (e) => {
                const [file] = e.target.files;
                if (!file) {
                    return;
                }
                const { type: fileType, size: fileSize } = file;
                // if (ACCEPT.indexOf(fileType) < 0) {
                if (!ACCEPT.includes(fileType)) {
                    alert(`不支持[${fileType}]文件类型`);
                    upload.value = '';
                    return;
                }
                if (fileSize > MAXSIZE) {
                    alert(`文件超出${MAXSIZE_STR}`);
                    upload.value = '';
                    return;
                }
                // 压缩
                convertImageToBase64(file, (base64Image) => compress(base64Image, uploadToServer));
            })
        </script>
    </body>
    
    </html>
    
  • 相关阅读:
    Git add回退 & commit回退
    NetCore/Net8下使用Redis的分布式锁实现秒杀功能
    【C++项目】高并发内存池第二讲中心缓存CentralCache框架+核心实现
    LiteFlow 开源编排规则引擎
    【数据结构】数组和字符串(四):特殊矩阵的压缩存储:稀疏矩阵——三元组表
    PHP图片压缩,再转base64传输
    设计模式之代理模式(十一)
    微信小程序_22,全局数据共享
    Pyhon中利用GM(1,1)和ARIMA模型对卫星DCB值进行预测
    在RabbitMQ中 WorkQueue 工作队列 和发布(publish)/订阅(Subscribe) 有什么区别?
  • 原文地址:https://blog.csdn.net/weixin_43777074/article/details/126855406