123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304 |
- <template>
- <div style="height: 100%; width: 100%">
- <div class="chart-title">
- <div class="name" :title="title">
- {{ title }}
- </div>
- <div class="operation">
- <!-- <el-button size="mini" plain @click="initChart()">
- <span class="icon iconfont icontjfx"></span>
- </el-button>
- <el-button size="mini" plain @click="initTable()">
- <span class="icon iconfont icontongjibiao"></span>
- </el-button> -->
- <el-radio v-model="showType" label="chart">chart</el-radio>
- <el-radio v-model="showType" label="table">表格</el-radio>
- <div class="operation-btn" @click="downLoadInfo()">
- <img class="icon" :src="require('../../images/download.png')" />
- <label>下载</label>
- </div>
- <!-- <div class="operation-btn">
- <img class="icon" :src="require('../../images/expand.png')" />
- <label>展开</label>
- </div> -->
- </div>
- </div>
- <div class="dataContainer">
- <div class="IndexLineChart" ref="chart" v-if="!isShowTable"></div>
- <el-table id="dataTable" :data="tableData" v-if="isShowTable" style="width: 100%; height: 100%; overflow: auto">
- <el-table-column
- v-for="item of tabelColumn"
- :key="item.value"
- :prop="item.prop"
- :label="item.label"
- show-overflow-tooltip
- ></el-table-column>
- </el-table>
- </div>
- </div>
- </template>
- <script lang='ts'>
- import echarts, { ECharts } from 'echarts'
- import html2canvas from 'html2canvas'
- import XLSX from 'xlsx'
- import FileSaver from 'file-saver'
- import { Vue, Component, Prop, Watch } from 'vue-property-decorator'
- @Component({ name: 'IndexLineChart', components: {} })
- export default class IndexLineChart extends Vue {
- @Prop({ type: Object, default: () => ({}) }) chartData!: any
- @Watch('chartData', { immediate: true })
- onChangeMethod() {
- this.$nextTick(() => {
- this.initialChart()
- })
- }
- @Prop({ type: Boolean, default: false }) isActive!: boolean
- @Watch('isActive', { immediate: true })
- refetchData(active: boolean) {
- if (active) this.onResize()
- }
- get title() {
- return `${this.chartData.siteName}:${this.chartData.indexName}${
- this.chartData.unit ? `(${this.chartData.unit})` : ''
- }`
- }
- myChart = null
- isShowTable = false
- tableData = []
- tabelColumn = [
- {
- prop: 'siteName',
- label: '厂站'
- },
- {
- prop: 'indexName',
- label: '指标'
- },
- {
- prop: 'staType',
- label: '统计内容'
- },
- {
- prop: 'data',
- label: '指标值'
- },
- {
- prop: 'time',
- label: '时间'
- }
- ]
- showType = 'chart'
- @Watch('showType', { immediate: true })
- showTypeChangeMethod(type) {
- this.$nextTick(() => {
- type == 'chart' ? this.initChart() : this.initTable()
- })
- }
- destroyChart() {
- if (this.myChart != null) {
- this.myChart.dispose()
- this.myChart = null
- }
- }
- onResize() {
- if (this.myChart) {
- this.myChart.resize()
- }
- }
- initialChart() {
- this.destroyChart()
- const { xData: xaxis, seriesData, tableData, siteName, indexName } = this.chartData
-
- this.tableData = tableData.map((i) => {
- return {
- ...i,
- siteName,
- indexName
- }
- })
-
- let seriesValue = []
- seriesData.forEach((item) => {
- seriesValue.push({
- name: item.name,
- data: item.data,
- type: 'line',
- smooth: true
-
- })
- })
- let option = {
- grid: {
- bottom: 20,
- top: 50,
- right: 20,
- left: 20,
- containLabel: true
- },
- tooltip: {
- trigger: 'axis'
- },
- xAxis: {
- type: 'category',
- axisLine: { show: false },
- axisTick: { show: false },
- data: xaxis
- },
- yAxis: {
- type: 'value',
- name: '',
- nameTextStyle: {
- padding: [0, 0, 0, -40],
- align: 'left',
- color: '#2D74E7',
- fontWeight: '500',
- fontSize: '14',
- fontFamily: 'Source Han Sans CN'
- },
- nameGap: 30,
- axisLine: { show: false },
- axisTick: { show: false }
- },
- series: seriesValue
- }
- this.creatChart(option, this.$refs.chart)
- }
- creatChart(option, ref) {
- this.myChart = echarts.init(ref)
- this.myChart.resize()
- this.myChart.setOption(option, {
- notMerge: true
- })
-
- window.addEventListener('resize', () => {
- this.myChart.resize()
- })
- }
- initTable() {
- this.isShowTable = true
- }
- initChart() {
- this.isShowTable = false
- this.$nextTick(() => {
- this.initialChart()
- })
- }
-
- downLoadInfo() {
- if (this.isShowTable) {
- this.exportTable()
- } else {
- this.exportChart()
- }
- }
- exportTable() {
- let wb = XLSX.utils.table_to_book(document.querySelector('#dataTable'), { raw: true })
- let wbout = XLSX.write(wb, {
- bookType: 'xlsx',
- bookSST: true,
- type: 'array'
- })
- try {
- FileSaver.saveAs(new Blob([wbout], { type: 'application/octet-stream' }), '数据表格.xlsx')
- } catch (e) {
- if (typeof console !== 'undefined') console.log(e, wbout)
- }
- return wbout
- }
- exportChart() {
-
-
- html2canvas(this.$refs.chart).then(function (canvas) {
- var img = canvas.toDataURL('image/png').replace('image/png', 'image/octet-stream')
-
- var creatIMg = document.createElement('a')
- creatIMg.download = `图表.png`
- creatIMg.href = img
- document.body.appendChild(creatIMg)
- creatIMg.click()
- creatIMg.remove()
- })
- }
- }
- </script>
- <style lang="scss" scoped>
- .chart-title {
- display: flex;
- justify-content: space-between;
- align-items: center;
- font-size: 16px;
- position: relative;
- margin-top: 10px;
- height: 20px;
- .name {
- font-family: Source Han Sans CN-Medium;
- font-style: normal;
- font-weight: 500;
- font-size: 14px;
- color: #2d74e7;
- white-space: nowrap;
- overflow: hidden;
- text-overflow: ellipsis;
- }
- .operation {
-
-
-
- display: flex;
- align-items: center;
- @mixin font() {
- color: #333333;
- font-family: Source Han Sans CN;
- font-style: normal;
- font-weight: 400;
- font-size: 14px;
- }
- .el-button {
- padding: 2px;
- border: none;
- color: #333333;
- }
- >>> .el-radio {
- .el-radio__label {
- @include font();
- padding-left: 5px;
- }
- .el-radio__inner::after {
- height: 8px;
- width: 8px;
- background-color: #2083e8;
- }
- .el-radio__inner {
- border: 1px solid rgba(128, 175, 214, 1);
- background-color: transparent;
- }
- }
- .operation-btn {
- display: flex;
- align-items: center;
- cursor: pointer;
- margin-right: 30px;
- .icon {
- height: 14px;
- width: 14px;
- margin-right: 5px;
- }
- label {
- @include font();
- cursor: pointer;
- white-space: nowrap;
- }
- }
- }
- }
- .dataContainer {
- width: 100%;
- height: calc(100% - 30px);
- .IndexLineChart {
- width: 100%;
- height: 100%;
- }
- }
- </style>
|