欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

使用Vue和ECharts創(chuàng)建交互式圖表的代碼示例

 更新時(shí)間:2024年11月18日 08:29:52   作者:漆黑的莫莫  
在現(xiàn)代 Web 應(yīng)用中,數(shù)據(jù)可視化是一個(gè)重要的組成部分,它不僅能夠幫助用戶更好地理解復(fù)雜的數(shù)據(jù),還能提升用戶體驗(yàn),本文給大家使用Vue和ECharts創(chuàng)建交互式圖表的示例,需要的朋友可以參考下

引言

在現(xiàn)代 Web 應(yīng)用中,數(shù)據(jù)可視化是一個(gè)重要的組成部分。它不僅能夠幫助用戶更好地理解復(fù)雜的數(shù)據(jù),還能提升用戶體驗(yàn)。

技術(shù)背景

Vue.js

Vue.js 是一個(gè)漸進(jìn)式 JavaScript 框架,用于構(gòu)建用戶界面。它易于上手,同時(shí)提供了強(qiáng)大的功能來構(gòu)建復(fù)雜的單頁應(yīng)用。Vue 的響應(yīng)式系統(tǒng)使得數(shù)據(jù)綁定變得簡單高效。

ECharts

ECharts 是一個(gè)基于 JavaScript 的開源可視化庫,由百度前端技術(shù)部開發(fā)。它提供了豐富的圖表類型和高度可定制的配置選項(xiàng),適用于各種數(shù)據(jù)可視化需求。

項(xiàng)目搭建

首先,需要?jiǎng)?chuàng)建一個(gè)新的 Vue 項(xiàng)目。如果還沒有安裝 Vue CLI,可以通過以下命令進(jìn)行安裝:

npm install -g @vue/cli

然后,創(chuàng)建一個(gè)新的 Vue 項(xiàng)目:

vue create my-chart-app
cd my-chart-app

接下來,安裝 ECharts:

npm install echarts

代碼說明

  1. 圖表容器

    • 使用 ref 獲取圖表容器的 DOM 元素。
    • 在 onMounted 生命周期鉤子中初始化 ECharts 實(shí)例并調(diào)用 updateChart 方法更新圖表配置。
  2. 圖表類型選擇

    • 使用 v-model 綁定圖表類型,并在選擇改變時(shí)調(diào)用 updateChart 方法更新圖表。
  3. 數(shù)據(jù)編輯

    • 提供兩個(gè)模態(tài)對話框,一個(gè)用于編輯單個(gè)數(shù)據(jù)點(diǎn),另一個(gè)用于編輯所有數(shù)據(jù)點(diǎn)。
    • 使用計(jì)算屬性 selectedXAxisValue 和 selectedSeriesValue 來同步選中的數(shù)據(jù)點(diǎn)的 X 軸值和系列數(shù)據(jù)值。
    • 提供 addDataPoint 和 deleteDataPoint 方法來添加和刪除數(shù)據(jù)點(diǎn),并在操作后調(diào)用 updateChart 方法更新圖表。
  4. 圖表配置

    • 根據(jù)不同的圖表類型(折線圖、柱狀圖、餅圖、散點(diǎn)圖),設(shè)置不同的圖表配置。
    • 使用 label 屬性常駐顯示數(shù)值標(biāo)簽,并在餅圖中使用 labelLine 屬性設(shè)置連接線的樣式。

代碼實(shí)現(xiàn)

<script setup lang="ts">
import { defineComponent, onMounted, ref, computed } from 'vue'
import * as echarts from 'echarts'

// 定義圖表容器引用
const chartRef = ref<HTMLDivElement | null>(null)
let chartInstance: echarts.ECharts | null = null

// 定義圖表數(shù)據(jù)
const xAxisData = ref(["初始階段", "開發(fā)階段", "完成階段"])
const seriesData = ref([10, 50, 80])

const chartType = ref('line')

