widgetOperating.ts 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332
  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 { compose } from 'redux'
  21. import { ViewModelTypes } from 'containers/View/constants'
  22. import { RequireAtLeastOne } from 'utils/types'
  23. import WidgetAbstract, { WidgetDimensions, IWidgetPool } from '../types'
  24. import { decodeMetricName } from 'containers/Widget/components/util'
  25. import {
  26. IWidgetDimension,
  27. WidgetMode,
  28. IWidgetFilter
  29. } from 'app/containers/Widget/components/Widget'
  30. import { OperateObjectAbstract } from 'utils/abstract/OperateObjectAbstract'
  31. import {
  32. getTypesOfModelByKeyName,
  33. getListsByViewModelTypes
  34. } from 'containers/View/util'
  35. import ChartTypes from 'containers/Widget/config/chart/ChartTypes'
  36. export default class OperatingWidget extends OperateObjectAbstract {
  37. private widgetPool: IWidgetPool
  38. private currentWidgetId: number
  39. private widgetProps: WidgetAbstract = new WidgetAbstract()
  40. public receive(widgetId: number) {
  41. const target = this.getWidgetById(widgetId)
  42. if (target) {
  43. this.currentWidgetId = widgetId
  44. this.main(target)
  45. }
  46. }
  47. private getWidgetPool() {
  48. return this.widgetPool
  49. }
  50. public main(target: WidgetAbstract) {
  51. this.setTargetProps<WidgetAbstract>(this.widgetProps, target)
  52. }
  53. public widgetIntoPool(widgets) {
  54. const widgetPool = widgets.reduce((iteratee, widget) => {
  55. const { id, config } = widget
  56. iteratee[Number(id)] = config // possible performance defects
  57. return iteratee
  58. }, {})
  59. this.widgetPool = widgetPool
  60. }
  61. private getWidgetById(widgetId: number): WidgetAbstract {
  62. return this.widgetPool[widgetId]
  63. }
  64. public getWidgetProps() {
  65. return this.getTarget<WidgetAbstract>(this.widgetProps)
  66. }
  67. public initGroups() {
  68. let widget = this.getWidgetById(this.currentWidgetId)
  69. if (!widget.initGroups) {
  70. const { rows, cols, color, label } = widget
  71. const setDefaultEmptyArray = setDefaultReplaceNull((f) => f, [])
  72. const groups = [
  73. ...compose(mappingName, filterByName, setDefaultEmptyArray)(cols),
  74. ...compose(mappingName, filterByName, setDefaultEmptyArray)(rows),
  75. ...compose(
  76. mappingName,
  77. setDefaultEmptyArray,
  78. getItem,
  79. setDefaultEmptyArray
  80. )(color),
  81. ...compose(
  82. mappingName,
  83. setDefaultEmptyArray,
  84. getItem,
  85. setDefaultEmptyArray
  86. )(label)
  87. ]
  88. widget = {
  89. ...widget,
  90. initGroups: groups
  91. }
  92. return groups
  93. }
  94. return widget.initGroups
  95. }
  96. public initAggregators() {
  97. const widget = this.getWidgetById(this.currentWidgetId)
  98. if (!widget.initAggregators) {
  99. const { metrics, secondaryMetrics, label, size, xAxis, tip } = widget
  100. const setDefaultEmptyArray = setDefaultReplaceNull((f) => f, [])
  101. const aggregators = [
  102. ...compose(mappingAggregators, setDefaultEmptyArray)(metrics),
  103. ...compose(mappingAggregators, setDefaultEmptyArray)(secondaryMetrics),
  104. ...compose(
  105. mappingAggregators,
  106. filterByValue,
  107. setDefaultEmptyArray,
  108. getItem,
  109. setDefaultEmptyArray
  110. )(label),
  111. ...compose(
  112. mappingAggregators,
  113. setDefaultEmptyArray,
  114. getItem,
  115. setDefaultEmptyArray
  116. )(size),
  117. ...compose(
  118. mappingAggregators,
  119. setDefaultEmptyArray,
  120. getItem,
  121. setDefaultEmptyArray
  122. )(xAxis),
  123. ...compose(
  124. mappingAggregators,
  125. setDefaultEmptyArray,
  126. getItem,
  127. setDefaultEmptyArray
  128. )(tip)
  129. ]
  130. widget.initAggregators = aggregators
  131. return aggregators
  132. }
  133. return widget.initAggregators
  134. }
  135. public getMode() {
  136. return this.getTargetPropsByProperty<WidgetAbstract, 'mode'>(
  137. this.widgetProps,
  138. 'mode'
  139. )
  140. }
  141. public isPivot() {
  142. return this.getMode() === 'pivot'
  143. }
  144. public getModel() {
  145. return this.getTargetPropsByProperty<WidgetAbstract, 'model'>(
  146. this.widgetProps,
  147. 'model'
  148. )
  149. }
  150. public isCoustomTable(): boolean {
  151. const selectedChart = this.getSelectedChart()
  152. return selectedChart === ChartTypes.Table
  153. }
  154. public getDimetionAxis() {
  155. return this.getTargetPropsByProperty<WidgetAbstract, 'dimetionAxis'>(
  156. this.widgetProps,
  157. 'dimetionAxis'
  158. )
  159. }
  160. public getSelectedChart() {
  161. return this.getTargetPropsByProperty<WidgetAbstract, 'selectedChart'>(
  162. this.widgetProps,
  163. 'selectedChart'
  164. )
  165. }
  166. public getRowsOrCols(dimension: WidgetDimensions) {
  167. return (
  168. this.getTargetPropsByProperty<WidgetAbstract, WidgetDimensions>(
  169. this.widgetProps,
  170. dimension
  171. ) || []
  172. )
  173. }
  174. public overWriteRowsOrCols(
  175. source: WidgetAbstract,
  176. dimension: WidgetDimensions,
  177. widgetDimension: RequireAtLeastOne<IWidgetDimension, keyof IWidgetDimension>
  178. ): WidgetAbstract {
  179. return {
  180. ...source,
  181. ...{ [dimension]: [widgetDimension] }
  182. }
  183. }
  184. public deleteWithSthRowsOrCols(
  185. source: WidgetAbstract,
  186. dimension: WidgetDimensions,
  187. widgetDimension: RequireAtLeastOne<IWidgetDimension, keyof IWidgetDimension>
  188. ): WidgetAbstract {
  189. const target = this.getTargetPropsByProperty<
  190. WidgetAbstract,
  191. WidgetDimensions
  192. >(source, dimension)
  193. return {
  194. ...source,
  195. ...{
  196. [dimension]: target.filter((dm) => dm.name !== widgetDimension['name'])
  197. }
  198. }
  199. }
  200. public insertSthInCursor(
  201. target: IWidgetDimension[],
  202. widgetDimension: RequireAtLeastOne<
  203. IWidgetDimension,
  204. keyof IWidgetDimension
  205. >,
  206. cursor?: Pick<IWidgetDimension, 'name'>
  207. ) {
  208. return cursor
  209. ? target.reduce((iteratee, t) => {
  210. iteratee = iteratee.concat(
  211. t.name === cursor.name ? [t, widgetDimension] : t
  212. )
  213. return iteratee
  214. }, [])
  215. : target.concat(widgetDimension as IWidgetDimension)
  216. }
  217. public insertWithSthRowsOrCols(
  218. source: WidgetAbstract,
  219. dimension: WidgetDimensions,
  220. widgetDimension: RequireAtLeastOne<
  221. IWidgetDimension,
  222. keyof IWidgetDimension
  223. >,
  224. cursor?: Pick<IWidgetDimension, 'name'>
  225. ): WidgetAbstract {
  226. const target = this.getTargetPropsByProperty<
  227. WidgetAbstract,
  228. WidgetDimensions
  229. >(source, dimension)
  230. const Bridged = this.insertSthInCursor(target, widgetDimension, cursor)
  231. return {
  232. ...source,
  233. ...{ [dimension]: Bridged }
  234. }
  235. }
  236. public initWidgetNativeFilters() {
  237. const filters = this.getTargetPropsByProperty<WidgetAbstract, 'filters'>(
  238. this.widgetProps,
  239. 'filters'
  240. )
  241. return filters && filters.length
  242. ? filters.reduce((iteratee, target: IWidgetFilter) => {
  243. iteratee = iteratee.concat(target.config.sqlModel)
  244. return iteratee
  245. }, [])
  246. : []
  247. }
  248. public getTypesOfModelByKeyName = getTypesOfModelByKeyName
  249. public getListsByViewModelTypes = getListsByViewModelTypes
  250. private jsonParse(widgetConfig: string) {
  251. try {
  252. return JSON.parse(widgetConfig)
  253. } catch (error) {
  254. throw new Error(error)
  255. }
  256. }
  257. private static instance: OperatingWidget
  258. private constructor() {
  259. super()
  260. }
  261. public static getInstance() {
  262. if (!OperatingWidget.instance) {
  263. OperatingWidget.instance = new OperatingWidget()
  264. }
  265. return OperatingWidget.instance
  266. }
  267. }
  268. export function filterByName(target) {
  269. return target.filter((t) => t.name !== '指标名称')
  270. }
  271. function filterByCategory(target) {
  272. return target.filter((t) => t.type === ViewModelTypes.Category)
  273. }
  274. function filterByValue(target) {
  275. return target.filter((t) => t.type === ViewModelTypes.Value)
  276. }
  277. function getItem(target) {
  278. return target.items
  279. }
  280. function mappingName(target) {
  281. return target.map((t) => t.name)
  282. }
  283. function mappingAggregators(target) {
  284. return target.map((t) => ({
  285. column: decodeMetricName(t.name),
  286. func: t.agg
  287. }))
  288. }
  289. export function setDefaultReplaceNull(func, others?): Function {
  290. const defaultValue = Array.prototype.slice.call(arguments, 1)
  291. return function (val?) {
  292. const arg = Array.from(arguments).map((t, i) => {
  293. return t != null ? t : defaultValue[i]
  294. })
  295. return func.apply(null, arg)
  296. }
  297. }
  298. export const operationWidgetProps = OperatingWidget.getInstance()