NEZ-3319 feat:dashboard bar图表类型样式优化
This commit is contained in:
4
nezha-fronted/package-lock.json
generated
4
nezha-fronted/package-lock.json
generated
@@ -17732,7 +17732,7 @@
|
|||||||
},
|
},
|
||||||
"node-sass": {
|
"node-sass": {
|
||||||
"version": "4.14.1",
|
"version": "4.14.1",
|
||||||
"resolved": "https://registry.npmmirror.com/node-sass/-/node-sass-4.14.1.tgz",
|
"resolved": "https://registry.npmjs.org/node-sass/-/node-sass-4.14.1.tgz",
|
||||||
"integrity": "sha512-sjCuOlvGyCJS40R8BscF5vhVlQjNN069NtQ1gSxyK1u9iqvn6tf7O1R4GNowVZfiZUCRt5MmMs1xd+4V/7Yr0g==",
|
"integrity": "sha512-sjCuOlvGyCJS40R8BscF5vhVlQjNN069NtQ1gSxyK1u9iqvn6tf7O1R4GNowVZfiZUCRt5MmMs1xd+4V/7Yr0g==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
@@ -24364,7 +24364,7 @@
|
|||||||
},
|
},
|
||||||
"webpack-bundle-analyzer": {
|
"webpack-bundle-analyzer": {
|
||||||
"version": "2.13.1",
|
"version": "2.13.1",
|
||||||
"resolved": "https://registry.npmmirror.com/webpack-bundle-analyzer/-/webpack-bundle-analyzer-2.13.1.tgz",
|
"resolved": "https://registry.npmjs.org/webpack-bundle-analyzer/-/webpack-bundle-analyzer-2.13.1.tgz",
|
||||||
"integrity": "sha512-rwxyfecTAxoarCC9VlHlIpfQCmmJ/qWD5bpbjkof+7HrNhTNZIwZITxN6CdlYL2axGmwNUQ+tFgcSOiNXMf/sQ==",
|
"integrity": "sha512-rwxyfecTAxoarCC9VlHlIpfQCmmJ/qWD5bpbjkof+7HrNhTNZIwZITxN6CdlYL2axGmwNUQ+tFgcSOiNXMf/sQ==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
|
|||||||
@@ -876,3 +876,155 @@
|
|||||||
height: auto !important;
|
height: auto !important;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.bar-item {
|
||||||
|
&:last-of-type{
|
||||||
|
margin: 0 !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.bar-basic-vertical{
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
display: flex;
|
||||||
|
overflow: hidden;
|
||||||
|
.bar-rect{
|
||||||
|
border-radius: 2px;
|
||||||
|
background: $--chart-bar-background;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
justify-content: flex-end;
|
||||||
|
.bar-actual{
|
||||||
|
border-radius: 2px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.bar-value{
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
white-space: nowrap;
|
||||||
|
line-height: 1;
|
||||||
|
color: $--color-text-primary;
|
||||||
|
}
|
||||||
|
.bar-title{
|
||||||
|
width: 100%;
|
||||||
|
font-size: 14px;
|
||||||
|
white-space: nowrap;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
overflow: hidden;
|
||||||
|
text-align: center;
|
||||||
|
line-height: 1.5;
|
||||||
|
color: $--color-text-primary;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.bar-basic-horizontal{
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
overflow: hidden;
|
||||||
|
.bar-item{
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
.bar-rect{
|
||||||
|
border-radius: 2px;
|
||||||
|
background: $--chart-bar-background;
|
||||||
|
.bar-actual{
|
||||||
|
border-radius: 2px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.bar-title{
|
||||||
|
padding-right: 10px;
|
||||||
|
box-sizing: border-box;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
overflow: hidden;
|
||||||
|
white-space: nowrap;
|
||||||
|
text-align: right;
|
||||||
|
color: $--color-text-primary;
|
||||||
|
}
|
||||||
|
.bar-value{
|
||||||
|
padding: 0 10px;
|
||||||
|
box-sizing: border-box;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: flex-end;
|
||||||
|
white-space: nowrap;
|
||||||
|
color: $--color-text-primary;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.bar-retro-vertical{
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
display: flex;
|
||||||
|
overflow: hidden;
|
||||||
|
.bar-item{
|
||||||
|
display: flex;
|
||||||
|
overflow: hidden;
|
||||||
|
flex-direction: column-reverse;
|
||||||
|
}
|
||||||
|
.bar-rect{
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column-reverse;
|
||||||
|
align-items: center;
|
||||||
|
.bar-cell{
|
||||||
|
border-radius: 2px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.bar-value{
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
white-space: nowrap;
|
||||||
|
line-height: 1;
|
||||||
|
color: $--color-text-primary;
|
||||||
|
}
|
||||||
|
.bar-title{
|
||||||
|
width: 100%;
|
||||||
|
font-size: 14px;
|
||||||
|
white-space: nowrap;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
overflow: hidden;
|
||||||
|
text-align: center;
|
||||||
|
line-height: 1.5;
|
||||||
|
color: $--color-text-primary;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.bar-retro-horizontal{
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
overflow: hidden;
|
||||||
|
.bar-item{
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
overflow: hidden;
|
||||||
|
.bar-rect{
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
.bar-cell{
|
||||||
|
border-radius: 2px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.bar-title{
|
||||||
|
padding-right: 10px;
|
||||||
|
box-sizing: border-box;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
overflow: hidden;
|
||||||
|
white-space: nowrap;
|
||||||
|
text-align: right;
|
||||||
|
color: $--color-text-primary;
|
||||||
|
}
|
||||||
|
.bar-value{
|
||||||
|
padding: 0 10px;
|
||||||
|
box-sizing: border-box;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: flex-end;
|
||||||
|
white-space: nowrap;
|
||||||
|
color: $--color-text-primary;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -261,6 +261,7 @@ $--chart-border-color: $--border-color-light;
|
|||||||
$--chart-title-hover-background-color: #323238;
|
$--chart-title-hover-background-color: #323238;
|
||||||
$--chart-box-border-color: $--border-color-light;
|
$--chart-box-border-color: $--border-color-light;
|
||||||
$--chart-shadow: -1px 0 8px -3px rgba(0,0,0,0.8);
|
$--chart-shadow: -1px 0 8px -3px rgba(0,0,0,0.8);
|
||||||
|
$--chart-bar-background: #2D2E35;
|
||||||
|
|
||||||
/* 14.popover */
|
/* 14.popover */
|
||||||
$--popover-background-color: $--background-color-empty;
|
$--popover-background-color: $--background-color-empty;
|
||||||
|
|||||||
@@ -258,6 +258,7 @@ $--chart-border-color: $--color-text-label;
|
|||||||
$--chart-title-hover-background-color: $--background-color-1;
|
$--chart-title-hover-background-color: $--background-color-1;
|
||||||
$--chart-box-border-color: $--border-color-light;
|
$--chart-box-border-color: $--border-color-light;
|
||||||
$--chart-shadow: -1px 0 8px -3px #ccc;
|
$--chart-shadow: -1px 0 8px -3px #ccc;
|
||||||
|
$--chart-bar-background: #F4F5F5;
|
||||||
|
|
||||||
/* 14.popover */
|
/* 14.popover */
|
||||||
$--popover-background-color: $--color-text-label;
|
$--popover-background-color: $--color-text-label;
|
||||||
|
|||||||
@@ -1,19 +1,265 @@
|
|||||||
<template>
|
<template>
|
||||||
<div
|
<div
|
||||||
:class="legendPlacement"
|
|
||||||
ref="bar-chart-box"
|
ref="bar-chart-box"
|
||||||
class="nz-chart__component nz-chart__component--time-series" @mouseenter="mouseEnterChart"
|
class="nz-chart__component" @mouseenter="mouseEnterChart"
|
||||||
@mouseleave="mouseLeaveChart"
|
@mouseleave="mouseLeaveChart"
|
||||||
>
|
>
|
||||||
<div :id="`chart-canvas-${chartId}`" class="chart__canvas" :class="{'chart-cursor-default':!(dataLink.length || chartInfo.datasource === 'metrics' || chartInfo.datasource === 'logs')}"></div>
|
<div :id="`chart-canvas-${chartId}`" class="chart__canvas" style="overflow: hidden;" :style="{padding:boxPadding + 'px'}">
|
||||||
<chart-legend
|
<!-- retro led -->
|
||||||
v-if="hasLegend"
|
<template v-if="chartInfo.param.displayMode==='led'">
|
||||||
:chart-data="chartData"
|
<!-- horizontal -->
|
||||||
:chart-info="chartInfo"
|
<ul class="bar-retro-horizontal" v-if="chartInfo.param.orientation==='horizontal'">
|
||||||
:legends="legends"
|
<li
|
||||||
:series="series"
|
class="bar-item"
|
||||||
:is-fullscreen="isFullscreen"
|
v-for="(item,index) in barData"
|
||||||
></chart-legend>
|
:key="index"
|
||||||
|
:style="{
|
||||||
|
height:item.height + 'px',
|
||||||
|
marginBottom:item.spacing + 'px',
|
||||||
|
}"
|
||||||
|
>
|
||||||
|
<template v-if="item.height!==undefined">
|
||||||
|
<!-- legend -->
|
||||||
|
<p
|
||||||
|
v-if="chartInfo.param.text === 'legend' || chartInfo.param.text === 'all'"
|
||||||
|
class="bar-title"
|
||||||
|
:title="item.alias"
|
||||||
|
:style="{
|
||||||
|
width: item.titleWidth + 'px',
|
||||||
|
fontSize: item.titleFontSize +'px'
|
||||||
|
}"
|
||||||
|
>
|
||||||
|
{{item.alias}}
|
||||||
|
</p>
|
||||||
|
<div class="bar-rect" :style="{width:item.width + 'px',}">
|
||||||
|
<div
|
||||||
|
v-for="(cell) in item.cellCount"
|
||||||
|
:key="cell"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
v-if="item.litCount >= cell"
|
||||||
|
class="bar-cell"
|
||||||
|
:class="{'chart-cursor-pointer':(dataLink.length || chartInfo.datasource === 'metrics' || chartInfo.datasource === 'logs')}"
|
||||||
|
:style="{
|
||||||
|
width:item.cellWidth + 'px',
|
||||||
|
height:item.cellHeight + 'px',
|
||||||
|
marginRight:item.spacing + 'px',
|
||||||
|
backgroundImage:item.cellBackgroundImage,
|
||||||
|
}"
|
||||||
|
@mouseenter="barEnter($event,item)"
|
||||||
|
@mousemove="barMove"
|
||||||
|
@mouseleave="barLeave"
|
||||||
|
@click="chartClick($event,item)"
|
||||||
|
>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
v-else
|
||||||
|
class="bar-cell"
|
||||||
|
:style="{
|
||||||
|
width:item.cellWidth + 'px',
|
||||||
|
height:item.cellHeight + 'px',
|
||||||
|
marginRight:item.spacing + 'px',
|
||||||
|
background:item.cellBackground,
|
||||||
|
}"
|
||||||
|
>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<!-- value -->
|
||||||
|
<p
|
||||||
|
v-if="chartInfo.param.text === 'value' || chartInfo.param.text === 'all'"
|
||||||
|
class="bar-value"
|
||||||
|
:style="{
|
||||||
|
width:item.valueWidth + 'px',
|
||||||
|
fontSize:item.valueFontSize + 'px',
|
||||||
|
color:item.mapping && item.mapping.color && item.mapping.color.text
|
||||||
|
}"
|
||||||
|
>
|
||||||
|
<i v-if="item.mapping && item.mapping.icon" :class="item.mapping.icon" :style="{color: item.mapping.color.icon,fontSize:'1em'}"></i>
|
||||||
|
<span>{{item.mapping ? handleDisplay(item.mapping.display, { ...item.label, value: item.showValue }) : item.showValue}}</span>
|
||||||
|
</p>
|
||||||
|
</template>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
<!-- vertical -->
|
||||||
|
<ul class="bar-retro-vertical" v-else>
|
||||||
|
<li
|
||||||
|
class="bar-item"
|
||||||
|
v-for="(item,index) in barData"
|
||||||
|
:key="index"
|
||||||
|
:style="{
|
||||||
|
width: item.width + 'px',
|
||||||
|
marginRight:item.spacing + 'px',
|
||||||
|
}"
|
||||||
|
>
|
||||||
|
<template v-if="item.width!==undefined">
|
||||||
|
<!-- legend -->
|
||||||
|
<p v-if="chartInfo.param.text === 'legend' || chartInfo.param.text === 'all'" class="bar-title" :title="item.alias">{{item.alias}}</p>
|
||||||
|
<div class="bar-rect" :style="{height:item.height + 'px',}">
|
||||||
|
<div
|
||||||
|
v-for="(cell) in item.cellCount"
|
||||||
|
:key="cell"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
v-if="item.litCount >= cell"
|
||||||
|
class="bar-cell"
|
||||||
|
:class="{'chart-cursor-pointer':(dataLink.length || chartInfo.datasource === 'metrics' || chartInfo.datasource === 'logs')}"
|
||||||
|
:style="{
|
||||||
|
width:item.cellWidth + 'px',
|
||||||
|
height:item.cellHeight + 'px',
|
||||||
|
marginTop:item.spacing + 'px',
|
||||||
|
backgroundImage:item.cellBackgroundImage,
|
||||||
|
}"
|
||||||
|
@mouseenter="barEnter($event,item)"
|
||||||
|
@mousemove="barMove"
|
||||||
|
@mouseleave="barLeave"
|
||||||
|
@click="chartClick($event,item)"
|
||||||
|
>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
v-else
|
||||||
|
class="bar-cell"
|
||||||
|
:style="{
|
||||||
|
width:item.cellWidth + 'px',
|
||||||
|
height:item.cellHeight + 'px',
|
||||||
|
marginTop:item.spacing + 'px',
|
||||||
|
background:item.cellBackground,
|
||||||
|
}"
|
||||||
|
>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<!-- value -->
|
||||||
|
<p
|
||||||
|
v-if="chartInfo.param.text === 'value' || chartInfo.param.text === 'all'"
|
||||||
|
class="bar-value"
|
||||||
|
:style="{
|
||||||
|
height:item.valueHeight + 'px',
|
||||||
|
fontSize:item.valueFontSize + 'px',
|
||||||
|
color:item.mapping && item.mapping.color && item.mapping.color.text
|
||||||
|
}"
|
||||||
|
>
|
||||||
|
<i v-if="item.mapping && item.mapping.icon" :class="item.mapping.icon" :style="{color: item.mapping.color.icon,fontSize:'1em'}"></i>
|
||||||
|
<span>{{item.mapping ? handleDisplay(item.mapping.display, { ...item.label, value: item.showValue }) : item.showValue}}</span>
|
||||||
|
</p>
|
||||||
|
</template>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</template>
|
||||||
|
<!-- basic -->
|
||||||
|
<template v-else>
|
||||||
|
<!-- horizontal -->
|
||||||
|
<ul class="bar-basic-horizontal" v-if="chartInfo.param.orientation==='horizontal'">
|
||||||
|
<li
|
||||||
|
class="bar-item"
|
||||||
|
v-for="(item,index) in barData"
|
||||||
|
:key="index"
|
||||||
|
:style="{
|
||||||
|
height:item.height + 'px',
|
||||||
|
marginBottom:item.spacing + 'px',
|
||||||
|
}"
|
||||||
|
>
|
||||||
|
<template v-if="item.height!==undefined">
|
||||||
|
<!-- legend -->
|
||||||
|
<p
|
||||||
|
v-if="chartInfo.param.text === 'legend' || chartInfo.param.text === 'all'"
|
||||||
|
class="bar-title"
|
||||||
|
:title="item.alias"
|
||||||
|
:style="{
|
||||||
|
width: item.titleWidth + 'px',
|
||||||
|
fontSize: item.titleFontSize +'px'
|
||||||
|
}"
|
||||||
|
>
|
||||||
|
{{item.alias}}
|
||||||
|
</p>
|
||||||
|
<div class="bar-rect" :style="{width:item.width + 'px',}">
|
||||||
|
<div
|
||||||
|
class="bar-actual"
|
||||||
|
:class="{'chart-cursor-pointer':(dataLink.length || chartInfo.datasource === 'metrics' || chartInfo.datasource === 'logs')}"
|
||||||
|
:style="{ width:item.actualWidth + 'px',height:item.height + 'px',background:item.background,}"
|
||||||
|
@mouseenter="barEnter($event,item)"
|
||||||
|
@mousemove="barMove"
|
||||||
|
@mouseleave="barLeave"
|
||||||
|
@click="chartClick($event,item)"
|
||||||
|
>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<!-- value -->
|
||||||
|
<p
|
||||||
|
v-if="chartInfo.param.text === 'value' || chartInfo.param.text === 'all'"
|
||||||
|
class="bar-value"
|
||||||
|
:style="{
|
||||||
|
width:item.valueWidth + 'px',
|
||||||
|
fontSize:item.valueFontSize + 'px',
|
||||||
|
color:item.mapping && item.mapping.color && item.mapping.color.text
|
||||||
|
}"
|
||||||
|
>
|
||||||
|
<i v-if="item.mapping && item.mapping.icon" :class="item.mapping.icon" :style="{color: item.mapping.color.icon,fontSize:'1em'}"></i>
|
||||||
|
<span>{{item.mapping ? handleDisplay(item.mapping.display, { ...item.label, value: item.showValue }) : item.showValue}}</span>
|
||||||
|
</p>
|
||||||
|
</template>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
<!-- vertical -->
|
||||||
|
<ul class="bar-basic-vertical" v-else>
|
||||||
|
<li
|
||||||
|
class="bar-item"
|
||||||
|
v-for="(item,index) in barData"
|
||||||
|
:key="index"
|
||||||
|
:style="{
|
||||||
|
width:item.width + 'px',
|
||||||
|
marginRight:item.spacing + 'px'
|
||||||
|
}"
|
||||||
|
>
|
||||||
|
<template v-if="item.width!==undefined">
|
||||||
|
<!-- value -->
|
||||||
|
<p
|
||||||
|
v-if="chartInfo.param.text === 'value' || chartInfo.param.text === 'all'"
|
||||||
|
class="bar-value"
|
||||||
|
:style="{
|
||||||
|
height:item.valueHeight + 'px',
|
||||||
|
fontSize:item.valueFontSize + 'px',
|
||||||
|
color:item.mapping && item.mapping.color && item.mapping.color.text
|
||||||
|
}"
|
||||||
|
>
|
||||||
|
<i v-if="item.mapping && item.mapping.icon" :class="item.mapping.icon" :style="{color: item.mapping.color.icon,fontSize:'1em'}"></i>
|
||||||
|
<span>{{item.mapping ? handleDisplay(item.mapping.display, { ...item.label, value: item.showValue }) : item.showValue}}</span>
|
||||||
|
</p>
|
||||||
|
<div class="bar-rect" :style="{height:item.height + 'px',}">
|
||||||
|
<div
|
||||||
|
class="bar-actual"
|
||||||
|
:class="{'chart-cursor-pointer':(dataLink.length || chartInfo.datasource === 'metrics' || chartInfo.datasource === 'logs')}"
|
||||||
|
:style="{ height:item.actualHeight + 'px', background:item.background,}"
|
||||||
|
@mouseenter="barEnter($event,item)"
|
||||||
|
@mousemove="barMove"
|
||||||
|
@mouseleave="barLeave"
|
||||||
|
@click="chartClick($event,item)"
|
||||||
|
>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<!-- legend -->
|
||||||
|
<p v-if="chartInfo.param.text === 'legend' || chartInfo.param.text === 'all'" class="bar-title" :title="item.alias">{{item.alias}}</p>
|
||||||
|
</template>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</template>
|
||||||
|
</div>
|
||||||
|
<!-- tooltip -->
|
||||||
|
<div :id="`chart-canvas-tooltip-${chartId}`" class="chart-canvas-tooltip no-style-class" :style="{left:tooltip.x+'px',top:tooltip.y+'px'}" v-if="tooltip.show">
|
||||||
|
<div class="chart-canvas-tooltip-title tooltip-title" :title="tooltip.title">
|
||||||
|
{{tooltip.title}}
|
||||||
|
</div>
|
||||||
|
<div class="chart-canvas-tooltip-content">
|
||||||
|
<div>value</div>
|
||||||
|
<div>
|
||||||
|
<div v-if="tooltip.mapping && tooltip.mapping.icon" style="display: inline-block">
|
||||||
|
<i :class="tooltip.mapping.icon" :style="{color: tooltip.mapping.color.icon}"></i>
|
||||||
|
</div>
|
||||||
|
<div style="display: inline-block">{{tooltip.value}}</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
<!-- toolbox -->
|
<!-- toolbox -->
|
||||||
<div :id="`chart-toolbox-${chartId}`" class="chart-canvas-tooltip no-style-class chart-toolbox" :style="{left:toolbox.x+'px',top:toolbox.y+'px'}" v-if="toolbox.show" v-clickoutside="clickout">
|
<div :id="`chart-toolbox-${chartId}`" class="chart-canvas-tooltip no-style-class chart-toolbox" :style="{left:toolbox.x+'px',top:toolbox.y+'px'}" v-if="toolbox.show" v-clickoutside="clickout">
|
||||||
<div class="chart-canvas-tooltip-title tooltip-title" :title="toolbox.title">{{toolbox.title}}</div>
|
<div class="chart-canvas-tooltip-title tooltip-title" :title="toolbox.title">{{toolbox.title}}</div>
|
||||||
@@ -40,25 +286,22 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<span class="temp-dom" ref="temp-dom"></span>
|
||||||
|
<span class="temp-dom" ref="temp-dom2"></span>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import legend from '@/components/chart/chart/legend'
|
|
||||||
import chartMixin from '@/components/chart/chartMixin'
|
import chartMixin from '@/components/chart/chartMixin'
|
||||||
import chartFormat from '@/components/chart/chartFormat'
|
import chartFormat from '@/components/chart/chartFormat'
|
||||||
import { chartLegendPlacement } from '@/components/common/js/constants'
|
|
||||||
import * as echarts from 'echarts'
|
|
||||||
import { getChart, setChart } from '@/components/common/js/common'
|
|
||||||
import { formatScientificNotation, getMetricTypeValue } from '@/components/common/js/tools'
|
import { formatScientificNotation, getMetricTypeValue } from '@/components/common/js/tools'
|
||||||
import chartDataFormat from '@/components/chart/chartDataFormat'
|
import chartDataFormat from '@/components/chart/chartDataFormat'
|
||||||
import { initColor } from '@/components/chart/chart/tools'
|
import { initColor } from '@/components/chart/chart/tools'
|
||||||
import lodash from 'lodash'
|
import lodash from 'lodash'
|
||||||
|
import tinycolor from 'tinycolor2'
|
||||||
export default {
|
export default {
|
||||||
name: 'chart-bar',
|
name: 'chart-bar',
|
||||||
components: {
|
components: {
|
||||||
chartLegend: legend
|
|
||||||
},
|
},
|
||||||
mixins: [chartMixin, chartFormat],
|
mixins: [chartMixin, chartFormat],
|
||||||
props: {
|
props: {
|
||||||
@@ -68,27 +311,6 @@ export default {
|
|||||||
isFullscreen: Boolean
|
isFullscreen: Boolean
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
hasLegend () {
|
|
||||||
try {
|
|
||||||
return [chartLegendPlacement.bottom, chartLegendPlacement.left, chartLegendPlacement.right].indexOf(this.chartInfo.param.legend.placement) > -1 && this.chartInfo.param.enable.legend
|
|
||||||
} catch (e) {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
},
|
|
||||||
legendPlacement () {
|
|
||||||
try {
|
|
||||||
switch (this.chartInfo.param.legend.placement) {
|
|
||||||
case 'left':
|
|
||||||
case 'right':
|
|
||||||
case 'bottom': {
|
|
||||||
return `nz-chart__component--${this.chartInfo.param.legend.placement}`
|
|
||||||
}
|
|
||||||
default: return ''
|
|
||||||
}
|
|
||||||
} catch (e) {
|
|
||||||
return ''
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
data () {
|
data () {
|
||||||
return {
|
return {
|
||||||
@@ -100,88 +322,284 @@ export default {
|
|||||||
active: '#53a3cb',
|
active: '#53a3cb',
|
||||||
inactive: '#7e7e7e'
|
inactive: '#7e7e7e'
|
||||||
},
|
},
|
||||||
chartId: ''
|
chartId: '',
|
||||||
|
barData: [],
|
||||||
|
boxWidth: 0,
|
||||||
|
boxHeight: 0,
|
||||||
|
boxPadding: 10
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
initChart (chartOption = this.chartOption) {
|
initChart () {
|
||||||
this.setDataLink()
|
this.setDataLink()
|
||||||
const self = this
|
|
||||||
this.legends = []
|
this.legends = []
|
||||||
this.series = chartOption.series = this.initBarData(this.chartInfo, chartOption.series[0], this.chartData) // 生成series和legends
|
this.initBarData(this.chartInfo, this.chartData)
|
||||||
if (this.isNoData) {
|
if (this.isNoData) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
chartOption.xAxis.data = chartOption.series[0].data.map(item => {
|
|
||||||
if (this.chartInfo.param.text == 'all' || this.chartInfo.param.text == 'legend') {
|
|
||||||
return item.name
|
|
||||||
} else {
|
|
||||||
return ''
|
|
||||||
}
|
|
||||||
})
|
|
||||||
chartOption.axisLabel = {
|
|
||||||
margin: 8,
|
|
||||||
formatter (params) {
|
|
||||||
const dataLength = chartOption.series[0].data.length || 1
|
|
||||||
const chartWidth = (document.getElementById('chart-canvas-' + self.chartInfo.id).offsetWidth - 80) / dataLength// 容器宽 - padding - 空余
|
|
||||||
const length = Math.ceil((chartWidth) / 16)
|
|
||||||
let val = ''
|
|
||||||
if (params.length > length) {
|
|
||||||
val = params.substr(0, length) + '...'
|
|
||||||
return val
|
|
||||||
} else {
|
|
||||||
return params
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
chartOption.yAxis.axisLabel.formatter = function (val, index) {
|
|
||||||
const value = formatScientificNotation(val, 6)
|
|
||||||
let chartUnit = self.chartInfo.unit
|
|
||||||
chartUnit = chartUnit || 2
|
|
||||||
const unit = chartDataFormat.getUnit(chartUnit)
|
|
||||||
return unit.compute(value, index, -1, 2)
|
|
||||||
}
|
|
||||||
chartOption.tooltip.formatter = this.formatterFunc
|
|
||||||
chartOption.tooltip.position = this.tooltipPosition
|
|
||||||
if (navigator.userAgent.match(/Mobi/i) ||
|
|
||||||
navigator.userAgent.match(/Android/i) ||
|
|
||||||
navigator.userAgent.match(/iPhone/i)) {
|
|
||||||
chartOption.tooltip.confine = true
|
|
||||||
chartOption.tooltip.appendToBody = false
|
|
||||||
delete chartOption.tooltip.position
|
|
||||||
}
|
|
||||||
/* 使用setTimeout延迟渲染图表,避免样式错乱 */
|
/* 使用setTimeout延迟渲染图表,避免样式错乱 */
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
const myChart = this.isInit ? echarts.init(document.getElementById(`chart-canvas-${this.chartId}`)) : getChart(this.chartId)
|
this.drawBarChart()
|
||||||
if (!myChart) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
myChart.setOption(chartOption)
|
|
||||||
this.isInit && setChart(this.chartId, myChart) // 缓存;不使用vue的data是为避免整个chart被监听导致卡顿
|
|
||||||
if (this.isInit && (this.dataLink.length || this.chartInfo.datasource === 'metrics' || this.chartInfo.datasource === 'logs')) {
|
|
||||||
myChart.on('click', this.chartClick)
|
|
||||||
}
|
|
||||||
this.isInit = false
|
this.isInit = false
|
||||||
}, 200)
|
}, 200)
|
||||||
},
|
},
|
||||||
initBarData (chartInfo, seriesTemplate, originalDatas) {
|
resize () {
|
||||||
|
setTimeout(() => {
|
||||||
|
this.drawBarChart()
|
||||||
|
}, 50)
|
||||||
|
},
|
||||||
|
drawBarChart () {
|
||||||
|
const wrap = document.getElementById(`chart-canvas-${this.chartId}`)
|
||||||
|
this.boxWidth = wrap.offsetWidth - 2 * this.boxPadding
|
||||||
|
this.boxHeight = wrap.offsetHeight - 2 * this.boxPadding
|
||||||
|
const displayMode = lodash.get(this.chartInfo, 'param.displayMode', 'basic')
|
||||||
|
if (displayMode === 'basic') {
|
||||||
|
this.renderBasicBars()
|
||||||
|
} else {
|
||||||
|
this.renderRetroBars()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
renderBasicBars () {
|
||||||
|
const orientation = lodash.get(this.chartInfo, 'param.orientation', 'vertical')
|
||||||
|
const maxValue = this.calcMax(this.barData)
|
||||||
|
const spacing = 10
|
||||||
|
const numBars = this.barData.length
|
||||||
|
const totalSpacing = (numBars - 1) * spacing
|
||||||
|
if (orientation === 'vertical') {
|
||||||
|
const width = (this.boxWidth - totalSpacing) / numBars
|
||||||
|
const minValueHeight = 18
|
||||||
|
const maxValueHeight = 50
|
||||||
|
const valueHeight = this.chartInfo.param.text === 'value' || this.chartInfo.param.text === 'all' ? Math.min(Math.max(this.boxHeight * 0.1, minValueHeight), maxValueHeight) : 0
|
||||||
|
const titleHeight = this.chartInfo.param.text === 'legend' || this.chartInfo.param.text === 'all' ? 14 * 1.5 : 0
|
||||||
|
const height = this.boxHeight - valueHeight - titleHeight
|
||||||
|
|
||||||
|
this.barData.forEach((item) => {
|
||||||
|
item.width = width
|
||||||
|
item.spacing = spacing
|
||||||
|
item.valueHeight = valueHeight
|
||||||
|
item.height = height
|
||||||
|
const valuePercent = this.getValuePercent(item.value, 0, maxValue)
|
||||||
|
item.actualHeight = item.height * valuePercent
|
||||||
|
|
||||||
|
let valueText = ''
|
||||||
|
if (item.mapping) {
|
||||||
|
valueText = this.handleDisplay(item.mapping.display, { ...item.label, value: item.showValue })
|
||||||
|
if (item.mapping.icon) {
|
||||||
|
valueText += 'AA'
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
valueText = item.showValue
|
||||||
|
}
|
||||||
|
item.valueFontSize = this.calculateFontSize(valueText, width, valueHeight, 1)
|
||||||
|
})
|
||||||
|
const valueFontArr = this.barData.map(item => item.valueFontSize)
|
||||||
|
const minValueFont = Math.min(...valueFontArr)
|
||||||
|
this.barData.forEach(item => {
|
||||||
|
item.valueFontSize = minValueFont
|
||||||
|
})
|
||||||
|
this.$forceUpdate()
|
||||||
|
} else {
|
||||||
|
const height = (this.boxHeight - totalSpacing) / numBars
|
||||||
|
const maxTitleHeightRatio = 0.6
|
||||||
|
const titleHeight = height * maxTitleHeightRatio
|
||||||
|
const titleFontSize = Math.min(titleHeight, 28)
|
||||||
|
|
||||||
|
const maxValueWidth = 150
|
||||||
|
const valueWidth = this.chartInfo.param.text === 'value' || this.chartInfo.param.text === 'all' ? Math.min(this.boxWidth * 0.2, maxValueWidth) : 0
|
||||||
|
|
||||||
|
this.barData.forEach((item) => {
|
||||||
|
item.height = height
|
||||||
|
item.spacing = spacing
|
||||||
|
|
||||||
|
item.titleFontSize = titleFontSize
|
||||||
|
const text = item.alias
|
||||||
|
const el = this.$refs['temp-dom2']
|
||||||
|
el.innerText = text
|
||||||
|
el.style.fontSize = titleFontSize + 'px'
|
||||||
|
item.titleWidth = el.offsetWidth
|
||||||
|
|
||||||
|
let valueText = ''
|
||||||
|
if (item.mapping) {
|
||||||
|
valueText = this.handleDisplay(item.mapping.display, { ...item.label, value: item.showValue })
|
||||||
|
if (item.mapping.icon) {
|
||||||
|
valueText += 'AA'
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
valueText = item.showValue
|
||||||
|
}
|
||||||
|
item.valueWidth = valueWidth
|
||||||
|
item.valueFontSize = this.calculateFontSize(valueText, item.valueWidth - 10 * 2, height, 1.2)
|
||||||
|
})
|
||||||
|
const titleWidthArr = this.barData.map(item => item.titleWidth)
|
||||||
|
const maxTitleWidth = Math.max(...titleWidthArr)
|
||||||
|
const titleWidth = this.chartInfo.param.text === 'legend' || this.chartInfo.param.text === 'all' ? Math.min(maxTitleWidth + 15, this.boxWidth * 0.4) : 0
|
||||||
|
|
||||||
|
const valueFontArr = this.barData.map(item => item.valueFontSize)
|
||||||
|
const minValueFont = Math.min(...valueFontArr)
|
||||||
|
this.barData.forEach(item => {
|
||||||
|
item.titleWidth = titleWidth
|
||||||
|
item.valueFontSize = minValueFont
|
||||||
|
item.width = this.boxWidth - item.titleWidth - item.valueWidth
|
||||||
|
const valuePercent = this.getValuePercent(item.value, 0, maxValue)
|
||||||
|
item.actualWidth = item.width * valuePercent
|
||||||
|
})
|
||||||
|
this.$forceUpdate()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
renderRetroBars () {
|
||||||
|
const orientation = lodash.get(this.chartInfo, 'param.orientation', 'vertical')
|
||||||
|
const maxValue = this.calcMax(this.barData)
|
||||||
|
const spacing = 2
|
||||||
|
const numBars = this.barData.length
|
||||||
|
const totalSpacing = (numBars - 1) * spacing
|
||||||
|
if (orientation === 'vertical') {
|
||||||
|
const width = (this.boxWidth - totalSpacing) / numBars
|
||||||
|
const minValueHeight = 18
|
||||||
|
const maxValueHeight = 50
|
||||||
|
const valueHeight = this.chartInfo.param.text === 'value' || this.chartInfo.param.text === 'all' ? Math.min(Math.max(this.boxHeight * 0.1, minValueHeight), maxValueHeight) : 0
|
||||||
|
const titleHeight = this.chartInfo.param.text === 'legend' || this.chartInfo.param.text === 'all' ? 14 * 1.5 : 0
|
||||||
|
const height = this.boxHeight - valueHeight - titleHeight
|
||||||
|
|
||||||
|
const cellHeight = 10
|
||||||
|
const cellWidth = width
|
||||||
|
const cellCount = Math.floor(height / (cellHeight + spacing))
|
||||||
|
|
||||||
|
this.barData.forEach((item, index) => {
|
||||||
|
item.width = width
|
||||||
|
item.spacing = spacing
|
||||||
|
item.valueHeight = valueHeight
|
||||||
|
item.height = height
|
||||||
|
|
||||||
|
let valueText = ''
|
||||||
|
if (item.mapping) {
|
||||||
|
valueText = this.handleDisplay(item.mapping.display, { ...item.label, value: item.showValue })
|
||||||
|
if (item.mapping.icon) {
|
||||||
|
valueText += 'AA'
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
valueText = item.showValue
|
||||||
|
}
|
||||||
|
item.valueFontSize = this.calculateFontSize(valueText, width * 0.9, valueHeight, 1)
|
||||||
|
|
||||||
|
item.cellWidth = cellWidth
|
||||||
|
item.cellHeight = cellHeight
|
||||||
|
item.cellCount = cellCount
|
||||||
|
item.litCount = Math.ceil(Math.max(item.value / (maxValue / item.cellCount), 1))
|
||||||
|
item.cellBackground = tinycolor(item.background).setAlpha(0.18).toRgbString()
|
||||||
|
item.cellBackgroundImage = `radial-gradient(${tinycolor(item.background).setAlpha(0.95).toRgbString()} 10%, ${tinycolor(item.background).setAlpha(0.55).toRgbString()})`
|
||||||
|
})
|
||||||
|
const valueFontArr = this.barData.map(item => item.valueFontSize)
|
||||||
|
const minValueFont = Math.min(...valueFontArr)
|
||||||
|
this.barData.forEach(item => {
|
||||||
|
item.valueFontSize = minValueFont
|
||||||
|
})
|
||||||
|
this.$forceUpdate()
|
||||||
|
} else {
|
||||||
|
const height = (this.boxHeight - totalSpacing) / numBars
|
||||||
|
const maxTitleHeightRatio = 0.6
|
||||||
|
const titleHeight = height * maxTitleHeightRatio
|
||||||
|
const titleFontSize = Math.min(titleHeight, 28)
|
||||||
|
const maxValueWidth = 150
|
||||||
|
const valueWidth = this.chartInfo.param.text === 'value' || this.chartInfo.param.text === 'all' ? Math.min(this.boxWidth * 0.2, maxValueWidth) : 0
|
||||||
|
|
||||||
|
const cellWidth = 10
|
||||||
|
const cellHeight = height
|
||||||
|
|
||||||
|
this.barData.forEach((item) => {
|
||||||
|
item.height = height
|
||||||
|
item.spacing = spacing
|
||||||
|
|
||||||
|
item.titleFontSize = titleFontSize
|
||||||
|
const text = item.alias
|
||||||
|
const el = this.$refs['temp-dom2']
|
||||||
|
el.innerText = text
|
||||||
|
el.style.fontSize = titleFontSize + 'px'
|
||||||
|
item.titleWidth = el.offsetWidth
|
||||||
|
|
||||||
|
let valueText = ''
|
||||||
|
if (item.mapping) {
|
||||||
|
valueText = this.handleDisplay(item.mapping.display, { ...item.label, value: item.showValue })
|
||||||
|
if (item.mapping.icon) {
|
||||||
|
valueText += 'AA'
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
valueText = item.showValue
|
||||||
|
}
|
||||||
|
item.valueWidth = valueWidth
|
||||||
|
item.valueFontSize = this.calculateFontSize(valueText, item.valueWidth - 10 * 2, height, 1.2)
|
||||||
|
})
|
||||||
|
const titleWidthArr = this.barData.map(item => item.titleWidth)
|
||||||
|
const maxTitleWidth = Math.max(...titleWidthArr)
|
||||||
|
const titleWidth = this.chartInfo.param.text === 'legend' || this.chartInfo.param.text === 'all' ? Math.min(maxTitleWidth + 15, this.boxWidth * 0.4) : 0
|
||||||
|
|
||||||
|
const valueFontArr = this.barData.map(item => item.valueFontSize)
|
||||||
|
const minValueFont = Math.min(...valueFontArr)
|
||||||
|
this.barData.forEach(item => {
|
||||||
|
item.titleWidth = titleWidth
|
||||||
|
item.valueFontSize = minValueFont
|
||||||
|
item.width = this.boxWidth - item.titleWidth - item.valueWidth
|
||||||
|
|
||||||
|
const cellCount = Math.floor(item.width / (cellWidth + spacing))
|
||||||
|
item.cellWidth = cellWidth
|
||||||
|
item.cellHeight = cellHeight
|
||||||
|
item.cellCount = cellCount
|
||||||
|
item.litCount = Math.ceil(Math.max(item.value / (maxValue / item.cellCount), 1))
|
||||||
|
item.cellBackground = tinycolor(item.background).setAlpha(0.18).toRgbString()
|
||||||
|
item.cellBackgroundImage = `radial-gradient(${tinycolor(item.background).setAlpha(0.95).toRgbString()} 10%, ${tinycolor(item.background).setAlpha(0.55).toRgbString()})`
|
||||||
|
})
|
||||||
|
this.$forceUpdate()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
// 计算字体大小
|
||||||
|
calculateFontSize (text, width, height, lineHeight = 1.2, maxSize) {
|
||||||
|
const el = this.$refs['temp-dom']
|
||||||
|
el.innerText = text
|
||||||
|
const elWidth = el.offsetWidth
|
||||||
|
const fontSizeBasedOnWidth = (width / elWidth) * 14
|
||||||
|
const fontSizeBasedOnHeight = height / lineHeight
|
||||||
|
|
||||||
|
const optimalSize = Math.min(fontSizeBasedOnHeight, fontSizeBasedOnWidth)
|
||||||
|
return Math.min(optimalSize, maxSize || optimalSize)
|
||||||
|
},
|
||||||
|
getValuePercent (value, minValue, maxValue) {
|
||||||
|
// Need special logic for when minValue === maxValue === value to prevent returning NaN
|
||||||
|
const valueRatio = Math.min((value - minValue) / (maxValue - minValue), 1)
|
||||||
|
return isNaN(valueRatio) ? 0 : valueRatio
|
||||||
|
},
|
||||||
|
calcMax (arr) {
|
||||||
|
let maxNum = arr.reduce((maxValue, obj) => {
|
||||||
|
return Math.max(maxValue, obj.value)
|
||||||
|
}, 0)
|
||||||
|
|
||||||
|
if (maxNum <= 1) {
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
|
||||||
|
let bite = 1
|
||||||
|
while (maxNum >= 10) {
|
||||||
|
maxNum /= 10
|
||||||
|
if (maxNum > 1) {
|
||||||
|
bite += 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return Math.pow(10, bite)
|
||||||
|
},
|
||||||
|
initBarData (chartInfo, originalDatas) {
|
||||||
|
this.barData = []
|
||||||
let colorIndex = 0
|
let colorIndex = 0
|
||||||
const self = this
|
|
||||||
const decimals = this.chartInfo.param.decimals || 2
|
const decimals = this.chartInfo.param.decimals || 2
|
||||||
const s = lodash.cloneDeep(seriesTemplate)
|
|
||||||
s.data = []
|
|
||||||
originalDatas.forEach((originalData, expressionIndex) => {
|
originalDatas.forEach((originalData, expressionIndex) => {
|
||||||
originalData.forEach((data, dataIndex) => {
|
originalData.forEach((data, dataIndex) => {
|
||||||
this.isNoData = false
|
this.isNoData = false
|
||||||
if (s) {
|
|
||||||
const value = getMetricTypeValue(data.values, chartInfo.param.statistics)
|
const value = getMetricTypeValue(data.values, chartInfo.param.statistics)
|
||||||
const showValue = chartDataFormat.getUnit(chartInfo.unit ? chartInfo.unit : 2).compute(value, null, -1, decimals)
|
const showValue = chartDataFormat.getUnit(chartInfo.unit ? chartInfo.unit : 2).compute(value, null, -1, decimals)
|
||||||
const mapping = this.selectMapping(value, chartInfo.param.valueMapping, chartInfo.param.enable && this.chartInfo.param.enable.valueMapping)
|
const mapping = this.selectMapping(value, chartInfo.param.valueMapping, chartInfo.param.enable && this.chartInfo.param.enable.valueMapping)
|
||||||
// eslint-disable-next-line vue/no-mutating-props
|
// eslint-disable-next-line vue/no-mutating-props
|
||||||
mapping && this.chartOption.color && (this.chartOption.color[colorIndex] = mapping.color.bac)
|
mapping && this.chartOption.color && (this.chartOption.color[colorIndex] = mapping.color.bac)
|
||||||
const legend = this.handleLegend(chartInfo, data, expressionIndex, dataIndex, colorIndex)
|
const legend = this.handleLegend(chartInfo, data, expressionIndex, dataIndex, colorIndex)
|
||||||
s.data.push({
|
this.barData.push({
|
||||||
value: value,
|
value: Number(value),
|
||||||
realValue: value,
|
realValue: value,
|
||||||
showValue: showValue,
|
showValue: showValue,
|
||||||
name: legend.name,
|
name: legend.name,
|
||||||
@@ -193,21 +611,12 @@ export default {
|
|||||||
expressionIndex: expressionIndex,
|
expressionIndex: expressionIndex,
|
||||||
dataIndex: dataIndex,
|
dataIndex: dataIndex,
|
||||||
mapping: mapping,
|
mapping: mapping,
|
||||||
label: {
|
background: mapping ? mapping.color.bac : this.colorList[colorIndex]
|
||||||
...s.label,
|
|
||||||
formatter: this.pieFormatterLabel,
|
|
||||||
color: mapping ? mapping.color.text : '#000000'
|
|
||||||
},
|
|
||||||
itemStyle: {
|
|
||||||
color: mapping ? mapping.color.bac : this.colorList[colorIndex]
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
colorIndex++
|
colorIndex++
|
||||||
}
|
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
this.$emit('chartIsNoData', this.isNoData)
|
this.$emit('chartIsNoData', this.isNoData)
|
||||||
return [s]
|
|
||||||
},
|
},
|
||||||
formatterFunc (params, ticket, callback) {
|
formatterFunc (params, ticket, callback) {
|
||||||
const self = this
|
const self = this
|
||||||
@@ -225,6 +634,44 @@ export default {
|
|||||||
</div>
|
</div>
|
||||||
`
|
`
|
||||||
},
|
},
|
||||||
|
barEnter (e, data) {
|
||||||
|
this.tooltip.title = data.alias
|
||||||
|
this.tooltip.value = data.mapping && data.mapping.display ? this.handleDisplay(data.mapping.display, { ...data.labels, value: data.showValue }) : data.showValue
|
||||||
|
this.tooltip.mapping = data.mapping
|
||||||
|
this.tooltip.show = true
|
||||||
|
this.setPosition(e)
|
||||||
|
},
|
||||||
|
barMove (e) {
|
||||||
|
this.tooltip.show = true
|
||||||
|
this.setPosition(e)
|
||||||
|
},
|
||||||
|
barLeave () {
|
||||||
|
this.tooltip.show = false
|
||||||
|
},
|
||||||
|
setPosition (e) {
|
||||||
|
const windowWidth = window.innerWidth// 窗口宽度
|
||||||
|
const windowHeight = window.innerHeight// 窗口高度
|
||||||
|
this.$nextTick(() => {
|
||||||
|
const box = document.getElementById(`chart-canvas-tooltip-${this.chartId}`)
|
||||||
|
if (box) {
|
||||||
|
const boxWidth = box.offsetWidth
|
||||||
|
const boxHeight = box.offsetHeight
|
||||||
|
if (e.pageX < (windowWidth / 2)) { // 说明鼠标在左边放不下提示框
|
||||||
|
this.tooltip.x = e.pageX + 15
|
||||||
|
} else {
|
||||||
|
this.tooltip.x = e.pageX - boxWidth - 15
|
||||||
|
}
|
||||||
|
if (e.pageY + 50 + boxHeight < windowHeight) { // 说明鼠标上面放不下提示框
|
||||||
|
this.tooltip.y = e.pageY + 15
|
||||||
|
} else {
|
||||||
|
this.tooltip.y = e.pageY - boxHeight - 10
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
this.tooltip.x = e.pageX + 15
|
||||||
|
this.tooltip.y = e.pageY + 15
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
toolboxPosition (e) {
|
toolboxPosition (e) {
|
||||||
const windowWidth = window.innerWidth// 窗口宽度
|
const windowWidth = window.innerWidth// 窗口宽度
|
||||||
const windowHeight = window.innerHeight// 窗口高度
|
const windowHeight = window.innerHeight// 窗口高度
|
||||||
@@ -248,18 +695,18 @@ export default {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
chartClick (params) {
|
chartClick (e, data) {
|
||||||
getChart(this.chartId).dispatchAction({
|
if (this.dataLink.length || this.chartInfo.datasource === 'metrics' || this.chartInfo.datasource === 'logs') {
|
||||||
type: 'hideTip'
|
this.tooltip.show = false
|
||||||
})
|
|
||||||
this.toolbox.title = params.data.alias
|
this.toolbox.title = data.alias
|
||||||
this.toolbox.value = params.data.mapping && params.data.mapping.display ? this.handleDisplay(params.data.mapping.display, { ...params.data.labels, value: params.data.showValue }) : params.data.showValue
|
this.toolbox.value = data.mapping && data.mapping.display ? this.handleDisplay(data.mapping.display, { ...data.labels, value: data.showValue }) : data.showValue
|
||||||
this.toolbox.mapping = params.data.mapping
|
this.toolbox.mapping = data.mapping
|
||||||
this.toolbox.show = true
|
this.toolbox.show = true
|
||||||
this.toolbox.metric.labels = params.data.labels
|
this.toolbox.metric.labels = data.labels
|
||||||
this.toolbox.metric.expressionIndex = params.data.expressionIndex
|
this.toolbox.metric.expressionIndex = data.expressionIndex
|
||||||
const e = params.event.event
|
|
||||||
this.toolboxPosition(e)
|
this.toolboxPosition(e)
|
||||||
|
}
|
||||||
},
|
},
|
||||||
clickout () {
|
clickout () {
|
||||||
if ((this.dataLink.length || this.chartInfo.datasource === 'metrics' || this.chartInfo.datasource === 'logs') && this.toolbox.show) {
|
if ((this.dataLink.length || this.chartInfo.datasource === 'metrics' || this.chartInfo.datasource === 'logs') && this.toolbox.show) {
|
||||||
|
|||||||
@@ -122,13 +122,13 @@ export default {
|
|||||||
colorIndex++
|
colorIndex++
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
this.maxValue = this.calcMax()
|
this.maxValue = this.calcMax(this.gaugeData)
|
||||||
this.$emit('chartIsNoData', this.isNoData)
|
this.$emit('chartIsNoData', this.isNoData)
|
||||||
resolve()
|
resolve()
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
calcMax () {
|
calcMax (arr) {
|
||||||
let maxNum = this.gaugeData.reduce((maxValue, obj) => {
|
let maxNum = arr.reduce((maxValue, obj) => {
|
||||||
return Math.max(maxValue, obj.value)
|
return Math.max(maxValue, obj.value)
|
||||||
}, 0)
|
}, 0)
|
||||||
|
|
||||||
@@ -199,7 +199,7 @@ export default {
|
|||||||
})
|
})
|
||||||
},
|
},
|
||||||
// 计算字体大小
|
// 计算字体大小
|
||||||
calculateFontSize (text, width, height, maxSize, lineHeight = 1.2) {
|
calculateFontSize (text, width, height, lineHeight = 1.2, maxSize) {
|
||||||
const el = this.$refs['temp-dom']
|
const el = this.$refs['temp-dom']
|
||||||
el.innerText = text
|
el.innerText = text
|
||||||
const elWidth = el.offsetWidth
|
const elWidth = el.offsetWidth
|
||||||
@@ -224,7 +224,7 @@ export default {
|
|||||||
showValue = this.handleDisplay(data.mapping.display, { ...data.label, value: showValue })
|
showValue = this.handleDisplay(data.mapping.display, { ...data.label, value: showValue })
|
||||||
}
|
}
|
||||||
const textWidth = dimension - (gaugeWidth * 4)
|
const textWidth = dimension - (gaugeWidth * 4)
|
||||||
const valueFontSize = this.calculateFontSize(showValue, textWidth, textWidth / 2, gaugeWidth * 2, 1)
|
const valueFontSize = this.calculateFontSize(showValue, textWidth, textWidth / 2, 1, gaugeWidth * 2)
|
||||||
return {
|
return {
|
||||||
gaugeWidth,
|
gaugeWidth,
|
||||||
valueFontSize
|
valueFontSize
|
||||||
|
|||||||
@@ -332,8 +332,8 @@ export default {
|
|||||||
} else {
|
} else {
|
||||||
valueFont = item.showValue
|
valueFont = item.showValue
|
||||||
}
|
}
|
||||||
titleFontSize = this.calculateFontSize(titleFont, (item.width - padding * 2), (item.height - padding * 2) * 0.4, 30)
|
titleFontSize = this.calculateFontSize(titleFont, (item.width - padding * 2), (item.height - padding * 2) * 0.4, 1.2, 30)
|
||||||
valueFontSize = this.calculateFontSize(valueFont, (item.width - padding * 2), (item.height - padding * 2) * 0.4)
|
valueFontSize = this.calculateFontSize(valueFont, (item.width - padding * 2), (item.height - padding * 2) * 0.4, 1.2)
|
||||||
titleFontSize = Math.min(valueFontSize * 0.7, titleFontSize)
|
titleFontSize = Math.min(valueFontSize * 0.7, titleFontSize)
|
||||||
break
|
break
|
||||||
case 'legend':
|
case 'legend':
|
||||||
@@ -343,7 +343,7 @@ export default {
|
|||||||
titleFont += 'AA'
|
titleFont += 'AA'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
valueFontSize = this.calculateFontSize(titleFont, (item.width - padding * 2), (item.height - padding * 2) * 0.4)
|
valueFontSize = this.calculateFontSize(titleFont, (item.width - padding * 2), (item.height - padding * 2) * 0.4, 1.2)
|
||||||
break
|
break
|
||||||
case 'none':
|
case 'none':
|
||||||
titleFontSize = ''
|
titleFontSize = ''
|
||||||
@@ -359,7 +359,7 @@ export default {
|
|||||||
} else {
|
} else {
|
||||||
valueFont = item.showValue
|
valueFont = item.showValue
|
||||||
}
|
}
|
||||||
valueFontSize = this.calculateFontSize(valueFont, (item.width - padding * 2), (item.height - padding * 2) * 0.4)
|
valueFontSize = this.calculateFontSize(valueFont, (item.width - padding * 2), (item.height - padding * 2) * 0.4, 1.2)
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
item.titleFontSize = titleFontSize
|
item.titleFontSize = titleFontSize
|
||||||
@@ -391,7 +391,7 @@ export default {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
// 计算字体大小
|
// 计算字体大小
|
||||||
calculateFontSize (text, width, height, maxSize, lineHeight = 1.2) {
|
calculateFontSize (text, width, height, lineHeight = 1.2, maxSize) {
|
||||||
const el = this.$refs['temp-dom']
|
const el = this.$refs['temp-dom']
|
||||||
el.innerText = text
|
el.innerText = text
|
||||||
const elWidth = el.offsetWidth
|
const elWidth = el.offsetWidth
|
||||||
|
|||||||
@@ -725,7 +725,7 @@ export default {
|
|||||||
handler () {
|
handler () {
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
this.resize()
|
this.resize()
|
||||||
}, 200)
|
}, 300)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
// 监听查看模式变化
|
// 监听查看模式变化
|
||||||
|
|||||||
@@ -390,9 +390,6 @@ export default {
|
|||||||
varValue: '',
|
varValue: '',
|
||||||
result: 'show'
|
result: 'show'
|
||||||
},
|
},
|
||||||
sparklineMode: 'line',
|
|
||||||
comparison: 'none',
|
|
||||||
colorMode: 'value',
|
|
||||||
dataLink: []
|
dataLink: []
|
||||||
}
|
}
|
||||||
break
|
break
|
||||||
|
|||||||
@@ -444,6 +444,32 @@
|
|||||||
<el-option :label="$t('project.topology.bac')" value="background"></el-option>
|
<el-option :label="$t('project.topology.bac')" value="background"></el-option>
|
||||||
</el-select>
|
</el-select>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
<!-- Layout orientation -->
|
||||||
|
<el-form-item :label="$t('dashboard.chartForm.orientation')" class="form-item--half-width" v-if="chartConfig.type==='bar'">
|
||||||
|
<el-select
|
||||||
|
v-model="chartConfig.param.orientation"
|
||||||
|
placeholder=""
|
||||||
|
popper-class="right-box-select-top prevent-clickoutside"
|
||||||
|
size="small"
|
||||||
|
@change="change"
|
||||||
|
>
|
||||||
|
<el-option :label="$t('dashboard.chartForm.vertical')" value="vertical"></el-option>
|
||||||
|
<el-option :label="$t('dashboard.chartForm.horizontal')" value="horizontal"></el-option>
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
<!-- Display mode -->
|
||||||
|
<el-form-item :label="$t('dashboard.chartForm.displayMode')" class="form-item--half-width" v-if="chartConfig.type==='bar'">
|
||||||
|
<el-select
|
||||||
|
v-model="chartConfig.param.displayMode"
|
||||||
|
placeholder=""
|
||||||
|
popper-class="right-box-select-top prevent-clickoutside"
|
||||||
|
size="small"
|
||||||
|
@change="change"
|
||||||
|
>
|
||||||
|
<el-option :label="$t('dashboard.chartForm.basic')" value="basic"></el-option>
|
||||||
|
<el-option :label="$t('dashboard.chartForm.retro')" value="led"></el-option>
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Right Y Axis -->
|
<!-- Right Y Axis -->
|
||||||
@@ -1540,6 +1566,8 @@ export default {
|
|||||||
varValue: '',
|
varValue: '',
|
||||||
result: 'show'
|
result: 'show'
|
||||||
},
|
},
|
||||||
|
orientation: 'vertical',
|
||||||
|
displayMode: 'basic',
|
||||||
dataLink: this.chartConfig.param.dataLink
|
dataLink: this.chartConfig.param.dataLink
|
||||||
}
|
}
|
||||||
break
|
break
|
||||||
|
|||||||
@@ -260,6 +260,10 @@ export default {
|
|||||||
delete params.param.comparison
|
delete params.param.comparison
|
||||||
delete params.param.colorMode
|
delete params.param.colorMode
|
||||||
}
|
}
|
||||||
|
if (params.type !== 'bar') {
|
||||||
|
delete params.param.orientation
|
||||||
|
delete params.param.displayMode
|
||||||
|
}
|
||||||
if (!params.x && !params.y && this.from === 'endpointQuery') { // endpointQuery 新增 放在最后
|
if (!params.x && !params.y && this.from === 'endpointQuery') { // endpointQuery 新增 放在最后
|
||||||
params.x = 0
|
params.x = 0
|
||||||
params.y = 999
|
params.y = 999
|
||||||
@@ -736,6 +740,10 @@ export default {
|
|||||||
if (obj.type == 'text' && !obj.param.editorType) {
|
if (obj.type == 'text' && !obj.param.editorType) {
|
||||||
obj.param.editorType = 'richText'
|
obj.param.editorType = 'richText'
|
||||||
}
|
}
|
||||||
|
if (obj.type === 'bar') {
|
||||||
|
if (!obj.param.orientation) { obj.param.orientation = 'vertical' }
|
||||||
|
if (!obj.param.displayMode) { obj.param.displayMode = 'basic' }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (obj.elements && obj.elements.length) {
|
if (obj.elements && obj.elements.length) {
|
||||||
obj.elements.forEach((item, index) => {
|
obj.elements.forEach((item, index) => {
|
||||||
|
|||||||
@@ -93,8 +93,8 @@ export default {
|
|||||||
case 'pie':
|
case 'pie':
|
||||||
case 'doughnut':
|
case 'doughnut':
|
||||||
case 'rose':
|
case 'rose':
|
||||||
case 'bar':
|
|
||||||
return true
|
return true
|
||||||
|
case 'bar':
|
||||||
case 'table':
|
case 'table':
|
||||||
case 'stat':
|
case 'stat':
|
||||||
case 'hexagon':
|
case 'hexagon':
|
||||||
|
|||||||
@@ -283,6 +283,32 @@
|
|||||||
<el-option :label="$t('project.topology.bac')" value="background"></el-option>
|
<el-option :label="$t('project.topology.bac')" value="background"></el-option>
|
||||||
</el-select>
|
</el-select>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
<!-- Layout orientation -->
|
||||||
|
<el-form-item :label="$t('dashboard.chartForm.orientation')" class="form-item--half-width" v-if="chartConfig.type==='bar'">
|
||||||
|
<el-select
|
||||||
|
v-model="chartConfig.param.orientation"
|
||||||
|
placeholder=""
|
||||||
|
popper-class="right-box-select-top prevent-clickoutside"
|
||||||
|
size="small"
|
||||||
|
@change="change"
|
||||||
|
>
|
||||||
|
<el-option :label="$t('dashboard.chartForm.vertical')" value="vertical"></el-option>
|
||||||
|
<el-option :label="$t('dashboard.chartForm.horizontal')" value="horizontal"></el-option>
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
<!-- Display mode -->
|
||||||
|
<el-form-item :label="$t('dashboard.chartForm.displayMode')" class="form-item--half-width" v-if="chartConfig.type==='bar'">
|
||||||
|
<el-select
|
||||||
|
v-model="chartConfig.param.displayMode"
|
||||||
|
placeholder=""
|
||||||
|
popper-class="right-box-select-top prevent-clickoutside"
|
||||||
|
size="small"
|
||||||
|
@change="change"
|
||||||
|
>
|
||||||
|
<el-option :label="$t('dashboard.chartForm.basic')" value="basic"></el-option>
|
||||||
|
<el-option :label="$t('dashboard.chartForm.retro')" value="led"></el-option>
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
</div>
|
</div>
|
||||||
<!--legend-->
|
<!--legend-->
|
||||||
<div v-if="isShowLegend(chartConfig.type)">
|
<div v-if="isShowLegend(chartConfig.type)">
|
||||||
@@ -1176,6 +1202,8 @@ export default {
|
|||||||
varValue: '',
|
varValue: '',
|
||||||
result: 'show'
|
result: 'show'
|
||||||
},
|
},
|
||||||
|
orientation: 'vertical',
|
||||||
|
displayMode: 'basic',
|
||||||
dataLink: this.chartConfig.param.dataLink
|
dataLink: this.chartConfig.param.dataLink
|
||||||
}
|
}
|
||||||
break
|
break
|
||||||
|
|||||||
Reference in New Issue
Block a user