Skip to content

Commit dbdc04e

Browse files
feat(statistic): SJIP-1379 improve download tsv (Ferlab-Ste-Justine#617)
1 parent 9e8ccd0 commit dbdc04e

File tree

6 files changed

+67
-17
lines changed

6 files changed

+67
-17
lines changed

packages/ui/Release.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
### 10.25.3 2025-06-17
2+
- feat: SJIP-1379 improve statistic download data
3+
14
### 10.25.2 2025-06-16
25
- feat: SJIP-1378 entity statistics download optionnal
36

packages/ui/package-lock.json

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

packages/ui/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@ferlab/ui",
3-
"version": "10.25.2",
3+
"version": "10.25.3",
44
"description": "Core components for scientific research data portals",
55
"publishConfig": {
66
"access": "public"

packages/ui/src/layout/ResizableGridLayout/ResizableGridCard/index.tsx

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ type TResizableGridCard = Omit<TGridCard, 'title' | 'resizable'> & {
3131
height: number;
3232
};
3333
tsvSettings?: {
34-
headers?: string[];
34+
headers?: string[] | string[][];
3535
contentMap?: string[];
3636
data: any[];
3737
};
@@ -156,14 +156,26 @@ const ResizableGridCard = ({
156156
if (!tsvSettings) {
157157
return;
158158
}
159-
tsvSettings.data.forEach((datum) => {
160-
let tsvContent = `${tsvSettings.headers?.join('\t') ?? DEFAULT_TSV_HEADERS.join('\t')}\n`;
159+
tsvSettings.data.forEach((datum, index) => {
160+
let tsvContent = '';
161+
// Manage specific headers for multiple data
162+
if (tsvSettings.headers && typeof tsvSettings.headers[0] === 'string') {
163+
tsvContent = `${tsvSettings.headers?.join('\t')}\n`;
164+
} else if (tsvSettings.headers && Array.isArray(tsvSettings.headers[0])) {
165+
const headerRow = tsvSettings.headers[index] as string[];
166+
tsvContent = `${headerRow.join('\t')}\n`;
167+
} else {
168+
tsvContent = `${DEFAULT_TSV_HEADERS.join('\t')}\n`;
169+
}
170+
161171
const tsvDataMapping = tsvSettings.contentMap ?? DEFAULT_TSV_CONTENT_MAP;
162172

163173
datum.forEach((e: any) => {
164-
tsvDataMapping.forEach((key) => {
165-
if (e[key]) {
174+
tsvDataMapping.forEach((key, index) => {
175+
if (e[key] && index < tsvDataMapping.length - 1) {
166176
tsvContent += `${e[key]}\t`;
177+
} else if (e[key] && index == tsvDataMapping.length - 1) {
178+
tsvContent += `${e[key]}`;
167179
}
168180
});
169181
tsvContent += `\n`;

packages/ui/src/layout/ResizableGridLayout/utils.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,17 @@ export const aggregationToChartData = (buckets: any[] = [], total?: number): any
1414
});
1515
};
1616

17+
export const formatAggregationChartData = (data: any[]): any[] =>
18+
data.map((d) => {
19+
if (d.frequency) {
20+
return {
21+
...d,
22+
frequency: d.frequency.toFixed(2),
23+
};
24+
}
25+
return d;
26+
});
27+
1728
export const treeNodeToChartData = (buckets: any[] = []): any[] =>
1829
buckets.map(({ exactTagCount, key, name }) => ({
1930
id: key,

packages/ui/src/pages/EntityPage/EntityStatistics/index.tsx

Lines changed: 33 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,11 @@ import Empty from '../../../components/Empty';
1212
import ResizableGridLayout, { serialize } from '../../../layout/ResizableGridLayout';
1313
import ResizableGridCard from '../../../layout/ResizableGridLayout/ResizableGridCard';
1414
import { TDownloadDictionary } from '../../../layout/ResizableGridLayout/ResizableGridCard/utils';
15-
import { mondoDefaultGridConfig, observedPhenotypeDefaultGridConfig } from '../../../layout/ResizableGridLayout/utils';
15+
import {
16+
formatAggregationChartData,
17+
mondoDefaultGridConfig,
18+
observedPhenotypeDefaultGridConfig,
19+
} from '../../../layout/ResizableGridLayout/utils';
1620
import { truncateString } from '../../../utils/stringUtils';
1721

1822
import entityTableStyles from '../EntityTable/index.module.css';
@@ -332,7 +336,7 @@ const getStatisticLayouts = ({ dictionary, statistic, withDownload = true }: get
332336
tsvSettings={{
333337
contentMap: ['label', 'value'],
334338
data: [phenotypesData],
335-
headers: ['Value', 'Count'],
339+
headers: ['Phenotype (HPO)', 'Count'],
336340
}}
337341
{...resizableCardSettings}
338342
/>
@@ -430,7 +434,7 @@ const getStatisticLayouts = ({ dictionary, statistic, withDownload = true }: get
430434
tsvSettings={{
431435
contentMap: ['label', 'value'],
432436
data: [mondoData],
433-
headers: ['Value', 'Count'],
437+
headers: ['Diagnosis (MONDO)', 'Count'],
434438
}}
435439
{...resizableCardSettings}
436440
/>
@@ -570,7 +574,17 @@ const getStatisticLayouts = ({ dictionary, statistic, withDownload = true }: get
570574
}
571575
theme="shade"
572576
tsvSettings={{
573-
data: [statistic.demography.sex, statistic.demography.race, statistic.demography.ethnicity],
577+
contentMap: ['label', 'value', 'frequency'],
578+
data: [
579+
formatAggregationChartData(statistic.demography.sex),
580+
formatAggregationChartData(statistic.demography.race),
581+
formatAggregationChartData(statistic.demography.ethnicity),
582+
],
583+
headers: [
584+
['Sex', 'Count', 'Frequency'],
585+
['Race', 'Count', 'Frequency'],
586+
['Ethnicity', 'Count', 'Frequency'],
587+
],
574588
}}
575589
{...resizableCardSettings}
576590
/>
@@ -640,7 +654,9 @@ const getStatisticLayouts = ({ dictionary, statistic, withDownload = true }: get
640654
theme="shade"
641655
titleTruncateThresholdWidth={100}
642656
tsvSettings={{
643-
data: [downSyndromeStatusData],
657+
contentMap: ['label', 'value', 'frequency'],
658+
data: [formatAggregationChartData(downSyndromeStatusData)],
659+
headers: ['Down Syndrome Status', 'Count', 'Frequency'],
644660
}}
645661
{...resizableCardSettings}
646662
/>
@@ -710,7 +726,9 @@ const getStatisticLayouts = ({ dictionary, statistic, withDownload = true }: get
710726
theme="shade"
711727
titleTruncateThresholdWidth={100}
712728
tsvSettings={{
713-
data: [sampleTypeData],
729+
contentMap: ['label', 'value', 'frequency'],
730+
data: [formatAggregationChartData(sampleTypeData)],
731+
headers: ['Sample Type', 'Count', 'Frequency'],
714732
}}
715733
{...resizableCardSettings}
716734
/>
@@ -780,7 +798,9 @@ const getStatisticLayouts = ({ dictionary, statistic, withDownload = true }: get
780798
theme="shade"
781799
titleTruncateThresholdWidth={100}
782800
tsvSettings={{
783-
data: [sampleAvailabilityData],
801+
contentMap: ['label', 'value', 'frequency'],
802+
data: [formatAggregationChartData(sampleAvailabilityData)],
803+
headers: ['Sample Availability', 'Count', 'Frequency'],
784804
}}
785805
{...resizableCardSettings}
786806
/>
@@ -893,7 +913,9 @@ const getStatisticLayouts = ({ dictionary, statistic, withDownload = true }: get
893913
}
894914
theme="shade"
895915
tsvSettings={{
896-
data: [dataCategoryData],
916+
contentMap: ['label', 'value', 'frequency'],
917+
data: [formatAggregationChartData(dataCategoryData)],
918+
headers: ['Data Category', 'Count', 'Frequency'],
897919
}}
898920
{...resizableCardSettings}
899921
/>
@@ -1006,7 +1028,9 @@ const getStatisticLayouts = ({ dictionary, statistic, withDownload = true }: get
10061028
}
10071029
theme="shade"
10081030
tsvSettings={{
1009-
data: [dataTypeData],
1031+
contentMap: ['label', 'value', 'frequency'],
1032+
data: [formatAggregationChartData(dataTypeData)],
1033+
headers: ['Data Type', 'Count', 'Frequency'],
10101034
}}
10111035
{...resizableCardSettings}
10121036
/>

0 commit comments

Comments
 (0)