// 初始化圖表
const initChart = () => {
    if (!chartRef.value) return
    chartInstance = echarts.init(chartRef.value)

    updateChart()
}

// 更新圖表配置
const updateChart = () => {
    if (!chartInstance) return

    let option;

    switch (chartType.value) {
        case 'line':
        case 'bar':
            option = {
                tooltip: {
                    trigger: 'axis',
                    formatter: ': {c}'
                },
                legend: {
                    orient: 'vertical',
                    left: 'left',
                    textStyle: { color: '#666' }
                },
                xAxis: {
                    show: true,
                    type: 'category',
                    data: xAxisData.value,
                    axisLine: { lineStyle: { color: '#999' } },
                    axisLabel: { color: '#666' }
                },
                yAxis: {
                    show: true,
                    type: 'value',
                    axisLine: { lineStyle: { color: '#999' } },
                    splitLine: { lineStyle: { color: ['#eaeaea'], width: 1, type: 'dashed' } },
                    axisLabel: { color: '#666' }
                },
                series: [
                    {
                        data: seriesData.value,
                        type: chartType.value,
                        itemStyle: { color: '#5470c6' },
                        label: { // 常駐顯示數(shù)值標(biāo)簽
                            show: true,
                            position: 'top', // 標(biāo)簽位置
                            color: '#666'
                        },
                        ...(chartType.value === 'line' ? { areaStyle: { color: 'rgba(84, 112, 198, 0.3)' } } : {})
                    }
                ],
                grid: { left: '5%', right: '5%', bottom: '10%' }
            };
            break;
        case 'pie':
            option = {
                tooltip: {
                    trigger: 'item',
                    formatter: '{a} <br/>: {c} (vvxyksv9kd%)'
                },
                legend: {
                    orient: 'vertical',
                    left: 'left',
                    textStyle: { color: '#666' }
                },
                xAxis: {
                    show: false // 明確禁用 X 軸
                },
                yAxis: {
                    show: false // 明確禁用 Y 軸
                },
                series: [
                    {
                        name: '數(shù)據(jù)',
                        type: 'pie',
                        radius: ['40%', '70%'],
                        avoidLabelOverlap: false,
                        label: {
                            show: true, // 常駐顯示數(shù)值標(biāo)簽
                            position: 'outside', // 標(biāo)簽位置
                            formatter: ': {c} (vvxyksv9kd%)', // 自定義標(biāo)簽格式
                            color: '#666'
                        },
                        emphasis: {
                            label: { show: true, fontSize: '20', fontWeight: 'bold' }
                        },
                        data: xAxisData.value.map((name, index) => ({
                            name,
                            value: seriesData.value[index],
                            itemStyle: { color: ['#5470c6', '#91cc75', '#fac858'][index % 3] }
                        }))
                    }
                ]
            };
            break;
        case 'scatter':
            option = {
                tooltip: {
                    trigger: 'item',
                    formatter: ': {c}'
                },
                legend: {
                    orient: 'vertical',
                    left: 'left',
                    textStyle: { color: '#666' }
                },
                xAxis: {
                    show: true,
                    type: 'category',
                    data: xAxisData.value,
                    axisLine: { lineStyle: { color: '#999' } },
                    axisLabel: { color: '#666' }
                },
                yAxis: {
                    show: true,
                    type: 'value',
                    axisLine: { lineStyle: { color: '#999' } },
                    splitLine: { lineStyle: { color: ['#eaeaea'], width: 1, type: 'dashed' } },
                    axisLabel: { color: '#666' }
                },
                series: [
                    {
                        symbolSize: 20,
                        data: xAxisData.value.map((name, index) => [index, seriesData.value[index]]),
                        type: 'scatter',
                        label: { // 常駐顯示數(shù)值標(biāo)簽
                            show: true,
                            position: 'top', // 標(biāo)簽位置
                            color: '#666'
                        },
                        itemStyle: { color: '#5470c6' }
                    }
                ]
            };
            break;
        default:
            option = {};
    }

    chartInstance.setOption(option)
    console.log('option',option)
}

