<template>
<div :id="chartId" style="width: 100%; height: 100%"></div>
</template>
<script>
import * as echarts from 'echarts';
export default {
props: {
data: {
type: Array,
default: () => {
return ['宿舍', '教学楼', '办公楼', '实验室', '后勤用房', '食堂', '体育场馆', '礼堂'];
}
},
xAxisData: {
type: Array,
default: () => {
return [56, 48, 32, 28, 20, 12, 6, 4];
}
},
title: {
type: String,
default: null
}
},
created() {
this.chartId = Math.random();
},
data: () => ({
chartId: null,
chart: null
}),
mounted() {
// 等待dom渲染完毕之后,在渲染图表
setTimeout(() => {
this.renderChart();
}, 500);
// 更新dom之后执行窗口自适应
this.$nextTick(() => {
window.addEventListener('resize', this.handleResize);
});
},
watch: {
// 监听data和xAxisData的变化,当数据发生改变时重新渲染图表
data: {
deep: true,
handler() {
this.renderChart();
}
},
xAxisData: {
deep: true,
handler() {
this.renderChart();
}
}
},
methods: {
renderChart() {
this.chart = echarts.init(document.getElementById(this.chartId));
// 配置图表选项
const options = {
title: {
text: this.title,
left: 'center', // 将标题水平居中
top: 'top' // 将标题垂直置顶
},
xAxis: {
type: 'category',
data: this.xAxisData,
position: 'bottom',
axisLabel: {
interval: 0 // 设置 x 轴标签全部显示
}
},
yAxis: {
type: 'value'
},
series: [
{
data: this.data,
type: 'bar',
barWidth: 20, // 调整柱状图的宽度为 5
showBackground: true,
itemStyle: {
color: '#5EAEE8' // 修改柱状图颜色为红色
},
backgroundStyle: {
color: 'rgba(180, 180, 180, 0)'
},
label: {
show: true,
position: 'top',
color: '#333',
fontSize: 12
}
}
],
grid: {
x: '10%', //x 偏移量
y: '10%', // y 偏移量
width: '85%', // 占canvas的宽度
height: '60%' // 占canvas的高度
}
};
//数用于清空图表的内容和状态。通过调用该函数,可以清除之前设置的数据、样式等配置项,使图表重新回到初始状态,以便进行新的数据渲染。
this.chart.clear();
// 函数用于设置图表的配置项。在该函数中,使用传入的 options 参数来更新图表的属性和样式。第二个参数 true 表示在设置配置项时,是否合并已有的配置项。如果为 true,则将新的配置项与已有的配置项进行合并;如果为 false,则使用新的配置项完全替换已有的配置项。
this.chart.setOption(options, true);
this.$nextTick(() => {
//使用 $nextTick() 来延迟执行图表的 resize() 方法,以确保在 DOM 更新完成后再调整图表的大小,以适应变化后的容器尺寸。
this.chart.resize();
});
},
handleResize() {
this.chart.resize();
}
},
beforeDestroy() {
//当不再需要使用某个图表实例时,可以调用 dispose() 方法来释放该实例。这会清除实例内部的资源,解绑事件处理程序,以及删除与图表相关的 DOM 元素。通过释放图表实例,可以避免内存泄漏和冗余的资源占用。
this.chart.dispose();
//销毁自适应函数
window.removeEventListener('resize', this.handleResize);
}
};
</script>
<style>
.chart-container {
width: 200px;
height: 200px;
}
</style>
以下是tab代码
结构:
<div class="tab-container">
<ul class="tab-nav">
<li v-for="(tab, index) in tabs" :key="index" :class="{ active: tab.expanded }" @click="changeTab(index)">
{{ tab.name }}
</li>
</ul>
</div>
<div class="bottom-card">
<div v-for="(tab, index) in tabs" :key="index" class="item-box" v-show="tabs[index].expanded">
<!-- 校区 -->
<div class="item-box-I-Content">
<el-row>
<el-col :span="8">
<el-card style="margin-right: 0px" class="first">
<span class="contentTitle">统计数据</span>
<div class="card-box">
<div class="card-box-itemI card-box-item">
<img src="@/assets/img/card3.png" alt="" class="card-img" />
<div class="card-text">
<div class="card-text-I">建筑总量</div>
<div class="card-text-II">{{ totalBuilding }}</div>
</div>
</div>
<div class="card-box-itemII card-box-item">
<img src="@/assets/img/card1.png" alt="" class="card-img" />
<div class="card-text">
<div class="card-text-I">消防重点部位</div>
<div class="card-text-II">{{ fireProtectionQuantity }}</div>
</div>
</div>
<div class="card-box-itemIII card-box-item">
<img src="@/assets/img/card2.png" alt="" class="card-img" />
<div class="card-text">
<div class="card-text-I">大修中</div>
<div class="card-text-II">{{ underRepair }}</div>
</div>
</div>
</div>
</el-card>
</el-col>
<el-col :span="8">
<div style="margin-right: 0px" class="first card-columnChart">
<span class="contentTitle">建筑类型分布</span>
<BarChart :data="BarData" :xAxisData="xAxisData"></BarChart>
</div>
</el-col>
<el-col :span="8">
<div class="first card-pieChart">
<span class="contentTitle">校区分布</span>
<pieChart :data="campusdata"></pieChart>
</div>
</el-col>
</el-row>
<div class="bottom-I">
<div class="right">
<div class="top">
<div class="first">
<span class="contentTitle"
>楼层分布 <el-link class="editLink" :underline="false">查看更多</el-link></span
>
<BarCharts :data="BarDataI" :xAxisData="xAxisDataI"></BarCharts>
</div>
<div class="second">
<span class="contentTitle"
>使用年限分布<el-link class="editLink" :underline="false">查看更多</el-link></span
>
<BarChartss :data="BarDataII" :xAxisData="xAxisDataII"></BarChartss>
</div>
</div>
<div class="bottom">
<div class="first">
<span class="contentTitle"
>建筑结构分布<el-link class="editLink" :underline="false">查看更多</el-link></span
>
<pieChart :data="buildingStructure"></pieChart>
</div>
<div class="second">
<span class="contentTitle"
>耐火等级<el-link class="editLink" :underline="false">查看更多</el-link></span
>
<pieChart :data="fireResistanceRating"></pieChart>
</div>
</div>
</div>
<div class="left">
<div class="div-table">
<el-table :data="tableData" class="table" style="width: 100%">
<el-table-column type="index" label="序号" align="center" width="100">
<template slot-scope="{ $index }">
<div>
<img
v-if="isImageRow($index)"
:src="getImageUrl($index)"
alt="Image"
width="20"
height="20"
/>
<span v-if="$index >= 3"> {{ $index + 1 }}</span>
</div>
</template>
</el-table-column>
<el-table-column prop="name" label="单位名称" align="center" />
<el-table-column prop="totalCount" label="建筑数量" align="center" />
</el-table>
</div>
</div>
</div>
</div>
</div>
</div>
<script>
import BarChart from '@/views/common/BarChart.vue';
import BarCharts from '@/views/common/BarCharts.vue';
import BarChartss from '@/views/common/BarChartss.vue';
import pieChart from '@/views/common/pieChart.vue';
import pieCharts from '@/views/common/pieChartS.vue';
import { headCount, dataScreening, getcampuslist } from '@/api/CenterArchitecture/buildingoverview.js';
export default {
components: {
BarChart,
pieChart,
BarCharts,
BarChartss
},
data() {
return {
activeIndex: 0, // 当前激活的tab索引
tabs: [{ name: '全校', content: '全校', expanded: true, id: null }], //校区tab
// 建筑类型分布
BarData: [],
xAxisData: [],
// 校区分布
campusdata: [],
// 楼层分布
xAxisDataI: [],
BarDataI: [],
// 使用年限分布
xAxisDataII: [],
BarDataII: [],
// 建筑结构
buildingStructure: [],
//耐火等级
fireResistanceRating: [],
// 建筑总量
tableData: [],
totalBuilding: '', //建筑总量
fireProtectionQuantity: '', //消防重点部位
underRepair: 0, //大修中,
campusId: null, //学校id
isApi: true
};
},
mounted() {
this.headCount();
this.overviewOfBuildingData();
this.getcampus();
},
methods: {
changeTab(index) {
this.tabs.forEach((item, id) => {
if (id == index) {
item.expanded = true;
if (index == 0) {
this.campusId = null;
this.clearData();
this.overviewOfBuildingData();
} else {
this.campusId = item.id;
this.clearData();
this.overviewOfBuildingData();
}
} else {
item.expanded = false;
}
});
},
//头部数据
headCount() {
headCount().then((res) => {
this.totalBuilding = res.data.allCount;
this.fireProtectionQuantity = res.data.priorityCount;
});
},
//建筑数据总览
async overviewOfBuildingData() {
console.log('杨浦校区的id', this.campusId);
let res = await dataScreening({ statusCode: '02' }, this.campusId ? [this.campusId] : []);
let aa = res.data.buildingTypeList;
this.xAxisData = aa.map((x) => {
if (x.name) {
return x.name;
} else {
return;
}
});
this.BarData = aa.map((x) => {
if (x.totalCount) {
return x.totalCount;
} else {
return;
}
});
let bb = res.data.campusList;
bb.map((x) => {
if (x.name && x.totalCount) {
return this.campusdata.push({ value: x.totalCount, name: x.name });
} else {
return;
}
});
let cc = res.data.floorList;
cc.map((x) => {
if (x.name && x.totalCount) {
return this.xAxisDataI.push(x.name), this.BarDataI.push(x.totalCount);
} else {
return;
}
});
let dd = res.data.serviceLifeList;
dd.map((x) => {
if (x.name && x.totalCount) {
return this.xAxisDataII.push(x.name), this.BarDataII.push(x.totalCount);
} else {
return;
}
});
let ee = res.data.buildingStructureList;
ee.map((x) => {
if (x.name && x.totalCount) {
return this.buildingStructure.push({ value: x.totalCount, name: x.name });
} else {
return;
}
});
let ff = res.data.fireproofLevelList;
ff.map((x) => {
if (x.name && x.totalCount) {
return this.fireResistanceRating.push({ value: x.totalCount, name: x.name });
} else {
return;
}
});
this.tableData = res.data.orgList;
},
clearData() {
this.xAxisData = [];
this.BarData = [];
this.campusdata = [];
this.xAxisDataI = [];
this.BarDataI = [];
this.xAxisDataII = [];
this.BarDataII = [];
this.buildingStructure = [];
this.fireResistanceRating = [];
},
// 学校数据
async getcampus() {
let result = await getcampuslist({});
console.log('学校', result);
result.data.map((item) => {
if (item.name != null) {
return this.tabs.push({ name: item.name, content: item.name, expanded: false, id: item.id });
}
});
console.log(this.tabs, 'this.tabs');
},
//表格----------------------------------------------------------------
isImageRow(index) {
// 判断当前行是否为前三行
if (index < 3) {
return true; // 前三行需要显示图片
}
return false; // 其他行不需要显示图片
},
getImageUrl(index) {
// 根据索引返回对应的图片地址
if (index === 0) {
return require('@/assets/img/table1.png');
} else if (index === 1) {
return require('@/assets/img/table2.png');
} else if (index === 2) {
return require('@/assets/img/table3.png');
}
// 其他情况返回默认图片地址
return '';
}
}
};
</script>
<style lang="scss" scoped>
@import '@/assets/css/CenterArchitecture/buildingoverview.scss';
</style>
点击tab切换时