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

vogievetsky pushed a commit to branch explore_source
in repository https://gitbox.apache.org/repos/asf/druid.git

commit affb3db90ddff066670b65262a8249a0fad37b97
Author: Vadim Ogievetsky <[email protected]>
AuthorDate: Tue Aug 13 12:06:51 2024 -0700

    progress
---
 .../_save/modules/bar-chart-echarts-module.ts      | 155 ---------------------
 web-console/src/modules/bar-chart-module.tsx       |  38 +++--
 web-console/src/modules/module-pane.tsx            |  13 +-
 .../modules/module-repository/module-repository.ts |   1 +
 .../droppable-container/droppable-container.tsx    |  67 ++++-----
 .../src/views/explore-view/explore-view.tsx        |  15 +-
 6 files changed, 77 insertions(+), 212 deletions(-)

diff --git a/web-console/_save/modules/bar-chart-echarts-module.ts 
b/web-console/_save/modules/bar-chart-echarts-module.ts
deleted file mode 100644
index 2e3bf8681d6..00000000000
--- a/web-console/_save/modules/bar-chart-echarts-module.ts
+++ /dev/null
@@ -1,155 +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 { C, SqlExpression } from '@druid-toolkit/query';
-import { typedVisualModule } from '@druid-toolkit/visuals-core';
-import * as echarts from 'echarts';
-
-import { highlightStore } from '../highlight-store/highlight-store';
-import { getInitQuery } from '../utils';
-
-export default typedVisualModule({
-  parameters: {
-    splitColumn: {
-      type: 'column',
-      control: {
-        label: 'Bar column',
-        // transferGroup: 'show',
-        required: true,
-      },
-    },
-    metric: {
-      type: 'aggregate',
-      default: { expression: SqlExpression.parse('COUNT(*)'), name: 'Count', 
sqlType: 'BIGINT' },
-      control: {
-        label: 'Metric to show',
-        // transferGroup: 'show-agg',
-        required: true,
-      },
-    },
-    metricToSort: {
-      type: 'aggregate',
-      control: {
-        label: 'Metric to sort (default to shown)',
-      },
-    },
-    limit: {
-      type: 'number',
-      default: 5,
-      control: {
-        label: 'Max bars to show',
-        required: true,
-      },
-    },
-  },
-  module: ({ container, host, updateWhere }) => {
-    const { sqlQuery } = host;
-    const myChart = echarts.init(container, 'dark');
-
-    myChart.setOption({
-      tooltip: {},
-      dataset: {
-        sourceHeader: false,
-        dimensions: ['dim', 'met'],
-        source: [],
-      },
-      xAxis: {
-        type: 'category',
-        axisLabel: { interval: 0, rotate: -30 },
-      },
-      yAxis: {},
-      series: [
-        {
-          type: 'bar',
-          encode: {
-            x: 'dim',
-            y: 'met',
-          },
-        },
-      ],
-    });
-
-    return {
-      async update({ table, where, parameterValues }) {
-        const { splitColumn, metric, metricToSort, limit } = parameterValues;
-
-        myChart.off('click');
-
-        if (!splitColumn) return;
-
-        const v = await sqlQuery(
-          getInitQuery(table, where)
-            .addSelect(splitColumn.expression.as('dim'), { addToGroupBy: 'end' 
})
-            .addSelect(metric.expression.as('met'), {
-              addToOrderBy: metricToSort ? undefined : 'end',
-              direction: 'DESC',
-            })
-            .applyIf(metricToSort, q =>
-              
q.addOrderBy(metricToSort!.expression.toOrderByExpression('DESC')),
-            )
-            .changeLimitValue(limit),
-        );
-        myChart.setOption({
-          dataset: {
-            source: v.toObjectArray(),
-          },
-        });
-
-        myChart.on('click', 'series', p => {
-          const { dim, met } = p.data as any;
-
-          const [x, y] = myChart.convertToPixel({ seriesIndex: 0 }, [dim, 
met]);
-
-          highlightStore.getState().setHighlight({
-            label: p.name,
-            x,
-            y: y - 20,
-            data: [dim, met],
-            onDrop: () => {
-              highlightStore.getState().dropHighlight();
-            },
-            onSave: () => {
-              
updateWhere(where.toggleClauseInWhere(C(splitColumn.name).equal(p.name)));
-              highlightStore.getState().dropHighlight();
-            },
-          });
-        });
-      },
-
-      resize() {
-        myChart.resize();
-
-        // if there is a highlight, update its x position
-        // by calculating new pixel position from the highlight's data
-        const highlight = highlightStore.getState().highlight;
-        if (highlight) {
-          const [x, y] = myChart.convertToPixel({ seriesIndex: 0 }, 
highlight.data as number[]);
-
-          highlightStore.getState().updateHighlight({
-            x,
-            y: y - 20,
-          });
-        }
-      },
-
-      destroy() {
-        myChart.dispose();
-      },
-    };
-  },
-});
diff --git a/web-console/src/modules/bar-chart-module.tsx 
b/web-console/src/modules/bar-chart-module.tsx
index a1c2b0dc1b8..ef6bcb7419b 100644
--- a/web-console/src/modules/bar-chart-module.tsx
+++ b/web-console/src/modules/bar-chart-module.tsx
@@ -29,6 +29,8 @@ import { ModuleRepository } from 
'./module-repository/module-repository';
 
 import './record-table-module.scss';
 
