首页 前端知识 ECharts接收dataset类型数据封装各类型图形组件

ECharts接收dataset类型数据封装各类型图形组件

2024-06-10 23:06:08 前端知识 前端哥 231 562 我要收藏

数据平台整合matabase图表,调用matabase已有接口使用echarts实现图表展示

目标

将各类型图形独立封装为组件
将多个组件整体封装成一个组件
使用时只需传入组件名和对应数据即可

展示

在这里插入图片描述

数据格式

ECharts中dataset配置
在这里插入图片描述

公共组件

在这里插入图片描述

示例饼图 pie-chart

在这里插入图片描述

pie-chart common.js
let commonOption = {
title: {
text: '标题',
},
legend: {},
tooltip: {
trigger: 'item',
},
toolbox: {
show: true,
feature: {
saveAsImage: { show: true },
},
},
dataset: {
dimensions: [],
source: [],
},
// grid: {
// top:"0",
// bottom: '0',
// containLabel: true,
// },
series: [
{
type: 'pie',
radius: ['40%', '70%'],
// center: ['50%', '25%'],
// label: {
// formatter: '{b}: {@2013} ({d}%)',
// },
encode: {
itemName: 'product',
value: '2013',
tooltip: [0, 1],
},
},
],
}
export { commonOption }
复制
pie-chart options.js
import { commonOption } from './common'
import { deepCopy } from '@utils/index'
function getOption(requestData, cardData) {
console.log('饼图CbnPieChart')
console.log('requestData', requestData)
console.log('cardData', cardData)
let option = deepCopy(commonOption)
// 数组数据对应字段名
option.dataset.dimensions = requestData.cols
// 二维数组数据
option.dataset.source = requestData.rows
// 左上角标题
option.title.text = cardData.name
// 维度
let itemName = cardData.visualization_settings['pie.dimension']
// 衡量标准
let value = cardData.visualization_settings['pie.metric']
// 设置series
option.series = [
{
type: 'pie',
radius: ['40%', '70%'],
encode: {
itemName: itemName,
value: value,
tooltip: Array.from(Array(requestData.cols.length), (v, k) => k),
},
},
]
return option
}
export { getOption }
复制
pie-chart index.vue
<template>
  <div class="chart-box">
    <div class="chart" ref="chart"></div>
  </div>
</template>

<script>
import { getOption } from './option'
import ChartShow from '@mixins/chart-show'
export default {
  name: 'CbnPieChart',
  mixins: [ChartShow(getOption)],
}
</script>
<style lang="scss" scoped>
.chart-box {
  width: 100%;
  height: 100%;

  .chart {
    width: 100%;
    height: 100%;
  }
}
</style>

复制

展示饼图

<div style="width: 100%; height: 800px">
      <cbn-chart :myComponent="myComponent8"></cbn-chart>
</div>
    
import CbnChart from '@components/cbn-chart'
import { data as data8, cardData as cardData8 } from './pieData'
components: {
    CbnChart,
  },
myComponent8: {
        componentName: 'CbnPieChart',
        requestData: data8.data,
        cardData: cardData8,
 },
