feat: 仪表盘阈值

This commit is contained in:
junjun 2022-03-08 15:44:40 +08:00
parent 6ccc29ebfd
commit 6a36dd456c
9 changed files with 233 additions and 12 deletions

View File

@ -1041,7 +1041,10 @@ export default {
field_fixed: 'Fixed',
line_type_dotted: 'Dotted',
value_can_not_empty: 'Value can not be empty',
value_error: 'Value illegal'
value_error: 'Value illegal',
threshold: 'Threshold',
threshold_range: 'Range',
gauge_threshold_format_error: 'Format Error'
},
dataset: {
sheet_warn: 'There are multiple sheet pages, and the first one is extracted by default',

View File

@ -1041,7 +1041,10 @@ export default {
field_fixed: '固定值',
line_type_dotted: '點',
value_can_not_empty: '值不能為空',
value_error: '值必須為數值'
value_error: '值必須為數值',
threshold: '閾值',
threshold_range: '閾值區間',
gauge_threshold_format_error: '格式錯誤'
},
dataset: {
sheet_warn: '有多個 Sheet 頁,默認抽取第一個',

View File

@ -1044,7 +1044,10 @@ export default {
field_fixed: '固定值',
line_type_dotted: '点',
value_can_not_empty: '值不能为空',
value_error: '值必须为数值'
value_error: '值必须为数值',
threshold: '阈值',
threshold_range: '阈值区间',
gauge_threshold_format_error: '格式错误'
},
dataset: {
sheet_warn: '有多个 Sheet 页,默认抽取第一个',

View File

@ -244,6 +244,9 @@ export const DEFAULT_FUNCTION_CFG = {
sliderShow: false,
sliderRange: [0, 10]
}
export const DEFAULT_THRESHOLD = {
gaugeThreshold: ''
}
// chart config
export const BASE_BAR = {
title: {

View File

@ -49,6 +49,34 @@ export function baseGaugeOption(chart_option, chart) {
value: chart.data.series[0].data[0]
}
chart_option.series[0].data.push(y)
// threshold
if (chart.senior) {
const range = []
const senior = JSON.parse(chart.senior)
const threshold = JSON.parse(JSON.stringify(senior.threshold))
if (threshold.gaugeThreshold && threshold.gaugeThreshold !== '') {
const arr = threshold.gaugeThreshold.split(',')
for (let i = 0; i < arr.length; i++) {
const ele = arr[i]
const p = parseInt(ele) / 100
range.push([p, hexColorToRGBA(customAttr.color.colors[i % 9], customAttr.color.alpha)])
}
range.push([1, hexColorToRGBA(customAttr.color.colors[arr.length % 9], customAttr.color.alpha)])
chart_option.series[0].axisLine = {
lineStyle: {
color: range
}
}
chart_option.series[0].itemStyle = {
color: 'auto'
}
chart_option.series[0].progress = {
show: false
}
}
}
}
}
// console.log(chart_option);

View File

@ -33,11 +33,39 @@ export function baseGaugeOptionAntV(plot, container, chart, action) {
labelContent = false
}
}
const per = (parseFloat(data) / parseFloat(max))
const range = [0]
let index = 0
let flag = false
let hasThreshold = false
if (chart.senior) {
const senior = JSON.parse(chart.senior)
const threshold = JSON.parse(JSON.stringify(senior.threshold))
if (threshold.gaugeThreshold && threshold.gaugeThreshold !== '') {
hasThreshold = true
const arr = threshold.gaugeThreshold.split(',')
for (let i = 0; i < arr.length; i++) {
const ele = arr[i]
const p = parseInt(ele) / 100
range.push(p)
if (!flag && per <= p) {
flag = true
index = i
}
}
if (!flag) {
index = arr.length
}
}
}
range.push(1)
// options
const options = {
theme: theme,
percent: (parseFloat(data) / parseFloat(max)),
percent: per,
startAngle: startAngel,
endAngle: endAngel,
appendPadding: getPadding(chart),
@ -52,6 +80,24 @@ export function baseGaugeOptionAntV(plot, container, chart, action) {
// lineCap: 'round'
// }
}
if (hasThreshold) {
options.range = {
color: theme.styleSheet.paletteQualitative10,
ticks: range
}
options.indicator = {
pointer: {
style: {
stroke: theme.styleSheet.paletteQualitative10[index % 9]
}
},
pin: {
style: {
stroke: theme.styleSheet.paletteQualitative10[index % 9]
}
}
}
}
// 开始渲染
if (plot) {

View File

@ -0,0 +1,123 @@
<template>
<div style="width: 100%">
<el-col v-if="chart.type && chart.type === 'gauge'">
<el-form ref="thresholdForm" :model="thresholdForm" label-width="80px" size="mini">
<el-form-item :label="$t('chart.threshold_range')+'(%)'" class="form-item">
<span>0,</span>
<el-input v-model="thresholdForm.gaugeThreshold" style="width: 160px;margin: 0 10px;" :placeholder="$t('chart.threshold_range')" size="mini" clearable @change="changeThreshold" />
<span>,100</span>
<el-tooltip class="item" effect="dark" placement="bottom">
<div slot="content">
阈值设置决定仪表盘区间颜色为空则不开启阈值范围(0-100)仅限整数且逐级递增
<br>
例如输入 30,70表示分为3段分别为[0,30],(30,70],(70,100]
</div>
<i class="el-icon-info" style="cursor: pointer;margin-left: 10px;font-size: 12px;" />
</el-tooltip>
</el-form-item>
</el-form>
</el-col>
</div>
</template>
<script>
import { DEFAULT_THRESHOLD } from '@/views/chart/chart/chart'
export default {
name: 'Threshold',
props: {
chart: {
type: Object,
required: true
}
},
data() {
return {
thresholdForm: JSON.parse(JSON.stringify(DEFAULT_THRESHOLD))
}
},
watch: {
'chart': {
handler: function() {
this.initData()
}
}
},
mounted() {
this.initData()
},
methods: {
initData() {
const chart = JSON.parse(JSON.stringify(this.chart))
if (chart.senior) {
let senior = null
if (Object.prototype.toString.call(chart.senior) === '[object Object]') {
senior = JSON.parse(JSON.stringify(chart.senior))
} else {
senior = JSON.parse(chart.senior)
}
if (senior.threshold) {
this.thresholdForm = senior.threshold
} else {
this.thresholdForm = JSON.parse(JSON.stringify(DEFAULT_THRESHOLD))
}
}
},
changeThreshold() {
// check input
if (this.thresholdForm.gaugeThreshold) {
const arr = this.thresholdForm.gaugeThreshold.split(',')
for (let i = 0; i < arr.length; i++) {
const ele = arr[i]
if (ele.indexOf('.') > -1 || parseInt(ele).toString() === 'NaN' || parseInt(ele) < 1 || parseInt(ele) > 99) {
this.$message({
message: this.$t('chart.gauge_threshold_format_error'),
type: 'error',
showClose: true
})
return
}
}
}
this.$emit('onThresholdChange', this.thresholdForm)
}
}
}
</script>
<style scoped>
.shape-item{
padding: 6px;
border: none;
width: 100%;
display: flex;
justify-content: space-between;
align-items: center;
}
.form-item-slider>>>.el-form-item__label{
font-size: 12px;
line-height: 38px;
}
.form-item>>>.el-form-item__label{
font-size: 12px;
}
.el-select-dropdown__item{
padding: 0 20px;
}
span{
font-size: 12px
}
.el-form-item{
margin-bottom: 6px;
}
.switch-style{
position: absolute;
right: 10px;
margin-top: -4px;
}
.color-picker-style{
cursor: pointer;
z-index: 1003;
}
</style>

View File

@ -309,7 +309,7 @@ import {
DEFAULT_YAXIS_EXT_STYLE,
DEFAULT_BACKGROUND_COLOR,
DEFAULT_SPLIT,
DEFAULT_FUNCTION_CFG
DEFAULT_FUNCTION_CFG, DEFAULT_THRESHOLD
} from '../chart/chart'
export default {
@ -767,7 +767,8 @@ export default {
})
view.senior = JSON.stringify({
functionCfg: DEFAULT_FUNCTION_CFG,
assistLine: []
assistLine: [],
threshold: DEFAULT_THRESHOLD
})
view.stylePriority = 'view' //
view.xaxis = JSON.stringify([])

View File

@ -813,11 +813,11 @@
<el-tab-pane :label="$t('chart.senior')" class="padding-tab" style="width: 360px;">
<el-row class="view-panel">
<div
v-if="view.type && (view.type.includes('bar') || view.type.includes('line') || view.type.includes('mix'))"
v-if="view.type && (view.type.includes('bar') || view.type.includes('line') || view.type.includes('mix') || view.type.includes('gauge'))"
style="overflow:auto;border-right: 1px solid #e6e6e6;height: 100%;width: 100%;"
class="attr-style theme-border-class"
>
<el-row>
<el-row v-if="view.type && (view.type.includes('bar') || view.type.includes('line') || view.type.includes('mix'))">
<span class="padding-lr">{{ $t('chart.senior_cfg') }}</span>
<el-collapse v-model="attrActiveNames" class="style-collapse">
<el-collapse-item name="function" :title="$t('chart.function_cfg')">
@ -825,12 +825,15 @@
</el-collapse-item>
</el-collapse>
</el-row>
<el-row>
<el-row v-if="view.type && (view.type.includes('bar') || view.type.includes('line') || view.type.includes('mix') || view.type.includes('gauge'))">
<span class="padding-lr">{{ $t('chart.analyse_cfg') }}</span>
<el-collapse v-model="styleActiveNames" class="style-collapse">
<el-collapse-item name="analyse" :title="$t('chart.assist_line')">
<el-collapse-item v-if="view.type && (view.type.includes('bar') || view.type.includes('line') || view.type.includes('mix'))" name="analyse" :title="$t('chart.assist_line')">
<assist-line :param="param" class="attr-selector" :chart="chart" @onAssistLineChange="onAssistLineChange" />
</el-collapse-item>
<el-collapse-item v-if="view.type && (view.type.includes('gauge'))" name="threshold" :title="$t('chart.threshold')">
<threshold :param="param" class="attr-selector" :chart="chart" @onThresholdChange="onThresholdChange" />
</el-collapse-item>
</el-collapse>
</el-row>
</div>
@ -1039,7 +1042,7 @@ import {
DEFAULT_LABEL,
DEFAULT_LEGEND_STYLE,
DEFAULT_SIZE,
DEFAULT_SPLIT,
DEFAULT_SPLIT, DEFAULT_THRESHOLD,
DEFAULT_TITLE_STYLE,
DEFAULT_TOOLTIP,
DEFAULT_XAXIS_STYLE,
@ -1084,9 +1087,11 @@ import DimensionExtItem from '@/views/chart/components/drag-item/DimensionExtIte
import PluginCom from '@/views/system/plugin/PluginCom'
import FunctionCfg from '@/views/chart/components/senior/FunctionCfg'
import AssistLine from '@/views/chart/components/senior/AssistLine'
import Threshold from '@/views/chart/components/senior/Threshold'
export default {
name: 'ChartEdit',
components: {
Threshold,
AssistLine,
FunctionCfg,
DimensionExtItem,
@ -1174,7 +1179,8 @@ export default {
},
senior: {
functionCfg: DEFAULT_FUNCTION_CFG,
assistLine: []
assistLine: [],
threshold: DEFAULT_THRESHOLD
},
customFilter: [],
render: 'antv',
@ -1756,6 +1762,11 @@ export default {
this.calcStyle()
},
onThresholdChange(val) {
this.view.senior.threshold = val
this.calcStyle()
},
showDimensionEditFilter(item) {
this.dimensionItem = JSON.parse(JSON.stringify(item))
this.dimensionFilterEdit = true