Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions packages/graphic-walker/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ import { getComputation } from './computation/clientComputation';
import LogPanel from './fields/datasetFields/logPanel';
import BinPanel from './fields/datasetFields/binPanel';
import RenamePanel from './components/renameField';
import FieldConfigDialog from './components/fieldConfigDialog';
import { ErrorContext } from './utils/reportError';
import { ErrorBoundary } from 'react-error-boundary';
import Errorpanel from './components/errorpanel';
Expand Down Expand Up @@ -234,6 +235,7 @@ export const VizApp = observer(function VizApp(props: BaseVizProps) {
<LogPanel />
<BinPanel />
<RenamePanel />
<FieldConfigDialog />
<ComputedFieldDialog />
<Painter themeConfig={appliedThemeConfig} themeKey={appliedThemeKey} />
{vizStore.showGeoJSONConfigPanel && <GeoConfigPanel geoList={props.geoList} />}
Expand Down
649 changes: 649 additions & 0 deletions packages/graphic-walker/src/components/fieldConfigDialog/index.tsx

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -385,7 +385,10 @@ const ChoroplethRenderer = forwardRef<IChoroplethRendererRef, IChoroplethRendere
<Tooltip>
<header>{name}</header>
{tooltipFields.map((f, j) => (
<p key={j}>{f.analyticType === 'measure' && f.aggName ? getMeaAggName(f.name, f.aggName) : f.name}: Null</p>
<p key={j}>
{f.titleOverride || (f.analyticType === 'measure' && f.aggName ? getMeaAggName(f.name, f.aggName) : f.name)}:
Null
</p>
))}
</Tooltip>
)}
Expand All @@ -409,7 +412,7 @@ const ChoroplethRenderer = forwardRef<IChoroplethRendererRef, IChoroplethRendere
<Tooltip>
<header>{name}</header>
{tooltipFields.map((f, j) => (
<p key={j}>{f.analyticType === 'measure' && f.aggName ? getMeaAggName(f.name, f.aggName) : f.name}: Null</p>
<p key={j}>{f.titleOverride || (f.analyticType === 'measure' && f.aggName ? getMeaAggName(f.name, f.aggName) : f.name)}: Null</p>
))}
</Tooltip>
</Polygon>
Expand Down
10 changes: 5 additions & 5 deletions packages/graphic-walker/src/components/painter/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -159,7 +159,7 @@ const produceChannel = (
if (domain.domain.value.every((x) => x instanceof Array)) {
return {
field: `${channel.fid}[0]`,
title: channel.name,
title: channel.titleOverride || channel.name,
type: domain.domain.type,
axis: { labelOverlap: true },
scale: {
Expand All @@ -172,7 +172,7 @@ const produceChannel = (
}
return {
field: channel.fid,
title: channel.name,
title: channel.titleOverride || channel.name,
type: domain.domain.type,
axis: { labelOverlap: true },
scale: { domain: domain.domain.type === 'nominal' && options?.reverseNominalDomain ? domain.domain.value.toReversed() : domain.domain.value },
Expand All @@ -190,7 +190,7 @@ const produceAggChannel = (
if (domain?.domain.value.every((x) => x instanceof Array)) {
return {
field: `${channel.fid}[0]`,
title: channel.name,
title: channel.titleOverride || channel.name,
type: getDomainType(channel.semanticType),
axis: { labelOverlap: true },
scale: domain
Expand All @@ -206,7 +206,7 @@ const produceAggChannel = (
}
return {
field: channel.fid,
title: channel.name,
title: channel.titleOverride || channel.name,
type: getDomainType(channel.semanticType),
axis: { labelOverlap: true },
scale: domain
Expand Down Expand Up @@ -339,7 +339,7 @@ const AggPainterContent = (props: {
if (c.aggregate === null) return;
const targetField = viewMeasures.find((f) => f.fid === c.field);
if (targetField) {
c.title = getMeaAggName(targetField.name, targetField.aggName);
c.title = targetField.titleOverride || getMeaAggName(targetField.name, targetField.aggName);
c.field = getMeaAggKey(targetField.fid, targetField.aggName);
}
});
Expand Down
50 changes: 45 additions & 5 deletions packages/graphic-walker/src/components/pivotTable/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,24 @@ import { dataQuery } from '../../computation';
import { useAppRootContext } from '../../components/appRoot';
import LeftTree from './leftTree';
import TopTree from './topTree';
import { DeepReadonly, DraggableFieldState, IRow, IThemeKey, IViewField, IVisualConfigNew, IVisualLayout, IVisualConfig } from '../../interfaces';
import {
DeepReadonly,
DraggableFieldState,
IManualSortValue,
IRow,
IThemeKey,
IViewField,
IVisualConfigNew,
IVisualLayout,
IVisualConfig,
} from '../../interfaces';
import { INestNode } from './inteface';
import { unstable_batchedUpdates } from 'react-dom';
import MetricTable from './metricTable';
import LoadingLayer from '../loadingLayer';
import { useCompututaion, useVizStore } from '../../store';
import { fold2 } from '../../lib/op/fold';
import { getFieldIdentifier, getSort, getSortedEncoding } from '../../utils';
import { getFieldIdentifier, getMeaAggKey, getSort, getSortedEncoding } from '../../utils';
import { GWGlobalConfig } from '@/vis/theme';
import { getAllFields, getViewEncodingFields } from '../../store/storeStateLib';

Expand Down Expand Up @@ -77,6 +87,30 @@ const PivotTable: React.FC<PivotTableProps> = function PivotTableComponent(props
return columns.filter((f) => f.analyticType === 'measure');
}, [columns]);

const manualSortConfig = useMemo<Record<string, IManualSortValue[]> | undefined>(() => {
const entries: Record<string, IManualSortValue[]> = {};
const collect = (field: IViewField) => {
if ((field.sortType ?? 'measure') !== 'manual') return;
if (!field.sortList || field.sortList.length === 0) return;
entries[field.fid] = field.sortList;
};
dimsInRow.forEach(collect);
dimsInColumn.forEach(collect);
return Object.keys(entries).length ? entries : undefined;
}, [dimsInRow, dimsInColumn]);

const alphabeticalSortConfig = useMemo<Record<string, 'ascending' | 'descending'> | undefined>(() => {
const entries: Record<string, 'ascending' | 'descending'> = {};
const collect = (field: IViewField) => {
if ((field.sortType ?? 'measure') !== 'alphabetical') return;
const order = field.sort && field.sort !== 'none' ? field.sort : 'ascending';
entries[field.fid] = order;
};
dimsInRow.forEach(collect);
dimsInColumn.forEach(collect);
return Object.keys(entries).length ? entries : undefined;
}, [dimsInRow, dimsInColumn]);

useEffect(() => {
if (!enableCollapse) {
generateNewTable();
Expand Down Expand Up @@ -121,17 +155,23 @@ const PivotTable: React.FC<PivotTableProps> = function PivotTableComponent(props
buildPivotTableService(
dimsInRow,
dimsInColumn,
[...measInRow, ...measInColumn],
data,
aggData.current,
Object.keys(tableCollapsedHeaderMap),
showTableSummary,
sort !== 'none' && sortedEncoding !== 'none'
? {
fid: sortedEncoding === 'column' ? `${measInRow[0].fid}_${measInRow[0].aggName}` : `${measInColumn[0].fid}_${measInColumn[0].aggName}`,
fid:
sortedEncoding === 'column'
? getMeaAggKey(measInRow[0].fid, measInRow[0].aggName, measInRow[0].windowAgg)
: getMeaAggKey(measInColumn[0].fid, measInColumn[0].aggName, measInColumn[0].windowAgg),
mode: sortedEncoding,
type: sort,
}
: undefined
: undefined,
manualSortConfig,
alphabeticalSortConfig
)
.then((data) => {
const { lt, tt, metric } = data;
Expand Down Expand Up @@ -246,7 +286,7 @@ const PivotTable: React.FC<PivotTableProps> = function PivotTableComponent(props
<tr className="">
{dimsInRow.map((x) => (
<td className="bg-secondary text-secondary-foreground p-2 m-1 text-xs border whitespace-nowrap" colSpan={1}>
{x.name}
{x.titleOverride || x.name}
</td>
))}
{measInRow.length > 0 && (
Expand Down
7 changes: 5 additions & 2 deletions packages/graphic-walker/src/components/pivotTable/inteface.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
import { IAggregator } from "../../interfaces";
export type NestSortToken = {
priority: number;
value: string | number;
};

export interface INestNode {
key: string | number;
value: string | number;
sort: string | number;
sort: NestSortToken;
uniqueKey: string;
fieldKey: string;
children: INestNode[];
Expand Down
12 changes: 6 additions & 6 deletions packages/graphic-walker/src/components/pivotTable/leftTree.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import React, { ReactNode, useMemo } from 'react';
import { INestNode } from './inteface';
import { IField } from '../../interfaces';
import { IField, IViewField } from '../../interfaces';
import { MinusCircleIcon, PlusCircleIcon } from '@heroicons/react/24/outline';
import { formatDate } from '@/utils';
import { formatDate, getMeaAggName } from '@/utils';
import { parsedOffsetDate } from '@/lib/op/offset';

function getChildCount(node: INestNode): number {
Expand Down Expand Up @@ -68,8 +68,8 @@ function renderTree(

export interface TreeProps {
data: INestNode;
dimsInRow: IField[];
measInRow: IField[];
dimsInRow: IViewField[];
measInRow: IViewField[];
onHeaderCollapse: (node: INestNode) => void;
enableCollapse: boolean;
displayOffset?: number;
Expand All @@ -89,7 +89,7 @@ const LeftTree: React.FC<TreeProps> = (props) => {
key={`0-${measInRow[0].fid}-${measInRow[0].aggName}`}
className="bg-secondary text-secondary-foreground whitespace-nowrap p-2 text-xs m-1 border"
>
{measInRow[0].aggName}({measInRow[0].name})
{measInRow[0].titleOverride || getMeaAggName(measInRow[0].name, measInRow[0].aggName, measInRow[0].windowAgg)}
</td>,
]);
for (let j = 1; j < measInRow.length; j++) {
Expand All @@ -98,7 +98,7 @@ const LeftTree: React.FC<TreeProps> = (props) => {
key={`${j}-${measInRow[j].fid}-${measInRow[j].aggName}`}
className="bg-secondary text-secondary-foreground whitespace-nowrap p-2 text-xs m-1 border"
>
{measInRow[j].aggName}({measInRow[j].name})
{measInRow[j].titleOverride || getMeaAggName(measInRow[j].name, measInRow[j].aggName, measInRow[j].windowAgg)}
</td>,
]);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,18 +1,18 @@
import React from 'react';
import { useMemo } from 'react';
import { IField, IRow, IVisualConfig } from '../../interfaces';
import { IRow, IViewField } from '../../interfaces';
import { getMeaAggKey } from '../../utils';
import { format } from 'd3-format';

interface MetricTableProps {
matrix: any[][];
meaInRows: IField[];
meaInColumns: IField[];
meaInRows: IViewField[];
meaInColumns: IViewField[];
numberFormat: string;
}

function getCellData(cell: IRow, measure: IField, formatter: (value: unknown) => string) {
const meaKey = getMeaAggKey(measure.fid, measure.aggName);
function getCellData(cell: IRow, measure: IViewField, formatter: (value: unknown) => string) {
const meaKey = getMeaAggKey(measure.fid, measure.aggName, measure.windowAgg);
if (cell[meaKey] === undefined) {
return '--';
}
Expand All @@ -23,7 +23,6 @@ function getCellData(cell: IRow, measure: IField, formatter: (value: unknown) =>
const MetricTable: React.FC<MetricTableProps> = React.memo(
(props) => {
const { matrix, meaInRows, meaInColumns, numberFormat } = props;

const numberFormatter = useMemo<(value: unknown) => string>(() => {
const numberFormatter = numberFormat ? format(numberFormat) : (v: number) => v.toLocaleString();
return (value: unknown) => {
Expand Down Expand Up @@ -106,7 +105,7 @@ const MetricTable: React.FC<MetricTableProps> = React.memo(
}

return false;
}
},
);

export default MetricTable;
10 changes: 5 additions & 5 deletions packages/graphic-walker/src/components/pivotTable/topTree.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import React, { ReactNode, useEffect, useMemo } from 'react';
import { INestNode } from './inteface';
import { IField } from '../../interfaces';
import { IField, IViewField } from '../../interfaces';
import { MinusCircleIcon, PlusCircleIcon } from '@heroicons/react/24/outline';
import { formatDate } from '@/utils';
import { formatDate, getMeaAggName } from '@/utils';
import { parsedOffsetDate } from '@/lib/op/offset';

function getChildCount(node: INestNode): number {
Expand Down Expand Up @@ -64,8 +64,8 @@ function renderTree(

export interface TreeProps {
data: INestNode;
dimsInCol: IField[];
measInCol: IField[];
dimsInCol: IViewField[];
measInCol: IViewField[];
onHeaderCollapse: (node: INestNode) => void;
onTopTreeHeaderRowNumChange: (num: number) => void;
enableCollapse: boolean;
Expand Down Expand Up @@ -98,7 +98,7 @@ const TopTree: React.FC<TreeProps> = (props) => {
key={`${cellRows.length}-${m.fid}-${m.aggName}-${idx}`}
className="bg-secondary text-secondary-foreground whitespace-nowrap p-2 text-xs m-1 border"
>
{m.aggName}({m.name})
{m.titleOverride || getMeaAggName(m.name, m.aggName, m.windowAgg)}
</td>
))
)
Expand Down
Loading