UNPKG

@opentiny/vue-renderless

Version:

An enterprise-class UI component library, support both Vue.js 2 and Vue.js 3, as well as PC and mobile.

184 lines (183 loc) 7.51 kB
import "../chunk-G2ADBYYC.js"; import { getFormated } from "../chart-core/deps/utils"; import { itemPoint, itemLabel, itemContent } from "../chart-core/deps/constants"; import { isNull } from "@opentiny/utils"; const DEF_MA = [5, 10, 20, 30]; const DEF_DOWN_COLOR = "#eb171f"; const DEF_UP_COLOR = "#00a874"; const DEF_START = 50; const DEF_END = 100; const SHOW_FALSE = { show: false }; let defaultKName = ""; const getCandleLegend = (args) => { const { MA, labelMap, legendName, showMA } = args; let data = [defaultKName]; showMA && (data = data.concat(MA.map((v) => `MA${v}`))); labelMap && (data = data.map((v) => isNull(labelMap[v]) ? v : labelMap[v])); function formatter(name) { return isNull(legendName[name]) ? name : legendName[name]; } return { data, formatter }; }; const getCandleTooltip = (args) => { const { dataType, digit, labelMap, metrics } = args; function position(pos, params, el, elRect, size) { const result = { top: 10 }; const side = pos[0] < size.viewSize[0] / 2 ? "right" : "left"; result[side] = 60; return result; } function formatter(options) { const tplt = []; tplt.push(`${itemContent(options[0].axisValue)}<br>`); options.forEach((opt) => { const { color, componentSubType, data, seriesName } = opt; const name = isNull(labelMap[seriesName]) ? seriesName : labelMap[seriesName]; tplt.push(`${itemPoint(color)}${itemContent(name)}: `); if (componentSubType === "candlestick") { tplt.push("<br>"); metrics.slice(0, 4).forEach((m, i) => { const name2 = isNull(labelMap[m]) ? m : labelMap[m]; const value = getFormated(data[i + 1], dataType, digit); tplt.push(`${itemLabel(`- ${name2}`)}${itemContent(value)}<br>`); }); } else if (componentSubType === "line") { const value = getFormated(data, dataType, digit); tplt.push(`${itemContent(value)}<br>`); } else if (componentSubType === "bar") { const value = getFormated(data[1], dataType, digit); tplt.push(`${itemContent(value)}<br>`); } }); return tplt.join(""); } return { axisPointer: { type: "cross" }, formatter, position, trigger: "axis" }; }; const getCandleVisualMap = (args) => { const { MA, downColor, showMA, upColor } = args; let seriesIndex = showMA ? 1 + MA.length : 1; let pieces = [ { value: 1, color: downColor }, { value: -1, color: upColor } ]; return { dimension: 2, pieces, seriesIndex, show: false }; }; const getCandleGrid = (args) => { const { showVol } = args; let height = showVol ? "50%" : "65%"; return [ { containLabel: false, left: "10%", right: "8%", top: "10%", height }, { containLabel: false, left: "10%", right: "8%", top: "65%", height: "16%" } ]; }; const getCandleXAxis = (args) => { const { dims: data } = args; const { type = "category", scale = true, boundaryGap = false, splitLine = SHOW_FALSE } = {}; const { axisLine = { onZero: false }, axisTick = SHOW_FALSE, axisLabel = SHOW_FALSE } = {}; const { min = "dataMin", max = "dataMax", gridIndex = 1 } = {}; return [ { axisLine, boundaryGap, data, max, min, scale, splitLine, type }, { axisLine, boundaryGap, data, max, min, scale, splitLine, type, axisLabel, axisTick, gridIndex } ]; }; const getCandleYAxis = (args) => { const { dataType, digit } = args; const { scale = true, gridIndex = 1, splitNumber = 2, axisLine = SHOW_FALSE } = {}; const { axisTick = SHOW_FALSE, axisLabel = SHOW_FALSE, splitLine = SHOW_FALSE } = {}; const formatter = (val) => getFormated(val, dataType, digit); return [ { scale, axisTick, axisLabel: { formatter } }, { scale, axisTick, axisLabel, gridIndex, splitNumber, axisLine, splitLine } ]; }; const getCandleDataZoom = (args) => { const { start, end } = args; return [ { type: "inside", xAxisIndex: [0, 1], start, end }, { type: "slider", xAxisIndex: [0, 1], start, end, show: true, top: "85%" } ]; }; const calculateMA = (dayCount, data, digit) => { let result = []; data.forEach((d, k) => { if (k < dayCount) { result.push("-"); } else { let { acc = 0, i = 0 } = {}; for (; i < dayCount; i++) { acc += data[k - i][1]; } result.push(Number((acc / dayCount).toFixed(digit))); } }); return result; }; const getCandleSeries = (args) => { const { MA, digit, downColor, itemStyle, labelMap, showMA, showVol, upColor, values, volumes } = args; const style = itemStyle || { color: upColor, color0: downColor, borderColor: null, borderColor0: null }; const lineStyle = { opacity: 0.5 }; const name = isNull(labelMap[defaultKName]) ? defaultKName : labelMap[defaultKName]; const series = [{ name, data: values, type: "candlestick", itemStyle: style }]; if (showMA) { MA.forEach((d) => { const key = `MA${d}`; const serieName = isNull(labelMap[key]) ? key : labelMap[key]; const serieData = calculateMA(d, values, digit); series.push({ name: serieName, data: serieData, type: "line", lineStyle, smooth: true }); }); } if (showVol) { series.push({ name: "Volume", data: volumes, type: "bar", xAxisIndex: 1, yAxisIndex: 1 }); } return series; }; const candle = (columns, rows, settings, extra) => { const { dimension = columns[0], metrics = columns.slice(1, 6), digit = 2, itemStyle } = settings; const { labelMap = {}, legendName = {}, MA = DEF_MA, showMA = false, showVol = false } = settings; const { showDataZoom = false, downColor = DEF_DOWN_COLOR, upColor = DEF_UP_COLOR } = settings; const { start = DEF_START, end = DEF_END, dataType } = settings; const { tooltipVisible, legendVisible, t } = extra; const isLiteData = Array.isArray(rows[0]); const { dims = [], values = [], volumes = [] } = {}; const candleMetrics = metrics.slice(0, 4); const volumeMetrics = metrics[4]; defaultKName = t("ui.chart.kName"); if (isLiteData) { rows.forEach((row) => { const itemResult = []; dims.push(row[columns.indexOf(dimension)]); candleMetrics.forEach((item) => itemResult.push(row[columns.indexOf(item)])); values.push(itemResult); volumeMetrics && volumes.push(row[columns.indexOf(volumeMetrics)]); }); } else { rows.forEach((row, index) => { const itemResult = []; dims.push(row[dimension]); candleMetrics.forEach((item) => itemResult.push(row[item])); values.push(itemResult); if (volumeMetrics) { const status = row[metrics[0]] > row[metrics[1]] ? 1 : -1; volumes.push([index, row[volumeMetrics], status]); } }); } let params = { MA, labelMap, legendName, showMA }; const legend = legendVisible && getCandleLegend(params); params = { dataType, digit, labelMap, metrics }; const tooltip = tooltipVisible && getCandleTooltip(params); params = { downColor, upColor, MA, showMA }; const visualMap = showVol && getCandleVisualMap(params); const dataZoom = showDataZoom && getCandleDataZoom({ start, end }); const grid = getCandleGrid({ showVol }); const xAxis = getCandleXAxis({ dims }); const yAxis = getCandleYAxis({ dataType, digit }); params = { values, volumes, upColor, downColor, showMA }; Object.assign(params, { MA, showVol, labelMap, digit, itemStyle }); const series = getCandleSeries(params); const axisPointer = { link: { xAxisIndex: "all" } }; return { legend, tooltip, visualMap, grid, xAxis, yAxis, dataZoom, series, axisPointer }; }; export { candle };