@genspectrum/dashboard-components 0.5.6 → 0.5.7

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@genspectrum/dashboard-components",
3
- "version": "0.5.6",
3
+ "version": "0.5.7",
4
4
  "description": "GenSpectrum web components for building dashboards",
5
5
  "type": "module",
6
6
  "license": "AGPL-3.0-only",
@@ -7,18 +7,24 @@ export type ScalingSelectorProps = {
7
7
  yAxisScaleType: ScaleType;
8
8
  setYAxisScaleType: (scaleType: ScaleType) => void;
9
9
  className?: string;
10
+ enabledTypes?: ScaleType[];
10
11
  };
11
12
 
13
+ const scaleTypeItem: { label: string; value: ScaleType }[] = [
14
+ { label: 'Linear', value: 'linear' },
15
+ { label: 'Logarithmic', value: 'logarithmic' },
16
+ { label: 'Logit', value: 'logit' },
17
+ ];
18
+
12
19
  export const ScalingSelector: FunctionComponent<ScalingSelectorProps> = ({
13
20
  yAxisScaleType,
14
21
  setYAxisScaleType,
15
22
  className,
23
+ enabledTypes,
16
24
  }) => {
17
25
  const items = [
18
26
  { label: 'y axis scaling type', value: 'none', disabled: true },
19
- { label: 'Linear', value: 'linear' },
20
- { label: 'Logarithmic', value: 'logarithmic' },
21
- { label: 'Logit', value: 'logit' },
27
+ ...scaleTypeItem.filter((item) => enabledTypes === undefined || enabledTypes.includes(item.value)),
22
28
  ];
23
29
 
24
30
  return (
@@ -198,7 +198,7 @@ const Toolbar: FunctionComponent<ToolbarProps> = ({
198
198
  <CsvDownloadButton
199
199
  className='mx-1 btn btn-xs'
200
200
  getData={() => getMutationsTableData(filteredData.tableData, proportionInterval)}
201
- filename='substitutionsAndDeletions.csv'
201
+ filename='substitutions_and_deletions.csv'
202
202
  />
203
203
  </>
204
204
  )}
@@ -5,14 +5,16 @@ import { getNumberOfSequencesOverTimeTableData } from './getNumberOfSequencesOve
5
5
  import { type NumberOfSequencesDatasets } from '../../query/queryNumberOfSequencesOverTime';
6
6
  import GsChart from '../components/chart';
7
7
  import { singleGraphColorRGBAById } from '../shared/charts/colors';
8
+ import { getYAxisScale, type ScaleType } from '../shared/charts/getYAxisScale';
8
9
 
9
10
  interface NumberSequencesOverBarChartProps {
10
11
  data: NumberOfSequencesDatasets;
12
+ yAxisScaleType: ScaleType;
11
13
  }
12
14
 
13
15
  Chart.register(...registerables);
14
16
 
15
- export const NumberSequencesOverTimeBarChart = ({ data }: NumberSequencesOverBarChartProps) => {
17
+ export const NumberSequencesOverTimeBarChart = ({ data, yAxisScaleType }: NumberSequencesOverBarChartProps) => {
16
18
  const config: ChartConfiguration = useMemo(
17
19
  () => ({
18
20
  type: 'bar',
@@ -22,6 +24,11 @@ export const NumberSequencesOverTimeBarChart = ({ data }: NumberSequencesOverBar
22
24
  options: {
23
25
  maintainAspectRatio: false,
24
26
  animation: false,
27
+ scales: {
28
+ y: {
29
+ type: getYAxisScale(yAxisScaleType).type,
30
+ },
31
+ },
25
32
  plugins: {
26
33
  legend: {
27
34
  display: false,
@@ -33,7 +40,7 @@ export const NumberSequencesOverTimeBarChart = ({ data }: NumberSequencesOverBar
33
40
  },
34
41
  },
35
42
  }),
36
- [data],
43
+ [data, yAxisScaleType],
37
44
  );
38
45
 
39
46
  return <GsChart configuration={config} />;
@@ -5,14 +5,16 @@ import { getNumberOfSequencesOverTimeTableData } from './getNumberOfSequencesOve
5
5
  import { type NumberOfSequencesDatasets } from '../../query/queryNumberOfSequencesOverTime';
6
6
  import GsChart from '../components/chart';
7
7
  import { singleGraphColorRGBAById } from '../shared/charts/colors';
8
+ import { getYAxisScale, type ScaleType } from '../shared/charts/getYAxisScale';
8
9
 
9
10
  interface NumberSequencesOverBarChartProps {
10
11
  data: NumberOfSequencesDatasets;
12
+ yAxisScaleType: ScaleType;
11
13
  }
12
14
 
13
15
  Chart.register(...registerables);
14
16
 
15
- export const NumberSequencesOverTimeLineChart = ({ data }: NumberSequencesOverBarChartProps) => {
17
+ export const NumberSequencesOverTimeLineChart = ({ data, yAxisScaleType }: NumberSequencesOverBarChartProps) => {
16
18
  const config: ChartConfiguration = useMemo(
17
19
  () => ({
18
20
  type: 'line',
@@ -22,6 +24,11 @@ export const NumberSequencesOverTimeLineChart = ({ data }: NumberSequencesOverBa
22
24
  options: {
23
25
  maintainAspectRatio: false,
24
26
  animation: false,
27
+ scales: {
28
+ y: {
29
+ type: getYAxisScale(yAxisScaleType).type,
30
+ },
31
+ },
25
32
  plugins: {
26
33
  legend: {
27
34
  display: false,
@@ -33,7 +40,7 @@ export const NumberSequencesOverTimeLineChart = ({ data }: NumberSequencesOverBa
33
40
  },
34
41
  },
35
42
  }),
36
- [data],
43
+ [data, yAxisScaleType],
37
44
  );
38
45
 
39
46
  return <GsChart configuration={config} />;
@@ -1,5 +1,6 @@
1
- import { useContext } from 'preact/hooks';
1
+ import { useContext, useState } from 'preact/hooks';
2
2
 
3
+ import { getNumberOfSequencesOverTimeTableData } from './getNumberOfSequencesOverTimeTableData';
3
4
  import { NumberSequencesOverTimeBarChart } from './number-sequences-over-time-bar-chart';
4
5
  import { NumberSequencesOverTimeLineChart } from './number-sequences-over-time-line-chart';
5
6
  import { NumberSequencesOverTimeTable } from './number-sequences-over-time-table';
@@ -9,13 +10,17 @@ import {
9
10
  } from '../../query/queryNumberOfSequencesOverTime';
10
11
  import type { NamedLapisFilter, TemporalGranularity } from '../../types';
11
12
  import { LapisUrlContext } from '../LapisUrlContext';
13
+ import { CsvDownloadButton } from '../components/csv-download-button';
12
14
  import { ErrorBoundary } from '../components/error-boundary';
13
15
  import { ErrorDisplay } from '../components/error-display';
14
16
  import Headline from '../components/headline';
17
+ import Info, { InfoHeadline1, InfoParagraph } from '../components/info';
15
18
  import { LoadingDisplay } from '../components/loading-display';
16
19
  import { NoDataDisplay } from '../components/no-data-display';
17
20
  import { ResizeContainer } from '../components/resize-container';
21
+ import { ScalingSelector } from '../components/scaling-selector';
18
22
  import Tabs from '../components/tabs';
23
+ import type { ScaleType } from '../shared/charts/getYAxisScale';
19
24
  import { useQuery } from '../useQuery';
20
25
 
21
26
  type NumberSequencesOverTimeView = 'bar' | 'line' | 'table';
@@ -86,12 +91,20 @@ interface NumberSequencesOverTimeTabsProps {
86
91
  }
87
92
 
88
93
  const NumberSequencesOverTimeTabs = ({ views, data, granularity, pageSize }: NumberSequencesOverTimeTabsProps) => {
94
+ const [yAxisScaleType, setYAxisScaleType] = useState<ScaleType>('linear');
95
+
89
96
  const getTab = (view: NumberSequencesOverTimeView) => {
90
97
  switch (view) {
91
98
  case 'bar':
92
- return { title: 'Bar', content: <NumberSequencesOverTimeBarChart data={data} /> };
99
+ return {
100
+ title: 'Bar',
101
+ content: <NumberSequencesOverTimeBarChart data={data} yAxisScaleType={yAxisScaleType} />,
102
+ };
93
103
  case 'line':
94
- return { title: 'Line', content: <NumberSequencesOverTimeLineChart data={data} /> };
104
+ return {
105
+ title: 'Line',
106
+ content: <NumberSequencesOverTimeLineChart data={data} yAxisScaleType={yAxisScaleType} />,
107
+ };
95
108
  case 'table':
96
109
  return {
97
110
  title: 'Table',
@@ -102,5 +115,55 @@ const NumberSequencesOverTimeTabs = ({ views, data, granularity, pageSize }: Num
102
115
  }
103
116
  };
104
117
 
105
- return <Tabs tabs={views.map((view) => getTab(view))} />;
118
+ return (
119
+ <Tabs
120
+ tabs={views.map((view) => getTab(view))}
121
+ toolbar={(activeTab) => (
122
+ <Toolbar
123
+ activeTab={activeTab}
124
+ data={data}
125
+ granularity={granularity}
126
+ yAxisScaleType={yAxisScaleType}
127
+ setYAxisScaleType={setYAxisScaleType}
128
+ />
129
+ )}
130
+ />
131
+ );
132
+ };
133
+
134
+ interface ToolbarProps {
135
+ activeTab: string;
136
+ data: NumberOfSequencesDatasets;
137
+ granularity: TemporalGranularity;
138
+ yAxisScaleType: ScaleType;
139
+ setYAxisScaleType: (scaleType: ScaleType) => void;
140
+ }
141
+
142
+ const Toolbar = ({ activeTab, data, granularity, yAxisScaleType, setYAxisScaleType }: ToolbarProps) => {
143
+ return (
144
+ <>
145
+ {activeTab !== 'Table' && (
146
+ <ScalingSelector
147
+ yAxisScaleType={yAxisScaleType}
148
+ setYAxisScaleType={setYAxisScaleType}
149
+ enabledTypes={['linear', 'logarithmic']}
150
+ />
151
+ )}
152
+ <CsvDownloadButton
153
+ className='mx-1 btn btn-xs'
154
+ getData={() => getNumberOfSequencesOverTimeTableData(data, granularity)}
155
+ filename='number_of_sequences_over_time.csv'
156
+ />
157
+ <NumberSequencesOverTimeInfo />
158
+ </>
159
+ );
106
160
  };
161
+
162
+ const NumberSequencesOverTimeInfo = () => (
163
+ <Info height='100px'>
164
+ <InfoHeadline1>Number of sequences over time</InfoHeadline1>
165
+ <InfoParagraph>
166
+ <a href='https://github.com/GenSpectrum/dashboard-components/issues/315'>TODO</a>
167
+ </InfoParagraph>
168
+ </Info>
169
+ );
@@ -235,7 +235,7 @@ const Toolbar: FunctionComponent<ToolbarProps> = ({
235
235
  <CsvDownloadButton
236
236
  className='mx-1 btn btn-xs'
237
237
  getData={() => getPrevalenceOverTimeTableData(data, granularity)}
238
- filename='prevalence-over-time.csv'
238
+ filename='prevalence_over_time.csv'
239
239
  />
240
240
 
241
241
  <PrevalenceOverTimeInfo />
@@ -1,16 +0,0 @@
1
- export type ScaleType = 'linear' | 'logarithmic' | 'logit';
2
-
3
- export function getYAxisScale(scaleType: ScaleType) {
4
- switch (scaleType) {
5
- case 'linear': {
6
- return { beginAtZero: true, type: 'linear' as const };
7
- }
8
- case 'logarithmic': {
9
- return { type: 'logarithmic' as const };
10
- }
11
- case 'logit':
12
- return { type: 'logit' as const };
13
- default:
14
- return { beginAtZero: true, type: 'linear' as const };
15
- }
16
- }