+const OVERALL_LABEL = 'Overall';
+
 interface RecordTableParameterValues {
   splitColumn: ExpressionMeta;
   metric: ExpressionMeta;
@@ -74,16 +76,17 @@ 
ModuleRepository.registerModule<RecordTableParameterValues>({
     },
   },
   component: function BarChartModule(props) {
-    const { querySource, parameterValues, stage, runSqlQuery } = props;
+    const { querySource, where, setWhere, parameterValues, stage, runSqlQuery 
} = props;
     const chartRef = useRef<ECharts>();
 
+    const { splitColumn, metric, metricToSort, limit } = parameterValues;
+
     const dataQuery = useMemo(() => {
       const source = querySource.query;
-      const { splitColumn, metric, metricToSort, limit } = parameterValues;
-
-      const splitExpression = splitColumn ? splitColumn.expression : 
L('Overall');
+      const splitExpression = splitColumn ? splitColumn.expression : 
L(OVERALL_LABEL);
 
       return SqlQuery.from(source)
+        .addWhere(where)
         .addSelect(splitExpression.as('dim'), { addToGroupBy: 'end' })
         .addSelect(metric.expression.as('met'), {
           addToOrderBy: metricToSort ? undefined : 'end',
@@ -93,7 +96,7 @@ ModuleRepository.registerModule<RecordTableParameterValues>({
           q.addOrderBy(metricToSort.expression.toOrderByExpression('DESC')),
         )
         .changeLimitValue(limit);
-    }, [querySource, parameterValues]);
+    }, [querySource, where, splitColumn, metric, metricToSort, limit]);
 
     const [dataState] = useQueryManager({
       query: dataQuery,
@@ -116,27 +119,36 @@ 
ModuleRepository.registerModule<RecordTableParameterValues>({
       });
 
       myChart.on('click', 'series', p => {
+        const label = p.name;
         const { dim, met } = p.data as any;
 
         const [x, y] = myChart.convertToPixel({ seriesIndex: 0 }, [dim, met]);
 
-        console.log(x, y);
         highlightStore.getState().setHighlight({
-          label: p.name,
+          label,
           x,
           y: y - 20,
           data: [dim, met],
           onDrop: () => {
             highlightStore.getState().dropHighlight();
           },
-          onSave: () => {
-            // 
updateWhere(where.toggleClauseInWhere(C(splitColumn.name).equal(p.name)));
-            console.log('onSave');
-            highlightStore.getState().dropHighlight();
-          },
+          onSave:
+            label !== OVERALL_LABEL
+              ? () => {
+                  if (splitColumn) {
+                    setWhere(
+                      SqlExpression.parse(
+                        // ToDo: remove SqlExpression.parse
+                        
where.toggleClauseInWhere(splitColumn.expression.equal(label)),
+                      ),
+                    );
+                  }
+                  highlightStore.getState().dropHighlight();
+                }
+              : undefined,
         });
       });
-    }, [chartRef.current, dataState.data]);
+    }, [dataState.data]);
 
     useEffect(() => {
       const myChart = chartRef.current;
diff --git a/web-console/src/modules/module-pane.tsx 
b/web-console/src/modules/module-pane.tsx
index a7cc32f94d3..e2d76d12e3c 100644
--- a/web-console/src/modules/module-pane.tsx
+++ b/web-console/src/modules/module-pane.tsx
@@ -19,7 +19,7 @@
 import { Button, Menu, MenuItem, Popover, ResizeSensor } from 
'@blueprintjs/core';
 import { IconNames } from '@blueprintjs/icons';
 import type { QueryResult, SqlExpression, SqlQuery } from 
'@druid-toolkit/query';
-import React, { forwardRef, useState } from 'react';
+import React, { useState } from 'react';
 
 import { Issue } from '../components';
 
@@ -46,8 +46,9 @@ export interface ModulePaneProps {
   moduleName: string;
   querySource: QuerySource;
   where: SqlExpression;
-  parameterValues: Record<string, any>;
+  setWhere(where: SqlExpression): void;
 
+  parameterValues: Record<string, any>;
   publicState: Readonly<Record<string, Readonly<Record<string, any>>>>;
   setPublicState(key: string, value: any): void;
   runSqlQuery(query: string | SqlQuery): Promise<QueryResult>;
@@ -55,12 +56,13 @@ export interface ModulePaneProps {
   onEdit?: () => void;
 }
 
-export const ModulePane = forwardRef<any, any>(function ModulePane(props: 
ModulePaneProps, ref) {
+export const ModulePane = function ModulePane(props: ModulePaneProps) {
   const {
     moduleId,
     moduleName,
     querySource,
     where,
+    setWhere,
     parameterValues,
     publicState,
     setPublicState,
@@ -81,6 +83,7 @@ export const ModulePane = forwardRef<any, any>(function 
ModulePane(props: Module
         stage,
         querySource,
         where,
+        setWhere,
         parameterValues: fillInDefaults(parameterValues, module.parameters),
         publicState,
         myPublicState: publicState[moduleName] ?? {},
@@ -101,7 +104,7 @@ export const ModulePane = forwardRef<any, any>(function 
ModulePane(props: Module
         setStage(newStage);
       }}
     >
-      <div className="module-pane" ref={ref}>
+      <div className="module-pane">
         {content}
         {onEdit && (
           <Button className="edit-button" icon={IconNames.EDIT} 
onClick={onEdit} minimal small />
@@ -119,4 +122,4 @@ export const ModulePane = forwardRef<any, any>(function 
ModulePane(props: Module
       </div>
     </ResizeSensor>
   );
-});
+};
diff --git a/web-console/src/modules/module-repository/module-repository.ts 
b/web-console/src/modules/module-repository/module-repository.ts
index 4036e244208..e134c25eaa3 100644
--- a/web-console/src/modules/module-repository/module-repository.ts
+++ b/web-console/src/modules/module-repository/module-repository.ts
@@ -32,6 +32,7 @@ interface ModuleComponentProps<P> {
   stage: Stage;
   querySource: QuerySource;
   where: SqlExpression;
+  setWhere(where: SqlExpression): void;
   parameterValues: P;
   publicState: Readonly<Record<string, Readonly<Record<string, any>>>>;
   myPublicState: Readonly<Record<string, any>>;
diff --git 
a/web-console/src/views/explore-view/droppable-container/droppable-container.tsx
 
b/web-console/src/views/explore-view/droppable-container/droppable-container.tsx
index 59292668121..7246177ab3b 100644
--- 
a/web-console/src/views/explore-view/droppable-container/droppable-container.tsx
+++ 
b/web-console/src/views/explore-view/droppable-container/droppable-container.tsx
@@ -18,7 +18,7 @@
 
 import type { Column } from '@druid-toolkit/query';
 import classNames from 'classnames';
-import React, { useState } from 'react';
+import React, { forwardRef, useState } from 'react';
 
 import { DragHelper } from '../drag-helper';
 
@@ -29,35 +29,38 @@ export interface DroppableContainerProps extends 
React.HTMLAttributes<HTMLDivEle
   children?: React.ReactNode;
 }
 
-export const DroppableContainer = function DroppableContainer(props: 
DroppableContainerProps) {
-  const { className, onDropColumn, children, ...rest } = props;
-  const [dropHover, setDropHover] = useState(false);
+export const DroppableContainer = forwardRef<HTMLDivElement, 
DroppableContainerProps>(
+  function DroppableContainer(props, ref) {
+    const { className, onDropColumn, children, ...rest } = props;
+    const [dropHover, setDropHover] = useState(false);
 
-  return (
-    <div
-      className={classNames('droppable-container', className, { 'drop-hover': 
dropHover })}
-      {...rest}
-      onDragOver={e => {
-        if (!DragHelper.dragColumn) return;
-        e.preventDefault();
-        e.dataTransfer.dropEffect = 'move';
-        setDropHover(true);
-      }}
-      onDragLeave={e => {
-        const currentTarget = e.currentTarget;
-        const relatedTarget = e.relatedTarget;
-        if (currentTarget.contains(relatedTarget as any)) return;
-        setDropHover(false);
-      }}
-      onDrop={() => {
-        if (!DragHelper.dragColumn) return;
-        const dragColumn = DragHelper.dragColumn;
-        DragHelper.dragColumn = undefined;
-        setDropHover(false);
-        onDropColumn(dragColumn);
-      }}
-    >
-      {children}
-    </div>
-  );
-};
+    return (
+      <div
+        ref={ref}
+        className={classNames('droppable-container', className, { 
'drop-hover': dropHover })}
+        {...rest}
+        onDragOver={e => {
+          if (!DragHelper.dragColumn) return;
+          e.preventDefault();
+          e.dataTransfer.dropEffect = 'move';
+          setDropHover(true);
+        }}
+        onDragLeave={e => {
+          const currentTarget = e.currentTarget;
+          const relatedTarget = e.relatedTarget;
+          if (currentTarget.contains(relatedTarget as any)) return;
+          setDropHover(false);
+        }}
+        onDrop={() => {
+          if (!DragHelper.dragColumn) return;
+          const dragColumn = DragHelper.dragColumn;
+          DragHelper.dragColumn = undefined;
+          setDropHover(false);
+          onDropColumn(dragColumn);
+        }}
+      >
+        {children}
+      </div>
+    );
+  },
+);
diff --git a/web-console/src/views/explore-view/explore-view.tsx 
b/web-console/src/views/explore-view/explore-view.tsx
index 15637657b7f..3178b601b6f 100644
--- a/web-console/src/views/explore-view/explore-view.tsx
+++ b/web-console/src/views/explore-view/explore-view.tsx
@@ -23,6 +23,7 @@ import { type QueryResult, L, QueryRunner, sql, SqlQuery, 
SqlTable, T } from '@d
 import classNames from 'classnames';
 import copy from 'copy-to-clipboard';
 import React, { useEffect, useRef, useState } from 'react';
+import { useStore } from 'zustand';
 
 import { ShowValueDialog } from 
'../../dialogs/show-value-dialog/show-value-dialog';
 import { useLocalStorageState, useQueryManager } from '../../hooks';
@@ -40,6 +41,7 @@ import { ExploreState } from './explore-state';
 import { FilterPane } from './filter-pane/filter-pane';
 import { FullSourcePane } from './full-source-pane/full-source-pane';
 import { HighlightBubble } from './highlight-bubble/highlight-bubble';
+import { highlightStore } from './highlight-store/highlight-store';
 import { ModulePicker } from './module-picker/module-picker';
 import { ResourcePane } from './resource-pane/resource-pane';
 import { SourcePane } from './source-pane/source-pane';
@@ -173,7 +175,7 @@ export const ExploreView = React.memo(function 
ExploreView() {
     },
   );
 
-  // const { dropHighlight } = useStore(highlightStore);
+  const { dropHighlight } = useStore(highlightStore);
 
   const { moduleId, source, where, parameterValues, showFullSource } = 
exploreState;
   const module = ModuleRepository.getModule(moduleId);
@@ -238,8 +240,6 @@ export const ExploreView = React.memo(function 
ExploreView() {
     );
   }
 
-  console.log('containerRef.current', containerRef.current);
-
   const querySource = querySourceState.getSomeData();
 
   const effectiveShowFullSource = showFullSource || parsedError;
@@ -254,7 +254,7 @@ export const ExploreView = React.memo(function 
ExploreView() {
       )}
       {parsedError && <div className="source-error">{`Source error: 
${parsedError}`}</div>}
       {parsedSource && (
-        <div className="explore-container" ref={containerRef}>
+        <div className="explore-container">
           <SourcePane
             selectedSource={parsedSource}
             onSelectedSourceChange={setSource}
@@ -296,7 +296,6 @@ export const ExploreView = React.memo(function 
ExploreView() {
             ]}
             selectedModuleId={moduleId}
             onSelectedModuleIdChange={id => {
-              setModuleId(id);
               // const currentParameterDefinitions = 
module?.parameterDefinitions || {};
               // const valuesToTransfer: TransferValue[] = filterMap(
               //   VISUAL_MODULES.find(vm => vm.moduleId === 
module?.moduleId)?.transfer || [],
@@ -309,8 +308,8 @@ export const ExploreView = React.memo(function 
ExploreView() {
               //   },
               // );
               //
-              // dropHighlight();
-              // setModuleId(m);
+              dropHighlight();
+              setModuleId(id);
               // resetParameterValues();
               //
               // const newModuleDef = VISUAL_MODULES.find(vm => vm.moduleId 
=== m);
@@ -388,6 +387,7 @@ export const ExploreView = React.memo(function 
ExploreView() {
           </div>
           <DroppableContainer
             className="main-cnt"
+            ref={containerRef}
             onDropColumn={column => {
               onShow(column);
             }}
@@ -401,6 +401,7 @@ export const ExploreView = React.memo(function 
ExploreView() {
                 moduleName="*"
                 querySource={querySource}
                 where={where}
+                setWhere={setWhere}
                 parameterValues={parameterValues}
                 publicState={{}}
                 setPublicState={() => null}


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to