可视化大屏(antv, echarts, 百度地图--初篇)

Canvas

放大会失真

html 复制代码
<canvas id="canvas" width="800" height="800"></canvas>
<script>
    let canvas = document.getElementById('canvas')
    // 获取Canvas对象
    let ctx = canvas.getContext('2d')
    // 设置红色
    ctx.fillStyle = 'red'
    // 设置坐标--- 前两个 x,y 坐标起始位置,后面是截至位置,x,y,绘制矩形
    ctx.fillRect(0, 0, 50, 50)
    // 开始绘制新的
    ctx.beginPath()
    // 绘制一个线,设置宽度
    ctx.lineWidth = 1
    // 设置线的颜色
    ctx.strokeStyle = 'blue'
    // 绘制起点位置
    ctx.moveTo(100, 100)
    // 绘制到终点位置
    ctx.lineTo(250, 70)
    // 再绘制一个
    ctx.lineTo(300, 100)
    // 开始绘制
    ctx.stroke()

    // 绘制圆形
    ctx.beginPath()
    ctx.lineWidth = 2
    // 线绿色
    ctx.strokeStyle = 'green'
    // 设置填充红色
    ctx.fillStyle = 'red'
    // 绘制圆形,x,y,半径,起始角度,终止角度
    ctx.arc(200, 200, 50, 0, 2 * Math.PI)
    // 开始绘制
    ctx.stroke()
    // 进行填充
    ctx.fill()
</script>

svg

不失真

html 复制代码
<svg width="800" height="800">
    <!--绘制方形-->
    <rect width="50" height="50" style="fill:red"/>
    <!--绘制线条-->
    <line x1="250" y1="75" x2="300" y2="100" style="stroke: blue;stroke-width: 1"/>
    <!--圆形-->
    <circle cx="200" cy="200" r="50" style="stroke: blue; stroke-width: 1" fill="red"/>
    <!--点-->
    <line x1="300" y1="300" x2="301" y2="301" style="stroke: red;stroke-width: 1"/>
</svg>

WebGL

3D 绘图

zrender 二维绘图引擎

提供 Cavans,SVG,VML 等多种渲染方式,也是 Echarts 的渲染器

html 复制代码
<!-- 创建一个具有 id "container" 的 <div> 元素,用作画布容器 -->
<div id="container" style="width: 800px;height: 800px"></div>
<script>
    // 创建 ZRender 实例
    let zr = zrender.init(document.getElementById('container'))// 在具有 id "container" 的 <div> 元素上创建 ZRender 实例
    // 创建矩形对象
    let rect = new zrender.Rect({
        shape: {
            x: 0,
            y: 0,
            width: 50,
            height: 50
        },
        style: {
            fill: 'red', // 填充红色
            lineWidth: 0 // 设置边框线宽度为0,即无边框
        }
    })

    // 创建线条
    let line = new zrender.Polyline({
        shape: {
            points: [
                [100, 100], // 第一个点
                [250, 75], // 第二个点
                [300, 100], // 第二个点
            ]
        },
        style: {
            stroke: 'blue', // 颜色蓝色
            lineWidth: 1 // 宽度1
        }
    });

    // 创建圆
    let circle = new zrender.Circle({
        shape: {
            // x 坐标
            cx: 200,
            // y 坐标
            cy: 200,
            // r 半径
            r: 50
        },
        style: {
            fill:  'red', // 填充颜色
            stroke: 'green', // 边框颜色
            lineWidth: 2
        }
    });

    // 创建点
    let point = new zrender.Polyline({
        shape: {
            points: [
                [300, 300], // 第一个点
                [301, 301], // 第二个点
            ]
        },
        style: {
            stroke: 'red', // 颜色蓝色
            lineWidth: 1 // 宽度1
        }
    });
    zr.add(rect)
    zr.add(line)
    zr.add(circle)
    zr.add(point)
</script>

d3

html 复制代码
<body>
<p>Vue</p>
<p>React</p>
<p>Agular</p>
<button id="datum">datum</button>
<button id="data">data</button>
</body>
<script>
    // 获取 d3 的body对象
    let body = d3.select('body');
    // 获取 d3 对象下面的 p标签
    let p = body.selectAll('p');

    let datum = document.getElementById('datum');
    let data = document.getElementById('data');
    datum.addEventListener('click', function (e) {
        const str = 'Framework'
        // 将数据绑定到 p标签上
        p.datum(str)
        p.text(function (d, i) {
            // 更新每一个 p标签的数据
            return `${d}-${i}`
        })
    })
    data.addEventListener('click', function (e) {
        const dataSet = ['Vue', 'React', 'Agular']
        // 按照每一项对应,根上面不同
        p.data(dataSet).text(function (d, i) {
            return `${d}-${i}`
        })
    })
</script>

three

基于 WebGL 的 JavaScript 3D 图形库

图片压缩案例

html 复制代码
<!--图片压缩算法-->
<input type="file" id="upload">
<script>
    const ACCEPT = ['image/jpg', 'image/png', 'image/jpeg']
    let upload = document.getElementById('upload');
    upload.addEventListener('change', function (e) {
        // 查看图片信息
        let [file] = e.target.files;
        console.log(file)
        if (!file) return
        // 重命名
        let {type: fileType, size: fileSize} = file;
        if (!ACCEPT.includes(fileType)) {
            upload.value = ''
            alert('不支持此类型')
            return;
        }
        if (fileSize > 1024 * 1024) {
            upload.value = ''
            alert('文件超出1MB')
        }

        convertImageToBase64(file, compress)

        // 图片容量检查
        // 压缩图片
        function convertImageToBase64(file, callback) {
            let fileReader = new FileReader()
            fileReader.addEventListener('load', function (e) {
                // 获取 base64 编码后的图片
                let base64Image = e.target.result;
                // 执行回调函数
                callback && callback(base64Image)
                // 将fileReader对象置为null,释放内存
                fileReader = null
            })
            fileReader.readAsDataURL(file)
        }

        // 算法
        /**
         * 1. 思路,创建 image 对象
         * 2. 获取宽高,对宽高进行压缩,Cavans 并绘制
         * 3. 对质量进行压缩
         */
        function compress(base64Image, callback) {
            let height = 1024
            let width = 1024
            let needCompress = false
            let image = new Image()
            // 当图片加载完毕执行
            image.addEventListener('load', function (e) {
                if (width < image.naturalWidth) {
                    // 同比例压缩
                    let radio = image.naturalWidth / width;
                    // 实际高度
                    height = image.naturalHeight / radio
                    needCompress = true
                }
                if (height < image.naturalHeight) {
                    let radio = image.naturalHeight / height
                    width = image.naturalWidth / radio
                    needCompress = true
                }
                // 不需要压缩
                if (!needCompress) {
                    width = image.naturalWidth
                    height = image.naturalHeight
                }
                // 开始绘制
                // 创建画布
                let canvas = document.createElement('canvas')
                canvas.setAttribute('id', '_compress_')
                canvas.width = width
                canvas.height = height
                canvas.style.visibility = 'visible' // 实际需要隐藏
                document.body.appendChild(canvas)

                // 绘制
                let ctx = canvas.getContext('2d');
                // 清楚画布指定区域
                ctx.clearRect(0, 0, width, height)
                // 绘制指定区域图片
                ctx.drawImage(image, 0, 0, width, height)
                // 转换为指定格式,并且图片质量为 0.1,最高1,返回base64 图片编码
                let compress = canvas.toDataURL('image/jpeg', 0.9);
                // 通常再这个时候会将图片编码上传
                callback && callback(compress)
                let image1 = new Image()
                image1.src = compress
                document.body.appendChild(image1)
                //移除画布
                canvas.remove()
            })

            image.src = base64Image
            document.body.appendChild(image)
        }
    })
