UNPKG

vislite

Version:

灵活、快速、简单的数据可视化交互式跨端前端库

250 lines (217 loc) 8.6 kB
import type BarLayoutType from '../../types/BarLayout' import type { BarResultType } from '../../types/Bar' import type BarOptionType from '../../types/BarOption' import type BarConfigType from '../../types/BarConfig' import { initOption } from '../common/option' import ruler from '../ruler' import { animation } from "oipage/web/animation/index" class BarLayout implements BarLayoutType { readonly name: string = 'BarLayout' private __config: BarConfigType constructor(config: BarConfigType = {}) { this.__config = initOption(config, { }) } private __option = { x: 50, y: 350, width: 400, height: 300, category: "xAxis", duration: 200 } setOption(option: BarOptionType) { initOption(option, this.__option) return this } private __rback: (bar: BarResultType) => void private __oralBar: any private __preBar: BarResultType | null use(initBar: any) { const bar: BarResultType = { coordinate: { x: this.__option.x, y: this.__option.y, width: this.__option.width, height: this.__option.height, xAxis: { type: this.__option.category === "xAxis" ? "category" : "value", data: [] }, yAxis: { type: this.__option.category === "xAxis" ? "value" : "category", data: [] } }, node: [] } let maxValue = void 0, minValue = void 0 // 求解一维最值 if (initBar.data) { for (const val of initBar.data) { if (maxValue === void 0 || val > maxValue) maxValue = val if (minValue === void 0 || val < minValue) minValue = val } } // 求解二维最值 else if (initBar.value) { for (const item of initBar.value) { for (const val of item.data) { if (maxValue === void 0 || val > maxValue) maxValue = val if (minValue === void 0 || val < minValue) minValue = val } } } else { throw new Error('No data leads to parsing errors') } const rulerArray = ruler(maxValue || 0, minValue || 0, 5) let categoryLen // 分类轴长度 let valueLen // 数值轴长度 if (this.__option.category === "xAxis") { // 设置刻度尺刻度 bar.coordinate.xAxis.data = initBar.category bar.coordinate.yAxis.data = rulerArray // 设置轴长度 categoryLen = this.__option.width valueLen = -1 * this.__option.height } else { bar.coordinate.xAxis.data = rulerArray bar.coordinate.yAxis.data = initBar.category categoryLen = this.__option.height valueLen = this.__option.width } // 求解分类轴刻度 const category: any = [] // 一维 const categorySingle1Width = categoryLen / initBar.category.length const categorySingle2Width = categorySingle1Width * 0.9 const categoryStart = categorySingle1Width * 0.05 if (initBar.data) { for (let i = 0; i < initBar.data.length; i++) { category.push([ categoryStart + categorySingle1Width * i, categorySingle2Width ]) } } // 二维 else { const categorySingle3Width = categorySingle2Width / initBar.value.length const categorySingle4Width = categorySingle3Width * 0.9 const categoryStartBlance = categorySingle3Width * 0.05 for (let i = 0; i < initBar.value[0].data.length; i++) { category[i] = [] for (let j = 0; j < initBar.value.length; j++) { category[i].push([ categoryStart + categorySingle1Width * i + categorySingle3Width * j + categoryStartBlance, categorySingle4Width ]) } } } // 根据值获取长度 const singleValueLen = valueLen / (rulerArray[rulerArray.length - 1] - rulerArray[0]) const getLenByValue = (value: number) => { return singleValueLen * (value - rulerArray[0]) } // 计算小矩形 if (this.__option.category === "xAxis") { // 分类在x轴,从左到右 if (initBar.data) { const nodeBar = [] for (let i = 0; i < initBar.data.length; i++) { nodeBar.push({ x: this.__option.x + category[i][0], y: this.__option.y, width: category[i][1], height: getLenByValue(initBar.data[i]), value: initBar.data[i] }) } bar.node.push({ bar: nodeBar }) } else { for (let j = 0; j < initBar.value.length; j++) { const nodeBar = [] for (let i = 0; i < initBar.value[j].data.length; i++) { nodeBar.push({ x: this.__option.x + category[i][j][0], y: this.__option.y, width: category[i][j][1], height: getLenByValue(initBar.value[j].data[i]), value: initBar.value[j].data[i] }) } bar.node.push({ name: initBar.value[j].name, bar: nodeBar }) } } } else { // 分类在y轴,从上到下 if (initBar.data) { const nodeBar = [] for (let i = 0; i < initBar.data.length; i++) { nodeBar.push({ x: this.__option.x, y: this.__option.y - this.__option.height + category[i][0], width: getLenByValue(initBar.data[i]), height: category[i][1], value: initBar.data[i] }) } bar.node.push({ bar: nodeBar }) } else { for (let j = 0; j < initBar.value.length; j++) { const nodeBar = [] for (let i = 0; i < initBar.value[j].data.length; i++) { nodeBar.push({ x: this.__option.x, y: this.__option.y - this.__option.height + category[i][j][0], width: getLenByValue(initBar.value[j].data[i]), height: category[i][j][1], value: initBar.value[j].data[i] }) } bar.node.push({ name: initBar.value[j].name, bar: nodeBar }) } } } return bar } bind(initBar: any, renderBack: (bar: BarResultType) => void) { this.__rback = renderBack this.__oralBar = initBar this.__preBar = this.use(this.__oralBar) this.__rback(this.__preBar) return this } unbind() { this.__rback = () => null this.__oralBar = null this.__preBar = null return this } doUpdate() { const newBar = this.use(this.__oralBar) const cacheBar = JSON.parse(JSON.stringify(newBar)) // eslint-disable-next-line @typescript-eslint/no-unused-vars animation((deep) => { if (this.__preBar) { // todo } else { this.__rback(cacheBar) } }, this.__option.duration, () => { this.__preBar = newBar this.__rback(this.__preBar) }) return this } } export default BarLayout