@orbcharts/plugins-basic 3.0.0-alpha.49 → 3.0.0-alpha.51
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/LICENSE +200 -200
- package/dist/orbcharts-plugins-basic.es.js +6325 -6272
- package/dist/orbcharts-plugins-basic.umd.js +8 -8
- package/dist/src/base/BaseGroupAxis.d.ts +1 -0
- package/dist/src/grid/index.d.ts +1 -1
- package/dist/src/grid/plugins/BarsPN.d.ts +1 -0
- package/dist/src/grid/types.d.ts +3 -2
- package/dist/src/multiGrid/defaults.d.ts +2 -1
- package/dist/src/multiGrid/index.d.ts +2 -0
- package/dist/src/multiGrid/multiGridObservables.d.ts +1 -1
- package/dist/src/multiGrid/plugins/MultiValueStackAxis.d.ts +1 -0
- package/dist/src/multiGrid/plugins/OverlappingValueStackAxes.d.ts +1 -0
- package/dist/src/multiGrid/types.d.ts +3 -0
- package/dist/src/series/types.d.ts +2 -3
- package/package.json +42 -42
- package/src/base/BaseBarStack.ts +778 -778
- package/src/base/BaseBars.ts +764 -764
- package/src/base/BaseBarsTriangle.ts +672 -672
- package/src/base/BaseDots.ts +513 -502
- package/src/base/BaseGroupAxis.ts +562 -496
- package/src/base/BaseLegend.ts +641 -641
- package/src/base/BaseLineAreas.ts +625 -625
- package/src/base/BaseLines.ts +699 -699
- package/src/base/BaseValueAxis.ts +478 -478
- package/src/base/types.ts +2 -2
- package/src/grid/defaults.ts +125 -121
- package/src/grid/gridObservables.ts +248 -247
- package/src/grid/index.ts +15 -15
- package/src/grid/plugins/BarStack.ts +43 -50
- package/src/grid/plugins/Bars.ts +44 -51
- package/src/grid/plugins/{BarsDiverging.ts → BarsPN.ts} +41 -41
- package/src/grid/plugins/BarsTriangle.ts +42 -50
- package/src/grid/plugins/Dots.ts +37 -37
- package/src/grid/plugins/GridLegend.ts +59 -59
- package/src/grid/plugins/GroupAux.ts +645 -645
- package/src/grid/plugins/GroupAxis.ts +35 -42
- package/src/grid/plugins/LineAreas.ts +39 -39
- package/src/grid/plugins/Lines.ts +38 -38
- package/src/grid/plugins/ScalingArea.ts +173 -173
- package/src/grid/plugins/ValueAxis.ts +36 -43
- package/src/grid/plugins/ValueStackAxis.ts +38 -79
- package/src/grid/types.ts +122 -120
- package/src/index.ts +9 -9
- package/src/multiGrid/defaults.ts +152 -147
- package/src/multiGrid/index.ts +14 -12
- package/src/multiGrid/multiGridObservables.ts +44 -43
- package/src/multiGrid/plugins/MultiBarStack.ts +78 -78
- package/src/multiGrid/plugins/MultiBars.ts +77 -77
- package/src/multiGrid/plugins/MultiBarsTriangle.ts +77 -77
- package/src/multiGrid/plugins/MultiDots.ts +65 -65
- package/src/multiGrid/plugins/MultiGridLegend.ts +89 -89
- package/src/multiGrid/plugins/MultiGroupAxis.ts +69 -69
- package/src/multiGrid/plugins/MultiLineAreas.ts +67 -67
- package/src/multiGrid/plugins/MultiLines.ts +66 -66
- package/src/multiGrid/plugins/MultiValueAxis.ts +69 -69
- package/src/multiGrid/plugins/MultiValueStackAxis.ts +69 -0
- package/src/multiGrid/plugins/OverlappingValueAxes.ts +166 -173
- package/src/multiGrid/plugins/OverlappingValueStackAxes.ts +167 -0
- package/src/multiGrid/types.ts +71 -67
- package/src/noneData/defaults.ts +64 -64
- package/src/noneData/index.ts +3 -3
- package/src/noneData/plugins/Container.ts +10 -10
- package/src/noneData/plugins/Tooltip.ts +310 -310
- package/src/noneData/types.ts +26 -26
- package/src/series/defaults.ts +126 -126
- package/src/series/index.ts +9 -9
- package/src/series/plugins/Bubbles.ts +545 -602
- package/src/series/plugins/Pie.ts +576 -576
- package/src/series/plugins/PieEventTexts.ts +262 -262
- package/src/series/plugins/PieLabels.ts +304 -304
- package/src/series/plugins/Rose.ts +472 -472
- package/src/series/plugins/RoseLabels.ts +362 -362
- package/src/series/plugins/SeriesLegend.ts +59 -59
- package/src/series/seriesObservables.ts +145 -145
- package/src/series/seriesUtils.ts +51 -51
- package/src/series/types.ts +83 -83
- package/src/tree/defaults.ts +22 -22
- package/src/tree/index.ts +3 -3
- package/src/tree/plugins/TreeLegend.ts +59 -59
- package/src/tree/plugins/TreeMap.ts +305 -305
- package/src/tree/types.ts +23 -23
- package/src/utils/commonUtils.ts +21 -21
- package/src/utils/d3Graphics.ts +124 -124
- package/src/utils/d3Utils.ts +73 -73
- package/src/utils/observables.ts +14 -14
- package/src/utils/orbchartsUtils.ts +100 -100
- package/tsconfig.dev.json +16 -16
- package/tsconfig.json +13 -13
- package/tsconfig.prod.json +13 -13
- package/vite.config.js +49 -49
- package/dist/src/grid/plugins/BarsDiverging.d.ts +0 -1
    
        package/src/utils/commonUtils.ts
    CHANGED
    
    | @@ -1,22 +1,22 @@ | |
| 1 | 
            -
            // 取得文字寬度
         | 
| 2 | 
            -
            export function measureTextWidth (text: string, size: number = 10) {
         | 
| 3 | 
            -
              const context = document.createElement("canvas").getContext("2d")
         | 
| 4 | 
            -
              let width = context?.measureText(text)?.width ?? 0
         | 
| 5 | 
            -
              return width * size / 10 // 以10為基準
         | 
| 6 | 
            -
            }
         | 
| 7 | 
            -
             | 
| 8 | 
            -
            // 取得最小及最大值 - 數字陣列
         | 
