parallel.ts 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231
  1. /*
  2. * <<
  3. * Davinci
  4. * ==
  5. * Copyright (C) 2016 - 2017 EDP
  6. * ==
  7. * Licensed under the Apache License, Version 2.0 (the "License");
  8. * you may not use this file except in compliance with the License.
  9. * You may obtain a copy of the License at
  10. *
  11. * http://www.apache.org/licenses/LICENSE-2.0
  12. *
  13. * Unless required by applicable law or agreed to in writing, software
  14. * distributed under the License is distributed on an "AS IS" BASIS,
  15. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  16. * See the License for the specific language governing permissions and
  17. * limitations under the License.
  18. * >>
  19. */
  20. import {
  21. IChartProps
  22. } from '../../components/Chart'
  23. import {
  24. decodeMetricName,
  25. getSizeValue,
  26. getSizeRate,
  27. getTextWidth,
  28. metricAxisLabelFormatter
  29. } from '../../components/util'
  30. import {
  31. getMetricAxisOption,
  32. getLabelOption,
  33. getLegendOption,
  34. getSymbolSize
  35. } from './util'
  36. export default function (chartProps: IChartProps) {
  37. const {
  38. width,
  39. height,
  40. data,
  41. cols,
  42. metrics,
  43. chartStyles,
  44. color,
  45. tip
  46. } = chartProps
  47. const {
  48. legend,
  49. axis,
  50. areaSelect,
  51. spec,
  52. toolbox
  53. } = chartStyles
  54. const {
  55. legendPosition,
  56. fontSize
  57. } = legend
  58. const {
  59. inverse,
  60. showLine,
  61. lineStyle,
  62. lineSize,
  63. lineColor,
  64. showLabel,
  65. labelFontFamily,
  66. labelFontSize,
  67. labelColor,
  68. labelStyle,
  69. labelWeight,
  70. titleFontFamily,
  71. titleFontSize,
  72. titleFontStyle,
  73. titleColor,
  74. nameLocation,
  75. nameRotate,
  76. nameGap,
  77. showTitleAndUnit
  78. } = axis
  79. const {
  80. layout,
  81. smooth
  82. } = spec
  83. const parallelPosition: {
  84. left: number,
  85. top: number,
  86. right: number,
  87. bottom: number
  88. } = { // by default
  89. left: 80,
  90. top: 60,
  91. right: 80,
  92. bottom: 60
  93. }
  94. let series
  95. let parallel = {
  96. layout,
  97. ...parallelPosition,
  98. parallelAxisDefault: {
  99. nameLocation,
  100. nameGap,
  101. nameRotate,
  102. inverse,
  103. nameTextStyle: {
  104. color: titleColor,
  105. fontStyle: titleFontStyle,
  106. fontFamily: titleFontFamily,
  107. fontSize: titleFontSize
  108. },
  109. axisLabel: {
  110. show: showLabel,
  111. color: labelColor,
  112. fontFamily: labelFontFamily,
  113. fontSize: labelFontSize
  114. },
  115. axisLine: {
  116. show: showLine,
  117. lineStyle: {
  118. color: lineColor,
  119. width: lineSize,
  120. type: lineStyle
  121. }
  122. },
  123. areaSelectStyle: areaSelect
  124. }
  125. }
  126. const legendData = []
  127. let axisDimensions = []
  128. if (cols.length) {
  129. axisDimensions = axisDimensions.concat(cols)
  130. }
  131. const dimensionsData = data.map((row) => (
  132. axisDimensions.map(({ name }) => row[name])
  133. ))
  134. if (color.items.length) {
  135. const groupKeys = color.items.map((c) => c.name)
  136. const grouped = data.reduce((obj, row) => {
  137. const grpText = groupKeys.map((key) => row[key]).join(String.fromCharCode(0))
  138. if (!obj[grpText]) {
  139. obj[grpText] = []
  140. }
  141. obj[grpText].push(row)
  142. return obj
  143. }, {})
  144. series = Object.entries(grouped).map(([grpText, rows]) => {
  145. legendData.push(grpText)
  146. const data = rows.map((r) => {
  147. const dimData = axisDimensions.map((name) => r[name])
  148. const metricData = metrics.map((m) => r[`${m.agg}(${decodeMetricName(m.name)})`])
  149. return dimData.concat(metricData)
  150. })
  151. return {
  152. name: grpText,
  153. type: 'parallel',
  154. smooth,
  155. lineStyle,
  156. data
  157. }
  158. })
  159. if (legend.showLegend) {
  160. const legendWidth = 56 + Math.max(...legendData.map((s) => getTextWidth(s, '', `${fontSize}px`)))
  161. switch (legendPosition) {
  162. case 'top':
  163. parallelPosition.top += 32
  164. break
  165. case 'bottom':
  166. parallelPosition.bottom += 32
  167. break
  168. case 'left':
  169. parallelPosition.left += legendWidth
  170. break
  171. case 'right':
  172. parallelPosition.right += legendWidth
  173. }
  174. parallel = {
  175. ...parallel,
  176. ...parallelPosition
  177. }
  178. }
  179. } else {
  180. series = [{
  181. name: '',
  182. type: 'parallel',
  183. smooth: smooth ? 1 : 0,
  184. lineStyle,
  185. data: data.map((row) => (
  186. [
  187. ...axisDimensions.map(({ name }) => row[name]),
  188. ...metrics.map((m) => row[`${m.agg}(${decodeMetricName(m.name)})`])
  189. ]
  190. ))
  191. }]
  192. }
  193. const parallelAxis = [
  194. ...axisDimensions.map(({ name }, idx) => ({
  195. dim: idx,
  196. name: showTitleAndUnit ? name : '',
  197. type: 'category',
  198. data: dimensionsData.map((d) => d[idx]).filter((d, dIdx, arr) => arr.indexOf(d) === dIdx)
  199. })),
  200. ...metrics.map((m, idx) => ({
  201. dim: axisDimensions.length + idx,
  202. name: showTitleAndUnit ? decodeMetricName(m.name) : '',
  203. axisLabel: {
  204. formatter: showLabel ? metricAxisLabelFormatter : ''
  205. }
  206. }))
  207. ]
  208. const legendOption = getLegendOption(legend, legendData)
  209. return {
  210. tooltip: {},
  211. legend: legendOption,
  212. parallel,
  213. parallelAxis,
  214. series
  215. }
  216. }