fix:添加曲线平滑 以及选中的圆点加粗

This commit is contained in:
zhangyu
2023-11-09 17:49:27 +08:00
parent 1396310b29
commit a91d866fce
4 changed files with 143 additions and 35 deletions

View File

@@ -162,7 +162,6 @@ export default {
methods: {
initChart (chartOptions = this.chartOption) {
this.setDataLink()
console.log(this.chartInfo.param)
try {
this.isStack = !!this.chartInfo.param.stack
} catch (e) {}
@@ -177,9 +176,18 @@ export default {
const cursLeft = -10
const cursTop = -10
const { seriesData, seriesAll } = this.initSeriesData(this.chartData)
this.isNoData = false
if (!seriesData.length || seriesData.length == 1) {
this.isNoData = true
this.$emit('chartIsNoData', this.isNoData)
}
if (this.isNoData) {
return
}
// .compute(minusVal, null, -1, decimals)
const opts = {
let opts = {
id: `chart-canvas-${this.chartId}-uplot`,
mode: 1,
width: 100,
height: 100,
cursor: {
@@ -188,6 +196,45 @@ export default {
},
drag: {
x: true
},
dataIdx: (self, seriesIdx, hoveredIdx, cursorXVal) => {
const seriesData = self.data[seriesIdx]
const hoverProximityPx = (self.valToPos(self.data[0][1], 'x') - self.valToPos(self.data[0][0], 'x')) / 2
if (seriesData[hoveredIdx] == null) {
let nonNullLft = null
let nonNullRgt = null
let i
i = hoveredIdx
while (nonNullLft == null && i-- > 0) {
if (seriesData[i] != null) { nonNullLft = i }
}
i = hoveredIdx
while (nonNullRgt == null && i++ < seriesData.length) {
if (seriesData[i] != null) { nonNullRgt = i }
}
const xVals = self.data[0]
const curPos = self.valToPos(cursorXVal, 'x')
const rgtPos = nonNullRgt == null ? Infinity : self.valToPos(xVals[nonNullRgt], 'x')
const lftPos = nonNullLft == null ? -Infinity : self.valToPos(xVals[nonNullLft], 'x')
const lftDelta = curPos - lftPos
const rgtDelta = rgtPos - curPos
if (lftDelta <= rgtDelta) {
if (lftDelta <= hoverProximityPx) { hoveredIdx = nonNullLft }
} else {
if (rgtDelta <= hoverProximityPx) { hoveredIdx = nonNullRgt }
}
}
return hoveredIdx
},
points: {
size: 10,
width: 5
}
},
plugins: [
@@ -202,18 +249,34 @@ export default {
show: false
},
series: [
{}
{
scale: 'x'
}
],
tzDate: ts => UPlot.tzDate(new Date(ts * 1e3), localStorage.getItem('nz-sys-timezone')),
fmtDate: () => {
return self.xAxisLabelFormatter(seriesData[0][0], seriesData[0][seriesData[0].length - 1])
},
axes: [
{},
{
scale: 'x',
gap: 5,
grid: {
show: true,
stroke: 'rgba(0, 10, 23, 0.09)',
width: 1
}
},
{
scale: 'left',
values: (u, vals, space) => vals.map(v => leftUnitCompute.compute(v, null, -1, decimals)),
incrs: incrs,
gap: 5,
grid: {
show: true,
stroke: 'rgba(0, 10, 23, 0.09)',
width: 1
},
// space: (self) => {
// console.log(self)
// return 50
@@ -242,8 +305,13 @@ export default {
{
show: true,
side: 1,
grid: { show: false },
grid: {
show: false,
stroke: 'rgba(0, 10, 23, 0.09)',
width: 1
},
scale: 'right',
gap: 5,
// space: (self) => {
// console.log(self)
// return 50
@@ -252,17 +320,52 @@ export default {
incrs: rightIncrs,
ticks: {
show: false // true
},
size (self, values, axisIdx, cycleNum) {
const axis = self.axes[axisIdx]
// bail out, force convergence
if (cycleNum > 1) { return axis._size }
let axisSize = axis.ticks.size + axis.gap
// find longest value
const longestVal = (values ?? []).reduce((acc, val) => (
val.length > acc.length ? val : acc
), '')
if (longestVal != '') {
self.ctx.font = axis.font[0]
axisSize += self.ctx.measureText(longestVal).width / devicePixelRatio
}
return Math.ceil(axisSize)
}
}
],
scales: {
x: {
key: 'x',
auto: true,
ori: 0,
dir: 1,
time: true
},
left: {
key: 'left',
time: false
time: false,
auto: true,
ori: 1,
dir: 1,
distr: 1
},
right: {
key: 'right',
time: false
time: false,
auto: true,
ori: 1,
dir: 1,
distr: 1
}
}
}
@@ -273,10 +376,12 @@ export default {
scales: [null, null]
}
}
const data = this.seriesData = seriesData
let data = this.seriesData = seriesData
opts.series.push(...seriesAll)
if (this.isStack) {
getStackedOpts('', opts, data)
const obj = getStackedOpts('', opts, data)
opts = obj.opts
data = obj.data
}
this.renderMinMax(opts)
if (getChart(this.chartId)) {
@@ -294,7 +399,6 @@ export default {
}, 100)
},
renderMinMax (opts) {
console.log(opts)
let leftMin = this.$lodash.get(this.chartInfo, 'param.min', undefined)
let leftMax = this.$lodash.get(this.chartInfo, 'param.max', undefined)
if (leftMin || leftMax) {
@@ -454,7 +558,6 @@ export default {
},
resize () {
setTimeout(() => {
console.log('chartMixinnz')
const dom = this.$refs['timeSeries-chart-box']
const width = dom.offsetWidth
const legendHeight = this.$lodash.get(this.$refs, 'legend.$el.offsetHeight', 40)

View File

@@ -6,6 +6,7 @@ import { formatScientificNotation, getMetricTypeValue } from '@/components/commo
import bus from '@/libs/bus'
import moment from 'moment-timezone'
import { getChart } from '@/components/common/js/common'
import uplot from 'uplot'
export default {
data () {
return {
@@ -68,6 +69,9 @@ export default {
item.statistics = statistics
item.values.forEach(value => {
let itemValue = value[1]
if (!isNaN(itemValue)) {
itemValue = Number(itemValue)
}
if (itemValue === null && nullValueMode !== 'null') {
if (nullValueMode === 'zero') {
itemValue = 0
@@ -103,24 +107,28 @@ export default {
this.seriesColor.push(randomcolor())
}
const legend = this.handleLegend(this.chartInfo, series, expressionIndex, dataIndex, chartIndex)
let isRight = false
let isRight
if (this.chartInfo.param.enable.rightYAxis) {
const elementNames = this.$lodash.get(this.chartInfo, 'param.rightYAxis.elementNames', [])
isRight = elementNames.indexOf(series.elements.name) !== -1
isRight = elementNames.indexOf(series.elements.name) !== -1 ? 1 : 0
}
const name = legend.name
const alias = legend.alias
const statistics = series.statistics
const chartType = this.chartInfo.type
const obj = {
name: name,
label: alias,
scale: isRight ? 'right' : 'left', // right
yAxisIndex: isRight ? 1 : 0, // right
values: (u, v) => series.elements.name + JSON.stringify(series.metric),
yAxisIndex: isRight, // right
// values: (u, v) => series.elements.name + JSON.stringify(series.metric),
stroke: this.seriesColor[chartIndex],
width: 1 / devicePixelRatio,
expressionIndex: series.expressionIndex
expressionIndex: series.expressionIndex,
paths (taht, seriesIdx, idx0, idx1, filtIdxs) {
return uplot.paths.spline(taht)(taht, seriesIdx, idx0, idx1, filtIdxs)
}
}
if (chartType === 'area') {
obj.fill = this.seriesColor[chartIndex] + '20' // 面积图使用
@@ -128,7 +136,10 @@ export default {
if (chartType === 'point') {
obj.points = {
show: true,
width: 2
size: 6,
width: 3,
fill: this.seriesColor[chartIndex],
stroke: this.seriesColor[chartIndex]
}
obj.width = 0
}

View File

@@ -7,10 +7,18 @@ function stack (data, omit) {
for (let i = 0; i < d0Len; i++) { accum[i] = 0 }
for (let i = 1; i < data.length; i++) { data2.push(omit(i) ? data[i] : data[i].map((v, i) => (accum[i] += +v))) }
for (let i = 1; i < data.length; i++) {
data2.push(data[i].map((v, i) => {
if (typeof (v) === 'undefined') {
return accum[i]
}
return (accum[i] += +v)
}))
}
for (let i = 1; i < data.length; i++) {
!omit(i) && bands.push({
dir: -1,
series: [
data.findIndex((s, j) => j > i && !omit(j)),
i
@@ -19,7 +27,8 @@ function stack (data, omit) {
}
bands = bands.filter(b => b.series[1] > -1)
bands = bands.filter(b => b.series[0] > -1)
bands = bands.reverse()
return {
data: [data[0]].concat(data2),
bands
@@ -34,25 +43,9 @@ export default function getStackedOpts (title, opt, data, interp) {
opts.bands = stacked.bands
opts.cursor = opts.cursor || {}
opts.cursor.dataIdx = (u, seriesIdx, closestIdx, xValue) => {
return data[seriesIdx][closestIdx] == null ? null : closestIdx
}
opts.series.forEach(s => {
s.value = (u, v, si, i) => data[si][i]
s.points = s.points || {}
// scan raw unstacked data to return only real points
s.points.filter = (u, seriesIdx, show, gaps) => {
if (show) {
const pts = []
data[seriesIdx].forEach((v, i) => {
v != null && pts.push(i)
})
return pts
}
}
})
// restack on toggle
opts.hooks = {

View File

@@ -5,6 +5,7 @@ import '@/assets/css/main.scss'
import '@/assets/css/font/iconfont.js'
import ElementUI from 'element-ui'
import i18n from '@/components/common/i18n'
import 'uplot/dist/uPlot.min.css'
import Vue from 'vue'
import Vuex from 'vuex'