36-Vue之ECharts高级-样式及自适应

ECharts样式与自适应配置详解
本文详细介绍了ECharts中如何进行样式配置,包括直接样式、高亮样式,以及如何实现图表的自适应。通过示例代码展示了如何设置饼图的itemStyle、textStyle、lineStyle等属性来自定义颜色和高亮效果,并演示了如何在窗口大小变化时自动调整图表大小。

ECharts高级-样式及自适应


前言

  • 本篇来学习下样式及自适应的使用

样式

直接样式
  • 这些样式一般都可以设置颜色或者背景或者字体等样式, 他们会覆盖主题中的样式
    • itemStyle
    • textStyle
    • lineStyle
    • areaStyle
    • label
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>样式</title>
    <!-- cdn方式 引入echarts.js文件 -->
    <script src="https://cdn.jsdelivr.net/npm/echarts@5.4.1/dist/echarts.min.js"></script>
</head>

<body>
<div id='app' style="width: 600px;height:400px"></div>
<script>
    var mCharts = echarts.init(document.getElementById("app"))
    var pieData = [
        {
            name: 'pass',
            value: 80,
            itemStyle: { // 控制pass这一区域的样式
                color: '#00FF00'
            }
        },
        {
            name: 'fail',
            value: 10
        },
        {
            name: 'skip',
            value: 5,
            itemStyle: { // 控制error这一区域的样式
                color: '#00FFFF'
            }
        },
        {
            name: 'error',
            value: 5,
            label: {
                color: '#FF0000'  // 文字(name值)颜色
            },
            itemStyle: { // 控制error这一区域的样式
                color: '#FF0000'
            }

        }
    ]
    var option = {
        title: {
            text: '测试结果',
            textStyle: { // 控制标题的文字样式
                color: 'blue'
            }
        },
        series: [
            {
                type: 'pie',
                data: pieData,
                label: {
                    show: true,
                    formatter: function (arg) {
                        console.log(arg)
                        return arg.data.name + '\n' + arg.percent + '%'

                    }
                },
                selectedMode: 'multiple',  // multiple 多选  single 单选
                selectedOffset: 30,// 偏移距离
                radius: ['50%', '80%']
            }

        ]
    }
    mCharts.setOption(option)
</script>
</body>

</html>

高亮样式
  • 鼠标滑过或者点击形成的高亮状态. 而高亮样式是针对于元素的高亮状态设定的样式
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>样式</title>
    <!-- cdn方式 引入echarts.js文件 -->
    <script src="https://cdn.jsdelivr.net/npm/echarts@5.4.1/dist/echarts.min.js"></script>
</head>

<body>
<div id='app' style="width: 600px;height:400px"></div>
<script>
    var mCharts = echarts.init(document.getElementById("app"))
    var pieData = [
        {
            name: 'pass',
            value: 80,
            itemStyle: { // 控制pass这一区域的样式
                color: '#00FF00'
            }
        },
        {
            name: 'fail',
            value: 10
        },
        {
            name: 'skip',
            value: 5,
            itemStyle: { // 控制error这一区域的样式
                color: '#00FFFF'
            },
            emphasis: {
                itemStyle: {   // 高亮(点击时显示的颜色)
                    color: 'pink'
                }
            }
        },
        {
            name: 'error',
            value: 5,
            label: {
                color: '#FF0000'  // 文字(name值)颜色
            },
            itemStyle: { // 控制error这一区域的样式
                color: '#FF0000'
            }

        }
    ]
    var option = {
        title: {
            text: '测试结果',
            textStyle: { // 控制标题的文字样式
                color: 'blue'
            }
        },
        series: [
            {
                type: 'pie',
                data: pieData,
                label: {
                    show: true,
                    formatter: function (arg) {
                        console.log(arg)
                        return arg.data.name + '\n' + arg.percent + '%'

                    }
                },
                selectedMode: 'multiple',  // multiple 多选  single 单选
                selectedOffset: 30,// 偏移距离
                radius: ['50%', '80%']
            }

        ]
    }
    mCharts.setOption(option)
</script>
</body>

</html>


自适应

  1. 监听窗口大小变化事件
  2. 在事件处理函数中调用 ECharts 实例对象的 resize 即可
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>自适应</title>
    <!-- cdn方式 引入echarts.js文件 -->
    <script src="https://cdn.jsdelivr.net/npm/echarts@5.4.1/dist/echarts.min.js"></script>
</head>