</script>

Antv

G2 plot 快速使用

图标

折线图

html 复制代码
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script type="text/javascript" src="https://unpkg.com/@antv/g2plot@latest/dist/g2plot.min.js"></script>
</head>
<body>
<div id="g2"></div>
<script>
    const data = [
        {year: '1991', value: 3},
        {year: '1992', value: 4},
        {year: '1993', value: 3.5},
        {year: '1994', value: 5},
        {year: '1995', value: 4.9},
        {year: '1996', value: 6},
        {year: '1997', value: 7},
        {year: '1998', value: 9},
        {year: '1999', value: 13},
    ];
    // 获取line
    let {Line} = G2Plot;
    let line = new Line('g2', {
        // 数据
        data,
        // x 轴
        xField: 'year',
        // y 轴
        yField: 'value',
        // 每一个y轴加 一个点
        point: {
            visible: true,
            size: 5, // 大小
            color: '#fff', // 颜色
            // 填充效果
            style: {
                // 边框颜色
                stroke: '#fe740c',
                // 边框大小
                lineWidth: 2,
                // 填充度
                fillOpacity: 0.6
            }
        },
        // 为每一个数据加标签
        // 添加label并格式化
        label: {
            visible: true,
            formatter: (v) => `${v.value}k`
        },
        // 折线图颜色
        color: '#f2740c',
        yAxis: {
            label: {
                formatter: (v) => {
                    return `${v}k`
                }
            }
        }
    });
    // 执行绘制
    line.render()
</script>

G6 快速入门

思维导图,关系图

html 复制代码
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="https://gw.alipayobjects.com/os/lib/antv/g6/4.3.11/dist/g6.min.js"></script>
</head>
<body>
<div id="g6"></div>
<script>
    let data = {
        // 点
        nodes: [
            {
                id: 'node1', // id表示是那个
                x: 120, // x坐标
                y: 200, // y 坐标
                label: '起始点', // 标签
                size: 60, // 大小
                // label 样式
                labelCfg: {
                    position: 'center', // 文本位置默认center
                    style: {
                        fontsize: 16, // 文本字体大小
                        fill: '#fff' // 填充颜色
                    }
                },
                style: {
                    // 圆形填充色
                    fill: '#ff0000',
                    // 边框色
                    stroke: '#888',
                    // 边框宽度
                    lineWidth: 1
                }
            },
            {
                id: 'node2',
                x: 320,
                y: 200,
                label: '目标点1',
                size: 60
            },
            {
                id: 'node3',
                x: 520,
                y: 200,
                label: '目标点2',
                size: 60
            }
        ],
        // 边
        edges: [
            {
                source: 'node1', // 源
                target: 'node2', // 目标
                label: '连接线1'
            },
            {
                source: 'node2',
                target: 'node3',
                label: '连接线2'
            }
        ],
    }
    // 绘制 G6 图的初始化
    let graph = new G6.Graph({
        container: 'g6',
        width: 800,
        height: 500
    });
    graph.data(data) // 绑定数据源
    // 绘制矢量图
    graph.render()
</script>
</body>

l7 快速入门

练习接口地址

html 复制代码
<head>
    <meta charset="UTF-8">
    <title>根据坐标高亮在地图中显示坐标</title>
    <script src="https://unpkg.com/@antv/l7"></script>
    <style>
        * {
            margin: 0;
            padding: 0;
        }
    </style>
</head>
<body>
<div id="l7"></div>
<!-- key 的密钥 -->
<script type="text/javascript">
    window._AMapSecurityConfig = {
        securityJsCode: '1686f7c0d6fa1825227u39ah74a826f2',
    }
</script>
<script>
    const scene = new L7.Scene({
        id: 'l7',
        // 使用高德地图
        map: new L7.GaodeMap({
            // token: // 需要自己申请 F12 会有提醒
            token: 'a0eb893d39e487072649a920124bc42c',
            style: 'dark', // 主题颜色
            // 默认坐标
            center: [120.19382669582967, 30.258134],
            // 倾斜角度,0表示平面
            pitch: 0,
            // 默认缩放比例
            zoom: 12
        }),
    });
    // 所有图层资源都加载完毕之后触发
    scene.on('loaded', function () {
        // fetch 发送请求函数返回一个 Promise 对象
        fetch('https://gw.alipayobjects.com/os/basement_prod/337ddbb7-aa3f-4679-ab60-d64359241955.json')
            .then(res => res.json())
            .then(data => {
                console.log(data)
                // 创建点的图层
                let pointLayer = new L7.PointLayer({})
                    // 传入数据信息
                    .source(data)
                    // 将显示信息设置为圆形
                    .shape('circle')
                    // 会自动去寻找capacity根据值判断,最小0,最大16--大小自适应
                    .size('capacity', [0, 16])
                    // 越大的颜色越深
                    .color('capacity', [
                        'rgb(239,243,255)',
                        'rgb(189,215,231)',
                        'rgb(107,174,214)',
                        'rgb(49,130,189)',
                        'rgb(8,81,156)'
                    ])
                    // 修改样式
                    .style({
                        // 不需要边框
                        strokeWidth: 0,
                        // 透明
                        opacity: 0.5
                    })
                    // 开启交互感
                    .active(true)
                // 将图层添加到场景
                scene.addLayer(pointLayer)
            })
    })
</script>
</body>

echarts

定制主题

在 echarts 中的下载可以下载定义的主题,在资源,主题构建进行构建

选中主题,进行下载

现在有 JS 版本和 JSON版本

JS 版本

  1. 选中复制即可
  2. 找到复制的重要代码
