vue3之echarts区域折线图

vue3之echarts区域折线图

效果:
在这里插入图片描述
核心代码:

<template>
    <div class="abnormal">
        <div class="per">单位:{{ obj.data?.unit }}</div>
        <div class="chart" ref="chartsRef"></div>
    </div>
</template>

<script setup>
import * as echarts from 'echarts';
import { reactive, onMounted } from 'vue';

const obj = reactive({
    data: {
        xdata: ['1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11', '12'],
        ydata: [ 0, 0, 0, 1354, 0, 254, 0, 468, 0, 16, 498, 0],
        unit: '次'
    },
    op: {
        tooltip: {},
        grid: {
            top: '5%',
            left: '0%',
            right: '2%',
            bottom: '0%',
            containLabel: true,
        },
        xAxis: null,
        yAxis: [
            {
                type: 'value',
                nameLocation: 'end',
                axisTick: {
                    show: false,
                },
                axisLine: {
                    show: false,
                },
                axisLabel: {
                    textStyle: {
                        fontSize: 13,
                        color: '#ffffff',
                        fontFamily: 'DINPro-Regular',
                    },
                    padding: [0, 0, 0, -10],
                },
                splitLine: {
                    lineStyle: {
                        type: 'dashed',
                        color: 'rgba(160, 169, 192, 0.8)',
                    },
                },
            },
        ],
        series: [],
    },
})
let myCharts = null;
let chartsRef = ref(null)

const flushChart = () => {
    obj.op.xAxis = {};
    obj.op.series = [];
    obj.op.tooltip = {};

    obj.op.tooltip = {
        trigger: 'axis',
        axisPointer: {
            type: 'shadow',
            lineStyle: {
                color: 'rgba(135, 140, 147, 0.6)',
            },
        },
        formatter(params) {
            return `${params[0].name}月 : ${params[1].value}`;
        },
        backgroundColor: 'rgba(45, 105, 133, 0.8)',
        borderWidth: 0,
        textStyle: {
            color: '#DAE3E7',
            fontFamily: 'DINPro-Regular',
        },
    };
    obj.op.xAxis = {
        type: 'category',
        boundaryGap: false, // 坐标轴两边留白
        data: obj.data.xdata,
        axisLabel: {
            margin: 10,
            textStyle: {
                color: '#ffffff',
                fontSize: 13,
                fontFamily: 'DINPro-Regular',
            },

        },
        axisLine: {
            lineStyle: {
                color: 'rgba(160, 169, 192, 0.6)',
            },
        },
        axisTick: {
            show: true,
        },
    };
    obj.op.series.push(
        {
            name: 'bg',
            type: 'bar',
            data: [...Array(obj.data.ydata.length).fill(Math.max(...obj.data.ydata) === 0 ? 10 : Math.max(...obj.data.ydata))],
            barWidth: '50%',
            itemStyle: {
                color: 'rgba(255, 255, 255, 0.02)',
            },
        },
    );
    obj.op.series.push(
        {
            type: 'line',
            symbol: 'none',
            itemStyle: {
                normal: {
                    color: '#68A4FF',
                    lineStyle: {
                        color: '#68A4FF',
                        width: 3,
                    },
                    areaStyle: {
                        // 区域填充样式
                        color: new echarts.graphic.LinearGradient(0, 1, 0, 0, [
                            {
                                offset: 0,
                                color: 'rgba(104,164,255,0)',
                            }, {
                                offset: 0.5,
                                color: 'rgba(104,164,255,0.6)',
                            },
                            {
                                offset: 1,
                                color: 'rgba(104,164,255,1)',
                            },
                        ]),
                    },
                },
            },
            toolbox: {
                show: false,
            },
            data: obj.data.ydata,
        },
    );
    myCharts.setOption(obj.op);
}

const initChart = () => {
    myCharts = echarts.init(chartsRef.value);
    flushChart();
} 

onMounted(() => {
    initChart();
})

const destroyChart = () => {
    if (!myCharts) {
        return;
    }
    myCharts.dispose();
    myCharts = null;
}

onBeforeMount(() => {
    destroyChart();
})
</script>