<body>
<!-- 准备一个呈现图表的盒子 -->
<div id='app' style="height:600px"></div>
<script>
    // 初始化echarts实例对象
    var myCharts = echarts.init(document.getElementById('app'))
    // 准备数据 将type的值设置为bar
    var xDataArr = ['张三', '李四', '王五', '大明白', '小糊涂'] // x轴数据
    var yDataArr = [88, 92, 63, 77, 94]  // y轴数据
    var option = {
        xAxis: {
            type: 'category',
            data: xDataArr
        },
        yAxis: {
            type: 'value'
        },
        series: [
            {
                name: '分数',
                type: 'bar',  // 图表类型  bar:柱状图   line:折线图   pie:饼图
                data: yDataArr,
                markPoint: {   // 标记最大最小值
                    data: [
                        {type: 'max', name: '最大值'},
                        {type: 'min', name: '最小值'}
                    ]
                },
                markLine: {
                    data: [
                        {
                            type: 'average', name: '平均值'
                        }
                    ]
                },
                label: {
                    show: true,  // 柱状图显示数值
                    rotate: 30, // 值旋转角度
                },
                barWidth: '30%' // 柱的宽度
            }
        ]
    }
    // 将配置项设置给echarts实例对象
    myCharts.setOption(option)
    // 监听window大小变化的事件
    window.onresize = function () {
        // 调用echarts示例对象的resize方法
        myCharts.resize()
    }
    // window.onresize = myCharts.resize  // 简单写法
</script>
</body>

</html>


