lambo-design-bi 0.0.233 → 0.0.234
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/bi/widget/num/index.vue
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<LamboNumberInfoBi :title="title" :sub-title="subTitle" :num="num" :sub-num1="subNum1" :trend1="trend1"
|
|
3
3
|
:widget="widget" :is-drill="isDrill" @on-drill="onDrill" :sub-num2="subNum2" :trend2="trend2" :polar1="polar1"
|
|
4
|
-
:polar2="polar2" :eva-level="evaLevel" :tab-clickable="tabClickable" :default-tab-active="defaultTabActive"
|
|
4
|
+
:polar2="polar2" :eva-level="evaLevel" :tab-clickable="tabClickable" :default-tab-active="defaultTabActive"
|
|
5
|
+
:show-trend-chart="isTrendCharts" :trend-chart-data="trendChartsData" @on-tab-click="onTabClick">
|
|
5
6
|
</LamboNumberInfoBi>
|
|
6
7
|
</template>
|
|
7
8
|
<script>
|
|
@@ -46,7 +47,9 @@ export default {
|
|
|
46
47
|
drillV3: null,
|
|
47
48
|
evaLevel: null,
|
|
48
49
|
tabClickable: false,
|
|
49
|
-
defaultTabActive: false
|
|
50
|
+
defaultTabActive: false,
|
|
51
|
+
isTrendCharts: false,
|
|
52
|
+
trendChartsData: []
|
|
50
53
|
}
|
|
51
54
|
},
|
|
52
55
|
methods: {
|
|
@@ -65,6 +68,29 @@ export default {
|
|
|
65
68
|
console.log("num-info initConfig 卡片初始设置为激活状态触发点击,START 当前实例:", this.widget.id + "_" + this.widget.name + ",defaultTabActive:" + this.widget.options["defaultTabActive"])
|
|
66
69
|
this.defaultTabActive = true
|
|
67
70
|
}
|
|
71
|
+
this.isTrendCharts = this.widget.options.isTrendCharts === true || this.widget.options.isTrendCharts === '1'
|
|
72
|
+
},
|
|
73
|
+
parseTrendChartsValue(value) {
|
|
74
|
+
if (Array.isArray(value)) {
|
|
75
|
+
return value
|
|
76
|
+
}
|
|
77
|
+
if (typeof value === 'string') {
|
|
78
|
+
const trimValue = value.trim()
|
|
79
|
+
if (trimValue.indexOf('[') === 0 && trimValue.lastIndexOf(']') === trimValue.length - 1) {
|
|
80
|
+
try {
|
|
81
|
+
const parseValue = JSON.parse(trimValue)
|
|
82
|
+
if (Array.isArray(parseValue)) {
|
|
83
|
+
return parseValue
|
|
84
|
+
}
|
|
85
|
+
} catch (e) {
|
|
86
|
+
console.log("BiNumIndex -- parseTrendChartsValue -- 字符串数组解析失败:", {
|
|
87
|
+
value,
|
|
88
|
+
error: e
|
|
89
|
+
})
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
return []
|
|
68
94
|
},
|
|
69
95
|
doSearch() {
|
|
70
96
|
if (!this.apiId) {
|
|
@@ -75,6 +101,7 @@ export default {
|
|
|
75
101
|
if (res.data.code === 0) {
|
|
76
102
|
console.error("数据卡片的调用服务[" + this.widget.options.apiId + "]失败:" + res.data.message)
|
|
77
103
|
} else {
|
|
104
|
+
this.trendChartsData = []
|
|
78
105
|
if (res.data.data.rows.length > 0) {
|
|
79
106
|
let row = res.data.data.rows[0]
|
|
80
107
|
if (row) {
|
|
@@ -105,6 +132,9 @@ export default {
|
|
|
105
132
|
if (Object.prototype.hasOwnProperty.call(row, 'eva_level')) {
|
|
106
133
|
this.evaLevel = row['eva_level'] || ''
|
|
107
134
|
}
|
|
135
|
+
if (this.isTrendCharts) {
|
|
136
|
+
this.trendChartsData = this.parseTrendChartsValue(row['trendChartsData'])
|
|
137
|
+
}
|
|
108
138
|
}
|
|
109
139
|
}
|
|
110
140
|
}
|
package/package.json
CHANGED
|
@@ -21,40 +21,45 @@
|
|
|
21
21
|
<div v-if="subTitle" class="ivu-number-info-subTitle">
|
|
22
22
|
<slot name="subTitle">{{ subTitle }}</slot>
|
|
23
23
|
</div>
|
|
24
|
-
<div class="
|
|
25
|
-
<
|
|
26
|
-
<
|
|
27
|
-
</
|
|
28
|
-
<
|
|
29
|
-
<
|
|
30
|
-
<
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
24
|
+
<div class="number-info-content" :class="{ 'has-trend-chart': hasTrendChart }">
|
|
25
|
+
<div v-if="hasTrendChart" class="number-info-trend-chart-bg">
|
|
26
|
+
<canvas ref="trendCanvas"></canvas>
|
|
27
|
+
</div>
|
|
28
|
+
<div class="ivu-number-info-value-lambo" :style="valueStyle">
|
|
29
|
+
<span class="ivu-number-info-total">
|
|
30
|
+
<slot name="num">{{ num }}</slot>
|
|
31
|
+
</span>
|
|
32
|
+
<span class="ivu-number-info-subTotal" v-if="subNum1 || subNum2">
|
|
33
|
+
<slot name="subNum">
|
|
34
|
+
<template v-if="subNum1">
|
|
35
|
+
<template v-if="trend1">
|
|
36
|
+
<template v-if="polar1 === 'pos'">
|
|
37
|
+
<Trend :flag="trend1" text-color reverse-color>{{ subNum1 }}</Trend>
|
|
38
|
+
</template>
|
|
39
|
+
<template v-else>
|
|
40
|
+
<Trend :flag="trend1" text-color>{{ subNum1 }}</Trend>
|
|
41
|
+
</template>
|
|
34
42
|
</template>
|
|
35
43
|
<template v-else>
|
|
36
|
-
|
|
44
|
+
{{ subNum1 }}
|
|
37
45
|
</template>
|
|
38
46
|
</template>
|
|
39
|
-
<template v-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
+
<template v-if="subNum2">
|
|
48
|
+
<template v-if="trend2">
|
|
49
|
+
<template v-if="polar2 === 'pos'">
|
|
50
|
+
<Trend :flag="trend2" text-color reverse-color>{{ subNum2 }}</Trend>
|
|
51
|
+
</template>
|
|
52
|
+
<template v-else>
|
|
53
|
+
<Trend :flag="trend2" text-color>{{ subNum2 }}</Trend>
|
|
54
|
+
</template>
|
|
47
55
|
</template>
|
|
48
56
|
<template v-else>
|
|
49
|
-
|
|
57
|
+
{{ subNum2 }}
|
|
50
58
|
</template>
|
|
51
59
|
</template>
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
</template>
|
|
56
|
-
</slot>
|
|
57
|
-
</span>
|
|
60
|
+
</slot>
|
|
61
|
+
</span>
|
|
62
|
+
</div>
|
|
58
63
|
</div>
|
|
59
64
|
<div class="card-bottom-line" :class="{ 'active': isActive }"></div>
|
|
60
65
|
</div>
|
|
@@ -129,6 +134,14 @@ export default {
|
|
|
129
134
|
type: Boolean,
|
|
130
135
|
default: false
|
|
131
136
|
},
|
|
137
|
+
showTrendChart: {
|
|
138
|
+
type: Boolean,
|
|
139
|
+
default: false
|
|
140
|
+
},
|
|
141
|
+
trendChartData: {
|
|
142
|
+
type: Array,
|
|
143
|
+
default: () => []
|
|
144
|
+
},
|
|
132
145
|
widget: {
|
|
133
146
|
type: Object,
|
|
134
147
|
default: () => ({})
|
|
@@ -139,6 +152,9 @@ export default {
|
|
|
139
152
|
return {
|
|
140
153
|
'margin-top': this.gap + 'px'
|
|
141
154
|
};
|
|
155
|
+
},
|
|
156
|
+
hasTrendChart() {
|
|
157
|
+
return this.showTrendChart && this.trendChartData && this.trendChartData.length > 0
|
|
142
158
|
}
|
|
143
159
|
},
|
|
144
160
|
data() {
|
|
@@ -189,6 +205,85 @@ export default {
|
|
|
189
205
|
}
|
|
190
206
|
console.log("num-info handleCardClick 卡片初始设置为激活状态触发点击,END 当前实例:", this.widget.id + "_" + this.widget.name)
|
|
191
207
|
}
|
|
208
|
+
},
|
|
209
|
+
drawTrendChart() {
|
|
210
|
+
const canvas = this.$refs.trendCanvas
|
|
211
|
+
if (!canvas) return
|
|
212
|
+
|
|
213
|
+
const width = canvas.clientWidth || 160
|
|
214
|
+
const height = canvas.clientHeight || 64
|
|
215
|
+
const data = this.trendChartData.map(item => Number(item))
|
|
216
|
+
const ctx = canvas.getContext('2d')
|
|
217
|
+
const ratio = window.devicePixelRatio || 1
|
|
218
|
+
canvas.width = width * ratio
|
|
219
|
+
canvas.height = height * ratio
|
|
220
|
+
canvas.style.width = width + 'px'
|
|
221
|
+
canvas.style.height = height + 'px'
|
|
222
|
+
ctx.setTransform(ratio, 0, 0, ratio, 0, 0)
|
|
223
|
+
ctx.clearRect(0, 0, width, height)
|
|
224
|
+
if (!data.length || data.some(item => isNaN(item))) {
|
|
225
|
+
return
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
const padding = { top: 5, right: 6, bottom: 5, left: 6 }
|
|
229
|
+
const chartW = width - padding.left - padding.right
|
|
230
|
+
const chartH = height - padding.top - padding.bottom
|
|
231
|
+
const dataMax = Math.max(...data)
|
|
232
|
+
const dataMin = Math.min(...data)
|
|
233
|
+
const dataRange = dataMax - dataMin || 1
|
|
234
|
+
const max = dataMax + dataRange * 0.04
|
|
235
|
+
const min = dataMin - dataRange * 0.04
|
|
236
|
+
const range = max - min || 1
|
|
237
|
+
const points = data.map((val, index) => ({
|
|
238
|
+
x: data.length === 1 ? width / 2 : padding.left + (index / (data.length - 1)) * chartW,
|
|
239
|
+
y: padding.top + chartH - ((val - min) / range) * chartH
|
|
240
|
+
}))
|
|
241
|
+
|
|
242
|
+
const gradient = ctx.createLinearGradient(0, padding.top, 0, height)
|
|
243
|
+
gradient.addColorStop(0, 'rgba(45, 140, 240, 0.32)')
|
|
244
|
+
gradient.addColorStop(0.55, 'rgba(45, 140, 240, 0.12)')
|
|
245
|
+
gradient.addColorStop(1, 'rgba(45, 140, 240, 0.03)')
|
|
246
|
+
|
|
247
|
+
ctx.beginPath()
|
|
248
|
+
ctx.moveTo(points[0].x, height - padding.bottom)
|
|
249
|
+
points.forEach((point, index) => {
|
|
250
|
+
if (index === 0) {
|
|
251
|
+
ctx.lineTo(point.x, point.y)
|
|
252
|
+
} else {
|
|
253
|
+
const prevPoint = points[index - 1]
|
|
254
|
+
const midX = (prevPoint.x + point.x) / 2
|
|
255
|
+
ctx.bezierCurveTo(midX, prevPoint.y, midX, point.y, point.x, point.y)
|
|
256
|
+
}
|
|
257
|
+
})
|
|
258
|
+
ctx.lineTo(points[points.length - 1].x, height - padding.bottom)
|
|
259
|
+
ctx.closePath()
|
|
260
|
+
ctx.fillStyle = gradient
|
|
261
|
+
ctx.fill()
|
|
262
|
+
|
|
263
|
+
ctx.beginPath()
|
|
264
|
+
points.forEach((point, index) => {
|
|
265
|
+
if (index === 0) {
|
|
266
|
+
ctx.moveTo(point.x, point.y)
|
|
267
|
+
} else {
|
|
268
|
+
const prevPoint = points[index - 1]
|
|
269
|
+
const midX = (prevPoint.x + point.x) / 2
|
|
270
|
+
ctx.bezierCurveTo(midX, prevPoint.y, midX, point.y, point.x, point.y)
|
|
271
|
+
}
|
|
272
|
+
})
|
|
273
|
+
ctx.strokeStyle = '#2d8cf0'
|
|
274
|
+
ctx.lineWidth = 1.8
|
|
275
|
+
ctx.lineJoin = 'round'
|
|
276
|
+
ctx.lineCap = 'round'
|
|
277
|
+
ctx.stroke()
|
|
278
|
+
|
|
279
|
+
const lastPoint = points[points.length - 1]
|
|
280
|
+
ctx.beginPath()
|
|
281
|
+
ctx.arc(lastPoint.x, lastPoint.y, 3, 0, Math.PI * 2)
|
|
282
|
+
ctx.fillStyle = 'rgba(45, 140, 240, 0.18)'
|
|
283
|
+
ctx.fill()
|
|
284
|
+
ctx.strokeStyle = '#2d8cf0'
|
|
285
|
+
ctx.lineWidth = 1.5
|
|
286
|
+
ctx.stroke()
|
|
192
287
|
}
|
|
193
288
|
},
|
|
194
289
|
created() {
|
|
@@ -196,13 +291,62 @@ export default {
|
|
|
196
291
|
},
|
|
197
292
|
mounted() {
|
|
198
293
|
this.initDefTabClickActiveStatus()
|
|
294
|
+
this.$nextTick(() => {
|
|
295
|
+
if (this.hasTrendChart) {
|
|
296
|
+
this.drawTrendChart()
|
|
297
|
+
}
|
|
298
|
+
})
|
|
199
299
|
},
|
|
200
300
|
beforeDestroy() {
|
|
201
301
|
this.eventBusOff()
|
|
302
|
+
},
|
|
303
|
+
watch: {
|
|
304
|
+
trendChartData() {
|
|
305
|
+
this.$nextTick(() => {
|
|
306
|
+
if (this.hasTrendChart) {
|
|
307
|
+
this.drawTrendChart()
|
|
308
|
+
}
|
|
309
|
+
})
|
|
310
|
+
},
|
|
311
|
+
showTrendChart() {
|
|
312
|
+
this.$nextTick(() => {
|
|
313
|
+
if (this.hasTrendChart) {
|
|
314
|
+
this.drawTrendChart()
|
|
315
|
+
}
|
|
316
|
+
})
|
|
317
|
+
}
|
|
202
318
|
}
|
|
203
319
|
};
|
|
204
320
|
</script>
|
|
205
321
|
<style scoped lang="less">
|
|
322
|
+
.number-info-content.has-trend-chart {
|
|
323
|
+
position: relative;
|
|
324
|
+
min-height: 64px;
|
|
325
|
+
overflow: hidden;
|
|
326
|
+
|
|
327
|
+
.number-info-trend-chart-bg {
|
|
328
|
+
position: absolute;
|
|
329
|
+
right: -2px;
|
|
330
|
+
bottom: 0;
|
|
331
|
+
width: 65%;
|
|
332
|
+
height: 64px;
|
|
333
|
+
opacity: 0.62;
|
|
334
|
+
pointer-events: none;
|
|
335
|
+
z-index: 0;
|
|
336
|
+
|
|
337
|
+
canvas {
|
|
338
|
+
display: block;
|
|
339
|
+
width: 100%;
|
|
340
|
+
height: 64px;
|
|
341
|
+
}
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
.ivu-number-info-value-lambo {
|
|
345
|
+
position: relative;
|
|
346
|
+
z-index: 1;
|
|
347
|
+
}
|
|
348
|
+
}
|
|
349
|
+
|
|
206
350
|
.ivu-number-info-value-lambo {
|
|
207
351
|
font-family: var("DIN Alternate", "Roboto Mono", Menlo, Consolas, monospace);
|
|
208
352
|
font-variant-numeric: tabular-nums;
|
|
@@ -214,6 +358,8 @@ export default {
|
|
|
214
358
|
text-overflow: ellipsis;
|
|
215
359
|
word-break: break-all;
|
|
216
360
|
display: flex;
|
|
361
|
+
flex: 1;
|
|
362
|
+
min-width: 0;
|
|
217
363
|
flex-direction: column;
|
|
218
364
|
}
|
|
219
365
|
|