复制
pieData.js
let data = {
data: {
rows: [
[42, 'Doohickey'],
[51, 'Gizmo'],
[53, 'Gadget'],
[54, 'Widget'],
],
cols: [
{
display_name: 'NUM',
source: 'native',
field_ref: ['field', 'NUM', { 'base-type': 'type/BigInteger' }],
name: 'NUM',
base_type: 'type/BigInteger',
effective_type: 'type/BigInteger',
},
{
display_name: 'CATEGORY',
source: 'native',
field_ref: ['field', 'CATEGORY', { 'base-type': 'type/Text' }],
name: 'CATEGORY',
base_type: 'type/Text',
effective_type: 'type/Text',
},
],
native_form: {
query: 'select count(id) num, category from products group by category',
params: null,
},
results_timezone: 'Asia/Shanghai',
results_metadata: {
columns: [
{
display_name: 'NUM',
field_ref: ['field', 'NUM', { 'base-type': 'type/BigInteger' }],
name: 'NUM',
base_type: 'type/BigInteger',
effective_type: 'type/BigInteger',
semantic_type: null,
fingerprint: {
global: { 'distinct-count': 4, 'nil%': 0.0 },
type: {
'type/Number': {
min: 42.0,
q1: 46.5,
q3: 53.5,
max: 54.0,
sd: 5.477225575051661,
avg: 50.0,
},
},
},
},
{
display_name: 'CATEGORY',
field_ref: ['field', 'CATEGORY', { 'base-type': 'type/Text' }],
name: 'CATEGORY',
base_type: 'type/Text',
effective_type: 'type/Text',
semantic_type: null,
fingerprint: {
global: { 'distinct-count': 4, 'nil%': 0.0 },
type: {
'type/Text': {
'percent-json': 0.0,
'percent-url': 0.0,
'percent-email': 0.0,
'percent-state': 0.0,
'average-length': 6.5,
},
},
},
},
],
},
insights: null,
},
database_id: 1,
started_at: '2023-01-14T14:53:22.235+08:00',
json_query: {
constraints: { 'max-results': 10000, 'max-results-bare-rows': 2000 },
type: 'native',
middleware: { 'js-int-to-string?': true, 'ignore-cached-results?': false },
native: {
query: 'select count(id) num, category from products group by category',
'template-tags': {},
},
database: 1,
'async?': true,
'cache-ttl': null,
},
average_execution_time: null,
status: 'completed',
context: 'dashboard',
row_count: 4,
running_time: 5,
}
let cardData = {
description: null,
archived: false,
collection_position: null,
table_id: null,
result_metadata: [
{
display_name: 'CATEGORY',
field_ref: [
'field',
'CATEGORY',
{
'base-type': 'type/Text',
},
],
name: 'CATEGORY',
base_type: 'type/Text',
effective_type: 'type/Text',
semantic_type: null,
fingerprint: {
global: {
'distinct-count': 4,
'nil%': 0.0,
},
type: {
'type/Text': {
'percent-json': 0.0,
'percent-url': 0.0,
'percent-email': 0.0,
'percent-state': 0.0,
'average-length': 6.5,
},
},
},
},
{
display_name: 'NUM',
field_ref: [
'field',
'NUM',
{
'base-type': 'type/BigInteger',
},
],
name: 'NUM',
base_type: 'type/BigInteger',
effective_type: 'type/BigInteger',
semantic_type: null,
fingerprint: {
global: {
'distinct-count': 4,
'nil%': 0.0,
},
type: {
'type/Number': {
min: 42.0,
q1: 46.5,
q3: 53.5,
max: 54.0,
sd: 5.477225575051661,
avg: 50.0,
},
},
},
},
],
database_id: 1,
enable_embedding: false,
collection_id: null,
query_type: 'native',
name: 'product-bing',
query_average_duration: 3,
creator_id: 5,
moderation_reviews: [],
updated_at: '2023-01-14T17:26:07.853',
made_public_by_id: null,
embedding_params: null,
cache_ttl: null,
dataset_query: {
type: 'native',
native: {
query: 'select category ,count(id) num from products group by category',
'template-tags': {},
},
database: 1,
},
id: 37,
display: 'pie',
visualization_settings: {
'pie.show_legend_perecent': true,
'pie.colors': {
Doohickey: '#509EE3',
Gadget: '#F9D45C',
Gizmo: '#A989C5',
Widget: '#F2A86F',
},
'pie.dimension': 'CATEGORY',
'pie.metric': 'NUM',
'table.pivot_column': 'CATEGORY',
'table.cell_column': 'NUM',
},
dataset: false,
created_at: '2023-01-14T14:11:42.502',
public_uuid: null,
}
export { data, cardData }
复制

公共index.js

批量获取组件导入整体组件

// 自动加载
const componentsContext = require.context('./', true, /(index\.vue)$/)
let components = {}
componentsContext.keys().forEach((component) => {
const componentConfig = componentsContext(component)
components[componentConfig.default.name] = componentConfig.default
})
export const importComponents = components
复制

整体组件index.vue

<template>
  <div class="charts">
    <component v-if="myComponent" :is="myComponent.componentName" v-bind="myComponent" />
  </div>
</template>

<script>
import { importComponents } from './components/index'
export default {
  name: 'Chart',
  components: {
    ...importComponents,
  },
  props: {
    myComponent: {
      type: Object,
      default: function () {
        return null
      },
    },
  },
}
</script>
<style lang="scss" scoped>
.charts {
  width: 100%;
  height: 100%;
}
</style>

复制

mixins写一个混入方法,将公共代码提取出来 chart-show.js

import '@components/cbn-chart/theme-walden.js'
export default function (getOption) {
return {
props: {
requestData: {
type: Object,
default: () => {
return {}
},
},
cardData: {
type: Object,
default: () => {
return {}
},
},
},
data() {
return {
myChart: null,
option: null,
}
},
mounted() {
this.reloadChart()
window.addEventListener('resize', () => {
this.reloadChart()
})
},
beforeDestroy() {
this.disposeChart()
},
methods: {
drawChart() {
this.option = getOption(this.requestData, this.cardData)
let chartDom = this.$refs.chart
this.$nextTick(() => {
this.myChart = this.$echarts.init(chartDom, 'walden')
this.myChart.setOption(this.option)
this.myChart.resize()
})
},
// 重新加载图表
reloadChart() {
this.disposeChart()
this.drawChart()
},
// 销毁图表以及重置各个数据
disposeChart() {
if (this.myChart) {
this.myChart.dispose()
}
},
},
}
}
复制

相关代码

链接:https://pan.baidu.com/s/1Ca34Xzp7jtE3nbzpJyNliw
提取码:ozbk

转载请注明出处或者链接地址:https://www.qianduange.cn//article/11812.html
标签
评论
还可以输入200
共0条数据,当前/页
发布的文章

JQuery中的load()、$

2024-05-10 08:05:15

大家推荐的文章
会员中心 联系我 留言建议 回顶部
复制成功!