js 复制代码
// 表示注册了一个场景叫做:purple-passion
echarts.registerTheme('purple-passion', {
  1. 使用场景
js 复制代码
var myChart = echarts.init(document.getElementById('main'), 'purple-passion');

如何将 echarts 渲染的图标设置为 svg,默认 Canvas

{renderer: 'svg'}

js 复制代码
var myChart = echarts.init(document.getElementById('main'), 'purple-passion', {renderer: 'svg'});

多系列坐标系

指一个坐标系,存在多个图例

js 复制代码
series: [
    // 第一个系列饼图
    {
        type: 'pie', // 表示饼图
        radius: 35, // 半径
        center: ['65%', 60],
        data: [ // 数据
            { value: 1048, name: 'Search Engine' },
            { value: 735, name: 'Direct' },
            { value: 580, name: 'Email' },
            { value: 484, name: 'Union Ads' },
            { value: 300, name: 'Video Ads' }
        ],
    },
    // 第二个系列饼图
    {
        data: [150, 230, 224, 218, 135, 147, 260],
        type: 'line' // 折线图
    },
    // 第三个系列饼图
    {
        name: '销量',
        type: 'bar', // 柱状图
        data: [5, 20, 36, 10, 10, 20]
    }
]

会带来坐标系问题,例如:折线图数据是百分之 0 到百分之 100%之间,而柱状图是几十万的数据。

dataset

集中管理多系列,使用 encode 去匹配数据

js 复制代码
<script type="text/javascript">
// 基于准备好的dom,初始化echarts实例
var myChart = echarts.init(document.getElementById('main'), 'light', { renderer: 'svg' });

// 指定图表的配置项和数据
var option = {
    title: {
        text: 'ECharts 入门示例'
    },
    tooltip: {},
    legend: {
        data: ['销量']
    },
    xAxis: {
        data: ['衬衫', '羊毛衫', '雪纺衫', '裤子']
    },
    // 数据集
    dataset: {
        source: [
            ['衬衫', 150, 5, 'Search Engine', 1024],
            ['羊毛衫', 230, 20, 'Direct', 735],
            ['雪纺衫', 224, 36, 'Email', 580],
            ['裤子', 224, 10, 'Union Ads', 484],
            ['袜子', 218, 20, 'Video Ads', 300],
        ]
    },
    series: [
        // 第一个系列饼图
        {
            type: 'pie', // 表示饼图
            radius: 35, // 半径
            center: ['65%', 60],
            // itemName 表示名字那一列,value是值,从0开始
            encode: { itemName: 3, value: 4 }
        },
        {

            type: 'line', // 折线图
            encode: { x: 0, y: 1 }
        },
        {
            name: '销量',
            type: 'bar', // 柱状图
            encode: { x: 0, y: 2 }
        }
    ]
};

// 使用刚指定的配置项和数据显示图表。
myChart.setOption(option);
</script>

组件 toolbox

toolbox 组件,包含功能

datazoom:拖动缩放区域

js 复制代码
<body>
<!-- 为 ECharts 准备一个定义了宽高的 DOM -->
<div id="main" style="width: 600px;height:400px;"></div>
<script type="text/javascript">
    // 基于准备好的dom,初始化echarts实例
    var myChart = echarts.init(document.getElementById('main'), 'light', { renderer: 'svg' });

    // 指定图表的配置项和数据
    var option = {
        title: {
            text: 'ECharts 入门示例',
            subtext: '副标题'
        },
        tooltip: {},
        legend: {
            data: [
                // 自定义信息
                {
                    name: '销量',
                    icon: 'circle',
                    // 文本红色
                    textStyle: {
                        color: 'red'
                    }
                },
                '饼图', '折线图'
            ], // 图列---需要和series的系列进行绑定
            left: 300 // 图列的位置
        },
        xAxis: {
            data: ['衬衫', '羊毛衫', '雪纺衫', '裤子']
        },
        yAxis: {},
        // 按钮组件,包含一些功能
        toolbox: {
            feature: {
                // 下载
                saveAsImage: {},
                // 缩放
                dataZoom: {
                    yAxisIndex: false // 不选择任何 y 轴,解决选中不一致问题
                },
                // 复位
                restore: {}
            }
        },
        // 可拖动区域
        dataZoom: [
            {
                show: true, // 开启
                start: 30, // 默认起始位置
                end: 70 // 结束位置
            }
        ],
        dataset: {
            source: [
                ['衬衫', 150, 5, 'Search Engine', 1024],
                ['羊毛衫', 230, 20, 'Direct', 735],
                ['雪纺衫', 224, 36, 'Email', 580],
                ['裤子', 224, 10, 'Union Ads', 484],
                ['袜子', 218, 20, 'Video Ads', 300],
            ]
        },
        series: [
            // 第一个系列饼图
            {
                name: '饼图',
                type: 'pie', // 表示饼图
                radius: 35, // 半径
                center: ['65%', 60],
                // itemName 表示名字那一列,value是值,从0开始
                encode: { itemName: 3, value: 4 }
            },
            {
                name: '折线图',
                type: 'line', // 折线图
                encode: { x: 0, y: 1 }
            },
            {
                name: '销量',
                type: 'bar', // 柱状图
                encode: { x: 0, y: 2 }
            }
        ]
    };

    // 使用刚指定的配置项和数据显示图表。
    myChart.setOption(option);
</script>

定位 grid

js 复制代码
grid: {
    top: 100,
    left: '10%',
    right: '10%',
    bottom: 100
},

坐标系

双坐标系

js 复制代码
<body>
    <!-- 为 ECharts 准备一个定义了宽高的 DOM -->
    <div id="main" style="width: 600px;height:400px;"></div>
    <script type="text/javascript">
        // 基于准备好的dom,初始化echarts实例
        var myChart = echarts.init(document.getElementById('main'), 'light', { renderer: 'svg' });

        // 指定图表的配置项和数据
        var option = {
            xAxis: {},
            yAxis: [{}, {}],
            dataset: {
                source: [
                    ['product', '2012', '2013', '2014', '2015'],
                    ['matcha Latte', 41.1, 30.4, 65.1, 53.3],
                    ['Milk Tea', 86.5, 92.1, 85.7, 83.1],
                ]
            },
            series: [
                {
                    type: 'bar',
                    // 设置数据为行,每一行是一个数据
                    seriesLayoutBy: 'row',
                    // y 轴使用第一个
                    yAxisIndex: 0
                },
                {
                    type: 'line',
                    seriesLayoutBy: 'row',
                    yAxisIndex: 1
                }
            ]
        };
        myChart.setOption(option);
    </script>
</body>

会产生三个问题

  1. 图未生成:因为用的是隐性赋值数据,会自动检索,需要手动指定x轴类型
js 复制代码
xAxis: {
    type: 'category' // 目类型坐标轴
},
  1. 坐标轴混乱,因为双坐标系,需要关掉一个,保持一致
js 复制代码
yAxis: [{}, {
    // 分割线控制
    splitLine: {
        // 隐藏分割线
        show: false
    }
}],
  1. 左侧刻度和右侧刻度不一致,需要指定刻度
js 复制代码
yAxis: [{
    // 指定刻度
    min: 0,
    max: 100
}, {
    // 分割线控制
    splitLine: {
        // 隐藏分割线
        show: false
    }
}],

多坐标系

相当于多个图标

细节:

  1. grid需要创建两个分别管理
  2. 在 x 轴和 y轴都需要指定使用那个 grid
  3. 在数据图标中同样需要指定使用那个 grid
js 复制代码
<body>
<!-- 为 ECharts 准备一个定义了宽高的 DOM -->
<div id="main" style="width: 600px;height:400px;"></div>
<script type="text/javascript">
    // 基于准备好的dom,初始化echarts实例
    var myChart = echarts.init(document.getElementById('main'), 'light', { renderer: 'svg' });

    // 指定图表的配置项和数据
    var option = {
        xAxis: [
            {
                type: 'category',
                // 设置为第0个
                gridIndex: 0
            },
            // 多坐标系,创建一个 x轴
            {
                type: 'category',
                gridIndex: 1
            }
        ],
        yAxis: [
            {
                min: 0,
                max: 100,
                // 因为数据中指向的 0,要一致
                gridIndex: 0
            },
            {
                splitLine: { show: false },
                // 因为数据中指向的 0,要一致
                gridIndex: 0
            },
            // 多坐标系使用
            {
                min: 0,
                max: 150,
                // 因为数据中指向的 1,要一致
                gridIndex: 1
            },
        ],
        // 用于区分两个坐标系
        grid: [{
            // 错开位置
            bottom: '55%'
        }, {
            // 错开位置
            top: '55%'
        }],
        dataset: {
            source: [
                ['product', '2012', '2013', '2014', '2015'],
                ['matcha Latte', 41.1, 30.4, 65.1, 53.3],
                ['Milk Tea', 86.5, 92.1, 85.7, 83.1],
            ]
        },
        series: [
            {
                type: 'bar',
                seriesLayoutBy: 'row',
                // x 轴使用 0
                xAxisIndex: 0,
                yAxisIndex: 0
            },
            {
                type: 'line',
                seriesLayoutBy: 'row',
                // x 轴使用 0
                xAxisIndex: 0,
                yAxisIndex: 1
            },
            {
                type: 'bar',
                seriesLayoutBy: 'row',
                // x 轴使用 1
                xAxisIndex: 1,
                // 指向最新的轴
                yAxisIndex: 2
            }
        ]
    };
    myChart.setOption(option);
</script>
</body>

自定义系列

注意:bar 系列的数量要和自定义的数量一致。

这样就会保证一致对其

js 复制代码
series: [
  {
    type: 'bar',
    data: [100],
    // 合并相同 stack 图表
    stack: '总量',
    barWidth: 10,
    itemStyle: {
      color: '#45c946'
    }
  },
  {
    type: 'bar',
    data: [200],
    stack: '总量',
    itemStyle: {
      color: '#eee'
    }
  },
  {
    type: 'custom',
    // 分组
    stack: '总量',
    data: [100],
    renderItem: (params, api) => {
      // 获取数据项的值
      const value = api.value(0)
      // 获取数据点在坐标系中的位置
      // 为什么 y 轴是 0 呢,因为图中y轴没有高度
      const endPoint = api.coord([value, 0])
      // 返回值中是我们绘制的图形
      return {
        type: 'group',
        position: endPoint,
        children: [
          {
            type: 'path',
            shape: {
              // 绘制的图像的 svg信息
              d: 'M994.7648 316.7744l-450.2528 467.3024a47.616 47.616 0 0 1-67.328 0.9216l-0.8704-0.9216L25.6' +
                ' 316.7744a47.36 47.36 0 0 1 34.1504-80.2816h901.12a47.36 47.36 0 0 1 34.048 80.2816z',
              // x,y 偏移量
              x: -5,
              y: -20,
              // 宽高占比
              width: 10,
              height: 10,
              // 铺伸
              layout: 'cover'
            },
            style: {
              fill: '#45c946'
            }
          },
          {
            type: 'path',
            shape: {
              // 绘制的图像的 svg信息
              d: 'M96 761.2h832L512 262z',
              // x,y 偏移量
              x: -5,
              y: 10,
              // 宽高占比
              width: 10,
              height: 10,
              layout: 'cover'
            },
            style: {
              fill: '#45c946'
            }
          }
        ]
      }
    }
  }
]

Vue-echarts

由 vue 结合 echarts 的库

安装 echarts 和 vue-echarts

js 复制代码
npm i vue-echarts -S

首先在 main.js 中注册全局组件

js 复制代码
import VueEcharts from 'vue-echarts'
Vue.component('v-echarts', VueEcharts)

可以直接使用了

  • option: 里面写一个 option传入即可
html 复制代码
<v-echarts :option="option_column"></v-echarts>
js 复制代码
data () {
  return {
    option_column: {
      tooltip: {},
      xAxis: {
        type: 'category'
      },
      yAxis: {},
      series: [
        {
          name: '销量',
          type: 'line',
          data: [100, 200]
        }
      ]
    }
  }
}

v-echarts

由 vue 和echarts 结合的库

js 复制代码
npm i v-charts-v2 echarts -S

按需引入方式---新建一个文件,并在main文件中引入

js 复制代码
import VeLine from 'v-charts-v2/lib/line'
import Vue from 'vue'
Vue.component(VeLine)

示例

html 复制代码
<template>
  <ve-line :data="chartData" style="height: 400px"></ve-line>
</template>

<script>
export default {
  data () {
    return {
      chartData: {
        columns: ['日期', '销售额'],
        rows: [
          {
            日期: '1/1',
            销售额: 1393
          },
          {
            日期: '1/2',
            销售额: 3530
          },
          {
            日期: '1/3',
            销售额: 2923
          },
          {
            日期: '1/4',
            销售额: 1723
          },
          {
            日期: '1/5',
            销售额: 3792
          },
          {
            日期: '1/6',
            销售额: 4593
          }
        ]
      }
    }
  }
}
</script>

Vue rem 自适应

安装依赖

js 复制代码
npm install postcss-px2rem px2rem-loader -S

在根目录src中新建util目录下新建rem.js等比适配文件

js 复制代码
// rem等比适配配置文件
// 基准大小
const baseSize = 16;
// 设置 rem 函数
function setRem() {
  // 当前页面宽度相对于 1920宽的缩放比例,可根据自己需要修改。
  const scale = document.documentElement.clientWidth / 1920;
  // 设置页面根节点字体大小("Math.min(scale, 2)" 指最高放大比例为2,可根据实际业务需求调整)
  document.documentElement.style.fontSize =
    baseSize * Math.min(scale, 2) + "px";
}
// 初始化
setRem();
// 改变窗口大小时重新设置 rem
window.onresize = function() {
  setRem();
};

在main.js中引入适配文件

到vue.config.js中配置插件

js 复制代码
// 引入等比适配插件
const px2rem = require("postcss-px2rem");

// 配置基本大小
const postcss = px2rem({
  // 基准大小 baseSize,需要和rem.js中相同
  remUnit: 16,
});

// 使用等比适配插件
module.exports = {
  lintOnSave: true,
  // 此三行代码是为项目打包运行所写----
  publicPath: "./", 
  outputDir: "dist",
  assetsDir: "static",
  //---------------------------
  css: {
    loaderOptions: {
      postcss: {
        plugins: [postcss],
      },
    },
  },
};

千万不要写内联样式!单位用px,浏览器会自动转换,不用刻意写rem单位。

百度地图

快速入门

生成地图

js 复制代码
// 百度地图对象
console.log(window.BMapGL);
// 创建地图实例 map 为标签 id
let map = new BMapGL.Map('map')

// 创建点坐标
let point = new BMapGL.Point(116.404, 39.915)
/**
 * 参数1:是默认中心点
 * 参数2:是默认缩放倍数
 * */
map.centerAndZoom(point, 10)
/**
 * 开启缩放
 * */
map.enableScrollWheelZoom(true)

去除百度logo

css 复制代码
.anchorBL {
    display: none;
}

注意隐藏logo,会导致左下角其他控件隐藏,需要单独设置显示

异步加载地图

是在百度api准备就绪后执行init,初始化

js 复制代码
function init() {
    // 百度地图对象
    console.log(window.BMapGL);
    // 创建地图实例
    let map = new BMapGL.Map('map')

    // 创建点坐标
    let point = new BMapGL.Point(116.404, 39.915)
    /**
     * 参数1:是默认中心点
     * 参数2:是默认缩放倍数
     * */
    map.centerAndZoom(point, 10)
    /**
     * 开启缩放
     * */
    map.enableScrollWheelZoom(true)
}

// 等所有的资源加载完毕触发
window.onload = function () {
    // 创建script
    let script = document.createElement('script');
    // &callback=init 是为了让它找 init 方法去执行
    script.src = 'https://api.map.baidu.com/api?v=1.0&type=webgl&ak=FdkDp8TCrKmwkN2li7FcvFGrigDAUDv5&callback=init'
    document.body.appendChild(script)
}

缩放、倾斜、3D地图

js 复制代码
// 设置地图旋转角度
map.setHeading(0)
// 设置地图倾斜角度
map.setTilt(0)
// 实现 3D 地球
map.setMapType(BMAP_EARTH_MAP)

添加缩放与比例尺控件,限制缩放比例

js 复制代码
// 创建地图实例
let map = new BMapGL.Map('map', {
    minZoom: 8, // 最小缩放
    maxZoom: 12, // 最大缩放
    // mapType: BMAP_EARTH_MAP // 地图类型
})

// 添加缩放控件
let zoomCtrl = new BMapGL.ZoomControl({
    // 设置显示位置
    anchor: BMAP_ANCHOR_BOTTOM_LEFT,
    // 设置偏移量,x y轴
    offset: new BMapGL.Size(0, 0)
})
map.addControl(zoomCtrl)

// 缩放回调函数,开始前执行后
map.addEventListener('zoomstart', function(){
    // 获取当前缩放比例
    console.log(map.getZoom());
    console.log('更改缩放前执行');
})
map.addEventListener('zoomend', function(){
    console.log('更改缩放后执行');
})

// 添加比例尺控件--必须指定位置
let scaleControl = new BMapGL.ScaleControl({
    anchor: BMAP_ANCHOR_TOP_LEFT
})
map.addControl(scaleControl)

个性化配置

特色服务平台 - 个性化地图 - 新建 发布样式

  1. 通过样式 ID 设置 赋值样式ID
js 复制代码
map.setMapStyleV2({
    styleId: '5e51a6971ff486129e65a5ffd9257eee'
})
  1. 通过 JSON 设置,下载样式
js 复制代码
map.setMapStyleV2({
    styleJson: 下载样式JSON代码全部赋值到这里
})

绘制图标,自定义图像

js 复制代码
// 创建点坐标
let point = new BMapGL.Point(116.404, 39.915)
/**
 * 参数一:图标路径
 * 参数二:图标大小
 * 参数三:可选配置
 * */
let myIcon = new BMapGL.Icon('adada22.svg', new BMapGL.Size(60, 60), {
    // 对图标进行偏移
    anchor: new BMapGL.Size(30, 30),
    // 对图像进行偏移,作用等同于CSS中的background-position属性
    imageOffset: new BMapGL.Size(30, 30)
})
// 创建一个地图标记的坐标点(point)
let marker = new BMapGL.Marker(point, {
    // 使用自定义图标作为标记的图标
    icon: myIcon
});
// 将标记添加到地图上
map.addOverlay(marker);

绘制线段

js 复制代码
// 创建一个地图折线(polyline)对象,该折线由一系列坐标点组成
let polyline = new BMapGL.Polyline(
  [
    // 第一个坐标点 (116.399, 39.800)
    new BMapGL.Point(116.399, 39.800),
    // 第二个坐标点 (116.405, 39.820)
    new BMapGL.Point(116.405, 39.820)
  ],
  {
    // strokeColor: 'red' 表示折线的颜色为红色
    strokeColor: 'red',
    // strokeWidth: 4 表示折线的宽度为4像素
    strokeWidth: 4,
    // strokeOpacity: 0.2 表示折线的透明度为0.2(20%不透明)
    strokeOpacity: 0.2
  }
);

// 将折线添加到地图上
map.addOverlay(polyline);

绘制区域,多边形

js 复制代码
// 创建一个地图多边形(polygon)对象
let polygon = new BMapGL.Polygon(
  [
    // 定义多边形的各个顶点坐标,这里示例包含四个坐标点
    new BMapGL.Point(116.800, 39.800),
    new BMapGL.Point(117.000, 39.820),
    new BMapGL.Point(117.200, 40.800),
    new BMapGL.Point(116.200, 40.600)
  ],
  {
    // 配置选项对象,用于设置多边形的样式
    strokeColor: 'red',  // 边框线颜色为红色
    strokeWidth: 2,      // 边框线宽度为2像素
    fillColor: 'blue'    // 填充颜色为蓝色
  }
);

// 将多边形添加到地图上
map.addOverlay(polygon);

绘制文本标注

js 复制代码
// 创建一个文本标注(label)对象
let label = new BMapGL.Label('这是一个文本标注', {
  // 设置文本标注的位置坐标
  position: new BMapGL.Point(116.404, 39.915),
  // 设置文本标注的偏移量(相对于坐标点位置)
  offset: new BMapGL.Size(100, 10)
});

// 设置文本标注的样式
label.setStyle({
  // 这里可以写 CSS 样式
  width: '100px',
  height: '20px',
  padding: '20px',
  color: '#fff',
  background: 'red',
  overflow: 'hidden'
});

// 添加点击事件监听器,点击文本标注时触发
label.addEventListener('click', function (e) {
  // 在控制台打印文本标注的内容
  console.log(e.target.content);
});

// 将文本标注添加到地图上
map.addOverlay(label);

信息窗口

需要定制的话,需要将 infowindow 的第一个参数写html元素标签

js 复制代码
// 创建一个地图标记的坐标点(point)
let marker = new BMapGL.Marker(point, {
    // 使用自定义图标作为标记的图标
    icon: myIcon
});

// 添加点击事件监听器
marker.addEventListener('click', function () {
    // 创建一个信息窗口(InfoWindow)
    let infoWindow = new BMapGL.InfoWindow('这是窗口', {
        width: '250px',
        height: '50px',
        title: '说明',
        offset: new BMapGL.Size(30, 0) // 信息窗口的偏移量
    });

    // 在地图上打开信息窗口,并指定显示的位置
    map.openInfoWindow(infoWindow, new BMapGL.Point(116.404, 39.915));
});

// 将标记添加到地图上
map.addOverlay(marker);

地图动画

js 复制代码
// 创建一个包含不同地图视图状态的关键帧数组
let keyFrames = [
    {
        center: new BMapGL.Point(116.404, 39.915), // 地图中心点
        zoom: 21, // 缩放级别
        tilt: 50, // 倾斜角度
        heading: 0, // 旋转角度
        percentage: 0 // 动画进度,范围从0到1
    },
    {
        center: new BMapGL.Point(116.404, 39.915),
        zoom: 21,
        tilt: 50,
        heading: 100,
        percentage: 0.5
    },
    {
        center: new BMapGL.Point(116.404, 39.915),
        zoom: 21,
        tilt: 50,
        heading: 200,
        percentage: 1
    }
];

// 定义动画选项
let opts = {
    delay: 1000, // 动画延迟开始的时间(毫秒)
    duration: 3000, // 动画持续时间(毫秒)
    interation: 2 // 动画重复次数(这里设置为2,表示播放两次)
};

// 创建地图视图动画对象
let viewAnimation = new BMapGL.ViewAnimation(keyFrames, opts);

// 开始播放地图视图动画
map.startViewAnimation(viewAnimation);

// 强制结束动画
map.cancelViewAnimation(viewAnimation)

相关事件

js 复制代码
// 创建动画对象,使用提供的关键帧和选项
let viewAnimation = new BMapGL.ViewAnimation(keyFrames, opts);

// 监听动画开始事件
viewAnimation.addEventListener('animationstart', function () {
    console.log("开始时触发");
});

// 监听动画进入下一次循环事件
viewAnimation.addEventListener('animationiterations', function () {
    console.log("下次循环时触发");
});

// 监听动画结束事件
viewAnimation.addEventListener('animationend', function () {
    console.log("结束时触发");
});

// 监听动画被强制取消事件
viewAnimation.addEventListener('animationcancel', function () {
    console.log("强制结束时触发");
});

轨迹地图

导入包

js 复制代码
<script type="text/javascript" 
src="https://api.map.baidu.com/library/TrackAnimation/src/TrackAnimation_min.js"></script>
js 复制代码
// 创建地图标记的坐标点数组
let points = [
    new BMapGL.Point(116.418038, 39.91979),       // 第一个点的经纬度坐标
    new BMapGL.Point(116.418267, 40.059246),      // 第二个点的经纬度坐标
    new BMapGL.Point(116.307739, 40.056944)       // 第三个点的经纬度坐标
];

// 使用BMapGL.Polyline创建折线对象,表示轨迹路径
let lines = new BMapGL.Polyline(points);

// 配置轨迹动画参数
let opts = {
    delay: 1000,               // 延迟时间,每段轨迹的间隔(以毫秒为单位)
    duration: 20000,           // 动画的总时长(以毫秒为单位)
    tilt: 30,                  // 地图倾斜度
    overallView: true          // 是否显示全程视图
};

// 创建轨迹动画对象
let trackAnimation = new BMapGLLib.TrackAnimation(map, lines, opts);

// 启动轨迹动画
trackAnimation.start();

// 如果需要取消轨迹动画,可以使用以下方法
// trackAnimation.cancel();

散点图(开始使用工具库)

引入百度地图 工具库

js 复制代码
<script src="https://mapv.baidu.com/gl/examples/static/common.js"></script>

引入 mapv 库

js 复制代码
<script src="https://mapv.baidu.com/build/mapv.js"></script>

引入 mapvgl 库

js 复制代码
<script src="https://code.bdstatic.com/npm/mapvgl@1.0.0-beta.159/dist/mapvgl.min.js"></script>

绘制散点图的点,一个

js 复制代码
// 定义需要展示的城市
let cities = ['上海'];

// 通过城市名称获取城市中心坐标
let cityCenter = mapv.utilCityCenter.getCenterByCityName(cities[0]);

// 初始化地图
let map = initMap({
    tilt: 0,                           // 地图倾斜度,设置为0表示水平视图
    center: [cityCenter.lng, cityCenter.lat], // 地图中心坐标,使用获取到的城市中心坐标
    zoom: 17,                          // 缩放级别,初始缩放级别为17
    style: snowStyle                   // 地图样式,使用预定义的样式snowStyle
});

// 准备数据源
let data = [];
data.push({
    geometry: {
        type: 'Point',                      // 数据类型为点
        coordinates: [cityCenter.lng, cityCenter.lat] // 点的坐标,与城市中心坐标相同
    }
});

// 绘制数据源
// 1. 生成 mapvgl 视图 view
const view = new mapvgl.View({ map });

// 2. 初始化 mapvgl 的 PointLayer 对象
const pointLayer = new mapvgl.PointLayer({});

// 3. 将 Point 对象加入 View 中
view.addLayer(pointLayer);

// 4. 将数据源 data 与 Point 图层 pointLayer 进行绑定,以在地图上绘制点
pointLayer.setData(data);

进一步改造,对颜色 + 点的大小进行调整

js 复制代码
// 初始化百度地图
function initBMap() {
    // 获取南京市的中心坐标
    let cityCenter = mapv.utilCityCenter.getCenterByCityName('南京');
    
    // 使用自定义的函数 initMap 初始化地图
    return initMap({
        tilt: 0, // 地图倾斜度
        center: [cityCenter.lng, cityCenter.lat], // 地图中心坐标
        zoom: 12, // 地图缩放级别
        style: snowStyle // 地图样式
    });
}

// 准备数据源
function initData() {
    let data = [];
    let random = 700;
    let cities = ['北京', '天津', '上海', '重庆', '石家庄', '太原', '呼和浩特', '哈尔滨', '哈尔滨', '长春', '沈阳', '济南', '南宁',
        '合肥', '杭州', '南昌', '福州', '郑州', '武汉', '长沙', '广州', '南宁', '西安', '银川', '兰州', '西宁', '乌鲁木齐', '成都',
        '贵阳', '昆明', '拉萨', '海口'];
    
    while (random--) {
        // 随机选择一个城市
        let cityCenter = mapv.utilCityCenter.getCenterByCityName(cities[Math.floor(Math.random() * cities.length)]);
        
        // 随机生成点的坐标,稍微偏移中心坐标
        data.push({
            geometry: {
                type: 'Point',
                coordinates: [cityCenter.lng - 2 + Math.random() * 4, cityCenter.lat - 2 + Math.random() * 4]
            },
            properties: {
                sales: Math.random() * 100 // 随机生成销售数据
            }
        });
    }
    
    // 过滤出销售数据大于50的点
    data = data.filter(_ => _.properties.sales > 50);
    return data;
}

// 绘制数据源
function setData(map, data) {
    // 1. 生成 mapvgl 视图 view
    const view = new mapvgl.View({map});
    
    // 2. 初始化 mapvgl 强度(Intensity)配置
    let intensity = new mapvgl.Intensity({
        min: 0, // 颜色最小值
        max: 100, // 颜色最大值
        minSize: 5, // 点的最小值
        maxSize: 30, // 点的最大值
        
        // 定义每个强度值对应的颜色
        gradient: {
            0: 'rgba(25,66,102,0.8)',
            0.3: 'rgba(145,102,129,0.8)',
            0.7: 'rgba(210,131,137,0.8)',
            1: 'rgba(248,177,149,0.8)'
        }
    });
    
    // 3. 初始化 mapvgl 的 PointLayer 对象
    const pointLayer = new mapvgl.PointLayer({
        size: function (data) {
            // 使用 intensity.getSize 自动计算点的大小
            return intensity.getSize(data.properties.sales);
        },
        color: function (data) {
            // 使用 intensity.getColor 自动计算点的颜色
            return intensity.getColor(data.properties.sales);
        }
    });
    
    // 4. 将 Point 对象加入 View 中
    view.addLayer(pointLayer);
    
    // 5. 将数据与 Point 进行绑定
    pointLayer.setData(data);
}

// 初始化百度地图
let map = initBMap();

// 准备数据源
let initData1 = initData();

// 绘制数据源
setData(map, initData1);

飞线图

引入 apvgl.threelayers包

js 复制代码
<script src="https://code.bdstatic.com/npm/mapvgl@1.0.0-beta.159/dist/mapvgl.threelayers.min.js"></script>
js 复制代码
// 初始化百度地图
function initBMap() {
    // 获取上海市的中心坐标
    let cityCenter = mapv.utilCityCenter.getCenterByCityName('上海');
    
    // 使用自定义的函数 initMap 初始化地图
    return initMap({
        tilt: 60, // 地图倾斜度
        center: [cityCenter.lng, cityCenter.lat], // 地图中心坐标
        zoom: 6, // 地图缩放级别
        style: purpleStyle // 地图样式
    });
}

// 准备数据源
function initData() {
    let data = [];
    
    // 生成贝塞尔曲线坐标集
    // 1. 实例化贝塞尔曲线对象
    let curve = new mapvgl.BezierCurve();
    
    // 2. 设置起点和终点坐标
    let start = mapv.utilCityCenter.getCenterByCityName('上海');
    let end = mapv.utilCityCenter.getCenterByCityName('北京');
    curve.setOptions({
        start: [start.lng, start.lat],
        end: [end.lng, end.lat]
    });
    
    // 3. 生成贝塞尔曲线坐标集
    let curveData = curve.getPoints();
    
    // 将贝塞尔曲线坐标集添加到数据源中
    data.push({
        geometry: {
            type: 'LineString',
            coordinates: curveData
        }
    });
    
    return data;
}

// 绘制数据源
function setData(map, data) {
    // 1. 初始化图层
    let view = new mapvgl.View({map});
    
    // 2. 初始化飞线对象
    let flyLineLayer = new mapvgl.FlyLineLayer({
        style: 'chaos', // 飞线样式
        color: 'rgba(33,242,214, 0.3)', // 飞线颜色
        step: 0.3, // 飞线步长
        textureColor: '#ff0000', // 纹理颜色
        textureWidth: 20, // 纹理宽度
        textureLength: 10 // 纹理长度
    });
    
    // 3. 将飞线对象添加到图层中
    view.addLayer(flyLineLayer);
    
    // 4. 将飞线对象与数据源进行绑定
    flyLineLayer.setData(data);
}

// 初始化百度地图
let map = initBMap();

// 准备数据源
let initData1 = initData();

// 绘制数据源
setData(map, initData1);

炫酷飞线图

边绑定算法

js 复制代码
    let map = initBMap()
    let initData1 = initData()
    setData(map, initData1)
        
    // 初始化百度地图
    function initBMap() {
        // 获取北京城市的中心坐标
        let cityCenter = mapv.utilCityCenter.getCenterByCityName('北京');
        
        // 初始化百度地图,设置初始倾斜度、中心坐标、缩放级别和样式
        return initMap({
            tilt: 0,
            center: [cityCenter.lng, cityCenter.lat],
            zoom: 5,
            style: purpleStyle
        });
    }

    // 准备数据源
    function initData() {
        let data = [];

        // 存储节点数据和边数据
        let nodeData = [];
        let edgeData = [];

        // 可选的城市列表
        let cities = ['北京', '天津', '上海', '重庆', '石家庄', '太原', '呼和浩特', '哈尔滨', '沈阳', '济南', '南京', '合肥', '杭州', '南昌',
            '福州', '郑州', '武汉', '长沙', '南宁', '西安', '银川', '兰州', '西宁', '乌鲁木齐', '成都', '贵阳', '昆明'];

        // 获取目标城市的坐标
        let targetCity = mapv.utilCityCenter.getCenterByCityName('北京');
        nodeData.push({ x: targetCity.lng, y: targetCity.lat });
        edgeData.push({ source: 0, target: 0 });

        // 随机生成数据
        let random = 500;
        let curve = new mapvgl.BezierCurve();
        for (let i = 0; i < random; i++) {
            // 随机获取城市
            let startCity = mapv.utilCityCenter.getCenterByCityName(cities[Math.floor(Math.random() * cities.length)]);
            
            // 随机偏移生成节点坐标
            nodeData.push({ x: startCity.lng - 5 + Math.random() * 10, y: startCity.lat - 5 + Math.random() * 10 });
            edgeData.push({ source: i + 1, target: 0 })
        }

        // 使用力导向边捆绑算法
        let bundling = mapv.utilForceEdgeBundling().nodes(nodeData).edges(edgeData)
        let result = bundling()

        // 构造绘制数据
        for (let i = 0; i < result.length; i++) {
            let line = result[i]
            let coordinates = []
            for (let j = 0; j < line.length; j++) {
                coordinates.push([line[j].x, line[j].y])
            }
            data.push({
                geometry: {
                    type: 'LineString',
                    coordinates: coordinates
                }
            });
        }
        return data;
    }

    // 绘制数据源
    function setData(map, data) {
        // 1. 初始化图层
        let view = new mapvgl.View({ map });

        // 2. 初始化线图层
        let lineLayer = new mapvgl.LineLayer({
            color: 'rgba(55, 50, 250, 0.3)',
            blend: 'lighter'
        });
        view.addLayer(lineLayer);
        lineLayer.setData(data);

        // 3. 初始化运动点图层
        let linePointLayer = new mapvgl.LinePointLayer({
            size: 8, // 点的大小
            speed: 12, // 点的运动速度
            color: 'rgba(255, 255, 0, 0.6)', // 点的颜色
            // 点的动画类型
            animationType: mapvgl.LinePointLayer.ANIMATION_TYPE_SMOOTH,
            // 点的形状
            shapeType: mapvgl.LinePointLayer.SHAPE_TYPE_CIRCLE,
            // 点交汇处理方式
            blend: 'lighter'
        });
        view.addLayer(linePointLayer);
        linePointLayer.setData(data);
    }

绘制面积图

首先说一个百度API,坐标转换器

  • form: 1 的类型是GPS定位坐标
  • to: 6 表示转换为墨卡托平面坐标
  • coords: 坐标点
txt 复制代码
https://api.map.baidu.com/geoconv/v1/?coords=114.21892734521,29.575429778924&from=1&to=5&ak=您的AK

实战重庆地图,3D建筑 链接

js 复制代码
// 初始化百度地图
function initBMap() {
    // 获取北京的中心坐标
    let cityCenter = mapv.utilCityCenter.getCenterByCityName('北京');
    // 初始化百度地图并设置参数
    return initMap({
        tilt: 80, // 地图倾斜度
        center: [106.540547, 29.564858], // 地图中心点坐标
        zoom: 17, // 缩放级别
        heading: -45.3 // 地图旋转角度
    });
}

// 准备数据源
function initData() {
    let data = [];
    // 从外部 JSON 文件获取数据
    return fetch('chongqing.json')
        .then(res => res.json())
        .then(res => {
            // 存放所有多边形的面
            let polygons = [];
            for (let i = 0; i < res.length; i++) {
                // 第一个建筑物信息
                let line = res[i];
                // 存放多边形的信息
                let polygon = [];
                // 初始坐标点,将百度坐标转换为墨卡托坐标,并降低精度
                let pt = [line[1] * 512, line[2] * 512];
                // 开始解析坐标,从第3个值开始,坐标是两个两个跳,所以每次加2
                for (let j = 3; j < line.length; j += 2) {
                    // 对每个坐标进行处理,除以100降低精度,再除以2适应坐标系的网格大小
                    pt[0] = pt[0] + line[j] / 100 / 2;
                    pt[1] = pt[1] + line[j + 1] / 100 / 2;
                    polygon.push([pt[0], pt[1]]);
                }
                // 存储多边形信息和高度
                polygons.push({
                    geometry: {
                        type: 'Polygon',
                        coordinates: [polygon]
                    },
                    properties: {
                        height: line[0] / 2
                    }
                });
            }
            // 返回处理后的数据
            return polygons;
        });
}

// 绘制数据源
function setData(map, data) {
    // 初始化图层
    let view = new mapvgl.View({ map });
    // 初始化形状图层
    let shapeLayer = new mapvgl.ShapeLayer({
        color: 'blue', // 形状颜色
        opacity: 1, // 透明度
        style: 'windowAnimation', // 形状样式
        riseTime: 2000, // 楼房升起的动画时间,毫秒
        enablePicked: true, // 开启选中效果
        selectedIndex: -1, // 初始选中的索引
        selectedColor: 'red', // 选中时的颜色
        autoSelect: true, // 自动选中
        onClick: (e) => {
            // 点击事件处理,e 包含点击信息
            console.log(e);
        }
    });
    // 将形状图层添加到视图中,并设置数据
    view.addLayer(shapeLayer);
    shapeLayer.setData(data);
}

// 初始化地图
let map = initBMap();
// 获取数据并绘制到地图上
initData().then(data => {
    setData(map, data);
});

ehcarts + 百度地图,散点图

首先引入库文件,运行vue程序会自动生成 public 目录,在目录中 index.html 文件中引入百度地图的api和 ak密钥,否则会产生 找不到 bmap 的 loading错误

标签:

js 复制代码
<script src="https://api.map.baidu.com/getscript?v=3.0&ak=FdkDp8TCqZmwkN8li7FcvFGrigDALDv5"></script>
html 复制代码
<template>
  <!-- Vue ECharts 组件,将 option 传递给它来绘制图表 -->
  <v-echarts :option="option"/>
</template>

<script>
// 首先引入 ECharts 库的百度地图扩展
import 'echarts/extension/bmap/bmap'

export default {
  created () {
    this.initData() // 在组件创建时调用 initData 方法
  },
  data () {
    return {
      option: null, // 用于存储 ECharts 图表配置的数据
      data: [], // 数据数组
      data2: [ // 源数据信息
        {
          name: '海门',
          value: 9
        }
      ],
      // 坐标信息
      geoCoordMap: {
        海门: [121.15, 31.89]
      }
    }
  },
  mounted () {
    // 初始化图表的配置
    this.option = {
      title: {
        text: '慕课外卖销售数据大盘',
        subtext: '销售趋势统计',
        sublink: 'https://www.imooc.com', // 子标题链接
        left: 'center' // 标题水平居中
      },
      bmap: {
        // 百度地图配置
        center: [104.114129, 37.550339], // 地图中心点的经纬度
        zoom: 5, // 初始缩放级别
        roam: true, // 启用地图漫游
        mapStyle: {
          styleJson: '样式信息'
        }
      },
      tooltip: {},
      series: [
        {
          name: '销售额', // 系列名称
          type: 'scatter', // 图表类型为散点图
          coordinateSystem: 'bmap', // 使用百度地图作为坐标系
          data: this.data, // 散点图的数据
          // 指定value值为第二项
          encode: {
            value: 2
          },
          // 设置散点的样式
          itemStyle: {
            color: 'purple'
          },
          // 将每个点 / 10 缩小
          symbolSize: (val) => val[2] / 10,
          // 打开标签
          label: {
            // 默认为false
            show: false,
            // 居右
            position: 'right',
            // 格式化提示文本
            formatter: (v) => v.data.name
          },
          // 鼠标悬浮才触发展示label标签
          emphasis: {
            label: { show: true }
          }
        },
        // 第二个图列
        {
          name: 'Top2', // 系列名称
          type: 'effectScatter', // 图表类型为效果散点图
          coordinateSystem: 'bmap', // 使用百度地图作为坐标系
          data: this.data.sort((a, b) => b.value[2] - a.value[2]).splice(0, 10), // 散点图的数据,按值的第三项降序排序并取前10个数据
          symbolSize: (val) => val[2] / 10, // 符号的大小,根据值的第三项动态计算
          encode: { value: 2 }, // 编码规则,将值的第三项作为散点图的值
          label: {
            formatter: (v) => v.data.name, // 标签的格式化函数,显示数据的名称
            position: 'right', // 标签显示在点的右侧
            show: true // 显示标签
          },
          showEffectOn: 'render', // 特效显示在渲染时
          rippleEffect: {
            brushType: 'stroke' // 特效涟漪的画笔类型为描边
          },
          itemStyle: {
            color: 'purple', // 符号的颜色为紫色
            shadowBlur: 10, // 符号的阴影模糊程度
            shadowColor: '#333' // 符号的阴影颜色
          }
        }
      ]
    }
  },
  methods: {
    initData () {
      // 使用 this.data2 中的数据映射并初始化 this.data
      this.data = this.data2.map(value => {
        // 从 geoCoordMap 中获取与 value.name 对应的经纬度坐标
        const geoCoord = this.geoCoordMap[value.name]
        // 创建一个对象,包含名称(name)、经度(经度)、纬度(纬度)和值(value)
        return {
          name: value.name,
          value: [geoCoord[0], geoCoord[1], value.value]
        }
      })
    }
  }
}
</script>
相关推荐
前端之虎陈随易30 分钟前
编程语言级别的Skill市场,AI Agent 的未来形态
前端·vue.js·人工智能·typescript·node.js
一路向北he32 分钟前
字节钢铁军团--“提供情境,而非控制”
java·开发语言·前端
kyriewen1 小时前
豆包和千问同时关了智能体,我用它们搭的 3 个自动化全废了——迁移方案整理
前端·javascript·ai编程
前端一小卒1 小时前
我用 TypeScript 从零手写了一个 Claude Code,然后发现它的核心只有 30 行
前端·agent
AI行业学习2 小时前
Notepad++ 官方下载 + 完整安装 + 全套优化配置(2026最新)
开发语言·人工智能·python·前端框架·html·notepad++
大圣编程3 小时前
Python中continue语句的用法是什么?
开发语言·前端·python
yuhaiqiang3 小时前
随手 vibecoding 的浏览器插件已经 6000 多次下载,聊聊他的产品设计
前端·后端·面试
之歆3 小时前
Vue商品详情与放大镜组件
前端·javascript·vue.js
再吃一根胡萝卜4 小时前
如何把小米 MiMo 接入 CodeBuddy,打造私有 Agent
前端
尘中远4 小时前
【Qwt 7.0 系列】坐标轴与刻度系统 —— 刻度引擎、网格、图例与刻度朝内
qt·数据可视化·qcustomplot·qwt·工业软件·科学绘图