introduction
Data visualization is an important component in modern web applications. It not only helps users better understand complex data, but also improves user experience.
Technical background
is a progressive JavaScript framework for building user interfaces. It is easy to get started while providing powerful features to build complex single-page applications. Vue's responsive system makes data binding simple and efficient.
ECharts
ECharts is an open source visualization library based on JavaScript, developed by Baidu Front-end Technology Department. It offers a wide range of chart types and highly customizable configuration options for a variety of data visualization needs.
Project construction
First, you need to create a new Vue project. If the Vue CLI has not been installed, you can install it through the following command:
npm install -g @vue/cli
Then, create a new Vue project:
vue create my-chart-app cd my-chart-app
Next, install ECharts:
npm install echarts
Code description
-
Chart container:
- use
ref
Gets the DOM element of the chart container. - exist
onMounted
Initialize the ECharts instance in the life cycle hook and call itupdateChart
Method update the chart configuration.
- use
-
Chart type selection:
- use
v-model
Bind the chart type and call it when the change is selectedupdateChart
Method update the chart.
- use
-
Data Editing:
- Two modal dialogs are provided, one for editing a single data point and the other for editing all data points.
- Use Computational Properties
selectedXAxisValue
andselectedSeriesValue
To synchronize the X-axis value and series data values of the selected data point. - supply
addDataPoint
anddeleteDataPoint
Method to add and delete data points and call them after operationupdateChart
Method update the chart.
-
Chart configuration:
- Set different chart configurations according to different chart types (line chart, histogram, pie chart, scatter chart).
- use
label
Attributes are resident to display numerical labels and used in pie chartslabelLine
Properties set the style of the connection line.
Code implementation
<script setup lang="ts"> import { defineComponent, onMounted, ref, computed } from 'vue' import * as echarts from 'echarts' // Define chart container referencesconst chartRef = ref<HTMLDivElement | null>(null) let chartInstance: | null = null // Define chart dataconst xAxisData = ref(["Initial Phase", "Development Phase", "Complete Phase"]) const seriesData = ref([10, 50, 80]) const chartType = ref('line') // Initialize the chartconst initChart = () => { if (!) return chartInstance = () updateChart() } // Update chart configurationconst updateChart = () => { if (!chartInstance) return let option; switch () { case 'line': case 'bar': option = { tooltip: { trigger: 'axis', formatter: '{b}: {c}' }, legend: { orient: 'vertical', left: 'left', textStyle: { color: '#666' } }, xAxis: { show: true, type: 'category', data: , 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: , type: , itemStyle: { color: '#5470c6' }, label: { //Resident display value tag show: true, position: 'top', // Tag location color: '#666' }, ...( === '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/>{b}: {c} ({d}%)' }, legend: { orient: 'vertical', left: 'left', textStyle: { color: '#666' } }, xAxis: { show: false // Exclusively disable the X-axis }, yAxis: { show: false // explicitly disable the Y axis }, series: [ { name: 'data', type: 'pie', radius: ['40%', '70%'], avoidLabelOverlap: false, label: { show: true, //Resident display value tag position: 'outside', // Tag location formatter: '{b}: {c} ({d}%)', // Customize the label format color: '#666' }, emphasis: { label: { show: true, fontSize: '20', fontWeight: 'bold' } }, data: ((name, index) => ({ name, value: [index], itemStyle: { color: ['#5470c6', '#91cc75', '#fac858'][index % 3] } })) } ] }; break; case 'scatter': option = { tooltip: { trigger: 'item', formatter: '{b}: {c}' }, legend: { orient: 'vertical', left: 'left', textStyle: { color: '#666' } }, xAxis: { show: true, type: 'category', data: , 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: ((name, index) => [index, [index]]), type: 'scatter', label: { //Resident display value tag show: true, position: 'top', // Tag location color: '#666' }, itemStyle: { color: '#5470c6' } } ] }; break; default: option = {}; } (option) ('option',option) } // Listen to the graph click eventonMounted(() => { initChart() chartInstance?.on('click', (params) => { = true; = ?? -1; }); }) // Handle X-axis data changesconst handleXAxisChange = (index: number, value: string) => { [index] = value updateChart() } // Process series of data changesconst handleSeriesChange = (index: number, value: string) => { [index] = parseFloat(value) updateChart() } // Modal dialog box statusconst showModalSingle = ref(false); const showModalAll = ref(false); const selectedDataIndex = ref(-1); // Calculate properties: Get the selected X-axis valueconst selectedXAxisValue = computed({ get: () => [], set: (newValue) => handleXAxisChange(, newValue) }); // Calculation attribute: Get the selected series data valueconst selectedSeriesValue = computed({ get: () => [].toString(), set: (newValue) => handleSeriesChange(, newValue) }); // Add data pointsconst addDataPoint = () => { (`New data points ${ + 1}`); (0); updateChart(); // Update the chart to reflect the added data points}; // Delete data pointsconst deleteDataPoint = (index: number) => { (index, 1); (index, 1); updateChart(); }; </script> <template> <!-- Chart container --> <div ref="chartRef" :style="{ width: '100%', height: '400px', backgroundColor: '#fff', borderRadius: '8px', boxShadow: '0 2px 4px rgba(0, 0, 0, 0.1)' }"></div> <!-- Chart type selection --> <select v-model="chartType" @change="updateChart" style="margin-top: 20px; padding: 8px; border: 1px solid #ccc; border-radius: 4px;"> <option value="line">Line chart</option> <option value="bar">Bar chart</option> <option value="pie">Pie chart</option> <option value="scatter">Scatter plot</option> </select> <!-- Edit all data button --> <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;"> Edit all data </button> <!-- Single Data Point Modal Dialog --> <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>Edit data points {{ selectedDataIndex + 1 }}</h3> <div> <label>XAxis data:</label> <input :value="selectedXAxisValue" @input="selectedXAxisValue = ($ as HTMLInputElement).value" style="width: 100%; padding: 8px; margin-top: 5px; border: 1px solid #ccc; border-radius: 4px;" /> </div> <div> <label>Series data:</label> <input :value="selectedSeriesValue" @input="selectedSeriesValue = ($ 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;"> closure </button> </div> </div> <!-- All data modal dialogs --> <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>Edit all data</h3> <table style="width: 100%; border-collapse: collapse;"> <thead> <tr> <th style="padding: 8px; text-align: left; background-color: #f2f2f2; color: #333;">Serial number</th> <th style="padding: 8px; text-align: left; background-color: #f2f2f2; color: #333;">X-axis data</th> <th style="padding: 8px; text-align: left; background-color: #f2f2f2; color: #333;">Series of data</th> <th style="padding: 8px; text-align: left; background-color: #f2f2f2; color: #333;">Operation</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, ($ 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, ($ 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;"> delete </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;"> Add data points </button> <button @click="showModalAll = false" style="margin-top: 10px; padding: 8px 16px; background-color: #5470c6; color: #fff; border: none; border-radius: 4px; cursor: pointer;"> closure </button> </div> </div> </template>
This is the end of this article about code examples for creating interactive charts using Vue and ECharts. For more related Vue ECharts interactive chart content, please search for my previous articles or continue browsing the related articles below. I hope everyone will support me in the future!