// 監(jiān)聽圖表點(diǎn)擊事件
onMounted(() => {
    initChart()

    chartInstance?.on('click', (params) => {
        showModalSingle.value = true;
        selectedDataIndex.value = params.dataIndex ?? -1;
    });
})

// 處理 X 軸數(shù)據(jù)變化
const handleXAxisChange = (index: number, value: string) => {
    xAxisData.value[index] = value
    updateChart()
}

// 處理系列數(shù)據(jù)變化
const handleSeriesChange = (index: number, value: string) => {
    seriesData.value[index] = parseFloat(value)
    updateChart()
}

// 模態(tài)對話框狀態(tài)
const showModalSingle = ref(false);
const showModalAll = ref(false);
const selectedDataIndex = ref(-1);

// 計(jì)算屬性:獲取選中的 X 軸值
const selectedXAxisValue = computed({
    get: () => xAxisData.value[selectedDataIndex.value],
    set: (newValue) => handleXAxisChange(selectedDataIndex.value, newValue)
});

// 計(jì)算屬性:獲取選中的系列數(shù)據(jù)值
const selectedSeriesValue = computed({
    get: () => seriesData.value[selectedDataIndex.value].toString(),
    set: (newValue) => handleSeriesChange(selectedDataIndex.value, newValue)
});

// 添加數(shù)據(jù)點(diǎn)
const addDataPoint = () => {
    xAxisData.value.push(`新數(shù)據(jù)點(diǎn) ${xAxisData.value.length + 1}`);
    seriesData.value.push(0);
    updateChart(); // 更新圖表以反映新增的數(shù)據(jù)點(diǎn)
};

// 刪除數(shù)據(jù)點(diǎn)
const deleteDataPoint = (index: number) => {
    xAxisData.value.splice(index, 1);
    seriesData.value.splice(index, 1);
    updateChart();
};
</script>

