This is an automated email from the ASF dual-hosted git repository.

rusackas pushed a commit to branch feat/glyph-single-file
in repository https://gitbox.apache.org/repos/asf/superset.git

commit 865b75c90e1cbe9766abb489c6e1af8b8ff9b3c9
Author: Evan Rusackas <[email protected]>
AuthorDate: Thu May 14 18:46:02 2026 -0700

    feat(glyph): consolidate deckgl Geojson layer to defineChart()
    
    Collapse multi-file plugin (buildQuery, controlPanel, transformProps,
    index) into single index.tsx. The Geojson.tsx component stays as
    sibling. Largest deckgl controlPanel so far due to extensive label /
    icon / JavaScript config controls.
    
    Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
---
 .../src/layers/Geojson/buildQuery.ts               |  86 ------------
 .../src/layers/Geojson/index.ts                    |  51 -------
 .../layers/Geojson/{controlPanel.ts => index.tsx}  | 151 +++++++++++++++++++--
 .../src/layers/Geojson/transformProps.ts           |  50 -------
 4 files changed, 143 insertions(+), 195 deletions(-)

diff --git 
a/superset-frontend/plugins/preset-chart-deckgl/src/layers/Geojson/buildQuery.ts
 
b/superset-frontend/plugins/preset-chart-deckgl/src/layers/Geojson/buildQuery.ts
deleted file mode 100644
index 67b5ddd2327..00000000000
--- 
a/superset-frontend/plugins/preset-chart-deckgl/src/layers/Geojson/buildQuery.ts
+++ /dev/null
@@ -1,86 +0,0 @@
-/**
- * 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 {
-  buildQueryContext,
-  ensureIsArray,
-  QueryFormColumn,
-  QueryObject,
-  QueryObjectFilterClause,
-  SqlaFormData,
-} from '@superset-ui/core';
-import {
-  addJsColumnsToColumns,
-  addTooltipColumnsToQuery,
-} from '../buildQueryUtils';
-
-export interface DeckGeoJsonFormData extends SqlaFormData {
-  geojson?: string;
-  filter_nulls?: boolean;
-  js_columns?: string[];
-  tooltip_contents?: unknown[];
-}
-
-export default function buildQuery(formData: DeckGeoJsonFormData) {
-  const {
-    geojson,
-    filter_nulls = true,
-    js_columns,
-    tooltip_contents,
-  } = formData;
-
-  if (!geojson) {
-    throw new Error('GeoJSON column is required for GeoJSON charts');
-  }
-
-  return buildQueryContext(formData, (baseQueryObject: QueryObject) => {
-    let columns: QueryFormColumn[] = [
-      ...ensureIsArray(baseQueryObject.columns || []),
-      geojson,
-    ];
-
-    // Add js_columns
-    const columnStrings = columns.map(col =>
-      typeof col === 'string' ? col : col.label || col.sqlExpression || '',
-    );
-    const withJsColumns = addJsColumnsToColumns(columnStrings, js_columns);
-    columns = withJsColumns as QueryFormColumn[];
-
-    // Add tooltip columns
-    columns = addTooltipColumnsToQuery(columns, tooltip_contents);
-
-    // Add null filter for geojson column
-    const filters: QueryObjectFilterClause[] = ensureIsArray(
-      baseQueryObject.filters || [],
-    );
-    if (filter_nulls) {
-      filters.push({ col: geojson, op: 'IS NOT NULL' });
-    }
-
-    return [
-      {
-        ...baseQueryObject,
-        columns,
-        metrics: [],
-        groupby: [],
-        filters,
-        is_timeseries: false,
-      },
-    ];
-  });
-}
diff --git 
a/superset-frontend/plugins/preset-chart-deckgl/src/layers/Geojson/index.ts 
b/superset-frontend/plugins/preset-chart-deckgl/src/layers/Geojson/index.ts
deleted file mode 100644
index 618beff2b46..00000000000
--- a/superset-frontend/plugins/preset-chart-deckgl/src/layers/Geojson/index.ts
+++ /dev/null
@@ -1,51 +0,0 @@
-/**
- * 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 { t } from '@apache-superset/core/translation';
-import { ChartMetadata, ChartPlugin, Behavior } from '@superset-ui/core';
-import thumbnail from './images/thumbnail.png';
-import thumbnailDark from './images/thumbnail-dark.png';
-import example from './images/example.png';
-import exampleDark from './images/example-dark.png';
-import controlPanel from './controlPanel';
-
-const metadata = new ChartMetadata({
-  category: t('Map'),
-  credits: ['https://uber.github.io/deck.gl'],
-  description: t(
-    'The GeoJsonLayer takes in GeoJSON formatted data and renders it as 
interactive polygons, lines and points (circles, icons and/or texts).',
-  ),
-  exampleGallery: [{ url: example, urlDark: exampleDark }],
-  name: t('deck.gl Geojson'),
-  thumbnail,
-  thumbnailDark,
-  tags: [t('deckGL'), t('2D')],
-  behaviors: [Behavior.InteractiveChart],
-});
-
-export default class GeojsonChartPlugin extends ChartPlugin {
-  constructor() {
-    super({
-      loadChart: () => import('./Geojson'),
-      loadTransformProps: () => import('./transformProps'),
-      loadBuildQuery: () => import('./buildQuery'),
-      controlPanel,
-      metadata,
-    });
-  }
-}
diff --git 
a/superset-frontend/plugins/preset-chart-deckgl/src/layers/Geojson/controlPanel.ts
 b/superset-frontend/plugins/preset-chart-deckgl/src/layers/Geojson/index.tsx
similarity index 71%
rename from 
superset-frontend/plugins/preset-chart-deckgl/src/layers/Geojson/controlPanel.ts
rename to 
superset-frontend/plugins/preset-chart-deckgl/src/layers/Geojson/index.tsx
index 6326968bad9..af7710fa0ed 100644
--- 
a/superset-frontend/plugins/preset-chart-deckgl/src/layers/Geojson/controlPanel.ts
+++ b/superset-frontend/plugins/preset-chart-deckgl/src/layers/Geojson/index.tsx
@@ -16,13 +16,32 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-import { ControlPanelConfig } from '@superset-ui/chart-controls';
 import { t } from '@apache-superset/core/translation';
 import {
-  legacyValidateInteger,
-  isFeatureEnabled,
+  Behavior,
+  buildQueryContext,
+  ChartProps,
+  ensureIsArray,
   FeatureFlag,
+  getColumnLabel,
+  isFeatureEnabled,
+  legacyValidateInteger,
+  QueryFormColumn,
+  QueryObject,
+  QueryObjectFilterClause,
+  SqlaFormData,
 } from '@superset-ui/core';
+import { defineChart } from '@superset-ui/glyph-core';
+import GeojsonComponent from './Geojson';
+import { DataRecord } from '../spatialUtils';
+import {
+  createBaseTransformResult,
+  getRecordsFromQuery,
+} from '../transformUtils';
+import {
+  addJsColumnsToColumns,
+  addTooltipColumnsToQuery,
+} from '../buildQueryUtils';
 import { formatSelectOptions } from '../../utilities/utils';
 import {
   filterNulls,
@@ -47,6 +66,99 @@ import {
 } from '../../utilities/Shared_DeckGL';
 import { dndGeojsonColumn } from '../../utilities/sharedDndControls';
 import { BLACK_COLOR } from '../../utilities/controls';
+import thumbnail from './images/thumbnail.png';
+import thumbnailDark from './images/thumbnail-dark.png';
+import example from './images/example.png';
+import exampleDark from './images/example-dark.png';
+
+// ─── Types 
───────────────────────────────────────────────────────────────────
+
+export interface DeckGeoJsonFormData extends SqlaFormData {
+  geojson?: string;
+  filter_nulls?: boolean;
+  js_columns?: string[];
+  tooltip_contents?: unknown[];
+}
+
+// ─── buildQuery 
──────────────────────────────────────────────────────────────
+
+export function buildQuery(formData: DeckGeoJsonFormData) {
+  const {
+    geojson,
+    filter_nulls = true,
+    js_columns,
+    tooltip_contents,
+  } = formData;
+
+  if (!geojson) {
+    throw new Error('GeoJSON column is required for GeoJSON charts');
+  }
+
+  return buildQueryContext(formData, (baseQueryObject: QueryObject) => {
+    let columns: QueryFormColumn[] = [
+      ...ensureIsArray(baseQueryObject.columns || []),
+      geojson,
+    ];
+
+    const columnStrings = columns.map(col =>
+      typeof col === 'string' ? col : col.label || col.sqlExpression || '',
+    );
+    const withJsColumns = addJsColumnsToColumns(columnStrings, js_columns);
+    columns = withJsColumns as QueryFormColumn[];
+
+    columns = addTooltipColumnsToQuery(columns, tooltip_contents);
+
+    const filters: QueryObjectFilterClause[] = ensureIsArray(
+      baseQueryObject.filters || [],
+    );
+    if (filter_nulls) {
+      filters.push({ col: geojson, op: 'IS NOT NULL' });
+    }
+
+    return [
+      {
+        ...baseQueryObject,
+        columns,
+        metrics: [],
+        groupby: [],
+        filters,
+        is_timeseries: false,
+      },
+    ];
+  });
+}
+
+// ─── transformProps 
──────────────────────────────────────────────────────────
+
+function transformProps(chartProps: ChartProps) {
+  const { rawFormData: formData } = chartProps;
+  const geojsonCol = formData.geojson
+    ? getColumnLabel(formData.geojson)
+    : undefined;
+
+  if (!geojsonCol) {
+    return createBaseTransformResult(chartProps, []);
+  }
+
+  const records = getRecordsFromQuery(chartProps.queriesData);
+
+  // Parse each record's geojson column value (replicates backend 
DeckGeoJson.get_properties)
+  const features = records
+    .map((record: DataRecord) => {
+      const geojsonStr = record[geojsonCol];
+      if (geojsonStr == null) return null;
+      try {
+        return JSON.parse(String(geojsonStr));
+      } catch {
+        return null;
+      }
+    })
+    .filter(Boolean);
+
+  return createBaseTransformResult(chartProps, features);
+}
+
+// ─── Default control config templates 
────────────────────────────────────────
 
 const defaultLabelConfigGenerator = `() => ({
   // Check the documentation at:
@@ -65,8 +177,26 @@ const defaultIconConfigGenerator = `() => ({
   iconSizeUnits: 'pixels',
 })`;
 
-const config: ControlPanelConfig = {
-  controlPanelSections: [
+// ─── Plugin definition 
───────────────────────────────────────────────────────
+
+// eslint-disable-next-line @typescript-eslint/no-explicit-any
+export default defineChart<Record<string, never>, any>({
+  metadata: {
+    name: t('deck.gl Geojson'),
+    description: t(
+      'The GeoJsonLayer takes in GeoJSON formatted data and renders it as 
interactive polygons, lines and points (circles, icons and/or texts).',
+    ),
+    category: t('Map'),
+    credits: ['https://uber.github.io/deck.gl'],
+    behaviors: [Behavior.InteractiveChart],
+    tags: [t('deckGL'), t('2D')],
+    thumbnail,
+    thumbnailDark,
+    exampleGallery: [{ url: example, urlDark: exampleDark }],
+  },
+  arguments: {},
+  suppressQuerySection: true,
+  prependSections: [
     {
       label: t('Query'),
       expanded: true,
@@ -374,6 +504,11 @@ const config: ControlPanelConfig = {
       ],
     },
   ],
-};
-
-export default config;
+  // eslint-disable-next-line @typescript-eslint/no-explicit-any
+  buildQuery: (formData: any) => buildQuery(formData as DeckGeoJsonFormData),
+  transform: chartProps => transformProps(chartProps),
+  render: ({ transformedProps }) => (
+    // eslint-disable-next-line @typescript-eslint/no-explicit-any
+    <GeojsonComponent {...(transformedProps as any)} />
+  ),
+});
diff --git 
a/superset-frontend/plugins/preset-chart-deckgl/src/layers/Geojson/transformProps.ts
 
b/superset-frontend/plugins/preset-chart-deckgl/src/layers/Geojson/transformProps.ts
deleted file mode 100644
index 572df299ade..00000000000
--- 
a/superset-frontend/plugins/preset-chart-deckgl/src/layers/Geojson/transformProps.ts
+++ /dev/null
@@ -1,50 +0,0 @@
-/**
- * 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 { ChartProps, getColumnLabel } from '@superset-ui/core';
-import { getRecordsFromQuery } from '../transformUtils';
-import { DataRecord } from '../spatialUtils';
-import { createBaseTransformResult } from '../transformUtils';
-
-export default function transformProps(chartProps: ChartProps) {
-  const { rawFormData: formData } = chartProps;
-  const geojsonCol = formData.geojson
-    ? getColumnLabel(formData.geojson)
-    : undefined;
-
-  if (!geojsonCol) {
-    return createBaseTransformResult(chartProps, []);
-  }
-
-  const records = getRecordsFromQuery(chartProps.queriesData);
-
-  // Parse each record's geojson column value (replicates backend 
DeckGeoJson.get_properties)
-  const features = records
-    .map((record: DataRecord) => {
-      const geojsonStr = record[geojsonCol];
-      if (geojsonStr == null) return null;
-      try {
-        return JSON.parse(String(geojsonStr));
-      } catch {
-        return null;
-      }
-    })
-    .filter(Boolean);
-
-  return createBaseTransformResult(chartProps, features);
-}

Reply via email to