# Conflicts:
#	src/views/charts/Chart2.vue
This commit is contained in:
zhangyu
2022-01-19 17:43:47 +08:00
8 changed files with 280 additions and 14 deletions

View File

@@ -115,6 +115,86 @@
left: 0;
top: -1px;
}
.header__operations {
display: flex;
justify-content: end;
align-items: center;
.header__operation-btn {
margin-left: 12px;
cursor: pointer;
color: #999;
}
.header__operation.header__operation--table {
display: flex;
align-items: center;
height: 22px;
margin-left: 10px;
color: $--color-primary;
border: 1px solid $--color-primary;
border-radius: $--border-radius-primary;
.option__button {
display: flex;
align-items: center;
height: 100%;
padding: 0 5px;
cursor: pointer;
background-color: white;
transition: all linear .2s;
}
.option__button:hover {
background-color: #EFF2F5;
}
.option__button.icon-group-item:first-of-type:not(:last-of-type) {
padding: 0 5px 0 0;
}
.option__button.icon-group-item:last-of-type:not(:first-of-type) {
padding: 0 0 0 5px;
}
.option__select {
.el-input__inner {
width: 80px;
padding-right: 20px;
border: none;
height: 100%;
line-height: 20px;
color: $--color-primary;
}
.el-input__prefix > div {
font-weight: normal;
line-height: 19px;
color: $--color-primary;
}
.el-input__suffix {
display: flex;
.el-input__suffix-inner {
line-height: 14px;
.el-select__caret {
line-height: 14px;
width: 16px;
color: $--color-primary;
}
}
}
}
.option__select.select-column {
.el-input__inner {
width: 86px;
padding-left: 8px;
}
}
.icon-group-divide {
height: 14px;
width: 1px;
background-color: $--color-primary;
}
i {
font-size: 12px;
}
}
}
}
&>.cn-chart {
position: relative;
@@ -419,7 +499,7 @@
height: calc(100% - 40px);
}
}
&>.cn-chart__table {
&>.cn-chart__table, {
.cn-chart__header {
border-bottom: 1px solid $--content-right-background-color;
.header__operations {
@@ -832,3 +912,16 @@
content: "!";
font-weight:normal;
}
.ip-detail-as {
color: #999;
font-size: 12px;
padding-left: 10px;
}
.option-popper {
.el-select-dropdown__item {
height: 24px;
line-height: 24px;
font-size: 12px;
}
}

View File

@@ -45,6 +45,10 @@ export default {
}
},
mounted () {
const _this = this
this.emitter.on('chart-pageNo', function () {
_this.resetPageNo()
})
this.$el.querySelector('.el-pagination__jump').childNodes[0].nodeValue = ''
}
}

View File

@@ -13,6 +13,8 @@ import 'highlight.js/styles/color-brewer.css'
import '@/assets/css/main.scss' // 样式入口
import VueGridLayout from 'vue-grid-layout'
import ElementPlus from 'element-plus'
import bus from 'tiny-emitter'
const emitter = new bus()
import dayjs from 'dayjs'
import utc from 'dayjs/plugin/utc' // dependent on utc plugin
import timezone from 'dayjs/plugin/timezone'
@@ -54,4 +56,6 @@ app.component('time-refresh', TimeRefresh)
app.component('panel-chart-list', PanelChartList)
app.mount('#app')
app.config.globalProperties.emitter = emitter
export default app

View File

@@ -68,6 +68,16 @@
:query-params="queryParams"
@showLoading="showLoading"
></chart-category-bar>
<chart-table
v-else-if="isTable"
:chart-info="chartInfo"
:chart-data="chartData"
:table="table"
:query-params="queryParams"
@showLoading="showLoading"
></chart-table>
</template>
</div>
</template>
@@ -83,6 +93,7 @@ import IpBasicInfo from '@/views/charts/charts/IpBasicInfo'
import ChartEchartLine from './charts/ChartEchartLine'
import ChartTimeBar from './charts/ChartTimeBar'
import ChartCategoryBar from './charts/ChartCategoryBar'
import ChartTable from "./charts/ChartTable";
import {
isEcharts,
isEchartsLine,
@@ -119,6 +130,7 @@ import _ from 'lodash'
export default {
name: 'chart',
components: {
ChartTable,
IpBasicInfo,
ChartSingleValue,
Loading,
@@ -140,7 +152,8 @@ export default {
loading: Boolean,
panelLock: Boolean,
entity: Object,
isError: Boolean
isError: Boolean,
table: Object
},
computed: {
isNoData () {

View File

@@ -1,8 +1,54 @@
<template>
<div class="chart-header" :class="{'chart-header--title-chart': isTitle}">
<div class="chart-header__title" :class="{'chart-header__title--block': isBlock}">{{chartInfo.name}}</div>
<div class="chart-header__title" v-if="!isTable" :class="{'chart-header__title--block': isBlock}">{{chartInfo.name}}</div>
<template v-if="isTable">
<div class="chart-header__title">
<span :title="chartInfo.i18n ? $t(chartInfo.i18n) : chartInfo.name">{{chartInfo.i18n ? $t(chartInfo.i18n) : chartInfo.name}}</span>
<span
v-if="chartInfo.params && chartInfo.params.as"
class="ip-detail-as"
>
as&nbsp;<span style="text-transform: capitalize">{{chartInfo.params.as}}</span>
</span>
</div>
<div class="header__operations">
<el-popover trigger="hover" placement="top" :content="chartInfo.remark" v-if="chartInfo.remark">
<template>
<span class="header__operation-btn"><i class="cn-icon el-icon-info"></i></span>
</template>
</el-popover>
<div class="header__operation header__operation--table">
<el-select
size="mini"
v-model="table.limit"
class="option__select select-topn"
placeholder=""
popper-class="option-popper"
@change="tableLimitChange"
>
<el-option v-for="item in chartTableTopOptions" :key="item" :value="item">TOP&nbsp;{{item}}</el-option>
<template #prefix>TOP&nbsp;</template>
</el-select>
</div>
<div class="header__operation header__operation--table">
<el-select
size="mini"
v-model="table.orderBy"
class="option__select select-column"
:placeholder="$t('overall.field')"
popper-class="option-popper"
@change="tableLimitChange"
>
<template v-for="(item, index) in table.tableColumns" :key="item.prop">
<el-option v-if="index > 0" :value="item.prop">{{item.prop}}</el-option>
</template>
</el-select>
</div>
<span class="header__operation-btn" @click="refresh"><i class="cn-icon cn-icon-refresh"></i></span>
</div>
</template>
<chart-error :isError="isError" :errorInfo="errorInfo"></chart-error>
<div class="chart-header__tools" v-if="!isTitle && !isTabs">
<div class="chart-header__tools" v-if="!isTitle && !isTabs && !isTable">
<div class="panel__time" v-if="chartInfo.params && chartInfo.params.showTimeTool">
<date-time-range class="date-time-range" :start-time="chartTimeFilter.startTime" :end-time="chartTimeFilter.endTime" ref="dateTimeRange" @change="reload"/>
<time-refresh class="date-time-range" @change="timeRefreshChange" :end-time="chartTimeFilter.endTime"/>
@@ -20,10 +66,11 @@
</template>
<script>
import { isTitle, isTabs, isBlock } from './charts/tools'
import { isTitle, isTabs, isBlock, isTable } from './charts/tools'
import ChartError from '@/components/charts/ChartError'
import { getNowTime } from '@/utils/date-util'
import { ref } from 'vue'
import {chartTableTopOptions} from "@/utils/constants";
export default {
name: 'ChartHeader',
@@ -36,7 +83,8 @@ export default {
isError: {
type: Boolean,
default: false
}
},
table: Object
},
components: {
ChartError
@@ -62,6 +110,9 @@ export default {
},
dateTimeRangeChange (s, e, v) {
this.chartTimeFilter = { startTime: s, endTime: e, dateRangeValue: v }
},
tableLimitChange () {
this.$emit('tableChange')
}
},
setup (props) {
@@ -71,9 +122,11 @@ export default {
const chartTimeFilter = ref({ startTime, endTime, dateRangeValue })
return {
chartTimeFilter,
chartTableTopOptions,
isTitle: isTitle(props.chartInfo.type),
isBlock: isBlock(props.chartInfo.type),
isTabs: isTabs(props.chartInfo.type)
isTabs: isTabs(props.chartInfo.type),
isTable: isTable(props.chartInfo.type)
}
}
}

View File

@@ -12,9 +12,11 @@
:error-info="errorInfo"
:chart-data="chartData"
:chart-info="chartInfo"
:table="table"
@loadMore="loadMore"
@refresh="refresh"
@showFullscreen="showFullscreen"
@tableChange="tableChange"
></chart-header>
<!-- chart -->
<!-- 数据查询后传入chart组件chart组件内不查询只根据接传递的数据来渲染 -->
@@ -29,6 +31,7 @@
:is-error="isError"
:loading="loading"
:entity="entity"
:table="table"
:is-fullscreen="isFullscreen"
@showLoading="showLoading"
></chart>
@@ -141,7 +144,10 @@ export default {
table: {
pageSize: chartTableDefaultPageSize,
limit: chartTableTopOptions[0], // top-n
orderBy: 'sessions'
orderBy: 'sessions',
tableColumns: [], // table字段
tableData: [], // table的所有数据
currentPageData: [] // table当前页的数据
}
}
},
@@ -186,6 +192,9 @@ export default {
}
if (response.code === 200) {
this.chartData = response.data.result
this.table.tableData = response.data.result
this.table.tableColumns = this.getTableTitle(response.data.result)
this.table.currentPageData = this.getTargetPageData(1, this.table.pageSize, this.table.tableData)
this.resultType = response.data.resultType
this.isError = false
} else {
@@ -230,6 +239,7 @@ export default {
this.standaloneTimeRange.use = true
this.standaloneTimeRange.startTime = myStartTime
this.standaloneTimeRange.endTime = myEndTime
this.emitter.emit('chart-pageNo')
this.getChartData(null, {}, true)
},
showFullscreen (show) {
@@ -284,6 +294,13 @@ export default {
},
showLoading (show) {
this.loading = show
},
tableChange () {
this.emitter.emit('chart-pageNo')
this.getChartData()
},
getTargetPageData (pageNum, pageSize, tableData) {
return this.$_.slice(tableData, (pageNum - 1) * pageSize, pageNum * pageSize)
}
},
mounted () {

View File

@@ -1,9 +1,9 @@
<template>
<div class="cn-chart__single-value chart-header-position" :class="singleValueClass(type)" :style="{backgroundColor:color}">
<div class="single-value-icon__box" v-if="chartInfo.type != 54">
<div class="single-value-icon__box" v-if="type !== 54">
<div class="single-value__icon"><i :class="icon"></i></div>
</div>
<div class="single-value__content" v-if="chartInfo.type == 51">
<div class="single-value__content" v-if="type === 51">
<div class="content__data">
<span>{{handleSingleValue[0] || handleSingleValue[0] === 0 ? handleSingleValue[0] : '-'}}</span>
<span class="single-value__unit">{{handleSingleValue[1]}}</span>
@@ -12,9 +12,12 @@
<span :title="chartInfo.i18n ? $t(chartInfo.i18n) : chartInfo.name">{{chartInfo.i18n ? $t(chartInfo.i18n) : chartInfo.name}}</span>
</div>
</div>
<div class="single-value__content single-value__content--with-chart" v-if="chartInfo.type == 52">
<div class="single-value__content single-value__content--with-chart" v-if="type === 52">
<div class="content__title">
<span :title="chartInfo.i18n ? $t(chartInfo.i18n) : chartInfo.name">{{chartInfo.i18n ? $t(chartInfo.i18n) : chartInfo.name}}</span>
<span v-if="chartInfo.params && chartInfo.params.as" class="ip-detail-as">
as&nbsp;<span style="text-transform: capitalize">{{chartInfo.params.as}}</span>
</span>
</div>
<div class="content__data">
<span>{{handleSingleValue[0] || handleSingleValue[0] === 0 ? handleSingleValue[0] : '-'}}</span>
@@ -24,7 +27,7 @@
<div class="chart-drawing" :id="`chart${chartInfo.id}`"></div>
</div>
</div>
<div class="single-value__content" v-if="chartInfo.type == 53">
<div class="single-value__content" v-if="type === 53">
<div class="content__title">
<span :title="chartInfo.i18n ? $t(chartInfo.i18n) : chartInfo.name">{{chartInfo.i18n ? $t(chartInfo.i18n) : chartInfo.name}}</span>
</div>
@@ -33,7 +36,7 @@
<span class="single-value__unit">{{handleSingleValue[1]}}</span>
</div>
</div>
<div class="single-value__content" v-if="chartInfo.type == 54" >
<div class="single-value__content" v-if="type === 54" >
<div class="single-value-icon__box" >
<div class="single-value__icon">
<!-- 使用图标-->
@@ -86,7 +89,7 @@ export default {
},
computed: {
handleSingleValue () {
const value = this.chartData ? this.chartData.value: ''
const value = this.chartData ? this.chartData : ''
const unitType = this.chartInfo.params.unitType
const result = unitConvert(value, unitType)
switch (unitType) {

View File

@@ -0,0 +1,79 @@
<template>
<div class="cn-chart__table">
<div class="cn-chart__body">
<el-table
style="width: 100%"
tooltip-effect="light"
:data="table.currentPageData"
>
<el-table-column
type="index"
label="#"
>
</el-table-column>
<el-table-column
v-for="(c, i) in table.tableColumns"
show-overflow-tooltip
:key="i"
:label="c.label"
:prop="c.prop"
>
<template #header>{{$t(c.label)}}</template>
<template #default="{ row }">
<span v-if="c.prop === 'bytes'">
{{unitConvert(row[c.prop], unitTypes.byte).join(' ')}}
</span>
<span v-else-if="c.prop === 'packets' || c.prop === 'sessions'">
{{unitConvert(row[c.prop], unitTypes.number).join(' ')}}
</span>
<span v-else>
{{row[c.prop]}}
</span>
</template>
</el-table-column>
</el-table>
</div>
<div class="cn-chart__footer">
<chart-table-pagination
ref="tablePagination"
:total="table.tableData.length"
@pageJump="pageJump"
></chart-table-pagination>
</div>
</div>
</template>
<script>
import {unitTypes} from '@/utils/constants'
import unitConvert from '@/utils/unit-convert'
import ChartTablePagination from '@/components/charts/ChartTablePagination'
export default {
name: "ChartTable",
components: {
ChartTablePagination
},
props: {
chartInfo: Object,
chartData: [Array, Object],
queryParams: Object,
table: Object
},
data () {
return {
unitConvert,
unitTypes
}
},
methods: {
pageJump (val) {
this.table.currentPageData = this.getTargetPageData(val, this.table.pageSize, this.table.tableData)
},
getTargetPageData (pageNum, pageSize, tableData) {
return this.$_.slice(tableData, (pageNum - 1) * pageSize, pageNum * pageSize)
},
},
mounted() {
}
}
</script>