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

数据可视化解决方案:

在这里插入图片描述

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>
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值