transformProps.test.ts 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251
  1. /**
  2. * Licensed to the Apache Software Foundation (ASF) under one
  3. * or more contributor license agreements. See the NOTICE file
  4. * distributed with this work for additional information
  5. * regarding copyright ownership. The ASF licenses this file
  6. * to you under the Apache License, Version 2.0 (the
  7. * "License"); you may not use this file except in compliance
  8. * with the License. You may obtain a copy of the License at
  9. *
  10. * http://www.apache.org/licenses/LICENSE-2.0
  11. *
  12. * Unless required by applicable law or agreed to in writing,
  13. * software distributed under the License is distributed on an
  14. * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
  15. * KIND, either express or implied. See the License for the
  16. * specific language governing permissions and limitations
  17. * under the License.
  18. */
  19. import {
  20. ChartProps,
  21. ChartPropsConfig,
  22. getNumberFormatter,
  23. SqlaFormData,
  24. supersetTheme,
  25. } from '@superset-ui/core';
  26. import { EchartsBubbleChartProps } from '../../src/Bubble/types';
  27. import transformProps, { formatTooltip } from '../../src/Bubble/transformProps';
  28. const defaultFormData: SqlaFormData = {
  29. datasource: '1__table',
  30. viz_type: 'echarts_bubble',
  31. entity: 'customer_name',
  32. x: 'count',
  33. y: {
  34. aggregate: 'sum',
  35. column: {
  36. column_name: 'price_each',
  37. },
  38. expressionType: 'simple',
  39. label: 'SUM(price_each)',
  40. },
  41. size: {
  42. aggregate: 'sum',
  43. column: {
  44. column_name: 'sales',
  45. },
  46. expressionType: 'simple',
  47. label: 'SUM(sales)',
  48. },
  49. xAxisBounds: [null, null],
  50. yAxisBounds: [null, null],
  51. };
  52. const queriesData = [
  53. {
  54. data: [
  55. {
  56. customer_name: 'AV Stores, Co.',
  57. count: 10,
  58. 'SUM(price_each)': 20,
  59. 'SUM(sales)': 30,
  60. },
  61. {
  62. customer_name: 'Alpha Cognac',
  63. count: 40,
  64. 'SUM(price_each)': 50,
  65. 'SUM(sales)': 60,
  66. },
  67. {
  68. customer_name: 'Amica Models & Co.',
  69. count: 70,
  70. 'SUM(price_each)': 80,
  71. 'SUM(sales)': 90,
  72. },
  73. ],
  74. },
  75. ];
  76. const chartConfig: ChartPropsConfig = {
  77. formData: defaultFormData,
  78. height: 800,
  79. width: 800,
  80. queriesData,
  81. theme: supersetTheme,
  82. };
  83. describe('Bubble transformProps', () => {
  84. it('Should transform props for viz', () => {
  85. const chartProps = new ChartProps(chartConfig);
  86. expect(transformProps(chartProps as EchartsBubbleChartProps)).toEqual(
  87. expect.objectContaining({
  88. width: 800,
  89. height: 800,
  90. echartOptions: expect.objectContaining({
  91. series: expect.arrayContaining([
  92. expect.objectContaining({
  93. data: expect.arrayContaining([
  94. [10, 20, 30, 'AV Stores, Co.', null],
  95. ]),
  96. }),
  97. expect.objectContaining({
  98. data: expect.arrayContaining([
  99. [40, 50, 60, 'Alpha Cognac', null],
  100. ]),
  101. }),
  102. expect.objectContaining({
  103. data: expect.arrayContaining([
  104. [70, 80, 90, 'Amica Models & Co.', null],
  105. ]),
  106. }),
  107. ]),
  108. }),
  109. }),
  110. );
  111. });
  112. it('Should transform props with undefined control values', () => {
  113. const formData: SqlaFormData = {
  114. ...defaultFormData,
  115. xAxisBounds: undefined,
  116. yAxisBounds: undefined,
  117. };
  118. const chartProps = new ChartProps({
  119. ...chartConfig,
  120. formData,
  121. });
  122. expect(transformProps(chartProps as EchartsBubbleChartProps)).toEqual(
  123. expect.objectContaining({
  124. width: 800,
  125. height: 800,
  126. echartOptions: expect.objectContaining({
  127. series: expect.arrayContaining([
  128. expect.objectContaining({
  129. data: expect.arrayContaining([
  130. [10, 20, 30, 'AV Stores, Co.', null],
  131. ]),
  132. }),
  133. expect.objectContaining({
  134. data: expect.arrayContaining([
  135. [40, 50, 60, 'Alpha Cognac', null],
  136. ]),
  137. }),
  138. expect.objectContaining({
  139. data: expect.arrayContaining([
  140. [70, 80, 90, 'Amica Models & Co.', null],
  141. ]),
  142. }),
  143. ]),
  144. }),
  145. }),
  146. );
  147. });
  148. });
  149. describe('Bubble formatTooltip', () => {
  150. const dollerFormatter = getNumberFormatter('$,.2f');
  151. const percentFormatter = getNumberFormatter(',.1%');
  152. it('Should generate correct bubble label content with dimension', () => {
  153. const params = {
  154. data: [10000, 20000, 3, 'bubble title', 'bubble dimension'],
  155. };
  156. const html = formatTooltip(
  157. params,
  158. 'x-axis-label',
  159. 'y-axis-label',
  160. 'size-label',
  161. dollerFormatter,
  162. dollerFormatter,
  163. percentFormatter,
  164. );
  165. expect(html).toContain('bubble title');
  166. expect(html).toContain('bubble dimension');
  167. expect(html).toContain('x-axis-label');
  168. expect(html).toContain('y-axis-label');
  169. expect(html).toContain('size-label');
  170. expect(html).toContain('$10,000.00');
  171. expect(html).toContain('$20,000.00');
  172. expect(html).toContain('300.0%');
  173. });
  174. it('Should generate correct bubble label content without dimension', () => {
  175. const params = {
  176. data: [10000, 25000, 3, 'bubble title', null],
  177. };
  178. const html = formatTooltip(
  179. params,
  180. 'x-axis-label',
  181. 'y-axis-label',
  182. 'size-label',
  183. dollerFormatter,
  184. dollerFormatter,
  185. percentFormatter,
  186. );
  187. expect(html).toContain('bubble title');
  188. expect(html).not.toContain('bubble dimension');
  189. expect(html).toContain('x-axis-label');
  190. expect(html).toContain('y-axis-label');
  191. expect(html).toContain('size-label');
  192. expect(html).toContain('$10,000.00');
  193. expect(html).toContain('$25,000.00');
  194. expect(html).toContain('300.0%');
  195. });
  196. });
  197. describe('legend sorting', () => {
  198. const createChartProps = (overrides = {}) =>
  199. new ChartProps({
  200. ...chartConfig,
  201. formData: {
  202. ...defaultFormData,
  203. ...overrides,
  204. },
  205. });
  206. it('preserves original data order when no sort specified', () => {
  207. const props = createChartProps({ legendSort: null });
  208. const result = transformProps(props as EchartsBubbleChartProps);
  209. const legendData = (result.echartOptions.legend as any).data;
  210. expect(legendData).toEqual([
  211. 'AV Stores, Co.',
  212. 'Alpha Cognac',
  213. 'Amica Models & Co.',
  214. ]);
  215. });
  216. it('sorts alphabetically ascending when legendSort is "asc"', () => {
  217. const props = createChartProps({ legendSort: 'asc' });
  218. const result = transformProps(props as EchartsBubbleChartProps);
  219. const legendData = (result.echartOptions.legend as any).data;
  220. expect(legendData).toEqual([
  221. 'Alpha Cognac',
  222. 'Amica Models & Co.',
  223. 'AV Stores, Co.',
  224. ]);
  225. });
  226. it('sorts alphabetically descending when legendSort is "desc"', () => {
  227. const props = createChartProps({ legendSort: 'desc' });
  228. const result = transformProps(props as EchartsBubbleChartProps);
  229. const legendData = (result.echartOptions.legend as any).data;
  230. expect(legendData).toEqual([
  231. 'AV Stores, Co.',
  232. 'Amica Models & Co.',
  233. 'Alpha Cognac',
  234. ]);
  235. });
  236. });