<style lang="scss" scoped>
.abnormal {
    position: relative;
    width: 100%;
    height: 276px;
    margin-top: 19px;
    display: inline-block;

    .per {
        font-size: 12px;
        color: rgba(255, 255, 255, 0.5);
        margin-bottom: 19px;
    }

    .chart {
        display: inline-block;
        width: 100%;
        height: 185px;
        zoom: 1;
    }
}
</style>

<think>好的,我现在需要帮用户在Vue2中集成ECharts实现折线图功能。用户已经提供了一些相关的引用内容,主要是关于Vue3ECharts的使用,但用户现在需要的是Vue2的示例教程。 首先,我得回顾一下Vue2和Vue3ECharts集成上的区别。Vue3使用Composition API,而Vue2主要使用Options API。因此,组件的初始化和生命周期钩子的使用会有所不同。比如,在Vue3中常用setup和onMounted,而Vue2则是在mounted钩子中初始化图表。 接下来,用户提供的引用内容中有安装ECharts的步骤,这在Vue2中应该也是类似的,即通过npm安装。然后,在组件中引入ECharts,但需要注意按需引入还是全量引入。引用3提到按需引入某些组件,但引用4则是全量引入。用户可能需要一个简单的示例,所以全量引入可能更直接,但也要提到按需引入的方法以减少包体积。 然后,关于DOM元素的引用,在Vue2中通常使用this.$refs来获取DOM节点,而不是Vue3中的ref函数。因此,在初始化图表时,需要用document.getElementById或者this.$refs来获取容器元素。 另外,组件的生命周期方面,Vue2中在mounted钩子初始化图表,而在beforeDestroy钩子中销毁图表实例,避免内存泄漏。这和Vue3的onMounted和onUnmounted类似,但语法不同。 用户可能需要完整的代码示例,包括模板部分和脚本部分。需要确保ECharts实例在DOM加载完成后初始化,并且在组件销毁时正确释放资源。此外,可能需要配置一个基本的折线图选项,包括x轴、y轴的数据和系列配置。 还需要考虑响应式布局,当窗口大小变化时,图表应自适应调整。这可以通过监听resize事件,并调用ECharts实例的resize方法来实现。 最后,根据用户之前的提问,他们可能对样式定制、动态数据更新有进一步的需求,因此可以在示例中简要提到这些方面,或者作为扩展内容提供。 总结步骤: 1. 安装ECharts依赖。 2. 在组件中引入ECharts3. 创建图表容器,使用ref或id获取DOM。 4. 在mounted钩子中初始化图表,配置选项。 5. 在beforeDestroy钩子中销毁图表实例。 6. 处理窗口resize事件以自适应调整。 7. 提供示例配置选项,包括xAxis、yAxis、series等。 8. 可能提到按需引入优化和动态数据更新的方法。 需要确保代码示例正确,并符合Vue2的语法习惯,比如使用this.$refs,Options API等。同时,注意代码格式和注释,使用户能够清晰理解每一步的作用。</think>### Vue2集成ECharts折线图完整教程 --- #### **步骤1:环境准备** ```bash npm install echarts vue-echarts --save ``` --- #### **步骤2:基础实现** ```vue <template> <div class="chart-wrapper"> <div ref="lineChart" style="width: 800px; height: 400px"></div> </div> </template> <script> import * as echarts from &#39;echarts&#39;; export default { mounted() { this.initChart(); }, beforeDestroy() { if (this.chart) { this.chart.dispose(); // 防止内存泄漏[^4] } }, methods: { initChart() { this.chart = echarts.init(this.$refs.lineChart); const option = { title: { text: &#39;Vue2销售额趋势&#39;, left: &#39;center&#39;, textStyle: { color: &#39;#666&#39; } }, tooltip: { trigger: &#39;axis&#39;, formatter: &#39;{b}<br/>{a}: ¥{c}万&#39; // 定制提示框格式[^3] }, xAxis: { type: &#39;category&#39;, data: [&#39;1月&#39;, &#39;2月&#39;, &#39;3月&#39;, &#39;4月&#39;, &#39;5月&#39;, &#39;6月&#39;], axisLabel: { rotate: 45 // X轴标签旋转 } }, yAxis: { type: &#39;value&#39;, axisLabel: { formatter: &#39;¥{value} 万&#39; // Y轴单位格式 } }, series: [{ name: &#39;销售额&#39;, type: &#39;line&#39;, smooth: true, // 平滑曲线[^1] data: [120, 200, 150, 80, 70, 110], itemStyle: { color: &#39;#1890ff&#39; // 线条颜色 }, areaStyle: { // 区域填充 color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [ { offset: 0, color: &#39;rgba(24,144,255,0.6)&#39; }, { offset: 1, color: &#39;rgba(24,144,255,0.1)&#39; } ]) } }] }; this.chart.setOption(option); // 窗口自适应 window.addEventListener(&#39;resize&#39;, () => { this.chart.resize(); }); } } } </script> ``` --- #### **步骤3:高级配置** **动态数据更新**: ```javascript // 在methods中添加 updateData(newData) { this.chart.setOption({ series: [{ data: newData }] }); } ``` **按需引入优化**: ```javascript // 替换全量引入 import echarts from &#39;echarts/lib/echarts&#39;; import &#39;echarts/lib/chart/line&#39;; import &#39;echarts/lib/component/tooltip&#39;; import &#39;echarts/lib/component/title&#39;; ``` --- #### **步骤4:关键配置解析** 1. **平滑曲线**:通过设置`smooth: true`实现曲线平滑过渡[^1] $$ \text{贝塞尔曲线算法}:B(t) = (1-t)^3P_0 + 3t(1-t)^2P_1 + 3t^2(1-t)P_2 + t^3P_3 $$ 2. **响应式布局**: ```javascript // 使用ResizeObserver更精准监听 const observer = new ResizeObserver(() => { this.chart.resize(); }); observer.observe(this.$refs.lineChart); ``` --- #### **常见问题解决** 1. **图表空白**: - 确保容器设置具体宽高 - 检查`mounted`生命周期是否正确触发 2. **内存泄漏**: ```javascript beforeDestroy() { window.removeEventListener(&#39;resize&#39;, this.resizeHandler); this.chart.dispose(); } ``` --- #### **效果增强技巧** ```javascript // 添加数据标记点 series: [{ // ... markPoint: { data: [ { type: &#39;max&#39;, name: &#39;最大值&#39; }, { type: &#39;min&#39;, name: &#39;最小值&#39; } ] } }] // 添加动画 animationDuration: 2000, animationEasing: &#39;elasticOut&#39; ``` --- ### 扩展应用场景 **动态更新示例**: ```vue <template> <div> <button @click="loadNewData">更新数据</button> <div ref="chart" style="width: 100%;height:400px"></div> </div> </template> ``` ```javascript methods: { loadNewData() { const newData = /* 获取新数据 */; this.chart.setOption({ series: [{ data: newData }] }); } } ``` --- ### 最佳实践建议 1. **性能优化**: - 大数据量使用`large: true`开启大数据模式 - 使用`dataZoom`进行数据区域缩放 2. **主题定制**: ```javascript // 注册主题 import theme from &#39;./theme.json&#39;; echarts.registerTheme(&#39;myTheme&#39;, theme); this.chart = echarts.init(this.$refs.chart, &#39;myTheme&#39;); ``` --- ### 可视化调试技巧 1. 使用`getOption()`方法获取当前配置 2. 通过Chrome开发者工具的ECharts Inspector插件调试 3. 控制台输入`chart.getDom().querySelector(&#39;canvas&#39;)`检查渲染状态 --- ### 相关引用说明 [^1]: 平滑曲线实现原理参考ECharts贝塞尔曲线算法 [^3]: 提示框格式配置参考官方文档Tooltip组件 [^4]: 内存管理要求必须调用dispose方法 --- ### 相关问题 1. 如何实现ECharts图表的多语言配置? 2. 大数据量下折线图的性能优化策略? 3. 如何保存ECharts图表为图片或PDF? 4. Vue2与Vue3在使用ECharts时的核心区别?
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值