You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@superset.apache.org by ru...@apache.org on 2025/08/18 20:22:40 UTC
(superset) branch move-controls updated: feat: Restructure Pie control panel with tabs for Data and Customize
This is an automated email from the ASF dual-hosted git repository.
rusackas pushed a commit to branch move-controls
in repository https://gitbox.apache.org/repos/asf/superset.git
The following commit(s) were added to refs/heads/move-controls by this push:
new 51c40dc971 feat: Restructure Pie control panel with tabs for Data and Customize
51c40dc971 is described below
commit 51c40dc97197b58467cc8ad91b82a17d5bebda48
Author: Evan Rusackas <ev...@rusackas.com>
AuthorDate: Mon Aug 18 13:22:20 2025 -0700
feat: Restructure Pie control panel with tabs for Data and Customize
- Added Ant Design Tabs to split controls into Data and Customize tabs
- Data tab contains: Group by, Metric, Filters, Row limit, Sort by metric
- Customize tab contains: Chart Options, Labels, and Pie shape sections
- Added chart/viz type picker above the tabs showing 'Pie Chart' title and description
- Maintains all existing controls and their conditional rendering logic
- Uses useState hook to manage active tab state
---
.../src/Pie/PieControlPanelSimple.tsx | 245 ++++++++++++---------
1 file changed, 143 insertions(+), 102 deletions(-)
diff --git a/superset-frontend/plugins/plugin-chart-echarts/src/Pie/PieControlPanelSimple.tsx b/superset-frontend/plugins/plugin-chart-echarts/src/Pie/PieControlPanelSimple.tsx
index 21e5f1fe2a..8e6a1f02cf 100644
--- a/superset-frontend/plugins/plugin-chart-echarts/src/Pie/PieControlPanelSimple.tsx
+++ b/superset-frontend/plugins/plugin-chart-echarts/src/Pie/PieControlPanelSimple.tsx
@@ -16,8 +16,9 @@
* specific language governing permissions and limitations
* under the License.
*/
-import { FC } from 'react';
+import { FC, useState } from 'react';
import { t } from '@superset-ui/core';
+import { Tabs } from 'antd';
import {
ColorSchemeControl,
D3_FORMAT_OPTIONS,
@@ -87,118 +88,122 @@ export const PieControlPanel: FC<PieControlPanelProps> = ({
// Get form values
const formValues = form_data || value || {};
- return (
- <div style={{ padding: '16px' }}>
- {/* Query Section */}
- <div style={{ marginBottom: 24 }}>
- <h4>{t('Query')}</h4>
+ // State for active tab
+ const [activeTab, setActiveTab] = useState('data');
+
+ // Data tab content
+ const dataTabContent = (
+ <div>
+ {/* Group by */}
+ <div style={{ marginBottom: 16 }}>
+ <ControlHeader
+ label={t('Group by')}
+ description={t('Columns to group by')}
+ hovered
+ />
+ {safeColumns.length > 0 ? (
+ <DndColumnSelect
+ value={formValues.groupby || []}
+ onChange={handleChange('groupby')}
+ options={safeColumns}
+ name="groupby"
+ label=""
+ multi
+ canDelete
+ ghostButtonText={t('Add dimension')}
+ type="DndColumnSelect"
+ actions={actions}
+ />
+ ) : (
+ <div style={{ padding: '10px' }}>
+ {t('No columns available. Please select a dataset first.')}
+ </div>
+ )}
+ </div>
- {/* Group by */}
- <div style={{ marginBottom: 16 }}>
- <ControlHeader
- label={t('Group by')}
- description={t('Columns to group by')}
- hovered
+ {/* Metric */}
+ <div style={{ marginBottom: 16 }}>
+ <ControlHeader
+ label={t('Metric')}
+ description={t('Metric to display')}
+ hovered
+ />
+ {safeDataSource && safeDataSource.columns ? (
+ <DndMetricSelect
+ value={formValues.metric}
+ onChange={handleChange('metric')}
+ datasource={safeDataSource}
+ name="metric"
+ label=""
+ multi={false}
+ savedMetrics={safeMetrics}
/>
- {safeColumns.length > 0 ? (
- <DndColumnSelect
- value={formValues.groupby || []}
- onChange={handleChange('groupby')}
- options={safeColumns}
- name="groupby"
- label=""
- multi
- canDelete
- ghostButtonText={t('Add dimension')}
- type="DndColumnSelect"
- actions={actions}
- />
- ) : (
- <div style={{ padding: '10px' }}>
- {t('No columns available. Please select a dataset first.')}
- </div>
- )}
- </div>
+ ) : (
+ <div style={{ padding: '10px' }}>{t('No metrics available.')}</div>
+ )}
+ </div>
- {/* Metric */}
- <div style={{ marginBottom: 16 }}>
- <ControlHeader
- label={t('Metric')}
- description={t('Metric to display')}
- hovered
+ {/* Filters */}
+ <div style={{ marginBottom: 16 }}>
+ <ControlHeader
+ label={t('Filters')}
+ description={t('Filters to apply to the data')}
+ hovered
+ />
+ {safeDataSource && safeColumns.length > 0 ? (
+ <DndFilterSelect
+ value={formValues.adhoc_filters || []}
+ onChange={handleChange('adhoc_filters')}
+ datasource={safeDataSource}
+ columns={safeColumns}
+ formData={formValues}
+ name="adhoc_filters"
+ savedMetrics={safeMetrics}
+ selectedMetrics={formValues.metric ? [formValues.metric] : []}
+ type="DndFilterSelect"
+ actions={actions}
/>
- {safeDataSource && safeDataSource.columns ? (
- <DndMetricSelect
- value={formValues.metric}
- onChange={handleChange('metric')}
- datasource={safeDataSource}
- name="metric"
- label=""
- multi={false}
- savedMetrics={safeMetrics}
- />
- ) : (
- <div style={{ padding: '10px' }}>{t('No metrics available.')}</div>
- )}
- </div>
+ ) : (
+ <div style={{ padding: '10px' }}>
+ {t('No columns available for filtering.')}
+ </div>
+ )}
+ </div>
- {/* Filters */}
- <div style={{ marginBottom: 16 }}>
+ {/* Row limit and Sort by metric */}
+ <div style={{ display: 'flex', gap: 16 }}>
+ <div style={{ flex: 1 }}>
<ControlHeader
- label={t('Filters')}
- description={t('Filters to apply to the data')}
+ label={t('Row limit')}
+ description={t('Limit the number of rows that are returned')}
hovered
/>
- {safeDataSource && safeColumns.length > 0 ? (
- <DndFilterSelect
- value={formValues.adhoc_filters || []}
- onChange={handleChange('adhoc_filters')}
- datasource={safeDataSource}
- columns={safeColumns}
- formData={formValues}
- name="adhoc_filters"
- savedMetrics={safeMetrics}
- selectedMetrics={formValues.metric ? [formValues.metric] : []}
- type="DndFilterSelect"
- actions={actions}
- />
- ) : (
- <div style={{ padding: '10px' }}>
- {t('No columns available for filtering.')}
- </div>
- )}
+ <TextControl
+ value={formValues.row_limit}
+ onChange={handleChange('row_limit')}
+ isInt
+ placeholder="100"
+ controlId="row_limit"
+ />
</div>
-
- {/* Row limit and Sort by metric */}
- <div style={{ display: 'flex', gap: 16 }}>
- <div style={{ flex: 1 }}>
- <ControlHeader
- label={t('Row limit')}
- description={t('Limit the number of rows that are returned')}
- hovered
- />
- <TextControl
- value={formValues.row_limit}
- onChange={handleChange('row_limit')}
- isInt
- placeholder="100"
- controlId="row_limit"
- />
- </div>
- <div style={{ flex: 1 }}>
- <CheckboxControl
- label={t('Sort by metric')}
- description={t(
- 'Whether to sort results by the selected metric in descending order',
- )}
- value={formValues.sort_by_metric ?? true}
- onChange={handleChange('sort_by_metric')}
- hovered
- />
- </div>
+ <div style={{ flex: 1 }}>
+ <CheckboxControl
+ label={t('Sort by metric')}
+ description={t(
+ 'Whether to sort results by the selected metric in descending order',
+ )}
+ value={formValues.sort_by_metric ?? true}
+ onChange={handleChange('sort_by_metric')}
+ hovered
+ />
</div>
</div>
+ </div>
+ );
+ // Customize tab content
+ const customizeTabContent = (
+ <div>
{/* Chart Options Section */}
<div style={{ marginBottom: 24 }}>
<h4>{t('Chart Options')}</h4>
@@ -482,6 +487,42 @@ export const PieControlPanel: FC<PieControlPanelProps> = ({
</div>
</div>
);
+
+ // Tab items
+ const tabItems = [
+ {
+ key: 'data',
+ label: t('Data'),
+ children: dataTabContent,
+ },
+ {
+ key: 'customize',
+ label: t('Customize'),
+ children: customizeTabContent,
+ },
+ ];
+
+ return (
+ <div style={{ padding: '16px' }}>
+ {/* Chart/Viz Type Picker */}
+ <div style={{ marginBottom: 16, padding: '12px', borderRadius: '4px' }}>
+ <div style={{ fontSize: '16px', fontWeight: 500, marginBottom: '8px' }}>
+ {t('Pie Chart')}
+ </div>
+ <div style={{ fontSize: '12px', color: '#666' }}>
+ {t('Visualize data as a pie or donut chart')}
+ </div>
+ </div>
+
+ {/* Tabs for Data and Customize */}
+ <Tabs
+ activeKey={activeTab}
+ onChange={setActiveTab}
+ items={tabItems}
+ size="large"
+ />
+ </div>
+ );
};
// Mark this component as a modern panel
@@ -606,4 +647,4 @@ const config = {
},
};
-export default config;
+export default config;
\ No newline at end of file