| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306 |
- /**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
- import { AxisType, ChartProps, supersetTheme } from '@superset-ui/core';
- import {
- LegendOrientation,
- LegendType,
- } from '@superset-ui/plugin-chart-echarts';
- import transformProps from '../../src/Gantt/transformProps';
- import {
- EchartsGanttChartProps,
- EchartsGanttFormData,
- } from '../../src/Gantt/types';
- const formData: EchartsGanttFormData = {
- viz_type: 'gantt_chart',
- datasource: '1__table',
- startTime: 'startTime',
- endTime: 'endTime',
- yAxis: {
- label: 'Y Axis',
- sqlExpression: 'y_axis',
- expressionType: 'SQL',
- },
- tooltipMetrics: ['tooltip_metric'],
- tooltipColumns: ['tooltip_column'],
- series: 'series',
- xAxisTimeFormat: '%H:%M',
- tooltipTimeFormat: '%H:%M',
- tooltipValuesFormat: 'DURATION_SEC',
- colorScheme: 'bnbColors',
- zoomable: true,
- xAxisTitleMargin: undefined,
- yAxisTitleMargin: undefined,
- xAxisTimeBounds: [null, '19:00:00'],
- subcategories: true,
- legendMargin: 0,
- legendOrientation: LegendOrientation.Top,
- legendType: LegendType.Scroll,
- showLegend: true,
- sortSeriesAscending: true,
- legendSort: null,
- };
- const queriesData = [
- {
- data: [
- {
- startTime: Date.UTC(2025, 1, 1, 13, 0, 0),
- endTime: Date.UTC(2025, 1, 1, 14, 0, 0),
- 'Y Axis': 'first',
- tooltip_column: 'tooltip value 1',
- series: 'series value 1',
- },
- {
- startTime: Date.UTC(2025, 1, 1, 18, 0, 0),
- endTime: Date.UTC(2025, 1, 1, 20, 0, 0),
- 'Y Axis': 'second',
- tooltip_column: 'tooltip value 2',
- series: 'series value 2',
- },
- ],
- colnames: ['startTime', 'endTime', 'Y Axis', 'tooltip_column', 'series'],
- },
- ];
- const chartPropsConfig = {
- formData,
- queriesData,
- theme: supersetTheme,
- };
- describe('Gantt transformProps', () => {
- it('should transform chart props', () => {
- const chartProps = new ChartProps(chartPropsConfig);
- const transformedProps = transformProps(
- chartProps as EchartsGanttChartProps,
- );
- expect(transformedProps.echartOptions.series).toHaveLength(4);
- const series = transformedProps.echartOptions.series as any[];
- const series0 = series[0];
- const series1 = series[1];
- // exclude renderItem because it can't be serialized
- expect(typeof series0.renderItem).toBe('function');
- delete series0.renderItem;
- expect(typeof series1.renderItem).toBe('function');
- delete series1.renderItem;
- delete transformedProps.echartOptions.series;
- expect(transformedProps).toEqual(
- expect.objectContaining({
- echartOptions: expect.objectContaining({
- useUTC: true,
- xAxis: {
- name: '',
- nameGap: 0,
- nameLocation: 'middle',
- max: Date.UTC(2025, 1, 1, 19, 0, 0),
- min: undefined,
- type: AxisType.Time,
- axisLabel: {
- hideOverlap: true,
- formatter: expect.anything(),
- },
- },
- yAxis: {
- name: '',
- nameGap: 0,
- nameLocation: 'middle',
- type: AxisType.Value,
- // always 0
- min: 0,
- // equals unique categories count
- max: 2,
- axisLabel: {
- show: false,
- },
- splitLine: {
- show: false,
- },
- },
- legend: expect.objectContaining({
- show: true,
- type: 'scroll',
- selector: ['all', 'inverse'],
- }),
- tooltip: {
- formatter: expect.anything(),
- },
- dataZoom: [
- expect.objectContaining({
- type: 'slider',
- filterMode: 'none',
- }),
- ],
- }),
- }),
- );
- expect(series0).toEqual({
- name: 'series value 1',
- type: 'custom',
- progressive: 0,
- itemStyle: {
- color: expect.anything(),
- },
- data: [
- {
- value: [
- Date.UTC(2025, 1, 1, 13, 0, 0),
- Date.UTC(2025, 1, 1, 14, 0, 0),
- 0,
- 2,
- Date.UTC(2025, 1, 1, 13, 0, 0),
- Date.UTC(2025, 1, 1, 14, 0, 0),
- 'first',
- 'tooltip value 1',
- 'series value 1',
- ],
- },
- ],
- dimensions: [
- 'startTime',
- 'endTime',
- 'index',
- 'seriesCount',
- 'startTime',
- 'endTime',
- 'Y Axis',
- 'tooltip_column',
- 'series',
- ],
- encode: {
- x: [0, 1],
- },
- });
- expect(series1).toEqual({
- name: 'series value 2',
- type: 'custom',
- progressive: 0,
- itemStyle: {
- color: expect.anything(),
- },
- data: [
- {
- value: [
- Date.UTC(2025, 1, 1, 18, 0, 0),
- Date.UTC(2025, 1, 1, 20, 0, 0),
- 1,
- 2,
- Date.UTC(2025, 1, 1, 18, 0, 0),
- Date.UTC(2025, 1, 1, 20, 0, 0),
- 'second',
- 'tooltip value 2',
- 'series value 2',
- ],
- },
- ],
- dimensions: [
- 'startTime',
- 'endTime',
- 'index',
- 'seriesCount',
- 'startTime',
- 'endTime',
- 'Y Axis',
- 'tooltip_column',
- 'series',
- ],
- encode: {
- x: [0, 1],
- },
- });
- expect(series[2]).toEqual({
- // just for markLines
- type: 'line',
- animation: false,
- markLine: {
- data: [{ yAxis: 1 }, { yAxis: 0 }],
- label: {
- show: false,
- },
- silent: true,
- symbol: ['none', 'none'],
- lineStyle: {
- type: 'dashed',
- color: '#dbe0ea',
- },
- },
- });
- expect(series[3]).toEqual({
- type: 'line',
- animation: false,
- markLine: {
- data: [
- { yAxis: 1.5, name: 'first' },
- { yAxis: 0.5, name: 'second' },
- ],
- label: {
- show: true,
- position: 'start',
- formatter: '{b}',
- color: 'rgba(0,0,0,0.88)',
- },
- lineStyle: expect.objectContaining({
- color: '#00000000',
- type: 'solid',
- }),
- silent: true,
- symbol: ['none', 'none'],
- },
- });
- });
- });
- describe('legend sorting', () => {
- const createChartProps = (overrides = {}) =>
- new ChartProps({
- ...chartPropsConfig,
- formData: {
- ...formData,
- ...overrides,
- },
- });
- it('preserves original data order when no sort specified', () => {
- const props = createChartProps({ legendSort: null });
- const result = transformProps(props as EchartsGanttChartProps);
- const legendData = (result.echartOptions.legend as any).data;
- expect(legendData).toEqual(['series value 1', 'series value 2']);
- });
- it('sorts alphabetically ascending when legendSort is "asc"', () => {
- const props = createChartProps({ legendSort: 'asc' });
- const result = transformProps(props as EchartsGanttChartProps);
- const legendData = (result.echartOptions.legend as any).data;
- expect(legendData).toEqual(['series value 1', 'series value 2']);
- });
- it('sorts alphabetically descending when legendSort is "desc"', () => {
- const props = createChartProps({ legendSort: 'desc' });
- const result = transformProps(props as EchartsGanttChartProps);
- const legendData = (result.echartOptions.legend as any).data;
- expect(legendData).toEqual(['series value 2', 'series value 1']);
- });
- });
|