<template>
  <!-- 圖表容器 -->
  <div ref="chartRef" :style="{ width: '100%', height: '400px', backgroundColor: '#fff', borderRadius: '8px', boxShadow: '0 2px 4px rgba(0, 0, 0, 0.1)' }"></div>

  <!-- 圖表類型選擇 -->
  <select v-model="chartType" @change="updateChart" style="margin-top: 20px; padding: 8px; border: 1px solid #ccc; border-radius: 4px;">
    <option value="line">折線圖</option>
    <option value="bar">柱狀圖</option>
    <option value="pie">餅圖</option>
    <option value="scatter">散點(diǎn)圖</option>
  </select>

  <!-- 編輯所有數(shù)據(jù)按鈕 -->
  <button @click="showModalAll = true" style="margin-top: 20px; margin-left: 10px; padding: 8px 16px; background-color: #5470c6; color: #fff; border: none; border-radius: 4px; cursor: pointer;">
    編輯所有數(shù)據(jù)
  </button>

  <!-- 單個(gè)數(shù)據(jù)點(diǎn)模態(tài)對話框 -->
  <div v-if="showModalSingle" style="position: fixed; top: 0; left: 0; right: 0; bottom: 0; background-color: rgba(0, 0, 0, 0.5); display: flex; justify-content: center; align-items: center;">
    <div style="background-color: white; padding: 20px; border-radius: 8px; box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);">
      <h3>編輯數(shù)據(jù)點(diǎn) {{ selectedDataIndex + 1 }}</h3>
      <div>
        <label>X軸數(shù)據(jù):</label>
        <input 
          :value="selectedXAxisValue" 
          @input="selectedXAxisValue = ($event.target as HTMLInputElement).value" 
          style="width: 100%; padding: 8px; margin-top: 5px; border: 1px solid #ccc; border-radius: 4px;"
        />
      </div>
      <div>
        <label>系列數(shù)據(jù):</label>
        <input 
          :value="selectedSeriesValue" 
          @input="selectedSeriesValue = ($event.target as HTMLInputElement).value" 
          style="width: 100%; padding: 8px; margin-top: 5px; border: 1px solid #ccc; border-radius: 4px;"
        />
      </div>
      <button @click="showModalSingle = false" style="margin-top: 10px; padding: 8px 16px; background-color: #5470c6; color: #fff; border: none; border-radius: 4px; cursor: pointer;">
        關(guān)閉
      </button>
    </div>
  </div>

  <!-- 所有數(shù)據(jù)模態(tài)對話框 -->
  <div v-if="showModalAll" style="position: fixed; top: 0; left: 0; right: 0; bottom: 0; background-color: rgba(0, 0, 0, 0.5); display: flex; justify-content: center; align-items: center;">
    <div style="background-color: white; padding: 20px; border-radius: 8px; box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1); width: 80%; max-width: 600px;">
      <h3>編輯所有數(shù)據(jù)</h3>
      <table style="width: 100%; border-collapse: collapse;">
        <thead>
          <tr>
            <th style="padding: 8px; text-align: left; background-color: #f2f2f2; color: #333;">序號</th>
            <th style="padding: 8px; text-align: left; background-color: #f2f2f2; color: #333;">X軸數(shù)據(jù)</th>
            <th style="padding: 8px; text-align: left; background-color: #f2f2f2; color: #333;">系列數(shù)據(jù)</th>
            <th style="padding: 8px; text-align: left; background-color: #f2f2f2; color: #333;">操作</th>
          </tr>
        </thead>
        <tbody>
          <tr v-for="(item, index) in xAxisData" :key="index">
            <td style="border-bottom: 1px solid #ddd; padding: 8px;">{{ index + 1 }}</td>
            <td style="border-bottom: 1px solid #ddd; padding: 8px;">
              <input 
                :value="xAxisData[index]" 
                @input="handleXAxisChange(index, ($event.target as HTMLInputElement).value)" 
                style="width: 100%; padding: 8px; border: 1px solid #ccc; border-radius: 4px;"
              />
            </td>
            <td style="border-bottom: 1px solid #ddd; padding: 8px;">
              <input 
                :value="seriesData[index]" 
                @input="handleSeriesChange(index, ($event.target as HTMLInputElement).value)" 
                style="width: 100%; padding: 8px; border: 1px solid #ccc; border-radius: 4px;"
              />
            </td>
            <td style="border-bottom: 1px solid #ddd; padding: 8px;">
              <button @click="deleteDataPoint(index)" style="padding: 8px 16px; background-color: #ff4d4f; color: #fff; border: none; border-radius: 4px; cursor: pointer;">
                刪除
              </button>
            </td>
          </tr>
        </tbody>
      </table>
      <button @click="addDataPoint" style="margin-top: 10px; padding: 8px 16px; background-color: #5470c6; color: #fff; border: none; border-radius: 4px; cursor: pointer;">
        添加數(shù)據(jù)點(diǎn)
      </button>
      <button @click="showModalAll = false" style="margin-top: 10px; padding: 8px 16px; background-color: #5470c6; color: #fff; border: none; border-radius: 4px; cursor: pointer;">
        關(guān)閉
      </button>
    </div>
  </div>
</template>