| 9 | 
            -
            export function getMinAndMax (data: number[]): [number, number] {
         | 
| 10 | 
            -
              const defaultMinAndMax: [number, number] = [0, 0] // default
         | 
| 11 | 
            -
              if (!data.length) {
         | 
| 12 | 
            -
                return defaultMinAndMax
         | 
| 13 | 
            -
              }
         | 
| 14 | 
            -
              const minAndMax: [number, number] = data.reduce((prev, current) => {
         | 
| 15 | 
            -
                // [min, max]
         | 
| 16 | 
            -
                return [
         | 
| 17 | 
            -
                  current < prev[0] ? current : prev[0],
         | 
| 18 | 
            -
                  current > prev[1] ? current : prev[1]
         | 
| 19 | 
            -
                ]
         | 
| 20 | 
            -
              }, [data[0], data[0]])
         | 
| 21 | 
            -
              return minAndMax
         | 
| 1 | 
            +
            // 取得文字寬度
         | 
| 2 | 
            +
            export function measureTextWidth (text: string, size: number = 10) {
         | 
| 3 | 
            +
              const context = document.createElement("canvas").getContext("2d")
         | 
| 4 | 
            +
              let width = context?.measureText(text)?.width ?? 0
         | 
| 5 | 
            +
              return width * size / 10 // 以10為基準
         | 
| 6 | 
            +
            }
         | 
| 7 | 
            +
             | 
| 8 | 
            +
            // 取得最小及最大值 - 數字陣列
         | 
| 9 | 
            +
            export function getMinAndMax (data: number[]): [number, number] {
         | 
| 10 | 
            +
              const defaultMinAndMax: [number, number] = [0, 0] // default
         | 
| 11 | 
            +
              if (!data.length) {
         | 
| 12 | 
            +
                return defaultMinAndMax
         | 
| 13 | 
            +
              }
         | 
| 14 | 
            +
              const minAndMax: [number, number] = data.reduce((prev, current) => {
         | 
| 15 | 
            +
                // [min, max]
         | 
| 16 | 
            +
                return [
         | 
| 17 | 
            +
                  current < prev[0] ? current : prev[0],
         | 
| 18 | 
            +
                  current > prev[1] ? current : prev[1]
         | 
| 19 | 
            +
                ]
         | 
| 20 | 
            +
              }, [data[0], data[0]])
         | 
| 21 | 
            +
              return minAndMax
         | 
| 22 22 | 
             
            }
         | 
    
        package/src/utils/d3Graphics.ts
    CHANGED
    
    | @@ -1,125 +1,125 @@ | |
| 1 | 
            -
             | 
| 2 | 
            -
            type RenderCircleTextParams = {
         | 
| 3 | 
            -
              text: string,
         | 
| 4 | 
            -
              radius: number,
         | 
| 5 | 
            -
              lineHeight: number,
         | 
| 6 | 
            -
              isBreakAll: boolean,
         | 
| 7 | 
            -
              limit?:number
         | 
| 8 | 
            -
            }
         | 
| 9 | 
            -
             | 
| 10 | 
            -
            type Line = { width: number; text: string }
         | 
| 11 | 
            -
             | 
| 12 | 
            -
            export function renderCircleText (selection: d3.Selection<any, any, any, any>, {
         | 
| 13 | 
            -
              text,
         | 
| 14 | 
            -
              radius,
         | 
| 15 | 
            -
              lineHeight,
         | 
| 16 | 
            -
              isBreakAll = false,
         | 
| 17 | 
            -
              limit = 0
         | 
| 18 | 
            -
            }: RenderCircleTextParams): d3.Selection<SVGTSpanElement, Line, SVGTextElement, any> | undefined {
         | 
| 19 | 
            -
              if (selection == null || text == null) {
         | 
| 20 | 
            -
                console.error("selection or text is not defined")
         | 
| 21 | 
            -
                return
         | 
| 22 | 
            -
              }
         | 
| 23 | 
            -
              if (radius == null) {
         | 
| 24 | 
            -
                const getBox = selection.node().getBBox()
         | 
| 25 | 
            -
                radius = getBox.width / 2
         | 
| 26 | 
            -
              }
         | 
| 27 | 
            -
             | 
| 28 | 
            -
              function getWords (text: string) {
         | 
| 29 | 
            -
                let words
         | 
| 30 | 
            -
                if (isBreakAll) {
         | 
| 31 | 
            -
                  words = text.split('')
         | 
| 32 | 
            -
                } else {
         | 
| 33 | 
            -
                  words = text.split(/\s+/g) // To hyphenate: /\s+|(?<=-)/
         | 
| 34 | 
            -
                }
         | 
| 35 | 
            -
                if (!words[words.length - 1]) words.pop()
         | 
| 36 | 
            -
                if (!words[0]) words.shift()
         | 
| 37 | 
            -
                return words
         | 
| 38 | 
            -
              }
         | 
| 39 | 
            -
             | 
| 40 | 
            -
              // 省略文章字數
         | 
| 41 | 
            -
              function ellipisText (text:string, limit:number) {
         | 
| 42 | 
            -
                if (text && limit) {
         | 
| 43 | 
            -
                  if (text.length > limit) {
         | 
| 44 | 
            -
                    text = text.substring(0, limit) + "..."; // 超過字數以"..."取代
         | 
| 45 | 
            -
                  }
         | 
| 46 | 
            -
                }
         | 
| 47 | 
            -
                return text;
         | 
| 48 | 
            -
              }
         | 
| 49 | 
            -
             | 
| 50 | 
            -
              function measureWidth (text: string) {
         | 
| 51 | 
            -
                const context = document.createElement("canvas").getContext("2d")
         | 
| 52 | 
            -
                // return text => context.measureText(text).width
         | 
| 53 | 
            -
                return context?.measureText(text)?.width ?? 0
         | 
| 54 | 
            -
              }
         | 
| 55 | 
            -
             | 
| 56 | 
            -
              function getTargetWidth (text: string) {
         | 
| 57 | 
            -
                const m = measureWidth(text.trim())
         | 
| 58 | 
            -
                const result = Math.sqrt(m * lineHeight)
         | 
| 59 | 
            -
                return result
         | 
| 60 | 
            -
                // return(
         | 
| 61 | 
            -
                  // Math.sqrt(measureWidth(text.trim()) * lineHeight)
         | 
| 62 | 
            -
                // )
         | 
| 63 | 
            -
              }
         | 
| 64 | 
            -
             | 
| 65 | 
            -
              function getLines (words: string[], targetWidth: number) {
         | 
| 66 | 
            -
                let line: Line = { width: 0, text: '' }
         | 
| 67 | 
            -
                let lineWidth0 = Infinity
         | 
| 68 | 
            -
                const lines: Array<Line> = []
         | 
| 69 | 
            -
                let space = " "
         | 
| 70 | 
            -
                if (isBreakAll) {
         | 
| 71 | 
            -
                  space = ""
         | 
| 72 | 
            -
                }
         | 
| 73 | 
            -
                for (let i = 0, n = words.length; i < n; ++i) {
         | 
| 74 | 
            -
                  const lineText1 = (line.text ? line.text + space : '') + words[i]
         | 
| 75 | 
            -
                  const lineWidth1 = measureWidth(lineText1)
         | 
| 76 | 
            -
                  if ((lineWidth0 + lineWidth1) / 2 < targetWidth) {
         | 
| 77 | 
            -
                    line.width = lineWidth0 = lineWidth1
         | 
| 78 | 
            -
                    line.text = lineText1
         | 
| 79 | 
            -
                  } else {
         | 
| 80 | 
            -
                    lineWidth0 = measureWidth(words[i])
         | 
| 81 | 
            -
                    line = {width: lineWidth0, text: words[i]}
         | 
| 82 | 
            -
                    lines.push(line)
         | 
| 83 | 
            -
                  }
         | 
| 84 | 
            -
                }
         | 
| 85 | 
            -
                return lines
         | 
| 86 | 
            -
              }
         | 
| 87 | 
            -
             | 
| 88 | 
            -
              function getTextRadius (lines: Array<Line>) {
         | 
| 89 | 
            -
                let radius = 0
         | 
| 90 | 
            -
                for (let i = 0, n = lines.length; i < n; ++i) {
         | 
| 91 | 
            -
                  const dy: number = (Math.abs(i - n / 2 + 0.5) + 0.5) * lineHeight
         | 
| 92 | 
            -
                  const dx: number = lines[i].width / 2
         | 
| 93 | 
            -
                  radius = Math.max(radius, Math.sqrt(dx ** 2 + dy ** 2))
         | 
| 94 | 
            -
                }
         | 
| 95 | 
            -
                return radius
         | 
| 96 | 
            -
              }
         | 
| 97 | 
            -
             | 
| 98 | 
            -
              function draw (selection: d3.Selection<any, any, any, any>, text: string) {
         | 
| 99 | 
            -
                if(limit > 0) text = ellipisText(text,limit)
         | 
| 100 | 
            -
                const words = getWords(text)
         | 
| 101 | 
            -
                const targetWidth = getTargetWidth(text)
         | 
| 102 | 
            -
                const lines = getLines(words, targetWidth)
         | 
| 103 | 
            -
                const textRadius = getTextRadius(lines)
         | 
| 104 | 
            -
             | 
| 105 | 
            -
                let t = selection.select<SVGTextElement>("text")
         | 
| 106 | 
            -
                if (!t.size()) {
         | 
| 107 | 
            -
                  t = selection.append("text")
         | 
| 108 | 
            -
                }
         | 
| 109 | 
            -
                t.attr("transform", `translate(${0},${0}) scale(${radius / textRadius})`)
         | 
| 110 | 
            -
                const tspanUpdate = t.selectAll<SVGTSpanElement, Line>("tspan")
         | 
| 111 | 
            -
                  .data(lines)
         | 
| 112 | 
            -
                const tspanEnter = tspanUpdate.enter()
         | 
| 113 | 
            -
                  .append<SVGTSpanElement>("tspan")
         | 
| 114 | 
            -
                  .attr("x", 0)
         | 
| 115 | 
            -
                  .merge(tspanUpdate as d3.Selection<SVGTSpanElement, Line, SVGTextElement, undefined>)
         | 
| 116 | 
            -
                  .attr("y", (d: Line, i: number) => (i - lines.length / 2 + 0.8) * lineHeight)
         | 
| 117 | 
            -
                  .text((d: Line) => d.text)
         | 
| 118 | 
            -
                tspanUpdate.exit().remove()
         | 
| 119 | 
            -
             | 
| 120 | 
            -
                // return selection.node()
         | 
| 121 | 
            -
                return tspanUpdate.merge(tspanEnter)
         | 
| 122 | 
            -
              }
         | 
| 123 | 
            -
             | 
| 124 | 
            -
              return draw(selection, text)
         | 
| 1 | 
            +
             | 
| 2 | 
            +
            type RenderCircleTextParams = {
         | 
| 3 | 
            +
              text: string,
         | 
| 4 | 
            +
              radius: number,
         | 
| 5 | 
            +
              lineHeight: number,
         | 
| 6 | 
            +
              isBreakAll: boolean,
         | 
| 7 | 
            +
              limit?:number
         | 
| 8 | 
            +
            }
         | 
| 9 | 
            +
             | 
| 10 | 
            +
            type Line = { width: number; text: string }
         | 
| 11 | 
            +
             | 
| 12 | 
            +
            export function renderCircleText (selection: d3.Selection<any, any, any, any>, {
         | 
| 13 | 
            +
              text,
         | 
| 14 | 
            +
              radius,
         | 
| 15 | 
            +
              lineHeight,
         | 
| 16 | 
            +
              isBreakAll = false,
         | 
| 17 | 
            +
              limit = 0
         | 
| 18 | 
            +
            }: RenderCircleTextParams): d3.Selection<SVGTSpanElement, Line, SVGTextElement, any> | undefined {
         | 
| 19 | 
            +
              if (selection == null || text == null) {
         | 
| 20 | 
            +
                console.error("selection or text is not defined")
         | 
| 21 | 
            +
                return
         | 
| 22 | 
            +
              }
         | 
| 23 | 
            +
              if (radius == null) {
         | 
| 24 | 
            +
                const getBox = selection.node().getBBox()
         | 
| 25 | 
            +
                radius = getBox.width / 2
         | 
| 26 | 
            +
              }
         | 
| 27 | 
            +
             | 
| 28 | 
            +
              function getWords (text: string) {
         | 
| 29 | 
            +
                let words
         | 
| 30 | 
            +
                if (isBreakAll) {
         | 
| 31 | 
            +
                  words = text.split('')
         | 
| 32 | 
            +
                } else {
         | 
| 33 | 
            +
                  words = text.split(/\s+/g) // To hyphenate: /\s+|(?<=-)/
         | 
| 34 | 
            +
                }
         | 
| 35 | 
            +
                if (!words[words.length - 1]) words.pop()
         | 
| 36 | 
            +
                if (!words[0]) words.shift()
         | 
| 37 | 
            +
                return words
         | 
| 38 | 
            +
              }
         | 
| 39 | 
            +
             | 
| 40 | 
            +
              // 省略文章字數
         | 
| 41 | 
            +
              function ellipisText (text:string, limit:number) {
         | 
| 42 | 
            +
                if (text && limit) {
         | 
| 43 | 
            +
                  if (text.length > limit) {
         | 
| 44 | 
            +
                    text = text.substring(0, limit) + "..."; // 超過字數以"..."取代
         | 
| 45 | 
            +
                  }
         | 
| 46 | 
            +
                }
         | 
| 47 | 
            +
                return text;
         | 
| 48 | 
            +
              }
         | 
| 49 | 
            +
             | 
| 50 | 
            +
              function measureWidth (text: string) {
         | 
| 51 | 
            +
                const context = document.createElement("canvas").getContext("2d")
         | 
| 52 | 
            +
                // return text => context.measureText(text).width
         | 
| 53 | 
            +
                return context?.measureText(text)?.width ?? 0
         | 
| 54 | 
            +
              }
         | 
| 55 | 
            +
             | 
| 56 | 
            +
              function getTargetWidth (text: string) {
         | 
| 57 | 
            +
                const m = measureWidth(text.trim())
         | 
| 58 | 
            +
                const result = Math.sqrt(m * lineHeight)
         | 
| 59 | 
            +
                return result
         | 
| 60 | 
            +
                // return(
         | 
| 61 | 
            +
                  // Math.sqrt(measureWidth(text.trim()) * lineHeight)
         | 
| 62 | 
            +
                // )
         | 
| 63 | 
            +
              }
         | 
| 64 | 
            +
             | 
| 65 | 
            +
              function getLines (words: string[], targetWidth: number) {
         | 
| 66 | 
            +
                let line: Line = { width: 0, text: '' }
         | 
| 67 | 
            +
                let lineWidth0 = Infinity
         | 
| 68 | 
            +
                const lines: Array<Line> = []
         | 
| 69 | 
            +
                let space = " "
         | 
| 70 | 
            +
                if (isBreakAll) {
         | 
| 71 | 
            +
                  space = ""
         | 
| 72 | 
            +
                }
         | 
| 73 | 
            +
                for (let i = 0, n = words.length; i < n; ++i) {
         | 
| 74 | 
            +
                  const lineText1 = (line.text ? line.text + space : '') + words[i]
         | 
| 75 | 
            +
                  const lineWidth1 = measureWidth(lineText1)
         | 
| 76 | 
            +
                  if ((lineWidth0 + lineWidth1) / 2 < targetWidth) {
         | 
| 77 | 
            +
                    line.width = lineWidth0 = lineWidth1
         | 
| 78 | 
            +
                    line.text = lineText1
         | 
| 79 | 
            +
                  } else {
         | 
| 80 | 
            +
                    lineWidth0 = measureWidth(words[i])
         | 
| 81 | 
            +
                    line = {width: lineWidth0, text: words[i]}
         | 
| 82 | 
            +
                    lines.push(line)
         | 
| 83 | 
            +
                  }
         | 
| 84 | 
            +
                }
         | 
| 85 | 
            +
                return lines
         | 
| 86 | 
            +
              }
         | 
| 87 | 
            +
             | 
| 88 | 
            +
              function getTextRadius (lines: Array<Line>) {
         | 
| 89 | 
            +
                let radius = 0
         | 
| 90 | 
            +
                for (let i = 0, n = lines.length; i < n; ++i) {
         | 
| 91 | 
            +
                  const dy: number = (Math.abs(i - n / 2 + 0.5) + 0.5) * lineHeight
         | 
| 92 | 
            +
                  const dx: number = lines[i].width / 2
         | 
| 93 | 
            +
                  radius = Math.max(radius, Math.sqrt(dx ** 2 + dy ** 2))
         | 
| 94 | 
            +
                }
         | 
| 95 | 
            +
                return radius
         | 
| 96 | 
            +
              }
         | 
| 97 | 
            +
             | 
| 98 | 
            +
              function draw (selection: d3.Selection<any, any, any, any>, text: string) {
         | 
| 99 | 
            +
                if(limit > 0) text = ellipisText(text,limit)
         | 
| 100 | 
            +
                const words = getWords(text)
         | 
| 101 | 
            +
                const targetWidth = getTargetWidth(text)
         | 
| 102 | 
            +
                const lines = getLines(words, targetWidth)
         | 
| 103 | 
            +
                const textRadius = getTextRadius(lines)
         | 
| 104 | 
            +
             | 
| 105 | 
            +
                let t = selection.select<SVGTextElement>("text")
         | 
| 106 | 
            +
                if (!t.size()) {
         | 
| 107 | 
            +
                  t = selection.append("text")
         | 
| 108 | 
            +
                }
         | 
| 109 | 
            +
                t.attr("transform", `translate(${0},${0}) scale(${radius / textRadius})`)
         | 
| 110 | 
            +
                const tspanUpdate = t.selectAll<SVGTSpanElement, Line>("tspan")
         | 
| 111 | 
            +
                  .data(lines)
         | 
| 112 | 
            +
                const tspanEnter = tspanUpdate.enter()
         | 
| 113 | 
            +
                  .append<SVGTSpanElement>("tspan")
         | 
| 114 | 
            +
                  .attr("x", 0)
         | 
| 115 | 
            +
                  .merge(tspanUpdate as d3.Selection<SVGTSpanElement, Line, SVGTextElement, undefined>)
         | 
| 116 | 
            +
                  .attr("y", (d: Line, i: number) => (i - lines.length / 2 + 0.8) * lineHeight)
         | 
| 117 | 
            +
                  .text((d: Line) => d.text)
         | 
| 118 | 
            +
                tspanUpdate.exit().remove()
         | 
| 119 | 
            +
             | 
| 120 | 
            +
                // return selection.node()
         | 
| 121 | 
            +
                return tspanUpdate.merge(tspanEnter)
         | 
| 122 | 
            +
              }
         | 
| 123 | 
            +
             | 
| 124 | 
            +
              return draw(selection, text)
         | 
| 125 125 | 
             
            }
         | 
    
        package/src/utils/d3Utils.ts
    CHANGED
    
    | @@ -1,73 +1,73 @@ | |
| 1 | 
            -
            import * as d3 from 'd3'
         | 
| 2 | 
            -
             | 
| 3 | 
            -
            export function getSvgGElementSize (selection: d3.Selection<SVGGElement, any, any, any>): DOMRect {
         | 
| 4 | 
            -
              try {
         | 
| 5 | 
            -
                return selection.node()!.getBBox()
         | 
| 6 | 
            -
              } catch (e: any) {
         | 
| 7 | 
            -
                throw new Error(e)
         | 
| 8 | 
            -
              }
         | 
| 9 | 
            -
            }
         | 
| 10 | 
            -
             | 
| 11 | 
            -
            // 使用字串加入svg
         | 
| 12 | 
            -
            export function appendSvg (selection: d3.Selection<any, any, any, any>, svgString: string): void {
         | 
| 13 | 
            -
              function parseSvg (svgString: string) {
         | 
| 14 | 
            -
                const div = document.createElementNS('http://www.w3.org/1999/xhtml', 'div');
         | 
| 15 | 
            -
                div.innerHTML= '<svg xmlns="http://www.w3.org/2000/svg">'+ svgString +'</svg>';
         | 
| 16 | 
            -
                const frag = document.createDocumentFragment()
         | 
| 17 | 
            -
                while (frag && div?.firstChild?.firstChild)
         | 
| 18 | 
            -
                    frag.appendChild(div.firstChild.firstChild);
         | 
| 19 | 
            -
                return frag;
         | 
| 20 | 
            -
              }
         | 
| 21 | 
            -
              // 刪除現有子節點
         | 
| 22 | 
            -
              const node = selection.node()
         | 
| 23 | 
            -
              while(node.hasChildNodes())
         | 
| 24 | 
            -
              {
         | 
| 25 | 
            -
                node.removeChild(node.firstChild);
         | 
| 26 | 
            -
              }
         | 
| 27 | 
            -
              // 加入dom
         | 
| 28 | 
            -
              selection.node().appendChild(parseSvg(svgString))
         | 
| 29 | 
            -
            }
         | 
| 30 | 
            -
             | 
| 31 | 
            -
            export function getD3TransitionEase (easeName: string) {
         | 
| 32 | 
            -
              if (easeName.substring(0, 4) !== 'ease') {
         | 
| 33 | 
            -
                return d3.easeCubic
         | 
| 34 | 
            -
              }
         | 
| 35 | 
            -
              return (d3 as any)[easeName] ?? d3.easeCubic
         | 
| 36 | 
            -
            }
         | 
| 37 | 
            -
             | 
| 38 | 
            -
            export function makeD3Arc ({ axisWidth, innerRadius, outerRadius, padAngle, cornerRadius }: {
         | 
| 39 | 
            -
              axisWidth: number
         | 
| 40 | 
            -
              innerRadius: number
         | 
| 41 | 
            -
              outerRadius: number
         | 
| 42 | 
            -
              padAngle: number
         | 
| 43 | 
            -
              cornerRadius: number
         | 
| 44 | 
            -
            }): d3.Arc<any, d3.DefaultArcObject> {
         | 
| 45 | 
            -
              const arcScale = d3.scaleLinear()
         | 
| 46 | 
            -
                .domain([0, 1])
         | 
| 47 | 
            -
                .range([0, axisWidth / 2])
         | 
| 48 | 
            -
              
         | 
| 49 | 
            -
              const _outerRadius = arcScale(outerRadius)!
         | 
| 50 | 
            -
             | 
| 51 | 
            -
              return d3.arc()
         | 
| 52 | 
            -
                .innerRadius(arcScale(innerRadius)!)
         | 
| 53 | 
            -
                .outerRadius(_outerRadius)
         | 
| 54 | 
            -
                .padAngle(padAngle)
         | 
| 55 | 
            -
                .padRadius(_outerRadius)
         | 
| 56 | 
            -
                .cornerRadius(cornerRadius)
         | 
| 57 | 
            -
            }
         | 
| 58 | 
            -
             | 
| 59 | 
            -
            export const parseTickFormatValue = (value: any, tickFormat: string | ((text: d3.NumberValue) => string)) => {
         | 
| 60 | 
            -
              if (tickFormat! instanceof Function == true) {
         | 
| 61 | 
            -
                return (tickFormat as ((text: d3.NumberValue) => string))(value)
         | 
| 62 | 
            -
              }
         | 
| 63 | 
            -
              return d3.format(tickFormat as string)!(value)
         | 
| 64 | 
            -
            }
         | 
| 65 | 
            -
             | 
| 66 | 
            -
            export const parseDateTickFormatValue = (value: any, tickFormat: string | ((text: d3.NumberValue) => string)) => {
         | 
| 67 | 
            -
              if (tickFormat! instanceof Function == true) {
         | 
| 68 | 
            -
                return (tickFormat as ((text: d3.NumberValue) => string))(value)
         | 
| 69 | 
            -
              }
         | 
| 70 | 
            -
              return d3.timeFormat(tickFormat as string)!(value)
         | 
| 71 | 
            -
            }
         | 
| 72 | 
            -
             | 
| 73 | 
            -
             | 
| 1 | 
            +
            import * as d3 from 'd3'
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            export function getSvgGElementSize (selection: d3.Selection<SVGGElement, any, any, any>): DOMRect {
         | 
| 4 | 
            +
              try {
         | 
| 5 | 
            +
                return selection.node()!.getBBox()
         | 
| 6 | 
            +
              } catch (e: any) {
         | 
| 7 | 
            +
                throw new Error(e)
         | 
| 8 | 
            +
              }
         | 
| 9 | 
            +
            }
         | 
| 10 | 
            +
             | 
| 11 | 
            +
            // 使用字串加入svg
         | 
| 12 | 
            +
            export function appendSvg (selection: d3.Selection<any, any, any, any>, svgString: string): void {
         | 
| 13 | 
            +
              function parseSvg (svgString: string) {
         | 
| 14 | 
            +
                const div = document.createElementNS('http://www.w3.org/1999/xhtml', 'div');
         | 
| 15 | 
            +
                div.innerHTML= '<svg xmlns="http://www.w3.org/2000/svg">'+ svgString +'</svg>';
         | 
| 16 | 
            +
                const frag = document.createDocumentFragment()
         | 
| 17 | 
            +
                while (frag && div?.firstChild?.firstChild)
         | 
| 18 | 
            +
                    frag.appendChild(div.firstChild.firstChild);
         | 
| 19 | 
            +
                return frag;
         | 
| 20 | 
            +
              }
         | 
| 21 | 
            +
              // 刪除現有子節點
         | 
| 22 | 
            +
              const node = selection.node()
         | 
| 23 | 
            +
              while(node.hasChildNodes())
         | 
| 24 | 
            +
              {
         | 
| 25 | 
            +
                node.removeChild(node.firstChild);
         | 
| 26 | 
            +
              }
         | 
| 27 | 
            +
              // 加入dom
         | 
| 28 | 
            +
              selection.node().appendChild(parseSvg(svgString))
         | 
| 29 | 
            +
            }
         | 
| 30 | 
            +
             | 
| 31 | 
            +
            export function getD3TransitionEase (easeName: string) {
         | 
| 32 | 
            +
              if (easeName.substring(0, 4) !== 'ease') {
         | 
| 33 | 
            +
                return d3.easeCubic
         | 
| 34 | 
            +
              }
         | 
| 35 | 
            +
              return (d3 as any)[easeName] ?? d3.easeCubic
         | 
| 36 | 
            +
            }
         | 
| 37 | 
            +
             | 
| 38 | 
            +
            export function makeD3Arc ({ axisWidth, innerRadius, outerRadius, padAngle, cornerRadius }: {
         | 
| 39 | 
            +
              axisWidth: number
         | 
| 40 | 
            +
              innerRadius: number
         | 
| 41 | 
            +
              outerRadius: number
         | 
| 42 | 
            +
              padAngle: number
         | 
| 43 | 
            +
              cornerRadius: number
         | 
| 44 | 
            +
            }): d3.Arc<any, d3.DefaultArcObject> {
         | 
| 45 | 
            +
              const arcScale = d3.scaleLinear()
         | 
| 46 | 
            +
                .domain([0, 1])
         | 
| 47 | 
            +
                .range([0, axisWidth / 2])
         | 
| 48 | 
            +
              
         | 
| 49 | 
            +
              const _outerRadius = arcScale(outerRadius)!
         | 
| 50 | 
            +
             | 
| 51 | 
            +
              return d3.arc()
         | 
| 52 | 
            +
                .innerRadius(arcScale(innerRadius)!)
         | 
| 53 | 
            +
                .outerRadius(_outerRadius)
         | 
| 54 | 
            +
                .padAngle(padAngle)
         | 
| 55 | 
            +
                .padRadius(_outerRadius)
         | 
| 56 | 
            +
                .cornerRadius(cornerRadius)
         | 
| 57 | 
            +
            }
         | 
| 58 | 
            +
             | 
| 59 | 
            +
            export const parseTickFormatValue = (value: any, tickFormat: string | ((text: d3.NumberValue) => string)) => {
         | 
| 60 | 
            +
              if (tickFormat! instanceof Function == true) {
         | 
| 61 | 
            +
                return (tickFormat as ((text: d3.NumberValue) => string))(value)
         | 
| 62 | 
            +
              }
         | 
| 63 | 
            +
              return d3.format(tickFormat as string)!(value)
         | 
| 64 | 
            +
            }
         | 
| 65 | 
            +
             | 
| 66 | 
            +
            export const parseDateTickFormatValue = (value: any, tickFormat: string | ((text: d3.NumberValue) => string)) => {
         | 
| 67 | 
            +
              if (tickFormat! instanceof Function == true) {
         | 
| 68 | 
            +
                return (tickFormat as ((text: d3.NumberValue) => string))(value)
         | 
| 69 | 
            +
              }
         | 
| 70 | 
            +
              return d3.timeFormat(tickFormat as string)!(value)
         | 
| 71 | 
            +
            }
         | 
| 72 | 
            +
             | 
| 73 | 
            +
             | 
    
        package/src/utils/observables.ts
    CHANGED
    
    | @@ -1,14 +1,14 @@ | |
| 1 | 
            -
            import * as d3 from 'd3'
         | 
| 2 | 
            -
            import { Observable, merge, distinctUntilChanged, fromEvent } from 'rxjs'
         | 
| 3 | 
            -
             | 
| 4 | 
            -
            export function d3EventObservable(selection: d3.Selection<any, any, any, any>, event: any) {
         | 
| 5 | 
            -
              // Start with an observable that will never emit
         | 
| 6 | 
            -
              let obs = new Observable(() => {});
         | 
| 7 | 
            -
              selection.each(function () {
         | 
| 8 | 
            -
                  // Create observables from each of the elements
         | 
| 9 | 
            -
                  const events = fromEvent(this as any, event);
         | 
| 10 | 
            -
                  // Merge the observables into one
         | 
| 11 | 
            -
                  obs = merge(obs, events);
         | 
| 12 | 
            -
              });
         | 
| 13 | 
            -
              return obs;
         | 
| 14 | 
            -
            }
         | 
| 1 | 
            +
            import * as d3 from 'd3'
         | 
| 2 | 
            +
            import { Observable, merge, distinctUntilChanged, fromEvent } from 'rxjs'
         | 
| 3 | 
            +
             | 
| 4 | 
            +
            export function d3EventObservable(selection: d3.Selection<any, any, any, any>, event: any) {
         | 
| 5 | 
            +
              // Start with an observable that will never emit
         | 
| 6 | 
            +
              let obs = new Observable(() => {});
         | 
| 7 | 
            +
              selection.each(function () {
         | 
| 8 | 
            +
                  // Create observables from each of the elements
         | 
| 9 | 
            +
                  const events = fromEvent(this as any, event);
         | 
| 10 | 
            +
                  // Merge the observables into one
         | 
| 11 | 
            +
                  obs = merge(obs, events);
         | 
| 12 | 
            +
              });
         | 
| 13 | 
            +
              return obs;
         | 
| 14 | 
            +
            }
         | 
| @@ -1,100 +1,100 @@ | |
| 1 | 
            -
            import type {
         | 
| 2 | 
            -
              AxisPosition,
         | 
| 3 | 
            -
              ColorType,
         | 
| 4 | 
            -
              ChartParams,
         | 
| 5 | 
            -
              ComputedDatumBase,
         | 
| 6 | 
            -
              ComputedDatumSeriesValue,
         | 
| 7 | 
            -
              ComputedDatumCategoryValue } from '@orbcharts/core'
         | 
| 8 | 
            -
            import { getMinAndMax } from './commonUtils'
         | 
| 9 | 
            -
             | 
| 10 | 
            -
            // 取得最小及最大值 - datum格式陣列資料
         | 
| 11 | 
            -
            export function getMinAndMaxValue (data: ComputedDatumBase[]): [number, number] {
         | 
| 12 | 
            -
              const arr = data
         | 
| 13 | 
            -
                .filter(d => d.value != null && d.visible != false)
         | 
| 14 | 
            -
                .map(d => d.value as number)
         | 
| 15 | 
            -
              return getMinAndMax(arr)
         | 
| 16 | 
            -
            }
         | 
| 17 | 
            -
             | 
| 18 | 
            -
            // 取得colorType顏色
         | 
| 19 | 
            -
            export function getColor (colorType: ColorType, fullChartParams: ChartParams) {
         | 
| 20 | 
            -
              const colors = fullChartParams.colors[fullChartParams.colorScheme]
         | 
| 21 | 
            -
              // 對應series資料中第1個顏色
         | 
| 22 | 
            -
              if (colorType === 'series') {
         | 
| 23 | 
            -
                return colors.series[0]
         | 
| 24 | 
            -
              }
         | 
| 25 | 
            -
              // 對應colorType設定的顏色
         | 
| 26 | 
            -
              // return colors[colorType] != null
         | 
| 27 | 
            -
              //   ? colors[colorType]
         | 
| 28 | 
            -
              //   : colors.primary
         | 
| 29 | 
            -
              return colorType == 'none'
         | 
| 30 | 
            -
                ? 'none'
         | 
| 31 | 
            -
                : colors[colorType] != undefined
         | 
| 32 | 
            -
                  ? colors[colorType]
         | 
| 33 | 
            -
                  : colors.primary // 如果比對不到
         | 
| 34 | 
            -
            }
         | 
| 35 | 
            -
             | 
| 36 | 
            -
            export function getSeriesValueColor () {
         | 
| 37 | 
            -
             | 
| 38 | 
            -
            }
         | 
| 39 | 
            -
             | 
| 40 | 
            -
            export function getCategoryValueColor ({ datum, colorType, fullChartParams }: { datum: ComputedDatumCategoryValue, colorType: ColorType, fullChartParams: ChartParams }) {
         | 
| 41 | 
            -
             | 
| 42 | 
            -
            }
         | 
| 43 | 
            -
             | 
| 44 | 
            -
            // // 取得Series顏色 @Q@ 待重構完後刪除
         | 
| 45 | 
            -
            // export function getSeriesColor (seriesIndex: number, fullChartParams: ChartParams) {
         | 
| 46 | 
            -
            //   const colorIndex = seriesIndex < fullChartParams.colors[fullChartParams.colorScheme].series.length
         | 
| 47 | 
            -
            //     ? seriesIndex
         | 
| 48 | 
            -
            //     : seriesIndex % fullChartParams.colors[fullChartParams.colorScheme].series.length
         | 
| 49 | 
            -
            //   return fullChartParams.colors[fullChartParams.colorScheme].series[colorIndex]
         | 
| 50 | 
            -
            // }
         | 
| 51 | 
            -
             | 
| 52 | 
            -
            // 取得Datum顏色 @Q@ 待重構完後刪除
         | 
| 53 | 
            -
            export function getDatumColor ({ datum, colorType, fullChartParams }: { datum: ComputedDatumBase, colorType: ColorType, fullChartParams: ChartParams }) {
         | 
| 54 | 
            -
              // 對應series資料中的顏色
         | 
| 55 | 
            -
              if (colorType === 'series') {
         | 
| 56 | 
            -
                if ((datum as unknown as ComputedDatumSeriesValue).color) {
         | 
| 57 | 
            -
                  return (datum as unknown as ComputedDatumSeriesValue).color
         | 
| 58 | 
            -
                } else {
         | 
| 59 | 
            -
                  // 非series類型的資料則回傳陣列中第1個顏色
         | 
| 60 | 
            -
                  return fullChartParams.colors[fullChartParams.colorScheme].series[0]
         | 
| 61 | 
            -
                }
         | 
| 62 | 
            -
              }
         | 
| 63 | 
            -
              // 對應colorType設定的顏色
         | 
| 64 | 
            -
              return colorType == 'none'
         | 
| 65 | 
            -
                ? 'none' 
         | 
| 66 | 
            -
                : fullChartParams.colors[fullChartParams.colorScheme][colorType] != undefined
         | 
| 67 | 
            -
                  ? fullChartParams.colors[fullChartParams.colorScheme][colorType]
         | 
| 68 | 
            -
                  : fullChartParams.colors[fullChartParams.colorScheme].primary
         | 
| 69 | 
            -
            }
         | 
| 70 | 
            -
             | 
| 71 | 
            -
            export function getClassName (pluginName: string, elementName: string, modifier?: string) {
         | 
| 72 | 
            -
              const modifierText = modifier ? `--${modifier}` : ''
         | 
| 73 | 
            -
              return `orbcharts-${pluginName}__${elementName}${modifierText}`
         | 
| 74 | 
            -
            }
         | 
| 75 | 
            -
             | 
| 76 | 
            -
            export function getUniID (pluginName: string, elementName: string) {
         | 
| 77 | 
            -
              const textLength = 5
         | 
| 78 | 
            -
              // 英文+數字
         | 
| 79 | 
            -
              const randomText: string = Math.random().toString(36).substr(2, textLength)
         | 
| 80 | 
            -
              
         | 
| 81 | 
            -
              return getClassName(pluginName, elementName, randomText)
         | 
| 82 | 
            -
            }
         | 
| 83 | 
            -
             | 
| 84 | 
            -
             | 
| 85 | 
            -
            export function calcAxesSize ({ xAxisPosition, yAxisPosition, width, height }: {
         | 
| 86 | 
            -
              xAxisPosition: AxisPosition
         | 
| 87 | 
            -
              yAxisPosition: AxisPosition
         | 
| 88 | 
            -
              width: number
         | 
| 89 | 
            -
              height: number
         | 
| 90 | 
            -
            }) {
         | 
| 91 | 
            -
              if ((xAxisPosition === 'bottom' || xAxisPosition === 'top') && (yAxisPosition === 'left' || yAxisPosition === 'right')) {
         | 
| 92 | 
            -
                return { width, height }
         | 
| 93 | 
            -
              } else if ((xAxisPosition === 'left' || xAxisPosition === 'right') && (yAxisPosition === 'bottom' || yAxisPosition === 'top')) {
         | 
| 94 | 
            -
                return {
         | 
| 95 | 
            -
                  width: height,
         | 
| 96 | 
            -
                  height: width
         | 
| 97 | 
            -
                }
         | 
| 98 | 
            -
              }
         | 
| 99 | 
            -
            }
         | 
| 100 | 
            -
             | 
| 1 | 
            +
            import type {
         | 
| 2 | 
            +
              AxisPosition,
         | 
| 3 | 
            +
              ColorType,
         | 
| 4 | 
            +
              ChartParams,
         | 
| 5 | 
            +
              ComputedDatumBase,
         | 
| 6 | 
            +
              ComputedDatumSeriesValue,
         | 
| 7 | 
            +
              ComputedDatumCategoryValue } from '@orbcharts/core'
         | 
| 8 | 
            +
            import { getMinAndMax } from './commonUtils'
         | 
| 9 | 
            +
             | 
| 10 | 
            +
            // 取得最小及最大值 - datum格式陣列資料
         | 
| 11 | 
            +
            export function getMinAndMaxValue (data: ComputedDatumBase[]): [number, number] {
         | 
| 12 | 
            +
              const arr = data
         | 
| 13 | 
            +
                .filter(d => d.value != null && d.visible != false)
         | 
| 14 | 
            +
                .map(d => d.value as number)
         | 
| 15 | 
            +
              return getMinAndMax(arr)
         | 
| 16 | 
            +
            }
         | 
| 17 | 
            +
             | 
| 18 | 
            +
            // 取得colorType顏色
         | 
| 19 | 
            +
            export function getColor (colorType: ColorType, fullChartParams: ChartParams) {
         | 
| 20 | 
            +
              const colors = fullChartParams.colors[fullChartParams.colorScheme]
         | 
| 21 | 
            +
              // 對應series資料中第1個顏色
         | 
| 22 | 
            +
              if (colorType === 'series') {
         | 
| 23 | 
            +
                return colors.series[0]
         | 
| 24 | 
            +
              }
         | 
| 25 | 
            +
              // 對應colorType設定的顏色
         | 
| 26 | 
            +
              // return colors[colorType] != null
         | 
| 27 | 
            +
              //   ? colors[colorType]
         | 
| 28 | 
            +
              //   : colors.primary
         | 
| 29 | 
            +
              return colorType == 'none'
         | 
| 30 | 
            +
                ? 'none'
         | 
| 31 | 
            +
                : colors[colorType] != undefined
         | 
| 32 | 
            +
                  ? colors[colorType]
         | 
| 33 | 
            +
                  : colors.primary // 如果比對不到
         | 
| 34 | 
            +
            }
         | 
| 35 | 
            +
             | 
| 36 | 
            +
            export function getSeriesValueColor () {
         | 
| 37 | 
            +
             | 
| 38 | 
            +
            }
         | 
| 39 | 
            +
             | 
| 40 | 
            +
            export function getCategoryValueColor ({ datum, colorType, fullChartParams }: { datum: ComputedDatumCategoryValue, colorType: ColorType, fullChartParams: ChartParams }) {
         | 
| 41 | 
            +
             | 
| 42 | 
            +
            }
         | 
| 43 | 
            +
             | 
| 44 | 
            +
            // // 取得Series顏色 @Q@ 待重構完後刪除
         | 
| 45 | 
            +
            // export function getSeriesColor (seriesIndex: number, fullChartParams: ChartParams) {
         | 
| 46 | 
            +
            //   const colorIndex = seriesIndex < fullChartParams.colors[fullChartParams.colorScheme].series.length
         | 
| 47 | 
            +
            //     ? seriesIndex
         | 
| 48 | 
            +
            //     : seriesIndex % fullChartParams.colors[fullChartParams.colorScheme].series.length
         | 
| 49 | 
            +
            //   return fullChartParams.colors[fullChartParams.colorScheme].series[colorIndex]
         | 
| 50 | 
            +
            // }
         | 
| 51 | 
            +
             | 
| 52 | 
            +
            // 取得Datum顏色 @Q@ 待重構完後刪除
         | 
| 53 | 
            +
            export function getDatumColor ({ datum, colorType, fullChartParams }: { datum: ComputedDatumBase, colorType: ColorType, fullChartParams: ChartParams }) {
         | 
| 54 | 
            +
              // 對應series資料中的顏色
         | 
| 55 | 
            +
              if (colorType === 'series') {
         | 
| 56 | 
            +
                if ((datum as unknown as ComputedDatumSeriesValue).color) {
         | 
| 57 | 
            +
                  return (datum as unknown as ComputedDatumSeriesValue).color
         | 
| 58 | 
            +
                } else {
         | 
| 59 | 
            +
                  // 非series類型的資料則回傳陣列中第1個顏色
         | 
| 60 | 
            +
                  return fullChartParams.colors[fullChartParams.colorScheme].series[0]
         | 
| 61 | 
            +
                }
         | 
| 62 | 
            +
              }
         | 
| 63 | 
            +
              // 對應colorType設定的顏色
         | 
| 64 | 
            +
              return colorType == 'none'
         | 
| 65 | 
            +
                ? 'none' 
         | 
| 66 | 
            +
                : fullChartParams.colors[fullChartParams.colorScheme][colorType] != undefined
         | 
| 67 | 
            +
                  ? fullChartParams.colors[fullChartParams.colorScheme][colorType]
         | 
| 68 | 
            +
                  : fullChartParams.colors[fullChartParams.colorScheme].primary
         | 
| 69 | 
            +
            }
         | 
| 70 | 
            +
             | 
| 71 | 
            +
            export function getClassName (pluginName: string, elementName: string, modifier?: string) {
         | 
| 72 | 
            +
              const modifierText = modifier ? `--${modifier}` : ''
         | 
| 73 | 
            +
              return `orbcharts-${pluginName}__${elementName}${modifierText}`
         | 
| 74 | 
            +
            }
         | 
| 75 | 
            +
             | 
| 76 | 
            +
            export function getUniID (pluginName: string, elementName: string) {
         | 
| 77 | 
            +
              const textLength = 5
         | 
| 78 | 
            +
              // 英文+數字
         | 
| 79 | 
            +
              const randomText: string = Math.random().toString(36).substr(2, textLength)
         | 
| 80 | 
            +
              
         | 
| 81 | 
            +
              return getClassName(pluginName, elementName, randomText)
         | 
| 82 | 
            +
            }
         | 
| 83 | 
            +
             | 
| 84 | 
            +
             | 
| 85 | 
            +
            export function calcAxesSize ({ xAxisPosition, yAxisPosition, width, height }: {
         | 
| 86 | 
            +
              xAxisPosition: AxisPosition
         | 
| 87 | 
            +
              yAxisPosition: AxisPosition
         | 
| 88 | 
            +
              width: number
         | 
| 89 | 
            +
              height: number
         | 
| 90 | 
            +
            }) {
         | 
| 91 | 
            +
              if ((xAxisPosition === 'bottom' || xAxisPosition === 'top') && (yAxisPosition === 'left' || yAxisPosition === 'right')) {
         | 
| 92 | 
            +
                return { width, height }
         | 
| 93 | 
            +
              } else if ((xAxisPosition === 'left' || xAxisPosition === 'right') && (yAxisPosition === 'bottom' || yAxisPosition === 'top')) {
         | 
| 94 | 
            +
                return {
         | 
| 95 | 
            +
                  width: height,
         | 
| 96 | 
            +
                  height: width
         | 
| 97 | 
            +
                }
         | 
| 98 | 
            +
              }
         | 
| 99 | 
            +
            }
         | 
| 100 | 
            +
             |