<think> 我们正在使用uni-app开发小程序,并且希望使用Echarts来绘制饼状图。由于小程序环境特殊,我们需要使用Echarts的小程序版本,即echarts-for-weixin。 步骤: 1. 在uni-app项目中引入echarts-for-weixin组件(或者使用uni-app的插件市场中的相关组件)。 2. 创建一个自定义组件,用于封装饼状图。 3. 在组件中引入Echarts,并初始化图表。 4. 通过props接收数据,并在数据变化时更新图表。 5. 考虑到小程序的性能,需要注意图表的销毁和内存释放。 具体步骤: 第一步:获取echarts-for-weixin 由于uni-app支持小程序,我们可以将echarts-for-weixin项目中的ec-canvas组件复制到我们的uni-app项目中。也可以使用npm安装,但是需要配置。 第二步:创建自定义饼图组件 在components目录下创建pie-chart目录,然后创建pie-chart.vue组件。 第三步:编写组件 在组件中,我们需要引入ec-canvas,并初始化一个ECharts实例。 考虑到代码的复杂性,这里提供一个简化的版本: 在pie-chart.vue中: - 使用ec-canvas组件 - 定义props,接收图表数据 - 在mounted中初始化图表(注意:小程序中不是mounted,使用onReady,但uni-app中可以使用mounted,因为uni-app会转译成小程序的onReady) - 使用watch来监听数据变化并更新图表 由于小程序的canvas限制,我们需要使用echarts-for-weixin提供的自定义组件ec-canvas,并且需要按照其要求进行初始化。 具体代码: 1. 在项目中放置ec-canvas组件:将ec-canvas目录(包括ec-canvas.js, ec-canvas.json, ec-canvas.wxml, ec-canvas.wxss)复制到项目的组件目录下(例如components/ec-canvas)。注意,由于uni-app支持多端,我们需要将wxss改为css(或者scss),并且将wxml改为vue的模板。但是,uni-app提供了兼容小程序的组件写法,我们可以直接使用。不过,为了简化,也可以使用uni-app插件市场已经封装好的组件,比如uCharts等。但这里我们按照echarts-for-weixin的官方步骤进行。 2. 在pie-chart.vue中引入ec-canvas组件,并注册。 3. 注意:在uni-app中,我们使用vue单文件组件,所以需要将ec-canvas组件适配为vue组件。但是ec-canvas是微信小程序原生组件,不能直接在vue模板中使用,因此我们需要使用小程序自定义组件的支持。 在uni-app中,我们可以在vue文件中使用小程序原生自定义组件,但需要配置: - 在pages.json中,配置usingComponents(全局或页面级)或者使用uni-app的easycom规则(推荐使用easycom,这样在组件中可以直接使用而无需注册)。 由于我们是在自定义组件中使用另一个自定义组件(ec-canvas),所以需要在pie-chart组件的配置中声明usingComponents。 但是,uni-app的vue组件中,可以直接在template中使用自定义组件标签,只要符合easycom规则(将组件放在正确的目录下,如components/ec-canvas/ec-canvas.vue,但注意,我们这里ec-canvas是微信小程序原生组件,不是vue组件,所以我们需要特殊处理)。 所以,我们可以这样做: - 在pie-chart.vue的同级目录下,创建一个ec-canvas目录,将echarts-for-weixin的ec-canvas组件文件放进去(包括.js, .json, .wxml, .wxss)。 - 在pie-chart.vue中,通过配置usingComponents来引入ec-canvas组件。 但是,在uni-app的vue组件中,我们无法直接配置usingComponents。所以,我们需要将pie-chart组件设置为小程序自定义组件模式?或者,我们可以将整个pie-chart组件也写成小程序原生自定义组件?这不符合uni-app的初衷。 因此,推荐做法是:使用uni-app的条件编译,在微信小程序环境下使用ec-canvas,其他环境使用其他方式(如H5可以使用普通的echarts)。但这里我们只考虑微信小程序。 另外,uni-app提供了一个插件:uni-app的插件市场有封装好的echarts组件,比如“ucharts”,但这里我们按照echarts-for-weixin的官方方式。 由于uni-app支持在vue组件中使用小程序自定义组件,但是需要在组件的配置中声明。在uni-app中,我们可以在组件内通过easycom自动引入,或者手动配置usingComponents。 在pie-chart.vue中,我们可以通过以下方式: 在script中: export default { components: { // 不能直接注册,因为ec-canvas是原生小程序组件,不是vue组件 } } 但是,我们可以在vue文件中使用<script module="test" lang="wxs">?不行。 实际上,uni-app支持在vue文件中使用小程序自定义组件,但需要在页面配置中声明。不过,我们这是一个组件,不是页面。所以,我们需要在组件的配置中声明。 在uni-app中,自定义组件(vue组件)中要使用小程序自定义组件,需要在组件的目录下创建index.json(用于微信小程序组件配置),然后在json文件中配置usingComponents。但是这样会使得这个组件成为小程序自定义组件,而无法跨平台。 因此,我们使用条件编译:在微信小程序平台下,使用ec-canvas,其他平台使用其他方案(这里不讨论)。 具体步骤: 1. 在components下创建pie-chart目录,然后创建pie-chart.vue文件,并创建platforms目录,在platforms目录下创建mp-weixin目录(用于存放微信小程序平台专用文件),在mp-weixin目录下创建pie-chart.vue(这个文件会覆盖根目录的pie-chart.vue,当编译到微信小程序平台时)。 2. 在platforms/mp-weixin/pie-chart.vue中,我们编写微信小程序专用的组件代码。 但是这样会使得维护困难,因此我们也可以直接使用条件编译标签。 在同一个vue文件中,使用条件编译: ```html <!-- #ifdef MP-WEIXIN --> <ec-canvas ...></ec-canvas> <!-- #endif --> ``` 并且,我们需要在微信小程序平台下引入ec-canvas组件,那么我们需要在pages.json中全局配置,或者在页面的json中配置。但是,由于我们的组件是动态引入的,所以最好在页面的json中配置usingComponents,但这会导致页面需要知道组件内部的实现细节。 因此,我们可以在pie-chart.vue中,通过uni-app的easycom规则,自动引入ec-canvas组件。easycom规则是:只要组件位于components目录下,并且符合命名规范,就可以直接使用。 我们将ec-canvas组件放在项目的components/ec-canvas目录下(即与pie-chart同级),然后ec-canvas目录下应该有四个文件:ec-canvas.js, ec-canvas.json, ec-canvas.wxml, ec-canvas.wxss。 然后,在pie-chart.vue中,我们可以直接使用<ec-canvas>标签,因为easycom会自动帮我们引入。 注意:在微信小程序中,ec-canvas组件需要传递canvas-id和ec属性,其中ec是一个在组件中定义的对象,用于初始化图表。 接下来,我们编写pie-chart.vue组件(微信小程序平台): 步骤: - 在template中添加ec-canvas,并设置canvas-id(动态生成,避免多个实例id相同)和ec属性(绑定到ec对象)。 - 在data中定义ec对象,其onInit方法用于初始化图表。 - 通过props接收option(图表配置项)和canvasId(用于指定canvas-id,避免重复)。 - 在onInit方法中,使用echarts.init方法初始化图表,并设置option。 注意:由于小程序中,canvas是原生组件,层级很高,所以需要注意与其他元素的覆盖问题。 代码示例(简化): pie-chart.vue(位于components/pie-chart目录下,并且只在微信小程序平台使用,其他平台可能需要条件编译或者另外实现): </think> ### 使用 uni-app、VueEcharts 封装小程序饼状图组件 下面是通过 6 个步骤实现的完整封装方案(基于 echarts-for-weixin 库): --- #### 1. **安装依赖** ```bash npm install echarts mpvue-echarts --save ``` #### 2. **创建组件文件** `/components/pie-chart/pie-chart.vue`: ```vue <template> <div class="chart-container"> <ec-canvas :canvas-id="canvasId" :ec="ec" :force-use-old-canvas="true" /> </div> </template> <script> import * as echarts from 'echarts' import ecCanvas from '@/components/ec-canvas/ec-canvas' export default { components: { ecCanvas }, props: { // 图表数据 chartData: { type: Array, default: () => [ { value: 335, name: '直接访问' }, { value: 310, name: '邮件营销' } ] }, // 自定义颜色 colorScheme: { type: Array, default: () => ['#5470c6', '#91cc75', '#fac858', '#ee6666', '#73c0de'] }, // 标题文本 title: { type: String, default: '访问来源' } }, data() { return { canvasId: `pie_${Date.now()}`, ec: { lazyLoad: true, onInit: this.initChart } } }, watch: { chartData: { deep: true, handler() { this.updateChart() } } }, mounted() { this.$nextTick(() => { this.initChart() }) }, methods: { // 初始化图表 initChart(canvas, width, height) { const chart = echarts.init(canvas, null, { width, height, devicePixelRatio: uni.getSystemInfoSync().pixelRatio }) canvas.setChart(chart) this.chart = chart this.updateChart() return chart }, // 更新图表数据 updateChart() { if (!this.chart) return const option = { tooltip: { trigger: 'item', formatter: '{a}<br/>{b}: {c} ({d}%)' }, legend: { orient: 'horizontal', bottom: 0, data: this.chartData.map(item => item.name) }, series: [{ name: this.title, type: 'pie', radius: ['40%', '70%'], avoidLabelOverlap: false, itemStyle: { borderRadius: 10, borderColor: '#fff', borderWidth: 2 }, label: { show: true, formatter: '{b}: {d}%' }, data: this.chartData, color: this.colorScheme }] } this.chart.setOption(option) } } } </script> <style scoped> .chart-container { width: 100%; height: 500rpx; position: relative; } </style> ``` #### 3. **注册全局组件** 在 `main.js` 中添加: ```javascript import PieChart from '@/components/pie-chart/pie-chart' Vue.component('PieChart', PieChart) ``` #### 4. **在页面中使用组件** ```vue <template> <view> <pie-chart :chartData="pieData" title="销售占比" :colorScheme="['#FF6B6B', '#4ECDC4', '#FFE66D', '#1A535C']" /> </view> </template> <script> export default { data() { return { pieData: [ { value: 1560, name: '电子产品' }, { value: 890, name: '服装' }, { value: 1290, name: '食品' }, { value: 740, name: '家居' } ] } } } </script> ``` #### 5. **性能优化建议** 1. **防抖处理**:频繁数据更新时添加防抖 ```javascript methods: { updateChart: _.debounce(function() { // 更新逻辑 }, 300) } ``` 2. **销毁实例**:组件卸载时释放资源 ```javascript beforeDestroy() { if (this.chart) { this.chart.dispose() this.chart = null } } ``` 3. **按需引入**:减少包体积 ```javascript import * as echarts from 'echarts/core'; import { PieChart } from 'echarts/charts'; import { CanvasRenderer } from 'echarts/renderers'; echarts.use([PieChart, CanvasRenderer]); ``` #### 6. **常见问题解决** - **层级问题**:小程序中 canvas 是原生组件,需在 `manifest.json` 配置: ```json "mp-weixin": { "appid": "YOUR_APPID", "setting": { "urlCheck": false }, "usingComponents": true, "navigateToMiniProgramAppIdList": ["wx1234567890"], "renderingMode": "seperated" // 解决覆盖问题 } ``` - **空白区域**:确保容器有明确尺寸: ```css .chart-container { width: 100%; height: 500rpx; position: relative; } ``` --- ### 关键点说明 1. **跨平台兼容**:通过 `ec-canvas` 组件解决小程序原生 canvas 限制 2. **响应式更新**:深度监听数据变化自动重绘 3. **按需渲染**:`lazyLoad` 属性延迟初始化提升性能 4. **样式隔离**:scoped CSS 避免样式冲突 5. **自适应尺寸**:动态获取设备像素比保证高清显示 > 完整实现参考 echarts-for-weixin 官方文档[^1] 和 uni-app 自定义组件规范[^2]。 --- ### 相关问题 1. 如何解决小程序中 echarts 图表显示不全的问题? 2. 在 uni-app 中如何实现 echarts 图表的点击事件交互? 3. echarts 在小程序端有哪些性能优化手段? 4. 如何实现多端(H5/小程序)统一的图表组件? 5. 大数据量下饼图的最佳实践是什么? [^1]: echarts-for-weixin 官方 GitHub 仓库 [^2]: uni-app 自定义组件开发
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

爱学习de测试小白

你的鼓励将是我创作的最大动力!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值