到此這篇關(guān)于使用Vue和ECharts創(chuàng)建交互式圖表的代碼示例的文章就介紹到這了,更多相關(guān)Vue ECharts交互式圖表內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Vue監(jiān)聽使用方法和過濾器實(shí)現(xiàn)

    Vue監(jiān)聽使用方法和過濾器實(shí)現(xiàn)

    這篇文章主要介紹了Vue監(jiān)聽使用方法和過濾器實(shí)現(xiàn),過濾器為頁面中數(shù)據(jù)進(jìn)行強(qiáng)化,具有局部過濾器和全局過濾器
    2022-06-06
  • vue插槽slot的簡單理解與用法實(shí)例分析

    vue插槽slot的簡單理解與用法實(shí)例分析

    這篇文章主要介紹了vue插槽slot的簡單理解與用法,結(jié)合實(shí)例形式分析了vue插槽slot的功能、原理、相關(guān)使用技巧與操作注意事項(xiàng),需要的朋友可以參考下
    2020-03-03
  • vue實(shí)現(xiàn)滾動(dòng)條始終懸浮在頁面最下方

    vue實(shí)現(xiàn)滾動(dòng)條始終懸浮在頁面最下方

    這篇文章主要為大家詳細(xì)介紹了vue實(shí)現(xiàn)滾動(dòng)條始終懸浮在頁面最下方,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-04-04
  • vue mvvm數(shù)據(jù)響應(yīng)實(shí)現(xiàn)

    vue mvvm數(shù)據(jù)響應(yīng)實(shí)現(xiàn)

    這篇文章主要介紹了vue mvvm數(shù)據(jù)響應(yīng)實(shí)現(xiàn)的方法,幫助大家更好的理解和使用vue,感興趣的朋友可以了解下
    2020-11-11
  • Vue3 ref構(gòu)建響應(yīng)式變量失效問題及解決

    Vue3 ref構(gòu)建響應(yīng)式變量失效問題及解決

    這篇文章主要介紹了Vue3 ref構(gòu)建響應(yīng)式變量失效問題及解決方案,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-04-04
  • el-form-item中表單項(xiàng)label和表單項(xiàng)內(nèi)容換行實(shí)現(xiàn)方法

    el-form-item中表單項(xiàng)label和表單項(xiàng)內(nèi)容換行實(shí)現(xiàn)方法

    這篇文章主要給大家介紹了el-form-item中表單項(xiàng)label和表單項(xiàng)內(nèi)容換行實(shí)現(xiàn)的相關(guān)資料,每個(gè)表單el-form由多個(gè)表單域el-form-item組成,需要的朋友可以參考下
    2023-09-09
  • Vue.js自定義指令的用法與實(shí)例解析

    Vue.js自定義指令的用法與實(shí)例解析

    自定義指令是用來操作DOM的。自定義指令就是一種有效的補(bǔ)充和擴(kuò)展,不僅可用于定義任何的DOM操作,并且是可復(fù)用的。這篇文章主要介紹了Vue.js自定義指令的用法與實(shí)例解析,一起看看吧
    2017-01-01
  • 如何使用 Vue Router 的 meta 屬性實(shí)現(xiàn)多種功能

    如何使用 Vue Router 的 meta 屬性實(shí)現(xiàn)多種功能

    在Vue.js中,Vue Router 提供了強(qiáng)大的路由管理功能,通過meta屬性,我們可以在路由定義中添加自定義元數(shù)據(jù),以實(shí)現(xiàn)訪問控制、頁面標(biāo)題設(shè)置、角色權(quán)限管理、頁面過渡效果,本文將總結(jié)如何使用 meta 屬性來實(shí)現(xiàn)這些常見的功能,感興趣的朋友一起看看吧
    2024-06-06
  • 深入理解Vue transition源碼分析

    深入理解Vue transition源碼分析

    本篇文章主要介紹了深入理解Vue transition源碼分析,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2017-07-07
  • Vue如何實(shí)現(xiàn)組件間通信

    Vue如何實(shí)現(xiàn)組件間通信

    組件間通信簡單來說就是組件間進(jìn)行數(shù)據(jù)傳遞。就像我們?nèi)粘5拇螂娫?,就是通訊的一種方式,你把話說給我聽,我把話說給你聽,說的話就是數(shù)據(jù)。電話就是通訊方式的一種。無論是 Vue 還是 React ,都得進(jìn)行組件間通信。
    2021-05-05

最新評論