提交 f12e2966 authored 作者: lidongxu's avatar lidongxu

feat(index.vue): 新增首页几个模拟图表

同上
上级 e34f913d
export * from './date.js'
export * from './resize.js'
import { onMounted, onBeforeUnmount } from 'vue';
export function useWindowResize(callback) {
let resizeTimer = null
let handleResize = () => {
clearTimeout(resizeTimer)
resizeTimer = setTimeout(() => {
callback()
}, 200)
}
let observer = new ResizeObserver(handleResize);
onMounted(() => {
// 监听侧边栏宽度改变,右边图表要重新绘制
observer.observe(document.querySelector('.sidebar-container'))
window.addEventListener('resize', callback);
});
onBeforeUnmount(() => {
if (observer) {
observer.disconnect();
clearTimeout(resizeTimer)
resizeTimer = null
observer = null
handleResize = null
}
window.removeEventListener('resize', callback);
});
}
\ No newline at end of file
......@@ -7,6 +7,7 @@
<script setup>
import * as echarts from 'echarts'
import { formatNumberWithUnit } from '@/utils'
import { useWindowResize } from '@/hooks'
const props = defineProps({
className: {
type: String,
......@@ -174,18 +175,16 @@ const initChart = () => {
const resize = () => {
chart.value.resize()
}
useWindowResize(resize)
onMounted(() => {
nextTick(() => {
initChart()
window.addEventListener('resize', resize)
})
})
onBeforeUnmount(() => {
if (!chart.value) {
return
}
window.removeEventListener('resize', resize)
chart.value.dispose()
chart.value = null
})
......
......@@ -62,7 +62,7 @@
import LineCharts from './LineAndBar.vue'
import { getCmmListAPI } from '@/api'
import { generatorDayList, parseTime, getBrandColor, resetObjValue } from '@/utils'
import { useDatePickerOptions } from '@/hooks/date'
import { useDatePickerOptions } from '@/hooks'
// 静态数据
const dateList = [new Date().setDate((new Date().getDate() - 30)), new Date().setDate((new Date().getDate() - 1))] // 最近 30 日日期数组
......
......@@ -7,6 +7,8 @@
<script setup>
import * as echarts from 'echarts'
import { formatNumberWithUnit } from '@/utils'
import { useWindowResize } from '@/hooks'
const props = defineProps({
className: {
type: String,
......@@ -108,11 +110,10 @@ const initChart = () => {
const resize = () => {
chart.value.resize()
}
useWindowResize(resize)
onMounted(() => {
nextTick(() => {
initChart()
window.addEventListener('resize', resize)
})
})
......@@ -120,7 +121,6 @@ onBeforeUnmount(() => {
if (!chart.value) {
return
}
window.removeEventListener('resize', resize)
chart.value.dispose()
chart.value = null
})
......
......@@ -66,7 +66,7 @@ import GradientArea from './GradientArea.vue';
import TableList from './TableList.vue';
import { getSycmStoreListAPI } from '@/api'
import { generatorDayList, parseTime, getBrandColor, resetObjValue } from '@/utils'
import { useDatePickerOptions } from '@/hooks/date'
import { useDatePickerOptions } from '@/hooks'
// 静态数据
const dateList = [new Date().setDate((new Date().getDate() - 30)), new Date().setDate((new Date().getDate() - 1))] // 最近 30 日日期数组
......
<template>
<div ref="chartRef"
:class="className"
:style="{ height: height, width: width }" />
</template>
<script setup>
import * as echarts from 'echarts'
import { useWindowResize } from '@/hooks'
defineProps({
className: {
type: String,
default: 'chart'
},
width: {
type: String,
default: '100%'
},
height: {
type: String,
default: '300px'
}
})
let chart = null
const chartRef = ref(null)
const initChart = () => {
chart = echarts.init(chartRef.value)
chart.setOption({
tooltip: {
trigger: 'axis',
axisPointer: { // 坐标轴指示器,坐标轴触发有效
type: 'shadow' // 默认为直线,可选为:'line' | 'shadow'
}
},
grid: {
top: 10,
left: '2%',
right: '2%',
bottom: '3%',
containLabel: true
},
xAxis: [{
type: 'category',
data: ['周一', '周二', '周三', '周四', '周五', '周六', '周日'],
axisTick: {
alignWithLabel: true
}
}],
yAxis: [{
type: 'value',
axisTick: {
show: false
}
}],
series: [{
name: '虎皮凤爪',
type: 'bar',
stack: 'vistors',
barWidth: '60%',
data: [79, 52, 200, 334, 390, 330, 220],
}, {
name: '冷热双吃',
type: 'bar',
stack: 'vistors',
barWidth: '60%',
data: [80, 52, 200, 334, 390, 330, 220],
}, {
name: '去骨凤爪',
type: 'bar',
stack: 'vistors',
barWidth: '60%',
data: [30, 52, 200, 334, 390, 330, 220],
}]
})
}
const resize = () => {
chart.resize()
}
useWindowResize(resize)
onMounted(() => {
nextTick(() => {
initChart()
})
})
onBeforeUnmount(() => {
if (!chart) {
return
}
chart.dispose()
chart = null
})
</script>
<template>
<div ref="chartRef"
:class="className"
:style="{ height: height, width: width }" />
</template>
<script setup>
import * as echarts from 'echarts'
import { useWindowResize } from '@/hooks'
const props = defineProps({
className: {
type: String,
default: 'chart'
},
width: {
type: String,
default: '100%'
},
height: {
type: String,
default: '350px'
},
autoResize: {
type: Boolean,
default: true
},
chartData: {
type: Object,
required: true
}
})
let chart = {}
const chartRef = ref(null)
const setOptions = () => {
chart.setOption({
xAxis: {
data: ['6月', '7月', '8月', '9月', '10月', '11月', '12月'],
boundaryGap: false,
axisTick: {
show: false
}
},
grid: {
left: 10,
right: 10,
bottom: 20,
top: 30,
containLabel: true
},
tooltip: {
trigger: 'axis',
axisPointer: {
type: 'cross'
},
padding: [5, 10]
},
yAxis: {
axisTick: {
show: false
}
},
legend: {
data: ['今年销量', '去年销量'],
textStyle: {
color: '#888'
}
},
series: [{
name: '今年销量', itemStyle: {
// normal: {
color: '#FF005A',
lineStyle: {
color: '#FF005A',
width: 2
}
// }
},
smooth: true,
type: 'line',
data: props.chartData.expectedData,
animationEasing: 'cubicInOut'
},
{
name: '去年销量',
smooth: true,
type: 'line',
itemStyle: {
// normal: {
color: '#3888fa',
lineStyle: {
color: '#3888fa',
width: 2
},
areaStyle: {
color: '#f3f8ff'
}
// }
},
data: props.chartData.actualData,
animationEasing: 'quadraticOut'
}]
})
}
watch(() => props.chartData, (newData, oldData) => {
setOptions();
}, { deep: true });
const initChart = () => {
chart = echarts.init(chartRef.value)
setOptions()
}
const resize = () => {
chart.resize()
}
useWindowResize(resize)
onMounted(() => {
nextTick(() => {
initChart()
})
})
onBeforeUnmount(() => {
if (!chart) {
return
}
chart.dispose()
chart = null
})
</script>
......@@ -91,7 +91,10 @@
<script setup>
import { CountTo } from 'vue3-count-to'
const handleSetLineChartData = () => {}
const emits = defineEmits(['handleSetLineChartData'])
const handleSetLineChartData = (type) => {
emits('handleSetLineChartData', type)
}
</script>
<style lang="scss"
......
<template>
<div ref="chartRef"
:class="className"
:style="{ height: height, width: width }" />
</template>
<script setup>
import * as echarts from 'echarts'
import { useWindowResize } from '@/hooks'
defineProps({
className: {
type: String,
default: 'chart'
},
width: {
type: String,
default: '100%'
},
height: {
type: String,
default: '300px'
}
})
let chart = null
const chartRef = ref(null)
const initChart = () => {
chart = echarts.init(chartRef.value)
chart.setOption({
tooltip: {
trigger: 'item',
formatter: '{a} <br/>{b} : {c} ({d}%)'
},
legend: {
left: 'center',
bottom: '10',
data: ['北京', '上海', '广州', '深圳', '杭州'],
textStyle: {
color: '#888'
}
},
series: [
{
name: '客户分布地图',
type: 'pie',
roseType: 'radius',
radius: [15, 95],
center: ['50%', '38%'],
data: [
{ value: 320, name: '北京' },
{ value: 240, name: '上海' },
{ value: 149, name: '广州' },
{ value: 100, name: '深圳' },
{ value: 59, name: '杭州' }
],
animationEasing: 'cubicInOut',
}
]
})
}
const resize = () => {
chart.resize()
}
useWindowResize(resize)
onMounted(() => {
nextTick(() => {
initChart()
})
})
onBeforeUnmount(() => {
if (!chart) {
return
}
chart.dispose()
chart = null
})
</script>
<template>
<div ref="chartRef"
:class="className"
:style="{ height: height, width: width }" />
</template>
<script setup>
import * as echarts from 'echarts'
import { onBeforeUnmount } from 'vue'
import { useWindowResize } from '@/hooks'
defineProps({
className: {
type: String,
default: 'chart'
},
width: {
type: String,
default: '100%'
},
height: {
type: String,
default: '300px'
}
})
let chart = null
const chartRef = ref(null)
const initChart = () => {
chart = echarts.init(chartRef.value)
chart.setOption({
tooltip: {
trigger: 'axis',
axisPointer: { // 坐标轴指示器,坐标轴触发有效
type: 'shadow' // 默认为直线,可选为:'line' | 'shadow'
}
},
radar: {
radius: '66%',
center: ['50%', '42%'],
splitNumber: 8,
splitArea: {
areaStyle: {
color: 'rgba(127,95,132,.3)',
opacity: 1,
shadowBlur: 45,
shadowColor: 'rgba(0,0,0,.5)',
shadowOffsetX: 0,
shadowOffsetY: 15
}
},
indicator: [
{ name: '北京', },
{ name: '上海', },
{ name: '广州', },
{ name: '深圳', },
{ name: '杭州', },
{ name: '厦门', }
]
},
legend: {
left: 'center',
bottom: '10',
data: ['营销中心', '人力资源中心', '财务中心'],
textStyle: {
color: '#888'
}
},
series: [{
type: 'radar',
symbolSize: 0,
areaStyle: {
// normal: {
shadowBlur: 13,
shadowColor: 'rgba(0,0,0,.2)',
shadowOffsetX: 0,
shadowOffsetY: 10,
opacity: 1
// }
},
data: [
{
value: [5000, 7000, 12000, 11000, 15000, 14000],
name: '营销中心'
},
{
value: [4000, 9000, 15000, 15000, 13000, 11000],
name: '人力资源中心'
},
{
value: [5500, 11000, 12000, 15000, 12000, 12000],
name: '财务中心'
}
]
}]
})
}
const resize = () => {
chart.resize()
}
useWindowResize(resize)
onMounted(() => {
nextTick(() => {
initChart()
})
})
onBeforeUnmount(() => {
if (!chart) {
return
}
chart.dispose()
chart = null
})
</script>
<template>
<div class="dashboard-editor-container">
<panel-group />
<panel-group @handleSetLineChartData="handleSetLineChartData" />
<common-menu></common-menu>
<el-row :gutter="32">
<el-col :xs="24"
:sm="24"
:lg="8">
<div class="chart-wrapper">
<raddar-chart />
</div>
</el-col>
<el-col :xs="24"
:sm="24"
:lg="8">
<div class="chart-wrapper">
<pie-chart />
</div>
</el-col>
<el-col :xs="24"
:sm="24"
:lg="8">
<div class="chart-wrapper">
<bar-chart />
</div>
</el-col>
</el-row>
<el-row class="line-chart">
<line-chart :chart-data="lineChartData" />
</el-row>
</div>
</template>
<script setup>
import PanelGroup from './dashboard/PanelGroup.vue'
import RaddarChart from './dashboard/RaddarChart'
import PieChart from './dashboard/PieChart'
import BarChart from './dashboard/BarChart'
import LineChart from './dashboard/LineChart'
const lineChartObj = {
newVisitis: {
expectedData: [100, 120, 161, 134, 105, 160, 165],
actualData: [120, 82, 91, 154, 162, 140, 145]
},
messages: {
expectedData: [200, 192, 120, 144, 160, 130, 140],
actualData: [180, 160, 151, 106, 145, 150, 130]
},
purchases: {
expectedData: [80, 100, 121, 104, 105, 90, 100],
actualData: [120, 90, 100, 138, 142, 130, 130]
},
shoppings: {
expectedData: [130, 140, 141, 142, 145, 150, 160],
actualData: [120, 82, 91, 154, 162, 140, 130]
}
}
const lineChartData = ref(lineChartObj.newVisitis)
const handleSetLineChartData = (type) => {
lineChartData.value = lineChartObj[type]
}
</script>
<style lang="scss"
scoped>
.dashboard-editor-container {
padding: 32px;
.chart-wrapper {
background: var(--el-bg-color-overlay);
padding: 16px 16px 0;
margin: 32px 0;
}
.line-chart {
background: var(--el-bg-color-overlay);
padding: 16px 16px 0;
margin-bottom: 32px;
}
}
</style>
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论