Skip to content

Commit 9fed0da

Browse files
committed
refactor: splitting single row mapping into category and language
1 parent b0b0277 commit 9fed0da

File tree

1 file changed

+56
-33
lines changed

1 file changed

+56
-33
lines changed

src/components/SimplePanel.tsx

Lines changed: 56 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,6 @@ import React from 'react';
22
import { PanelProps } from '@grafana/data';
33
import { SimpleOptions } from 'types';
44
import './SimplePanel.css';
5-
// import { css, cx } from '@emotion/css';
6-
// import { useStyles2, useTheme2 } from '@grafana/ui';
7-
// import { PanelDataErrorView } from '@grafana/runtime';
85

96
interface Props extends PanelProps<SimpleOptions> {}
107

@@ -25,64 +22,89 @@ export const SimplePanel: React.FC<Props> = ({ options, data, width, height }) =
2522

2623
// Handle no data case
2724
if (!data.series.length) {
28-
return <div className="panel-container">No data to display</div>;
25+
return <div className="panel-container">No data to display</div>
2926
}
3027

3128
// Use the first series (Grafana data frame)
3229
const frame = data.series[0];
33-
34-
//responsive breakpoint helper
35-
const isNarrow = width < 300;
3630

37-
// Extract rows
38-
const rows = Array.from({ length: frame.length || frame.fields[0].values.length }, (_, i) => {
39-
const get = (field?: string) => {
40-
const f = field ? frame.fields.find(f => f.name === field) : undefined;
41-
return f ? f.values.get(i) : undefined;
31+
const length = frame.length || frame.fields[0].values.length;
32+
33+
// helper to get value at specific index
34+
const getValue = (fieldName: string | undefined, index: number) => {
35+
if (!fieldName) {return undefined;}
36+
const field = frame.fields.find(f => f.name === fieldName);
37+
return field ? field.values[index] : undefined;
4238
};
4339

44-
return {
45-
category: get(fieldCategory),
46-
mentionsPercent: get(fieldMentionsPercent),
47-
mentionsCount: get(fieldMentionsCount),
48-
voicesCount: get(totalVoicesCount),
49-
platformCount: get(platformVoicesCount),
50-
socialCount: get(socialVoicesCount),
51-
languages: get(fieldLanguage),
52-
languagesPercent: get(fieldLanguagePercent),
53-
icon: get(icon),
54-
iconColor: get(iconColor),
55-
statColor: get(statColor),
40+
// extract KPI stats from the first row
41+
const stats = {
42+
voicesCount: getValue(totalVoicesCount, 0),
43+
platformCount: getValue(platformVoicesCount, 0),
44+
socialCount: getValue(socialVoicesCount, 0),
5645
};
57-
});
46+
47+
// extract category rows; filter out empty categories
48+
const platformRows = [];
49+
for (let i = 0; i < length; i++) {
50+
const category = getValue(fieldCategory, i);
51+
52+
// only add to list if category exists
53+
if (category) {
54+
platformRows.push({
55+
category: category,
56+
mentionsPercent: getValue(fieldMentionsPercent, i),
57+
mentionsCount: getValue(fieldMentionsCount, i),
58+
icon: getValue(icon, i),
59+
iconColor: getValue(iconColor, i),
60+
});
61+
}
62+
}
63+
64+
// extract language rows; filter out empty languages
65+
const languageRows = [];
66+
for (let i = 0; i < length; i++) {
67+
const lang = getValue(fieldLanguage, i);
68+
69+
// only add to list if language exists
70+
if (lang) {
71+
languageRows.push({
72+
language: lang,
73+
percent: getValue(fieldLanguagePercent, i),
74+
});
75+
}
76+
}
77+
78+
//responsive breakpoint helper
79+
const isNarrow = width < 300;
5880

5981
return (
6082
<div className="panel-container" style={{ width, height }}>
6183

6284
<h2 className="panel-section-header">Community Engagement</h2>
6385

6486
<div className={`panel-stats-row ${isNarrow ? 'is-narrow' : ''}`}
65-
style={{ color: options.statColor }}
87+
style={{ color: statColor }}
6688
>
6789
<div className="panel-stat-item">
68-
<div className="panel-stat-value">{rows[0]?.voicesCount ?? 0}</div>
90+
<div className="panel-stat-value">{stats.voicesCount ?? 0}</div>
6991
<div className="panel-stat-label">Total Voices</div>
7092
</div>
7193

7294
<div className="panel-stat-item">
73-
<div className="panel-stat-value">{rows[0]?.platformCount ?? 0}</div>
95+
<div className="panel-stat-value">{stats.platformCount ?? 0}</div>
7496
<div className="panel-stat-label">Platform Posts</div>
7597
</div>
7698

7799
<div className="panel-stat-item">
78-
<div className="panel-stat-value">{rows[0]?.socialCount ?? 0}</div>
100+
<div className="panel-stat-value">{stats.socialCount ?? 0}</div>
79101
<div className="panel-stat-label">Social Media</div>
80102
</div>
81103
</div>
82104

83105
<h2 className="panel-section-header top-spacing">Platform Breakdown</h2>
84106

85-
{rows.map((row, i) => (
107+
{platformRows.map((row, i) => (
86108
<div key={i} className="panel-card">
87109
{/* row wrapper for icon and details */}
88110
<div className={`panel-card-inner ${isNarrow ? 'is-narrow' : ''}`}>
@@ -102,7 +124,7 @@ export const SimplePanel: React.FC<Props> = ({ options, data, width, height }) =
102124
<div className={`panel-card-header-row ${isNarrow ? 'is-narrow' : ''}`}>
103125
<h3 className="panel-category-title">
104126
{options.showNumbering ? `${i + 1}. ` : ''}
105-
{row.category ?? 'category'}
127+
{row.category}
106128
</h3>
107129

108130
<div className="panel-percent-pill">
@@ -123,9 +145,10 @@ export const SimplePanel: React.FC<Props> = ({ options, data, width, height }) =
123145

124146
<h2 className="panel-section-header top-spacing">Language Distribution</h2>
125147
<div className="panel-lang-container">
126-
{rows.map((row, i) => (
148+
149+
{languageRows.map((row, i) => (
127150
<div key={i} className="panel-lang-pill">
128-
{row.languages ?? 'language'} {Number(row.languagesPercent ?? '0').toFixed(
151+
{row.language} {Number(row.percent ?? '0').toFixed(
129152
options.decimalPlaces ?? 1)}%
130153
</div>
131154
))}

0 commit comments

Comments
 (0)