CN-268 feat: panel重构--entity详情、ip基础信息等(部分)
This commit is contained in:
@@ -86,9 +86,6 @@
|
|||||||
font-weight:normal;
|
font-weight:normal;
|
||||||
}
|
}
|
||||||
|
|
||||||
.cn-panel-crypto {
|
|
||||||
grid-template-columns: repeat(36, 1fr) !important;
|
|
||||||
}
|
|
||||||
.cn-chart:not(.cn-chart__group):not(.cn-chart__block) {
|
.cn-chart:not(.cn-chart__group):not(.cn-chart__block) {
|
||||||
&>.cn-chart__body {
|
&>.cn-chart__body {
|
||||||
height: 100%;
|
height: 100%;
|
||||||
@@ -672,7 +669,7 @@
|
|||||||
height: 100%;
|
height: 100%;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
overflow: auto;
|
overflow: auto;
|
||||||
&>div {
|
/*&>div {
|
||||||
display: grid;
|
display: grid;
|
||||||
grid-template-columns: repeat(30, 1fr);
|
grid-template-columns: repeat(30, 1fr);
|
||||||
grid-auto-flow: row;
|
grid-auto-flow: row;
|
||||||
@@ -701,7 +698,7 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}*/
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.el-overlay {
|
.el-overlay {
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
@import 'components/advancedSearch/advanced-search';
|
@import 'components/advancedSearch/advanced-search';
|
||||||
@import './components/charts/panel';
|
// @import './components/charts/panel';
|
||||||
@import 'components/common/TimeRange/date-time-range';
|
@import 'components/common/TimeRange/date-time-range';
|
||||||
@import 'components/common/TimeRange/time-refresh';
|
@import 'components/common/TimeRange/time-refresh';
|
||||||
@import './components/common/pagination';
|
@import './components/common/pagination';
|
||||||
|
|||||||
@@ -58,118 +58,36 @@
|
|||||||
color: #333;
|
color: #333;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
}
|
}
|
||||||
/*&:hover {
|
|
||||||
background-color: $--chart-title-hover-background-color;
|
|
||||||
|
|
||||||
.chart-header__tools {
|
|
||||||
.chart-header__tool .tool__icon {
|
|
||||||
visibility: visible;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}*/
|
|
||||||
.chart-header__title {
|
.chart-header__title {
|
||||||
max-width: calc(100% - 100px);
|
max-width: calc(100% - 100px);
|
||||||
text-overflow: ellipsis;
|
text-overflow: ellipsis;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
|
&.chart-header__title--block {
|
||||||
|
color: #1890FF;
|
||||||
|
font-weight: bold;
|
||||||
|
font-size: 16px;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
.chart-header__tools {
|
.chart-header__tools {
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
|
|
||||||
|
.header__operation-btn {
|
||||||
|
margin-left: 12px;
|
||||||
|
cursor: pointer;
|
||||||
|
color: #999;
|
||||||
|
}
|
||||||
.chart-header__tool {
|
.chart-header__tool {
|
||||||
margin-left: 20px;
|
margin-left: 20px;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
|
|
||||||
.tool__icon {
|
.tool__icon {
|
||||||
// visibility: hidden;
|
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
color: $--color-text-primary;
|
color: $--color-text-primary;
|
||||||
}
|
}
|
||||||
.nz-chart-dropdown {
|
.cn-chart-dropdown {
|
||||||
position: absolute;
|
|
||||||
top: 44px;
|
|
||||||
right: 0;
|
|
||||||
left: unset;
|
|
||||||
transform-origin: center top;
|
|
||||||
z-index: 1000;
|
|
||||||
width: 180px;
|
|
||||||
li {
|
|
||||||
padding-left: 15px !important;
|
|
||||||
padding-right: 0 !important;
|
|
||||||
width: calc(100% - 15px);
|
|
||||||
text-align: left;
|
|
||||||
i {
|
|
||||||
margin-right: 10px;
|
|
||||||
}
|
|
||||||
&:hover i {
|
|
||||||
color: $--color-primary;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.chart-header-error{
|
|
||||||
position: absolute;
|
|
||||||
left: 0;
|
|
||||||
top: -1px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.chart-screen-header.list-page{
|
|
||||||
background: $--background-color-empty;
|
|
||||||
}
|
|
||||||
.chart-screen-header {
|
|
||||||
display: flex;
|
|
||||||
justify-content:space-between;
|
|
||||||
align-items:center;
|
|
||||||
padding: 0 20px 0 20px;
|
|
||||||
height: 39px;
|
|
||||||
font-size: 14px;
|
|
||||||
line-height: 40px;
|
|
||||||
color: $--color-text-primary;
|
|
||||||
transition: all 0.2s;
|
|
||||||
width: 100%;
|
|
||||||
box-sizing: border-box;
|
|
||||||
margin-top: 15px;
|
|
||||||
&.chart-header--float {
|
|
||||||
position: absolute;
|
|
||||||
width: 100%;
|
|
||||||
z-index: 100;
|
|
||||||
box-sizing: border-box;
|
|
||||||
height: 10px;
|
|
||||||
opacity: 0;
|
|
||||||
transition: all linear .2s;
|
|
||||||
|
|
||||||
&:hover {
|
|
||||||
height: 39px;
|
|
||||||
opacity: 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.chart-header__title {
|
|
||||||
max-width: calc(100% - 100px);
|
|
||||||
text-overflow: ellipsis;
|
|
||||||
overflow: hidden;
|
|
||||||
white-space: nowrap;
|
|
||||||
font-size: 18px;
|
|
||||||
color: #333;
|
|
||||||
font-weight: 700;
|
|
||||||
}
|
|
||||||
.chart-header__tools {
|
|
||||||
display: flex;
|
|
||||||
justify-content: space-between;
|
|
||||||
align-items: center;
|
|
||||||
|
|
||||||
.chart-header__tool {
|
|
||||||
margin-left: 20px;
|
|
||||||
cursor: pointer;
|
|
||||||
|
|
||||||
.tool__icon {
|
|
||||||
visibility: hidden;
|
|
||||||
font-size: 14px;
|
|
||||||
color: $--color-text-primary;
|
|
||||||
}
|
|
||||||
.nz-chart-dropdown {
|
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 44px;
|
top: 44px;
|
||||||
right: 0;
|
right: 0;
|
||||||
@@ -208,7 +126,8 @@
|
|||||||
height: 100%;
|
height: 100%;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
.cn-chart__single-value.cn-chart__single-value--detail-overview.cn-chart__single-value--icon-left {
|
&>.cn-chart__single-value {
|
||||||
|
&.cn-chart__single-value--detail-overview.cn-chart__single-value--icon-left {
|
||||||
.single-value__icon {
|
.single-value__icon {
|
||||||
width: 38px;
|
width: 38px;
|
||||||
height: 38px;
|
height: 38px;
|
||||||
@@ -226,7 +145,7 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.cn-chart__single-value.cn-chart__single-value--icon-left {
|
&.cn-chart__single-value--icon-left {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
@@ -287,7 +206,7 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.cn-chart__single-value.cn-chart__single-value--icon-right {
|
&.cn-chart__single-value--icon-right {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: row-reverse;
|
flex-direction: row-reverse;
|
||||||
justify-content: space-around;
|
justify-content: space-around;
|
||||||
@@ -337,7 +256,7 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.cn-chart__single-value.cn-chart__single-value--icon-right--color {
|
&.cn-chart__single-value--icon-right--color {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: row-reverse;
|
flex-direction: row-reverse;
|
||||||
justify-content: space-around;
|
justify-content: space-around;
|
||||||
@@ -406,7 +325,7 @@
|
|||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.cn-chart__single-value.cn-chart__single-value--chart {
|
&.cn-chart__single-value--chart {
|
||||||
display: flex;
|
display: flex;
|
||||||
padding: 13px 20px;
|
padding: 13px 20px;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
@@ -438,43 +357,11 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.chart-table-pagination.el-pagination {
|
|
||||||
padding: 12px 0 9px 0;
|
|
||||||
text-align: center;
|
|
||||||
height: 100%;
|
|
||||||
width: 100%;
|
|
||||||
|
|
||||||
.el-pagination__jump {
|
|
||||||
margin-left: 10px;
|
|
||||||
}
|
}
|
||||||
}
|
&>.cn-chart__whois {
|
||||||
}
|
|
||||||
&>.cn-chart__whois>.cn-chart__body {
|
|
||||||
overflow: auto;
|
overflow: auto;
|
||||||
}
|
}
|
||||||
&>.cn-chart__echarts, &>.cn-chart__table, &>.cn-chart__map, &>.cn-chart__group, &>.cn-chart__block, &>.cn-chart__whois, &>.cn-chart__dns-record, &>.cn-chart__app-basic {
|
&>.cn-chart__ip-basic {
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
.cn-chart__header {
|
|
||||||
display: flex;
|
|
||||||
justify-content: space-between;
|
|
||||||
align-items: center;
|
|
||||||
flex-shrink: 0;
|
|
||||||
padding: 10px 20px 10px 18px;
|
|
||||||
height: 47px;
|
|
||||||
|
|
||||||
.cn-chart__title {
|
|
||||||
font-size: 16px;
|
|
||||||
color: #333333;
|
|
||||||
font-weight: bold;
|
|
||||||
}
|
|
||||||
.header__operations {
|
|
||||||
color: #999;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.cn-chart__body {
|
|
||||||
flex: auto;
|
|
||||||
display: flex;
|
display: flex;
|
||||||
.el-descriptions {
|
.el-descriptions {
|
||||||
padding-top: 30px;
|
padding-top: 30px;
|
||||||
@@ -493,19 +380,8 @@
|
|||||||
color: #3976CB;
|
color: #3976CB;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
&>.cn-chart__block {
|
&>.cn-chart__block {
|
||||||
&>.cn-chart__header {
|
.cn-chart {
|
||||||
height: 60px;
|
|
||||||
border-bottom: none !important;
|
|
||||||
}
|
|
||||||
&>.cn-chart__body {
|
|
||||||
display: grid !important;
|
|
||||||
grid-template-columns: repeat(30, 1fr);
|
|
||||||
grid-auto-flow: row;
|
|
||||||
grid-gap: 10px;
|
|
||||||
padding: 0 20px;
|
|
||||||
&>.cn-chart {
|
|
||||||
border: 1px solid #E7EAED;
|
border: 1px solid #E7EAED;
|
||||||
}
|
}
|
||||||
/* detail页面block下的五连图的标题样式改变 */
|
/* detail页面block下的五连图的标题样式改变 */
|
||||||
@@ -520,21 +396,6 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
.cn-chart__group {
|
|
||||||
.cn-chart__header {
|
|
||||||
border-bottom: 1px solid $--content-right-background-color;
|
|
||||||
}
|
|
||||||
&>.cn-chart__body {
|
|
||||||
display: grid !important;
|
|
||||||
grid-gap: 10px;
|
|
||||||
padding: 0 20px;
|
|
||||||
.cn-chart {
|
|
||||||
border: none;
|
|
||||||
box-shadow: none;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
&>.cn-chart__title {
|
&>.cn-chart__title {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
@@ -772,7 +633,7 @@
|
|||||||
padding: 10px 30px 30px;
|
padding: 10px 30px 30px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.pie-table {
|
&>.pie-table {
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
color: #333333;
|
color: #333333;
|
||||||
font-weight: 500;
|
font-weight: 500;
|
||||||
@@ -798,6 +659,18 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.chart-table-pagination.el-pagination {
|
||||||
|
padding: 12px 0 9px 0;
|
||||||
|
text-align: center;
|
||||||
|
height: 100%;
|
||||||
|
width: 100%;
|
||||||
|
|
||||||
|
.el-pagination__jump {
|
||||||
|
margin-left: 10px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
.chart__legend {
|
.chart__legend {
|
||||||
width: calc(100% - 40px);
|
width: calc(100% - 40px);
|
||||||
border: 1px solid #E7EAED;
|
border: 1px solid #E7EAED;
|
||||||
@@ -875,3 +748,87 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.entity-detail-tool {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
margin: 10px 20px 10px 0;
|
||||||
|
padding: 0 20px;
|
||||||
|
height: 60px;
|
||||||
|
background-color: #FFFFFF;
|
||||||
|
box-shadow: 0 1px 2px 0 rgba(0,0,0,0.06);
|
||||||
|
border-radius: 2px;
|
||||||
|
|
||||||
|
.cn-icon-arrow-left-circle {
|
||||||
|
color: $--color-primary;
|
||||||
|
font-size: 20px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.chart-error-popper{
|
||||||
|
word-wrap:break-word;
|
||||||
|
word-break:break-word;
|
||||||
|
border: 1px solid #e02f44;
|
||||||
|
min-width: 180px !important;
|
||||||
|
max-width: 280px !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.chart-error-popper.el-popper.is-light {
|
||||||
|
background: #e02f44;
|
||||||
|
border: 1px solid #e02f44;
|
||||||
|
}
|
||||||
|
.chart-error-popper.el-popover.el-popper {
|
||||||
|
color:white;
|
||||||
|
}
|
||||||
|
|
||||||
|
.chart-error-popper.el-popper.is-light[data-popper-placement^='top'] .el-popper__arrow::before {
|
||||||
|
border-color: #e02f44;
|
||||||
|
background: #e02f44;
|
||||||
|
bottom:0px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.chart-error-popper.el-popper.is-light[data-popper-placement^='bottom'] .el-popper__arrow::before {
|
||||||
|
border-color: #e02f44;
|
||||||
|
background: #e02f44;
|
||||||
|
}
|
||||||
|
|
||||||
|
.chart-info-corner {
|
||||||
|
color: #767980;
|
||||||
|
cursor: pointer;
|
||||||
|
position: absolute;
|
||||||
|
display: none;
|
||||||
|
left: 0;
|
||||||
|
width: 28px;
|
||||||
|
height: 28px;
|
||||||
|
z-index: 2;
|
||||||
|
top: 0;
|
||||||
|
}
|
||||||
|
.chart-info-corner--error {
|
||||||
|
display: block;
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
.chart-info-corner--error .chart-info-corner-inner {
|
||||||
|
border-left: 28px solid #e02f44;
|
||||||
|
border-right: none;
|
||||||
|
border-bottom: 28px solid rgba(0,0,0,0);
|
||||||
|
}
|
||||||
|
.chart-info-corner-inner {
|
||||||
|
width: 0;
|
||||||
|
height: 0;
|
||||||
|
position: absolute;
|
||||||
|
left: 0;
|
||||||
|
bottom: 0;
|
||||||
|
}
|
||||||
|
.chart-info-corner .fa {
|
||||||
|
position: absolute;
|
||||||
|
top: 2px;
|
||||||
|
left: 6px;
|
||||||
|
font-size: 65%;
|
||||||
|
z-index: 3;
|
||||||
|
font-style: normal;
|
||||||
|
}
|
||||||
|
.cn-chart-icon-warning:before {
|
||||||
|
content: "!";
|
||||||
|
font-weight:normal;
|
||||||
|
}
|
||||||
|
|||||||
@@ -68,6 +68,7 @@
|
|||||||
height: calc(100% - 28px);
|
height: calc(100% - 28px);
|
||||||
flex: 1;
|
flex: 1;
|
||||||
padding: 10px;
|
padding: 10px;
|
||||||
|
overflow: auto;
|
||||||
background-color: $--content-right-background-color;
|
background-color: $--content-right-background-color;
|
||||||
|
|
||||||
&>.cn-entity-detail .entity-detail__body>.cn-panel {
|
&>.cn-entity-detail .entity-detail__body>.cn-panel {
|
||||||
|
|||||||
@@ -16,7 +16,15 @@ const locale = require('element-plus/lib/locale')
|
|||||||
const debounce = require('lodash/debounce')
|
const debounce = require('lodash/debounce')
|
||||||
const ElScrollbar = require('element-plus/lib/el-scrollbar')
|
const ElScrollbar = require('element-plus/lib/el-scrollbar')
|
||||||
const union = require('lodash/union')
|
const union = require('lodash/union')
|
||||||
|
const utc = require('dayjs/plugin/utc')
|
||||||
|
const timezone = require('dayjs/plugin/timezone')
|
||||||
|
const advancedFormat = require('dayjs/plugin/advancedFormat')
|
||||||
|
const weekday = require('dayjs/plugin/weekday')
|
||||||
|
dayjs.extend(utc)
|
||||||
|
dayjs.extend(timezone)
|
||||||
|
dayjs.extend(advancedFormat)
|
||||||
|
dayjs.extend(weekday)
|
||||||
|
window.$dayJs = dayjs
|
||||||
function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { default: e } }
|
function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { default: e } }
|
||||||
|
|
||||||
const dayjs__default = /* #__PURE__ */_interopDefaultLegacy(window.$dayJs)
|
const dayjs__default = /* #__PURE__ */_interopDefaultLegacy(window.$dayJs)
|
||||||
|
|||||||
@@ -19,15 +19,17 @@ import timezone from 'dayjs/plugin/timezone'
|
|||||||
import advancedFormat from 'dayjs/plugin/advancedFormat'
|
import advancedFormat from 'dayjs/plugin/advancedFormat'
|
||||||
import weekday from 'dayjs/plugin/weekday'
|
import weekday from 'dayjs/plugin/weekday'
|
||||||
|
|
||||||
|
import DateTimeRange from '@/components/common/TimeRange/DateTimeRange'
|
||||||
|
import TimeRefresh from '@/components/common/TimeRange/TimeRefresh'
|
||||||
import PanelChartList from '@/views/charts/PanelChartList'
|
import PanelChartList from '@/views/charts/PanelChartList'
|
||||||
|
|
||||||
const _ = require('lodash') // lodash工具
|
const _ = require('lodash') // lodash工具
|
||||||
|
|
||||||
dayjs.extend(utc)
|
/*dayjs.extend(utc)
|
||||||
dayjs.extend(timezone)
|
dayjs.extend(timezone)
|
||||||
dayjs.extend(advancedFormat)
|
dayjs.extend(advancedFormat)
|
||||||
dayjs.extend(weekday)
|
dayjs.extend(weekday)
|
||||||
window.$dayJs = dayjs
|
window.$dayJs = dayjs*/
|
||||||
|
|
||||||
const app = createApp(App)
|
const app = createApp(App)
|
||||||
|
|
||||||
@@ -47,6 +49,8 @@ app.config.globalProperties.$_ = _
|
|||||||
|
|
||||||
app.mixin(commonMixin)
|
app.mixin(commonMixin)
|
||||||
|
|
||||||
|
app.component('date-time-range', DateTimeRange)
|
||||||
|
app.component('time-refresh', TimeRefresh)
|
||||||
app.component('panel-chart-list', PanelChartList)
|
app.component('panel-chart-list', PanelChartList)
|
||||||
|
|
||||||
app.mount('#app')
|
app.mount('#app')
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ import { storageKey } from '@/utils/constants'
|
|||||||
import { loadI18n } from '@/i18n'
|
import { loadI18n } from '@/i18n'
|
||||||
|
|
||||||
const loginWhiteList = ['/login', '/'] // 免登陆白名单
|
const loginWhiteList = ['/login', '/'] // 免登陆白名单
|
||||||
const permissionWhiteList = [...loginWhiteList] // 权限白名单
|
const permissionWhiteList = [...loginWhiteList, '/entityDetail'] // 权限白名单
|
||||||
|
|
||||||
router.beforeEach(async (to, from, next) => {
|
router.beforeEach(async (to, from, next) => {
|
||||||
// 加载iso-3166-2资源
|
// 加载iso-3166-2资源
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="cn-chart">
|
<div class="cn-chart">
|
||||||
<loading :loading="loading && !isTabs"></loading>
|
<loading :loading="loading && !isTabs && !isBlock"></loading>
|
||||||
<chart-no-data v-if="isNoData"></chart-no-data>
|
<chart-no-data v-if="isNoData"></chart-no-data>
|
||||||
<template v-else>
|
<template v-else>
|
||||||
|
|
||||||
@@ -8,13 +8,15 @@
|
|||||||
v-if="isTabs"
|
v-if="isTabs"
|
||||||
:chart-info="chartInfo"
|
:chart-info="chartInfo"
|
||||||
:query-params="queryParams"
|
:query-params="queryParams"
|
||||||
|
:entity="entity"
|
||||||
></chart-tabs>
|
></chart-tabs>
|
||||||
|
|
||||||
<chart-map
|
<chart-map
|
||||||
v-else-if="isMap"
|
v-else-if="isMap && !isIpBasicInfo"
|
||||||
:chart-info="chartInfo"
|
:chart-info="chartInfo"
|
||||||
:chart-data="chartData"
|
:chart-data="chartData"
|
||||||
:query-params="queryParams"
|
:query-params="queryParams"
|
||||||
|
:entity="entity"
|
||||||
@showLoading="showLoading"
|
@showLoading="showLoading"
|
||||||
></chart-map>
|
></chart-map>
|
||||||
|
|
||||||
@@ -26,7 +28,19 @@
|
|||||||
@showLoading="showLoading"
|
@showLoading="showLoading"
|
||||||
></chart-single-value>
|
></chart-single-value>
|
||||||
|
|
||||||
<div v-else style="height: 100%; width: 100%; background-color: lightcyan;"></div>
|
<chart-block
|
||||||
|
v-else-if="isBlock"
|
||||||
|
:chart-info="chartInfo"
|
||||||
|
:chart-data="chartData"
|
||||||
|
:entity="entity"
|
||||||
|
></chart-block>
|
||||||
|
|
||||||
|
<ip-basic-info
|
||||||
|
v-else-if="isIpBasicInfo"
|
||||||
|
:chart-info="chartInfo"
|
||||||
|
:chart-data="chartData"
|
||||||
|
:entity="entity"
|
||||||
|
></ip-basic-info>
|
||||||
|
|
||||||
<chart-echart-line
|
<chart-echart-line
|
||||||
v-else-if="isEchartsLine"
|
v-else-if="isEchartsLine"
|
||||||
@@ -47,6 +61,8 @@ import ChartNoData from './charts/ChartNoData'
|
|||||||
import ChartTabs from './charts/ChartTabs'
|
import ChartTabs from './charts/ChartTabs'
|
||||||
import ChartMap from './charts/ChartMap'
|
import ChartMap from './charts/ChartMap'
|
||||||
import ChartSingleValue from './charts/ChartSingleValue'
|
import ChartSingleValue from './charts/ChartSingleValue'
|
||||||
|
import ChartBlock from './charts/ChartBlock'
|
||||||
|
import IpBasicInfo from '@/views/charts/charts/IpBasicInfo'
|
||||||
import ChartEchartLine from './charts/ChartEchartLine'
|
import ChartEchartLine from './charts/ChartEchartLine'
|
||||||
import {
|
import {
|
||||||
isEcharts,
|
isEcharts,
|
||||||
@@ -84,12 +100,14 @@ import _ from 'lodash'
|
|||||||
export default {
|
export default {
|
||||||
name: 'chart',
|
name: 'chart',
|
||||||
components: {
|
components: {
|
||||||
|
IpBasicInfo,
|
||||||
ChartSingleValue,
|
ChartSingleValue,
|
||||||
Loading,
|
Loading,
|
||||||
ChartNoData,
|
ChartNoData,
|
||||||
ChartTabs,
|
ChartTabs,
|
||||||
ChartMap,
|
ChartMap,
|
||||||
ChartEchartLine
|
ChartEchartLine,
|
||||||
|
ChartBlock
|
||||||
},
|
},
|
||||||
props: {
|
props: {
|
||||||
chartInfo: Object,
|
chartInfo: Object,
|
||||||
@@ -100,6 +118,7 @@ export default {
|
|||||||
isFullscreen: Boolean,
|
isFullscreen: Boolean,
|
||||||
loading: Boolean,
|
loading: Boolean,
|
||||||
panelLock: Boolean,
|
panelLock: Boolean,
|
||||||
|
entity: Object,
|
||||||
isError: Boolean
|
isError: Boolean
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
|
|||||||
@@ -1,21 +1,30 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="chart-header" :class="{'chart-header--title-chart': isTitle}">
|
<div class="chart-header" :class="{'chart-header--title-chart': isTitle}">
|
||||||
<div class="chart-header__title">{{chartInfo.name}}</div>
|
<div class="chart-header__title" :class="{'chart-header__title--block': isBlock}">{{chartInfo.name}}</div>
|
||||||
<chart-error :isError="isError" :errorInfo="errorInfo"></chart-error>
|
<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">
|
||||||
|
<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"/>
|
||||||
|
</div>
|
||||||
|
<template v-else-if="!isBlock">
|
||||||
<el-popover trigger="click" placement="top" :content="chartInfo.remark" v-if="chartInfo.remark">
|
<el-popover trigger="click" placement="top" :content="chartInfo.remark" v-if="chartInfo.remark">
|
||||||
<template #reference>
|
<template #reference>
|
||||||
<span class="header__operation-btn"><i class="cn-icon el-icon-info"></i></span>
|
<span class="header__operation-btn"><i class="cn-icon el-icon-info"></i></span>
|
||||||
</template>
|
</template>
|
||||||
</el-popover>
|
</el-popover>
|
||||||
<span class="header__operation-btn" @click="refresh"><i class="cn-icon cn-icon-refresh"></i></span>
|
<span class="header__operation-btn" @click="refresh"><i class="cn-icon cn-icon-refresh"></i></span>
|
||||||
|
</template>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { isTitle, isTabs } from './charts/tools'
|
import { isTitle, isTabs, isBlock } from './charts/tools'
|
||||||
import ChartError from '@/components/charts/ChartError'
|
import ChartError from '@/components/charts/ChartError'
|
||||||
|
import { getNowTime } from '@/utils/date-util'
|
||||||
|
import { ref } from 'vue'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'ChartHeader',
|
name: 'ChartHeader',
|
||||||
props: {
|
props: {
|
||||||
@@ -41,11 +50,29 @@ export default {
|
|||||||
methods: {
|
methods: {
|
||||||
refresh () {
|
refresh () {
|
||||||
this.$emit('refresh')
|
this.$emit('refresh')
|
||||||
|
},
|
||||||
|
timeRefreshChange () {
|
||||||
|
if (!this.$refs.dateTimeRange.isCustom) {
|
||||||
|
const value = this.chartTimeFilter.dateRangeValue
|
||||||
|
this.$refs.dateTimeRange.quickChange(value)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
reload (s, e, v) {
|
||||||
|
this.dateTimeRangeChange(s, e, v)
|
||||||
|
},
|
||||||
|
dateTimeRangeChange (s, e, v) {
|
||||||
|
this.chartTimeFilter = { startTime: s, endTime: e, dateRangeValue: v }
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
setup (props) {
|
setup (props) {
|
||||||
|
const dateRangeValue = 60
|
||||||
|
const { startTime, endTime } = getNowTime(dateRangeValue)
|
||||||
|
// entity详情内的chart时间工具不是公共的,需要单独定义
|
||||||
|
const chartTimeFilter = ref({ startTime, endTime, dateRangeValue })
|
||||||
return {
|
return {
|
||||||
|
chartTimeFilter,
|
||||||
isTitle: isTitle(props.chartInfo.type),
|
isTitle: isTitle(props.chartInfo.type),
|
||||||
|
isBlock: isBlock(props.chartInfo.type),
|
||||||
isTabs: isTabs(props.chartInfo.type)
|
isTabs: isTabs(props.chartInfo.type)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,8 +2,8 @@
|
|||||||
<div style="padding: 10px 10px 20px 10px; overflow: auto" v-if="!isEntityDetail">
|
<div style="padding: 10px 10px 20px 10px; overflow: auto" v-if="!isEntityDetail">
|
||||||
<div id="cn-panel" class="cn-panel2">
|
<div id="cn-panel" class="cn-panel2">
|
||||||
<div class="panel__time">
|
<div class="panel__time">
|
||||||
<DateTimeRange class="date-time-range" :start-time="timeFilter.startTime" :end-time="timeFilter.endTime" ref="dateTimeRange" @change="reload"/>
|
<date-time-range class="date-time-range" :start-time="timeFilter.startTime" :end-time="timeFilter.endTime" ref="dateTimeRange" @change="reload"/>
|
||||||
<TimeRefresh class="date-time-range" @change="timeRefreshChange" :end-time="timeFilter.endTime"/>
|
<time-refresh class="date-time-range" @change="timeRefreshChange" :end-time="timeFilter.endTime"/>
|
||||||
</div>
|
</div>
|
||||||
<panel-chart-list
|
<panel-chart-list
|
||||||
:time-filter="timeFilter"
|
:time-filter="timeFilter"
|
||||||
@@ -11,46 +11,26 @@
|
|||||||
:panel-lock="panelLock"
|
:panel-lock="panelLock"
|
||||||
>
|
>
|
||||||
</panel-chart-list>
|
</panel-chart-list>
|
||||||
<!-- <chart
|
|
||||||
v-for="chart in chartList"
|
|
||||||
:key="chart.id"
|
|
||||||
:chart="chart"
|
|
||||||
:time-filter="timeFilter"
|
|
||||||
:ref="`chart-${chart.id}`"
|
|
||||||
:entity="entity"
|
|
||||||
@getCurrentTimeRange="getCurrentTimeRange"
|
|
||||||
></chart>-->
|
|
||||||
<!-- <grid-layout v-model:layout="chartList"
|
|
||||||
:col-num="12"
|
|
||||||
:row-height="30"
|
|
||||||
:is-draggable="draggable"
|
|
||||||
:is-resizable="resizable"
|
|
||||||
:vertical-compact="compact"
|
|
||||||
:use-css-transforms="true"
|
|
||||||
>
|
|
||||||
<grid-item v-for="item in chartList" :key="item.i"
|
|
||||||
:x="item.x"
|
|
||||||
:y="item.y"
|
|
||||||
:w="item.w"
|
|
||||||
:h="item.h"
|
|
||||||
:i="item.i"
|
|
||||||
>
|
|
||||||
<span class="text">{{ item.i }}</span>
|
|
||||||
</grid-item>
|
|
||||||
</grid-layout>-->
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="cn-entity-detail" id="cn-entity-detail" v-else>
|
<div class="cn-entity-detail" id="cn-entity-detail" v-else>
|
||||||
<div class="entity-detail__body">
|
<div class="entity-detail__body">
|
||||||
<div class="cn-panel" @scroll="scroll" id="cn-panel">
|
<div class="cn-panel2" id="cn-panel">
|
||||||
<template v-for="chart in chartList" :key="chart.id">
|
<panel-chart-list
|
||||||
<!-- <chart
|
:time-filter="timeFilter"
|
||||||
|
:data-list="chartList"
|
||||||
|
:panel-lock="panelLock"
|
||||||
|
:entity="entity"
|
||||||
|
>
|
||||||
|
</panel-chart-list>
|
||||||
|
<!-- <template v-for="chart in chartList" :key="chart.id">
|
||||||
|
<chart
|
||||||
:chart="chart"
|
:chart="chart"
|
||||||
:ref="`chart-${chart.id}`"
|
:ref="`chart-${chart.id}`"
|
||||||
:entity="entity"
|
:entity="entity"
|
||||||
@getCurrentTimeRange="getCurrentTimeRange"
|
@getCurrentTimeRange="getCurrentTimeRange"
|
||||||
></chart>-->
|
></chart>
|
||||||
</template>
|
</template>-->
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -62,8 +42,6 @@ import { ref } from 'vue'
|
|||||||
import { panelTypeAndRouteMapping } from '@/utils/constants'
|
import { panelTypeAndRouteMapping } from '@/utils/constants'
|
||||||
import { api, getPanelList, getChartList } from '@/utils/api'
|
import { api, getPanelList, getChartList } from '@/utils/api'
|
||||||
import { getNowTime } from '@/utils/date-util'
|
import { getNowTime } from '@/utils/date-util'
|
||||||
import DateTimeRange from '@/components/common/TimeRange/DateTimeRange'
|
|
||||||
import TimeRefresh from '@/components/common/TimeRange/TimeRefresh'
|
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'Panel',
|
name: 'Panel',
|
||||||
@@ -72,10 +50,6 @@ export default {
|
|||||||
isEntityDetail: Boolean,
|
isEntityDetail: Boolean,
|
||||||
typeName: String
|
typeName: String
|
||||||
},
|
},
|
||||||
components: {
|
|
||||||
DateTimeRange,
|
|
||||||
TimeRefresh
|
|
||||||
},
|
|
||||||
data () {
|
data () {
|
||||||
return {
|
return {
|
||||||
chartList: [], // 普通panel的chart
|
chartList: [], // 普通panel的chart
|
||||||
@@ -125,16 +99,13 @@ export default {
|
|||||||
this.chartList = allCharts
|
this.chartList = allCharts
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
this.$emit('chartLoaded', allCharts)
|
this.$emit('chartLoaded', allCharts)
|
||||||
})
|
}, 1000)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
changeTab ({ index }) {
|
changeTab ({ index }) {
|
||||||
this.currentTab = this.detailTabs[index].id + ''
|
this.currentTab = this.detailTabs[index].id + ''
|
||||||
this.detailChartList = this.detailTabs[index].children
|
this.detailChartList = this.detailTabs[index].children
|
||||||
},
|
},
|
||||||
scroll (e) {
|
|
||||||
this.$emit('scroll', { top: e.target.scrollTop })
|
|
||||||
},
|
|
||||||
recursionParamsConvert (chart) {
|
recursionParamsConvert (chart) {
|
||||||
chart.params = chart.params ? JSON.parse(chart.params) : null
|
chart.params = chart.params ? JSON.parse(chart.params) : null
|
||||||
if (!this.$_.isEmpty(chart.children)) {
|
if (!this.$_.isEmpty(chart.children)) {
|
||||||
@@ -165,9 +136,6 @@ export default {
|
|||||||
this.chartList.forEach(chart => {
|
this.chartList.forEach(chart => {
|
||||||
this.$refs[`chart-${chart.id}`] && this.$refs[`chart-${chart.id}`].reloadChart()
|
this.$refs[`chart-${chart.id}`] && this.$refs[`chart-${chart.id}`].reloadChart()
|
||||||
})
|
})
|
||||||
},
|
|
||||||
jumpToTop (top) {
|
|
||||||
document.querySelector('#cn-panel').scrollTop = top
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,9 +1,13 @@
|
|||||||
<template>
|
<template>
|
||||||
<!-- chart外层箱子 -->
|
<!-- chart外层箱子 -->
|
||||||
<div :class="{'panel-chart--fullscreen': isFullscreen, 'panel-chart--title-chart': isTitle}" class="panel-chart" :id="isFullscreen ? ('chart-screen-' + chartInfo.id ) : ('chart-local-' + chartInfo.id)">
|
<div
|
||||||
|
:class="{'panel-chart--fullscreen': isFullscreen, 'panel-chart--title-chart': isTitle}"
|
||||||
|
class="panel-chart"
|
||||||
|
:id="isFullscreen ? ('chart-screen-' + chartInfo.id ) : ('chart-local-' + chartInfo.id)"
|
||||||
|
>
|
||||||
<!-- title和工具栏,支持浮动 -->
|
<!-- title和工具栏,支持浮动 -->
|
||||||
<chart-header
|
<chart-header
|
||||||
v-if="!isFullscreen && showHeader && !isSingleValue"
|
v-if="!isFullscreen && showHeader && !isSingleValue && !isTabs"
|
||||||
:is-error="isError"
|
:is-error="isError"
|
||||||
:error-info="errorInfo"
|
:error-info="errorInfo"
|
||||||
:chart-data="chartData"
|
:chart-data="chartData"
|
||||||
@@ -16,7 +20,7 @@
|
|||||||
<!-- 数据查询后传入chart组件,chart组件内不查询,只根据接传递的数据来渲染 -->
|
<!-- 数据查询后传入chart组件,chart组件内不查询,只根据接传递的数据来渲染 -->
|
||||||
<chart
|
<chart
|
||||||
ref="chart"
|
ref="chart"
|
||||||
v-if="(!isGroup || !chartInfo.param.collapse) && !isTitle"
|
v-if="(!isGroup || !(chartInfo.params && chartInfo.params.collapse)) && !isTitle"
|
||||||
:chart-data="chartData"
|
:chart-data="chartData"
|
||||||
:result-type="resultType"
|
:result-type="resultType"
|
||||||
:chart-info="chartInfo"
|
:chart-info="chartInfo"
|
||||||
@@ -24,6 +28,7 @@
|
|||||||
:panel-lock="panelLock"
|
:panel-lock="panelLock"
|
||||||
:is-error="isError"
|
:is-error="isError"
|
||||||
:loading="loading"
|
:loading="loading"
|
||||||
|
:entity="entity"
|
||||||
:is-fullscreen="isFullscreen"
|
:is-fullscreen="isFullscreen"
|
||||||
@showLoading="showLoading"
|
@showLoading="showLoading"
|
||||||
></chart>
|
></chart>
|
||||||
@@ -80,6 +85,7 @@ export default {
|
|||||||
timeFilter: Object, // 时间范围
|
timeFilter: Object, // 时间范围
|
||||||
isFullscreen: Boolean,
|
isFullscreen: Boolean,
|
||||||
panelLock: Boolean,
|
panelLock: Boolean,
|
||||||
|
entity: Object,
|
||||||
showHeader: {
|
showHeader: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
default: true
|
default: true
|
||||||
|
|||||||
@@ -25,12 +25,14 @@
|
|||||||
:isResizable = "item.type === 'group' ? false: null"
|
:isResizable = "item.type === 'group' ? false: null"
|
||||||
dragAllowFrom=".chart-header"
|
dragAllowFrom=".chart-header"
|
||||||
dragIgnoreFrom=".chart-header__tools"
|
dragIgnoreFrom=".chart-header__tools"
|
||||||
|
v-bind="anchorPoint(item)"
|
||||||
>
|
>
|
||||||
<panel-chart
|
<panel-chart
|
||||||
:ref="'chart' + item.id"
|
:ref="'chart' + item.id"
|
||||||
:chart-info="item"
|
:chart-info="item"
|
||||||
:show-header="true"
|
:show-header="true"
|
||||||
:time-filter="timeFilter"
|
:time-filter="timeFilter"
|
||||||
|
:entity="entity"
|
||||||
@showFullscreen="showFullscreen"
|
@showFullscreen="showFullscreen"
|
||||||
></panel-chart>
|
></panel-chart>
|
||||||
</grid-item>
|
</grid-item>
|
||||||
@@ -64,6 +66,7 @@
|
|||||||
import PanelChart from '@/views/charts/PanelChart'
|
import PanelChart from '@/views/charts/PanelChart'
|
||||||
import VueGridLayout from 'vue-grid-layout'
|
import VueGridLayout from 'vue-grid-layout'
|
||||||
import { getTypeCategory } from './charts/tools'
|
import { getTypeCategory } from './charts/tools'
|
||||||
|
import _ from 'lodash'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'PanelChartList',
|
name: 'PanelChartList',
|
||||||
@@ -76,6 +79,7 @@ export default {
|
|||||||
timeFilter: Object, // 时间范围
|
timeFilter: Object, // 时间范围
|
||||||
panelLock: { type: Boolean, default: true },
|
panelLock: { type: Boolean, default: true },
|
||||||
isGroup: Boolean,
|
isGroup: Boolean,
|
||||||
|
entity: Object,
|
||||||
dataList: Array // 看板中所有图表信息
|
dataList: Array // 看板中所有图表信息
|
||||||
},
|
},
|
||||||
data () {
|
data () {
|
||||||
@@ -109,9 +113,21 @@ export default {
|
|||||||
this.fullscreen.visible = show
|
this.fullscreen.visible = show
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
computed: {
|
||||||
|
anchorPoint () {
|
||||||
|
return function (chart) {
|
||||||
|
if (!_.isEmpty(chart.params && chart.params.anchorPoint)) {
|
||||||
|
return { 'anchor-point': chart.params.anchorPoint }
|
||||||
|
} else {
|
||||||
|
return ''
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
watch: {
|
watch: {
|
||||||
dataList: {
|
dataList: {
|
||||||
deep: true,
|
deep: true,
|
||||||
|
immediate: true,
|
||||||
handler (n, o) {
|
handler (n, o) {
|
||||||
this.gridLayoutShow = false
|
this.gridLayoutShow = false
|
||||||
this.gridLayoutLoading = true
|
this.gridLayoutLoading = true
|
||||||
|
|||||||
23
src/views/charts/charts/ChartBlock.vue
Normal file
23
src/views/charts/charts/ChartBlock.vue
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
<template>
|
||||||
|
<panel-chart-list
|
||||||
|
:time-filter="timeFilter"
|
||||||
|
:data-list="chartInfo.children"
|
||||||
|
:panel-lock="true"
|
||||||
|
:entity="entity"
|
||||||
|
>
|
||||||
|
</panel-chart-list>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import chartMixin from '@/views/charts/charts/chart-mixin'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'ChartBlock',
|
||||||
|
mixins: [chartMixin],
|
||||||
|
props: {
|
||||||
|
timeFilter: Object
|
||||||
|
},
|
||||||
|
mounted () {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
@@ -4,21 +4,16 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import * as L from 'leaflet'
|
|
||||||
import * as am4Core from '@amcharts/amcharts4/core'
|
import * as am4Core from '@amcharts/amcharts4/core'
|
||||||
import * as am4Maps from '@amcharts/amcharts4/maps'
|
import * as am4Maps from '@amcharts/amcharts4/maps'
|
||||||
import { getGeoData, replaceUrlPlaceholder } from '@/utils/tools'
|
import { getGeoData, replaceUrlPlaceholder } from '@/utils/tools'
|
||||||
import { storageKey } from '@/utils/constants'
|
import { storageKey } from '@/utils/constants'
|
||||||
import 'leaflet/dist/leaflet.css'
|
|
||||||
import icon from 'leaflet/dist/images/marker-icon.png'
|
import { isMapBlock } from './tools'
|
||||||
import iconShadow from 'leaflet/dist/images/marker-shadow.png'
|
|
||||||
import {
|
|
||||||
isIpBasicInfo,
|
|
||||||
isMapBlock
|
|
||||||
} from './tools'
|
|
||||||
import unitConvert, { valueToRangeValue } from '@/utils/unit-convert'
|
import unitConvert, { valueToRangeValue } from '@/utils/unit-convert'
|
||||||
import { HeatLegend } from '@/components/amcharts/heatLegend'
|
import { HeatLegend } from '@/components/amcharts/heatLegend'
|
||||||
import { getData } from '@/utils/api'
|
import { getData } from '@/utils/api'
|
||||||
|
import chartMixin from './chart-mixin'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'ChartMap',
|
name: 'ChartMap',
|
||||||
@@ -31,46 +26,9 @@ export default {
|
|||||||
countrySeries: null // 下钻国家series
|
countrySeries: null // 下钻国家series
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
props: {
|
mixins: [chartMixin],
|
||||||
chartInfo: Object,
|
|
||||||
chartData: [Array, Object],
|
|
||||||
queryParams: Object
|
|
||||||
},
|
|
||||||
methods: {
|
methods: {
|
||||||
initMap (id) {
|
initMap (id) {
|
||||||
if (this.isIpBasicInfo) {
|
|
||||||
L.Marker.prototype.options.icon = L.icon({
|
|
||||||
iconUrl: icon,
|
|
||||||
shadowUrl: iconShadow
|
|
||||||
})
|
|
||||||
const map = L.map(`chart${this.chartInfo.id}`, {
|
|
||||||
minZoom: 3,
|
|
||||||
maxZoom: 7,
|
|
||||||
zoom: 5,
|
|
||||||
attributionControl: false,
|
|
||||||
zoomControl: false,
|
|
||||||
maxBounds: L.latLngBounds(L.latLng(-90, -180), L.latLng(90, 180))
|
|
||||||
})
|
|
||||||
L.tileLayer(
|
|
||||||
this.mapPictureUrl,
|
|
||||||
{ noWrap: true }
|
|
||||||
).addTo(map)
|
|
||||||
|
|
||||||
const attribution = L.control.attribution({ position: 'bottomright', prefix: '' })
|
|
||||||
attribution.addAttribution(' © OpenStreetMap contributors')
|
|
||||||
attribution.addTo(map)
|
|
||||||
|
|
||||||
/* L.control.zoom({
|
|
||||||
position: 'bottomright',
|
|
||||||
zoomInText: '<i class="nz-icon nz-icon-enlarge"></i>',
|
|
||||||
zoomOutText: '<i class="nz-icon nz-icon-narrow"></i>',
|
|
||||||
zoomInTitle: '',
|
|
||||||
zoomOutTitle: ''
|
|
||||||
}).addTo(map) */
|
|
||||||
|
|
||||||
this.myChart = map
|
|
||||||
this.loadLeafletMap()
|
|
||||||
} else {
|
|
||||||
const chart = am4Core.create(id, am4Maps.MapChart)
|
const chart = am4Core.create(id, am4Maps.MapChart)
|
||||||
chart.geodata = getGeoData(storageKey.iso36112WorldLow)
|
chart.geodata = getGeoData(storageKey.iso36112WorldLow)
|
||||||
chart.projection = new am4Maps.projections.Miller()
|
chart.projection = new am4Maps.projections.Miller()
|
||||||
@@ -112,7 +70,6 @@ export default {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
|
||||||
},
|
},
|
||||||
loadAm4ChartMap (polygonSeries, country, chartData) {
|
loadAm4ChartMap (polygonSeries, country, chartData) {
|
||||||
if (chartData) {
|
if (chartData) {
|
||||||
@@ -196,20 +153,6 @@ export default {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
loadLeafletMap () {
|
|
||||||
this.$emit('showLoading', true)
|
|
||||||
try {
|
|
||||||
this.myChart.setView([this.chartData.latitude, this.chartData.longitude], 5)
|
|
||||||
const myIcon = L.divIcon({
|
|
||||||
className: 'cn-icon cn-icon-position2 position-icon'
|
|
||||||
})
|
|
||||||
L.marker([this.chartData.latitude, this.chartData.longitude], { icon: myIcon }).addTo(this.myChart)
|
|
||||||
} finally {
|
|
||||||
setTimeout(() => {
|
|
||||||
this.$emit('showLoading', false)
|
|
||||||
}, 200)
|
|
||||||
}
|
|
||||||
},
|
|
||||||
mapBack () {
|
mapBack () {
|
||||||
this.countrySeries.hide()
|
this.countrySeries.hide()
|
||||||
this.$nextTick(() => {
|
this.$nextTick(() => {
|
||||||
@@ -264,7 +207,6 @@ export default {
|
|||||||
},
|
},
|
||||||
setup (props) {
|
setup (props) {
|
||||||
return {
|
return {
|
||||||
isIpBasicInfo: isIpBasicInfo(props.chartInfo.type),
|
|
||||||
isMapBlock: isMapBlock(props.chartInfo.type)
|
isMapBlock: isMapBlock(props.chartInfo.type)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,6 +15,7 @@
|
|||||||
:time-filter="timeFilter"
|
:time-filter="timeFilter"
|
||||||
:data-list="tab.children"
|
:data-list="tab.children"
|
||||||
:panel-lock="true"
|
:panel-lock="true"
|
||||||
|
:entity="entity"
|
||||||
>
|
>
|
||||||
</panel-chart-list>
|
</panel-chart-list>
|
||||||
</el-tab-pane>
|
</el-tab-pane>
|
||||||
@@ -23,14 +24,10 @@
|
|||||||
|
|
||||||
<script>
|
<script>
|
||||||
import _ from 'lodash'
|
import _ from 'lodash'
|
||||||
|
import chartMixin from '@/views/charts/charts/chart-mixin'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'ChartTabs',
|
name: 'ChartTabs',
|
||||||
props: {
|
|
||||||
chartInfo: Object,
|
|
||||||
chartData: [Object, Array, String], // 数据在父组件查询后传入,本组件内不查询,只根据接传递的数据来渲染
|
|
||||||
queryParams: Object // 接口请求参数
|
|
||||||
},
|
|
||||||
computed: {
|
computed: {
|
||||||
timeFilter () {
|
timeFilter () {
|
||||||
return {
|
return {
|
||||||
@@ -39,6 +36,7 @@ export default {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
mixins: [chartMixin],
|
||||||
methods: {
|
methods: {
|
||||||
showFullscreen () {
|
showFullscreen () {
|
||||||
|
|
||||||
|
|||||||
115
src/views/charts/charts/IpBasicInfo.vue
Normal file
115
src/views/charts/charts/IpBasicInfo.vue
Normal file
@@ -0,0 +1,115 @@
|
|||||||
|
<template>
|
||||||
|
<div class="cn-chart__ip-basic">
|
||||||
|
<el-descriptions :column="1">
|
||||||
|
<el-descriptions-item label="ASN:">{{(chartData && chartData.asn) || '-'}}</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="AS Org:">{{(chartData && chartData.asOrganization) || '-'}}</el-descriptions-item>
|
||||||
|
<el-descriptions-item :label="$t('entities.asSubnet') + ':'">{{(chartData && chartData.asSubnet) || '-'}}</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="ISP:">{{(chartData && chartData.isp) || '-'}}</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="DNS PTR:">{{(chartData && chartData.dnsPtr) || '-'}}</el-descriptions-item>
|
||||||
|
</el-descriptions>
|
||||||
|
<div class="chart-location">
|
||||||
|
<el-descriptions :column="1">
|
||||||
|
<el-descriptions-item :label="$t('overall.location') + ':'">{{location}}</el-descriptions-item>
|
||||||
|
</el-descriptions>
|
||||||
|
<div class="chart-drawing" style="padding: 0 36px 30px 0;" :id="`chart${chartInfo.id}`"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import chartMixin from '@/views/charts/charts/chart-mixin'
|
||||||
|
import * as L from 'leaflet'
|
||||||
|
import icon from 'leaflet/dist/images/marker-icon.png'
|
||||||
|
import iconShadow from 'leaflet/dist/images/marker-shadow.png'
|
||||||
|
import 'leaflet/dist/leaflet.css'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'IpBasicInfo',
|
||||||
|
mixins: [chartMixin],
|
||||||
|
data () {
|
||||||
|
return {
|
||||||
|
myChart: null,
|
||||||
|
mapPictureUrl: '/Tiles/{z}/{x}/{y}.png'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
location () {
|
||||||
|
let location = ''
|
||||||
|
if (this.chartInfo) {
|
||||||
|
if (this.chartInfo.country) {
|
||||||
|
location = this.chartInfo.country
|
||||||
|
if (this.chartInfo.province) {
|
||||||
|
location += ', '
|
||||||
|
location += this.chartInfo.province
|
||||||
|
if (this.chartInfo.city) {
|
||||||
|
location += ', '
|
||||||
|
location += this.chartInfo.city
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (this.chartInfo.province) {
|
||||||
|
location = this.chartInfo.province
|
||||||
|
if (this.chartInfo.city) {
|
||||||
|
location += ', '
|
||||||
|
location += this.chartInfo.city
|
||||||
|
}
|
||||||
|
} else if (this.chartInfo.city) {
|
||||||
|
location = this.chartInfo.city
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return location
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
initMap (id) {
|
||||||
|
L.Marker.prototype.options.icon = L.icon({
|
||||||
|
iconUrl: icon,
|
||||||
|
shadowUrl: iconShadow
|
||||||
|
})
|
||||||
|
const map = L.map(`chart${this.chartInfo.id}`, {
|
||||||
|
minZoom: 3,
|
||||||
|
maxZoom: 7,
|
||||||
|
zoom: 5,
|
||||||
|
attributionControl: false,
|
||||||
|
zoomControl: false,
|
||||||
|
maxBounds: L.latLngBounds(L.latLng(-90, -180), L.latLng(90, 180))
|
||||||
|
})
|
||||||
|
L.tileLayer(
|
||||||
|
this.mapPictureUrl,
|
||||||
|
{ noWrap: true }
|
||||||
|
).addTo(map)
|
||||||
|
|
||||||
|
const attribution = L.control.attribution({ position: 'bottomright', prefix: '' })
|
||||||
|
attribution.addAttribution(' © OpenStreetMap contributors')
|
||||||
|
attribution.addTo(map)
|
||||||
|
|
||||||
|
/* L.control.zoom({
|
||||||
|
position: 'bottomright',
|
||||||
|
zoomInText: '<i class="nz-icon nz-icon-enlarge"></i>',
|
||||||
|
zoomOutText: '<i class="nz-icon nz-icon-narrow"></i>',
|
||||||
|
zoomInTitle: '',
|
||||||
|
zoomOutTitle: ''
|
||||||
|
}).addTo(map) */
|
||||||
|
|
||||||
|
this.myChart = map
|
||||||
|
this.loadLeafletMap()
|
||||||
|
},
|
||||||
|
loadLeafletMap () {
|
||||||
|
if (this.chartData.latitude && this.chartData.longitude) {
|
||||||
|
this.myChart.setView([this.chartData.latitude, this.chartData.longitude], 5)
|
||||||
|
const myIcon = L.divIcon({
|
||||||
|
className: 'cn-icon cn-icon-position2 position-icon'
|
||||||
|
})
|
||||||
|
L.marker([this.chartData.latitude, this.chartData.longitude], { icon: myIcon }).addTo(this.myChart)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
watch: {
|
||||||
|
chartData: {
|
||||||
|
deep: true,
|
||||||
|
handler (n) {
|
||||||
|
this.initMap(`chart${this.chartInfo.id}`)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
8
src/views/charts/charts/chart-mixin.js
Normal file
8
src/views/charts/charts/chart-mixin.js
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
export default {
|
||||||
|
props: {
|
||||||
|
chartInfo: Object,
|
||||||
|
chartData: [Object, Array, String], // 数据在父组件查询后传入,本组件内不查询,只根据接传递的数据来渲染
|
||||||
|
entity: Object,
|
||||||
|
queryParams: Object // 接口请求参数
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -12,13 +12,12 @@
|
|||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
</div>
|
</div>
|
||||||
<div class="entity-detail__content">
|
<div class="entity-detail__content" @scroll="scroll" id="detailWrapper">
|
||||||
<cn-panel
|
<cn-panel
|
||||||
ref="cnPanel"
|
ref="cnPanel"
|
||||||
:entity="entityData"
|
:entity="entityData"
|
||||||
:is-entity-detail="true"
|
:is-entity-detail="true"
|
||||||
@chartLoaded="chartLoaded"
|
@chartLoaded="chartLoaded"
|
||||||
@scroll="scroll"
|
|
||||||
></cn-panel>
|
></cn-panel>
|
||||||
</div>
|
</div>
|
||||||
</main>
|
</main>
|
||||||
@@ -75,16 +74,16 @@ export default {
|
|||||||
chartLoaded (chartList) {
|
chartLoaded (chartList) {
|
||||||
this.anchorPoints = []
|
this.anchorPoints = []
|
||||||
let anchorPoints = []
|
let anchorPoints = []
|
||||||
const panelDom = document.querySelector('#cn-panel')
|
const panelDom = document.querySelector('#detailWrapper')
|
||||||
this.scrollHeight = panelDom.scrollHeight
|
this.scrollHeight = panelDom.scrollHeight
|
||||||
this.clientHeight = panelDom.clientHeight
|
this.clientHeight = panelDom.clientHeight
|
||||||
chartList.forEach(chart => {
|
chartList.forEach(chart => {
|
||||||
if (chart.params.anchorPoint) {
|
if (chart.params.anchorPoint) {
|
||||||
const dom = document.querySelector(`#${chart.params.anchorPoint}`)
|
const dom = document.querySelector(`[anchor-point='${chart.params.anchorPoint}']`)
|
||||||
anchorPoints.push({
|
dom && anchorPoints.push({
|
||||||
id: chart.params.anchorPoint,
|
id: chart.params.anchorPoint,
|
||||||
label: chart.i18n ? this.$t(chart.i18n) : chart.name,
|
label: chart.i18n ? this.$t(chart.i18n) : chart.name,
|
||||||
top: dom.offsetTop/* ,
|
top: dom.offsetTop + 10/* ,
|
||||||
height: document.querySelector(`#${chart.params.anchorPoint}}`).scrollHeight */
|
height: document.querySelector(`#${chart.params.anchorPoint}}`).scrollHeight */
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@@ -98,12 +97,12 @@ export default {
|
|||||||
}
|
}
|
||||||
this.anchorPoints = anchorPoints
|
this.anchorPoints = anchorPoints
|
||||||
},
|
},
|
||||||
scroll ({ top }) {
|
scroll (e) {
|
||||||
this.top = top || 0
|
this.top = (e.target.scrollTop + 10) || 0
|
||||||
},
|
},
|
||||||
jumpToAnchor (anchor) {
|
jumpToAnchor (anchor) {
|
||||||
this.top = anchor.top
|
this.top = anchor.top
|
||||||
this.$refs.cnPanel.jumpToTop(anchor.top)
|
document.querySelector('#detailWrapper').scrollTop = this.top
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
@@ -133,7 +132,7 @@ export default {
|
|||||||
},
|
},
|
||||||
currentAnchor () {
|
currentAnchor () {
|
||||||
let currentAnchor = null
|
let currentAnchor = null
|
||||||
if (this.top + this.clientHeight === this.scrollHeight) {
|
if (this.top + this.clientHeight - 10 === this.scrollHeight) {
|
||||||
currentAnchor = this.anchorPoints[this.anchorPoints.length - 1]
|
currentAnchor = this.anchorPoints[this.anchorPoints.length - 1]
|
||||||
} else {
|
} else {
|
||||||
this.anchorPoints.forEach(anchor => {
|
this.anchorPoints.forEach(anchor => {
|
||||||
|
|||||||
Reference in New Issue
Block a user