some optmization

This commit is contained in:
jiaming 2018-12-23 19:06:42 +08:00
parent 0223458f72
commit 81ec6a8fc1
2 changed files with 425 additions and 214 deletions

View File

@ -24,290 +24,501 @@ export default {
return { return {
ref: `radar-chart-${(new Date()).getTime()}`, ref: `radar-chart-${(new Date()).getTime()}`,
axisType: 'column', // axis base config
boundaryGap: true,
mulValueAdd: true,
horizon: false,
defaultColumnType: 'butt', columnData: [],
defaultBGColor: 'rgba(250, 250, 250, 0.2)', columnItemSeriesNum: 0,
defaultMulItemDrawType: 'link', columnItemAllWidth: 0,
defaultShowColumnBG: false, columnItemWidth: 0,
columnItemOffset: [],
columnType: '', valuePointPos: []
columnWidth: '',
columnItemREPos: [],
mulItemDrawType: '',
showColumnBG: false,
bgColor: '',
bgColorMul: false,
columnData: []
} }
}, },
props: ['data', 'colors'], props: ['data', 'colors'],
methods: { methods: {
async init () { async init () {
const { initCanvas, data, draw } = this const { initCanvas, initColors } = this
await initCanvas() await initCanvas()
initColors()
const { data, draw } = this
data && draw() data && draw()
}, },
draw () { draw () {
const { clearCanvas, initColors, initAxis, drawAxis, calcColumnConfig, drawColumnBG } = this const { clearCanvas } = this
clearCanvas() clearCanvas()
initColors() const { calcHorizon, initAxis, drawAxis } = this
calcHorizon()
initAxis() initAxis()
drawAxis() drawAxis()
const { calcBGConfig, drawColumn, calcColumnData } = this const { switchNormalOrCenterOriginType } = this
calcBGConfig() switchNormalOrCenterOriginType()
},
calcHorizon () {
const { data: { horizon } } = this
this.horizon = horizon
},
switchNormalOrCenterOriginType () {
const { centerOrigin, drawNormalTypeColumnChart, drawCenterOriginTypeColumnChart } = this
if (centerOrigin) drawCenterOriginTypeColumnChart()
if (!centerOrigin) drawNormalTypeColumnChart()
},
drawNormalTypeColumnChart () {
const { calcColumnConfig, calcColumnItemOffset, calcValuePointPos } = this
calcColumnConfig() calcColumnConfig()
calcColumnData() calcColumnItemOffset()
drawColumnBG() calcValuePointPos()
drawColumn() const { drawFigure } = this
drawFigure()
}, },
calcColumnConfig () { calcColumnConfig () {
const { data, labelTagGap, defaultMulItemDrawType, defaultColumnType } = this const { data: { data }, labelAxisTagPos, axisOriginPos, horizon } = this
const { data: td, columnType, mulItemDrawType } = data const columnData = this.columnData = data.filter(({ type }) =>
!(type === 'polyline' || type === 'smoothline'))
const halfGap = labelTagGap / 2 const columnItemSeriesNum = this.columnItemSeriesNum = columnData.length
const columnWidth = this.columnWidth = labelTagGap / (td.length + 1) const columnItemAllWidth = this.columnItemAllWidth = (horizon
? axisOriginPos[1] - labelAxisTagPos[0][1]
: labelAxisTagPos[0][0] - axisOriginPos[0]) * 2
this.columnItemREPos = new Array(td.length).fill(0).map((t, i) => this.columnItemWidth = columnItemAllWidth / (columnItemSeriesNum + 1)
(i + 1) * columnWidth).map(pos => pos - halfGap)
this.columnType = columnType || defaultColumnType
this.mulItemDrawType = mulItemDrawType || defaultMulItemDrawType
}, },
calcBGConfig () { calcColumnItemOffset () {
const { data, defaultBGColor, drawColors, defaultShowColumnBG } = this const { columnItemSeriesNum, columnItemAllWidth, columnItemWidth } = this
const { showColumnBG, bgColor } = data const { data: { spaceBetween } } = this
this.showColumnBG = showColumnBG || defaultShowColumnBG const halfColumnWidth = columnItemWidth / 2
let trueBGColor = bgColor || defaultBGColor const halfColumnItemAllWidth = columnItemAllWidth / 2
trueBGColor === 'colors' && (trueBGColor = drawColors) let columnItemOffset = new Array(columnItemSeriesNum).fill(0)
this.bgColor = trueBGColor if (spaceBetween) {
const spaceGap = columnItemWidth / (columnItemSeriesNum + 1)
this.bgColorMul = trueBGColor instanceof Array this.columnItemOffset = columnItemOffset.map((t, i) =>
spaceGap * (i + 1) + columnItemWidth * i + halfColumnWidth - halfColumnItemAllWidth)
}
if (!spaceBetween) {
this.columnItemOffset = columnItemOffset.map((t, i) =>
columnItemWidth * (i + 1) - halfColumnItemAllWidth)
}
}, },
calcColumnData () { calcValuePointPos () {
const { labelAxisPos, horizon, defaultMulItemDrawType, data, filterNull } = this const { getAxisPointsPos, valueAxisMaxMin, agValueAxisMaxMin } = this
const { getAxisPointsPos, axisMaxMin, axisOriginPos, axisWH, deepClone, multipleSum } = this const { labelAxisTagPos, deepClone, filterNull, multipleSum } = this
const { mulItemDrawType, data: td } = data const { data: { data }, axisOriginPos, axisWH, horizon } = this
const trueMulItemDrawType = this.mulItemDrawType = mulItemDrawType || defaultMulItemDrawType const dealAfterData = deepClone(data).map(({ data, againstAxis }) => {
if (!(data[0] instanceof Array)) return { data, againstAxis }
this.columnData = td.map(({ data: values }, i) => const td = data.map(series => series.map((v, i) => {
values.map((v, j) => { if (!v && v !== 0) return false
if (!v) return false
let beginPoint = labelAxisPos[j] return multipleSum(...filterNull(series.slice(0, i + 1)))
if (v instanceof Array) {
return v.map((ci, k) => {
if (!ci) return false
if (trueMulItemDrawType === 'cover') {
return [
beginPoint,
getAxisPointsPos(axisMaxMin, ci, axisOriginPos, axisWH, beginPoint, horizon)
]
} else {
const beReutrn = [
deepClone(beginPoint),
getAxisPointsPos(axisMaxMin,
multipleSum(...filterNull(v.slice(0, k + 1))), axisOriginPos, axisWH, beginPoint, horizon)
]
beginPoint = deepClone(beReutrn[1])
return beReutrn
}
})
} else {
if (!v) return false
return [
deepClone(beginPoint),
getAxisPointsPos(axisMaxMin, v, axisOriginPos, axisWH, beginPoint, horizon)
]
}
})) }))
return { data: td, againstAxis }
})
this.valuePointPos = dealAfterData.map(({ data, againstAxis }) =>
getAxisPointsPos(
againstAxis ? agValueAxisMaxMin : valueAxisMaxMin,
data,
axisOriginPos,
axisWH,
labelAxisTagPos,
horizon
))
console.error(this.valuePointPos)
}, },
drawColumnBG () { drawFigure () {
const { ctx, showColumnBG, columnWidth, axisWH } = this const { data: { data, roundColumn }, valuePointPos } = this
const { bgColor, bgColorMul, horizon, labelAxisPos } = this const { drawColumn, drawRoundColumn, drawLeftEchelon, drawRightEchelon, drawPolyline, drawSmoothline } = this
const { columnType, data } = this data.forEach((series, i) => {
switch (series.type) {
case 'leftEchelon': drawLeftEchelon(series, valuePointPos[i], i)
break
case 'rightEchelon': drawRightEchelon(series, valuePointPos[i], i)
break
case 'polyline': drawPolyline(series, valuePointPos[i], i)
break
case 'smoothline': drawSmoothline(series, valuePointPos[i], i)
break
if (!showColumnBG) return default: roundColumn ? drawRoundColumn(series, valuePointPos[i], i) : drawColumn(series, valuePointPos[i], i)
break
}
})
},
getCurrentColor (i) {
// const { drawColors } = this
},
getGradientColor (value, colors) {
const { data: { localGradient }, axisAnglePos, horizon } = this
!bgColorMul && (ctx.strokeStyle = bgColor) const { ctx, canvas: { getLinearGradientColor } } = this
const bgColorNum = bgColor.length if (localGradient) {
return getLinearGradientColor(ctx,
...(horizon
? [value, [axisAnglePos.leftTop[0], value[1]]]
: [value, [value[0], axisAnglePos.leftBottom[1]]]),
colors)
} else {
return getLinearGradientColor(ctx,
...(horizon
? [axisAnglePos.leftTop, axisAnglePos.rightTop]
: [axisAnglePos.leftTop, axisAnglePos.leftBottom]),
colors)
}
},
drawColumn ({ fillColor }, points, i) {
const { columnItemWidth, columnItemOffset, labelAxisTagPos, getOffsetPoint } = this
const bgColumnWidth = columnWidth * data.data.length const { ctx, drawColors, getGradientColor, deepClone } = this
ctx.lineWidth = bgColumnWidth
ctx.setLineDash([10, 0]) ctx.setLineDash([10, 0])
ctx.lineCap = columnType ctx.lineWidth = columnItemWidth
const halfColumnWidth = bgColumnWidth / 2 const currentColor = fillColor || drawColors[i]
labelAxisPos.forEach((pos, i) => { const currentOffset = columnItemOffset.shift()
const movePos = pos
const endPos = horizon ? [pos[0] + axisWH[0], pos[1]] : [pos[0], pos[1] - axisWH[1]]
if (columnType === 'round') { const offsetTagPos = deepClone(labelAxisTagPos).map(p => getOffsetPoint(p, currentOffset))
if (horizon) {
movePos[0] += halfColumnWidth points.forEach((point, i) => {
endPos[0] -= halfColumnWidth if (point[0] instanceof Array) {
} else { let lastEnd = offsetTagPos[i]
movePos[1] -= halfColumnWidth
endPos[1] += halfColumnWidth point.forEach((item, j) => {
} const beginPoint = getOffsetPoint(item, currentOffset)
// if (j === 0) return
if (j === 1) return
if (j === 2) return
ctx.beginPath()
ctx.strokeStyle = 'blue'
ctx.moveTo(...beginPoint)
ctx.lineTo(...lastEnd)
ctx.stroke()
lastEnd = deepClone(beginPoint)
})
return
} }
bgColorMul && (ctx.strokeStyle = bgColor[i % bgColorNum])
ctx.beginPath() ctx.beginPath()
ctx.strokeStyle = getGradientColor(point, currentColor)
ctx.moveTo(...movePos) ctx.moveTo(...getOffsetPoint(point, currentOffset))
ctx.lineTo(...endPos) ctx.lineTo(...offsetTagPos[i])
ctx.stroke() ctx.stroke()
}) })
}, },
drawColumn () { getOffsetPoint ([x, y], offset) {
const { ctx, drawColors, drawColorsMul, data: { data: td }, horizon } = this
const { columnWidth, columnItemREPos, columnData, getREPos, canvas } = this
const { axisOriginPos, axisWH, columnType, getRoundLinePoints } = this
const { getLinearGradientColor } = canvas
const halfColumnWidth = columnWidth / 2
ctx.lineWidth = columnWidth
!drawColorsMul && (ctx.strokeStyle = drawColors)
ctx.setLineDash([10, 0])
ctx.lineCap = columnType
const drawColorsNum = drawColors.length
const linearGradientColorPos = horizon ? [
axisOriginPos,
[axisOriginPos[0] + axisWH[0], axisOriginPos[1]]
] : [
axisOriginPos,
[axisOriginPos[0], axisOriginPos[1] - axisWH[1]]
]
columnData.forEach((column, i) => {
drawColorsMul && (ctx.strokeStyle = drawColors[i % drawColorsNum])
let currentFillColor = td[i].fillColor
currentFillColor === 'colors' && (currentFillColor = drawColors)
const currentFillColorMul = currentFillColor instanceof Array
const currentFillColorNum = currentFillColorMul ? currentFillColor.length : 0
currentFillColor && (ctx.strokeStyle = getLinearGradientColor(ctx, ...linearGradientColorPos, currentFillColor))
column[0][0][0] instanceof Array && column.forEach((ci, j) =>
ci.forEach((cii, k) => {
if (!cii) return
drawColorsMul && (ctx.strokeStyle = drawColors[(i + k) % drawColorsNum])
if (currentFillColorMul) (ctx.strokeStyle = currentFillColor[k % currentFillColorNum])
ctx.beginPath()
let currentREPos = cii.map(tci => getREPos(tci, columnItemREPos[i]))
columnType === 'round' && (currentREPos = getRoundLinePoints(currentREPos, halfColumnWidth))
ctx.moveTo(...currentREPos[0])
ctx.lineTo(...currentREPos[1])
ctx.stroke()
}))
!(column[0][0][0] instanceof Array) && column.forEach((ci, j) => {
if (!ci) return
ctx.beginPath()
let currentREPos = ci.map(tci => getREPos(tci, columnItemREPos[i]))
columnType === 'round' && (currentREPos = getRoundLinePoints(currentREPos, halfColumnWidth))
ctx.moveTo(...currentREPos[0])
ctx.lineTo(...currentREPos[1])
ctx.stroke()
})
})
},
getREPos ([x, y], datum) {
const { horizon } = this const { horizon } = this
return [ return horizon
horizon ? x : x + datum, ? [x, y + offset]
horizon ? y + datum : y : [x + offset, y]
]
}, },
getRoundLinePoints ([pa, pb], columnWidth) { drawRoundColumn () {},
const { horizon } = this drawLeftEchelon () {},
drawRightEchelon () {},
drawPolyline () {},
drawSmoothline () {},
drawCenterOriginTypeColumnChart () {}
// draw () {
// const { clearCanvas, initColors, initAxis, drawAxis, calcColumnConfig, drawColumnBG } = this
let [a, b, c, d] = [0, 0, 0, 0] // clearCanvas()
if (horizon) { // initColors()
a = pa[0] + columnWidth
b = pa[1]
c = pb[0] - columnWidth
d = pb[1]
} else {
a = pa[0]
b = pa[1] - columnWidth
c = pb[0]
d = pb[1] + columnWidth
}
return horizon ? [ // initAxis()
[a > c ? c : a, b],
[c, d] // drawAxis()
] : [
[a, b], // const { calcBGConfig, drawColumn, calcColumnData } = this
[c, b > d ? d : b]
] // calcBGConfig()
}
// calcColumnConfig()
// calcColumnData()
// drawColumnBG()
// drawColumn()
// },
// calcColumnConfig () {
// const { data, labelTagGap, defaultMulItemDrawType, defaultColumnType } = this
// const { data: td, columnType, mulItemDrawType } = data
// const halfGap = labelTagGap / 2
// const columnWidth = this.columnWidth = labelTagGap / (td.length + 1)
// this.columnItemREPos = new Array(td.length).fill(0).map((t, i) =>
// (i + 1) * columnWidth).map(pos => pos - halfGap)
// this.columnType = columnType || defaultColumnType
// this.mulItemDrawType = mulItemDrawType || defaultMulItemDrawType
// },
// calcBGConfig () {
// const { data, defaultBGColor, drawColors, defaultShowColumnBG } = this
// const { showColumnBG, bgColor } = data
// this.showColumnBG = showColumnBG || defaultShowColumnBG
// let trueBGColor = bgColor || defaultBGColor
// trueBGColor === 'colors' && (trueBGColor = drawColors)
// this.bgColor = trueBGColor
// this.bgColorMul = trueBGColor instanceof Array
// },
// calcColumnData () {
// const { labelAxisPos, horizon, defaultMulItemDrawType, data, filterNull } = this
// const { getAxisPointsPos, axisMaxMin, axisOriginPos, axisWH, deepClone, multipleSum } = this
// const { mulItemDrawType, data: td } = data
// const trueMulItemDrawType = this.mulItemDrawType = mulItemDrawType || defaultMulItemDrawType
// this.columnData = td.map(({ data: values }, i) =>
// values.map((v, j) => {
// if (!v) return false
// let beginPoint = labelAxisPos[j]
// if (v instanceof Array) {
// return v.map((ci, k) => {
// if (!ci) return false
// if (trueMulItemDrawType === 'cover') {
// return [
// beginPoint,
// getAxisPointsPos(axisMaxMin, ci, axisOriginPos, axisWH, beginPoint, horizon)
// ]
// } else {
// const beReutrn = [
// deepClone(beginPoint),
// getAxisPointsPos(axisMaxMin,
// multipleSum(...filterNull(v.slice(0, k + 1))), axisOriginPos, axisWH, beginPoint, horizon)
// ]
// beginPoint = deepClone(beReutrn[1])
// return beReutrn
// }
// })
// } else {
// if (!v) return false
// return [
// deepClone(beginPoint),
// getAxisPointsPos(axisMaxMin, v, axisOriginPos, axisWH, beginPoint, horizon)
// ]
// }
// }))
// },
// drawColumnBG () {
// const { ctx, showColumnBG, columnWidth, axisWH } = this
// const { bgColor, bgColorMul, horizon, labelAxisPos } = this
// const { columnType, data } = this
// if (!showColumnBG) return
// !bgColorMul && (ctx.strokeStyle = bgColor)
// const bgColorNum = bgColor.length
// const bgColumnWidth = columnWidth * data.data.length
// ctx.lineWidth = bgColumnWidth
// ctx.setLineDash([10, 0])
// ctx.lineCap = columnType
// const halfColumnWidth = bgColumnWidth / 2
// labelAxisPos.forEach((pos, i) => {
// const movePos = pos
// const endPos = horizon ? [pos[0] + axisWH[0], pos[1]] : [pos[0], pos[1] - axisWH[1]]
// if (columnType === 'round') {
// if (horizon) {
// movePos[0] += halfColumnWidth
// endPos[0] -= halfColumnWidth
// } else {
// movePos[1] -= halfColumnWidth
// endPos[1] += halfColumnWidth
// }
// }
// bgColorMul && (ctx.strokeStyle = bgColor[i % bgColorNum])
// ctx.beginPath()
// ctx.moveTo(...movePos)
// ctx.lineTo(...endPos)
// ctx.stroke()
// })
// },
// drawColumn () {
// const { ctx, drawColors, drawColorsMul, data: { data: td }, horizon } = this
// const { columnWidth, columnItemREPos, columnData, getREPos, canvas } = this
// const { axisOriginPos, axisWH, columnType, getRoundLinePoints } = this
// const { getLinearGradientColor } = canvas
// const halfColumnWidth = columnWidth / 2
// ctx.lineWidth = columnWidth
// !drawColorsMul && (ctx.strokeStyle = drawColors)
// ctx.setLineDash([10, 0])
// ctx.lineCap = columnType
// const drawColorsNum = drawColors.length
// const linearGradientColorPos = horizon ? [
// axisOriginPos,
// [axisOriginPos[0] + axisWH[0], axisOriginPos[1]]
// ] : [
// axisOriginPos,
// [axisOriginPos[0], axisOriginPos[1] - axisWH[1]]
// ]
// columnData.forEach((column, i) => {
// drawColorsMul && (ctx.strokeStyle = drawColors[i % drawColorsNum])
// let currentFillColor = td[i].fillColor
// currentFillColor === 'colors' && (currentFillColor = drawColors)
// const currentFillColorMul = currentFillColor instanceof Array
// const currentFillColorNum = currentFillColorMul ? currentFillColor.length : 0
// currentFillColor && (ctx.strokeStyle = getLinearGradientColor(ctx, ...linearGradientColorPos, currentFillColor))
// column[0][0][0] instanceof Array && column.forEach((ci, j) =>
// ci.forEach((cii, k) => {
// if (!cii) return
// drawColorsMul && (ctx.strokeStyle = drawColors[(i + k) % drawColorsNum])
// if (currentFillColorMul) (ctx.strokeStyle = currentFillColor[k % currentFillColorNum])
// ctx.beginPath()
// let currentREPos = cii.map(tci => getREPos(tci, columnItemREPos[i]))
// columnType === 'round' && (currentREPos = getRoundLinePoints(currentREPos, halfColumnWidth))
// ctx.moveTo(...currentREPos[0])
// ctx.lineTo(...currentREPos[1])
// ctx.stroke()
// }))
// !(column[0][0][0] instanceof Array) && column.forEach((ci, j) => {
// if (!ci) return
// ctx.beginPath()
// let currentREPos = ci.map(tci => getREPos(tci, columnItemREPos[i]))
// columnType === 'round' && (currentREPos = getRoundLinePoints(currentREPos, halfColumnWidth))
// ctx.moveTo(...currentREPos[0])
// ctx.lineTo(...currentREPos[1])
// ctx.stroke()
// })
// })
// },
// getREPos ([x, y], datum) {
// const { horizon } = this
// return [
// horizon ? x : x + datum,
// horizon ? y + datum : y
// ]
// },
// getRoundLinePoints ([pa, pb], columnWidth) {
// const { horizon } = this
// let [a, b, c, d] = [0, 0, 0, 0]
// if (horizon) {
// a = pa[0] + columnWidth
// b = pa[1]
// c = pb[0] - columnWidth
// d = pb[1]
// } else {
// a = pa[0]
// b = pa[1] - columnWidth
// c = pb[0]
// d = pb[1] + columnWidth
// }
// return horizon ? [
// [a > c ? c : a, b],
// [c, d]
// ] : [
// [a, b],
// [c, b > d ? d : b]
// ]
// }
}, },
mounted () { mounted () {
const { init } = this const { init } = this

View File

@ -13,11 +13,11 @@ import canvasMixin from '../../mixins/canvasMixin.js'
import colorsMixin from '../../mixins/colorsMixin.js' import colorsMixin from '../../mixins/colorsMixin.js'
import axisMixinEx from '../../mixins/axisMixinEx.js' import axisMixin from '../../mixins/axisMixin.js'
export default { export default {
name: 'PointChart', name: 'PointChart',
mixins: [canvasMixin, colorsMixin, axisMixinEx], mixins: [canvasMixin, colorsMixin, axisMixin],
props: ['data', 'colors'], props: ['data', 'colors'],
data () { data () {
return { return {