Skip to content

Commit

Permalink
fix: cannot edit single facet with agg (#378)
Browse files Browse the repository at this point in the history
* fix: cannot edit single facet with agg

* chore: add comment

* chore: update dsl-parser

* fix: sort nominal domain

* fix: new aggergation
  • Loading branch information
islxyqwe authored May 7, 2024
1 parent 8456440 commit 63d18e5
Show file tree
Hide file tree
Showing 3 changed files with 132 additions and 92 deletions.
2 changes: 1 addition & 1 deletion packages/duckdb-wasm-computation/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
"dependencies": {
"@duckdb/duckdb-wasm": "^1.28.0",
"@kanaries/graphic-walker": "0.4.63",
"@kanaries/gw-dsl-parser": "^0.1.45-rc4",
"@kanaries/gw-dsl-parser": "^0.1.48-rc3",
"apache-arrow": "^13.0.0",
"nanoid": "^5.0.1"
},
Expand Down
192 changes: 119 additions & 73 deletions packages/graphic-walker/src/components/painter/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,6 @@ function getMarkFor(types: ISemanticType[]) {
return 'square';
}


type Dimension = {
field: IViewField;
domain?: IPaintDimension;
Expand Down Expand Up @@ -173,16 +172,32 @@ const AggPainterContent = (props: {
const { t } = useTranslation();
const mediaTheme = useContext(themeContext);
const computation = useCompututaion();
const fields = useMemo(
() => [props.x, props.y, props.color, props.size, props.opacity, props.shape].filter((x) => x).map((x) => x!.field),
[props.x, props.y, props.color, props.size, props.opacity, props.shape]
);
const [viewDimensions, viewMeasures] = useMemo(() => {
const fields = [props.x, props.y, props.color, props.size, props.opacity, props.shape].filter((x) => x).map((x) => x!.field);
return [fields.filter((x) => x.analyticType === 'dimension'), fields.filter((x) => x.analyticType === 'measure')];
}, [props.x, props.y, props.color, props.size, props.opacity, props.shape]);
const totalFields = deduper(
fields.concat(
props.facets.flatMap((x) =>
x.dimensions.map((d) => ({
fid: d.fid,
name: d.fid,
semanticType: d.domain.type,
analyticType: d.domain.type === 'nominal' ? 'dimension' : 'measure',
}))
)
),
(x) => x.fid
);
return [totalFields.filter((x) => x.analyticType === 'dimension'), fields.filter((x) => x.analyticType === 'measure')];
}, [fields, props.facets]);
const paintDimensions = useMemo(() => {
return deduper(
[props.x, props.y, props.color, props.size, props.opacity, props.shape].filter((x) => x).filter((x) => x!.domain),
(x) => x!.field.fid
).map((x) => x!.domain!);
}, [props.x, props.y, props.color, props.size, props.opacity, props.shape]);
}, []);
const brushSizeRef = useRef(GLOBAL_CONFIG.PAINT_DEFAULT_BRUSH_SIZE);
const [brushSize, setBrushSize] = useState(GLOBAL_CONFIG.PAINT_DEFAULT_BRUSH_SIZE);
brushSizeRef.current = brushSize;
Expand All @@ -208,7 +223,7 @@ const AggPainterContent = (props: {
const pid = props.paintMapRef.current![indexes[i]];
return {
...x,
[PAINT_FIELD_ID]: pid === 0 ? facetResult[i] : props.dict[pid]?.name,
[PAINT_FIELD_ID]: pid === 0 ? facetResult[i] ?? props.dict[1].name : props.dict[pid]?.name,
[PIXEL_INDEX]: indexes[i],
};
});
Expand Down Expand Up @@ -302,7 +317,7 @@ const AggPainterContent = (props: {
Object.values(spec.encoding).forEach((c: any) => {
if (!c) return;
if (c.aggregate === null) return;
const targetField = props.allFields.find((f) => f.fid === c.field && f.analyticType === 'measure');
const targetField = viewMeasures.find((f) => f.fid === c.field);
if (targetField) {
c.title = getMeaAggName(targetField.name, targetField.aggName);
c.field = getMeaAggKey(targetField.fid, targetField.aggName);
Expand Down Expand Up @@ -351,7 +366,7 @@ const AggPainterContent = (props: {
);
rerender();
};
const handleDraw = (e: ScenegraphEvent, item: Item<any> | null | undefined) => {
const handleDraw = (e: ScenegraphEvent) => {
e.stopPropagation();
e.preventDefault();
const paint = (x: number, y: number) => {
Expand Down Expand Up @@ -542,16 +557,24 @@ const PainterContent = (props: {
const mediaTheme = useContext(themeContext);
const computation = useCompututaion();
const fields = useMemo(
() => [
{
...props.x,
analyticType: 'measure' as const,
},
{
...props.y,
analyticType: 'measure' as const,
},
],
() =>
deduper(
[
{
...props.x,
analyticType: 'measure' as const,
},
{
...props.y,
analyticType: 'measure' as const,
},
].concat(
props.facets.flatMap((x) =>
x.dimensions.map((d) => ({ fid: d.fid, name: d.fid, semanticType: d.domain.type, analyticType: 'measure' as const }))
)
),
(x) => x.fid
),
[props.x, props.y]
);
const brushSizeRef = useRef(GLOBAL_CONFIG.PAINT_DEFAULT_BRUSH_SIZE);
Expand Down Expand Up @@ -922,7 +945,7 @@ const Painter = ({ themeConfig, themeKey }: { themeConfig?: GWGlobalConfig; them
};
} else {
const res = await fieldStat(compuation, f, { range: false, values: true, valuesMeta: false }, allFields);
const value = res.values.map((x) => x.value);
const value = res.values.map((x) => x.value).sort();
return {
domain: {
type: 'nominal',
Expand Down Expand Up @@ -966,64 +989,87 @@ const Painter = ({ themeConfig, themeKey }: { themeConfig?: GWGlobalConfig; them
if (paintInfo) {
if (paintInfo.type === 'exist') {
const lastFacet = paintInfo.item.facets.at(-1)!;
if (
paintInfo.new.type === 'new' &&
(lastFacet.dimensions[0]?.fid !== paintInfo.new.y.fid ||
if (paintInfo.new.type === 'new') {
// is non-aggergated paint map
if (
lastFacet.dimensions[0]?.fid !== paintInfo.new.y.fid ||
lastFacet.dimensions[1]?.fid !== paintInfo.new.x.fid ||
!isDomainZeroscaledAs(lastFacet.dimensions[0]?.domain, zeroScale) ||
!isDomainZeroscaledAs(lastFacet.dimensions[1]?.domain, zeroScale))
) {
const { domainX, domainY, map } = await getNewMap(paintInfo.new);
// adapter for old single facet
if (paintInfo.item.facets[0] && !paintInfo.item.facets[0].usedColor) {
paintInfo.item.facets[0].usedColor = paintInfo.item.usedColor;
!isDomainZeroscaledAs(lastFacet.dimensions[1]?.domain, zeroScale)
) {
// is not same channel, create a new facet
const { domainX, domainY, map } = await getNewMap(paintInfo.new);
// adapter for old single facet
if (paintInfo.item.facets[0] && !paintInfo.item.facets[0].usedColor) {
paintInfo.item.facets[0].usedColor = paintInfo.item.usedColor;
}
paintMapRef.current = map;
unstable_batchedUpdates(() => {
setDict(paintInfo.item.dict);
setDomainX(domainX);
setDomainY(domainY);
setFacets(paintInfo.item.facets);
setX(paintInfo.new.x);
setY(paintInfo.new.y);
setAggInfo(null);
setLoading(false);
});
} else {
// editing the existing paint map
const x = lastFacet.dimensions.at(-1)?.fid;
const y = lastFacet.dimensions.at(-2)?.fid;
const xf = allFields.find((a) => a.fid === x);
const yf = allFields.find((a) => a.fid === y);
unstable_batchedUpdates(() => {
setDict(paintInfo.item.dict);
setDomainX(lastFacet.dimensions.at(-1));
setDomainY(lastFacet.dimensions.at(-2));
setFacets(paintInfo.item.facets.slice(0, -1));
setX(xf);
setY(yf);
setAggInfo(null);
setLoading(false);
});
}
} else if (paintInfo.new.type === 'agg') {
// is aggergated paint map
if (
!getAggDimensionFields(paintInfo.new).every((f, i) => {
const last = lastFacet.dimensions[i];
return f?.fid === last?.fid && isDomainZeroscaledAs(last?.domain, zeroScale);
})
) {
// is not same channel, create a new facet
const { map, ...info } = await getNewAggMap(paintInfo.new);
paintMapRef.current = map;
unstable_batchedUpdates(() => {
setDict(defaultScheme);
setAggInfo(info);
setFacets(paintInfo.item.facets);
setDomainX(undefined);
setDomainY(undefined);
setX(undefined);
setY(undefined);
setLoading(false);
});
} else {
// editing the existing aggergated paint map
paintMapRef.current = await decompressBitMap(lastFacet.map);
const { map, ...info } = await getNewAggMap(paintInfo.new);

unstable_batchedUpdates(() => {
setDict(paintInfo.item.dict);
setAggInfo(info);
setFacets(paintInfo.item.facets.slice(0, -1));
setDomainX(undefined);
setDomainY(undefined);
setX(undefined);
setY(undefined);
setLoading(false);
});
}
paintMapRef.current = map;
unstable_batchedUpdates(() => {
setDict(paintInfo.item.dict);
setDomainX(domainX);
setDomainY(domainY);
setFacets(paintInfo.item.facets);
setX(paintInfo.new.x);
setY(paintInfo.new.y);
setAggInfo(null);
setLoading(false);
});
} else if (
paintInfo.new.type === 'agg' &&
!getAggDimensionFields(paintInfo.new).every((f, i) => {
const last = lastFacet.dimensions[i];
return f?.fid === last?.fid && isDomainZeroscaledAs(last?.domain, zeroScale);
})
) {
const { map, ...info } = await getNewAggMap(paintInfo.new);
paintMapRef.current = map;
unstable_batchedUpdates(() => {
setDict(defaultScheme);
setAggInfo(info);
setFacets([]);
setDomainX(undefined);
setDomainY(undefined);
setX(undefined);
setY(undefined);
setLoading(false);
});
} else {
paintMapRef.current = await decompressBitMap(lastFacet.map);
const x = lastFacet.dimensions.at(-1)?.fid;
const y = lastFacet.dimensions.at(-2)?.fid;
const xf = allFields.find((a) => a.fid === x);
const yf = allFields.find((a) => a.fid === y);
unstable_batchedUpdates(() => {
setDict(paintInfo.item.dict);
setDomainX(lastFacet.dimensions.at(-1));
setDomainY(lastFacet.dimensions.at(-2));
setFacets(paintInfo.item.facets.slice(0, -1));
setX(xf);
setY(yf);
setAggInfo(null);
setLoading(false);
});
throw new Error('paintInfo.new.type is not supported');
}
} else if (paintInfo.type === 'new') {
const { domainX, domainY, map } = await getNewMap(paintInfo);
Expand Down
30 changes: 12 additions & 18 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -1018,10 +1018,10 @@
"@jridgewell/resolve-uri" "3.1.0"
"@jridgewell/sourcemap-codec" "1.4.14"

"@kanaries/gw-dsl-parser@^0.1.45-rc4":
version "0.1.45-rc4"
resolved "https://registry.npmjs.org/@kanaries/gw-dsl-parser/-/gw-dsl-parser-0.1.45-rc4.tgz#5ac6c41fda03ae3d0e8b5f7e136d2e751040d58f"
integrity sha512-RpvxPyct7qw8NBjHgTjGNQv0V/3NB17OJ1g8/jbysyrO02L+o6h9MLwiJBIE7vzpk9sBVeQzXjw3fU/nclxj0g==
"@kanaries/gw-dsl-parser@^0.1.48-rc3":
version "0.1.48-rc3"
resolved "https://registry.yarnpkg.com/@kanaries/gw-dsl-parser/-/gw-dsl-parser-0.1.48-rc3.tgz#021fc2e082d55050b0282aa6dd28ffb22e4cd53f"
integrity sha512-nN0q5bGL4GaHGf19JO80/UMIq6hbkxbseB4qK6rm1qxu/87tsuMq8xZuLb10yCBeia0wFo3+Fn/ulDJ/eSp+LQ==

"@kanaries/react-beautiful-dnd@^0.1.1":
version "0.1.1"
Expand Down Expand Up @@ -2036,10 +2036,10 @@
"@types/react" "*"
"@types/reactcss" "*"

"@types/react-dom@*", "@types/react-dom@^18.2.15":
version "18.2.21"
resolved "https://registry.yarnpkg.com/@types/react-dom/-/react-dom-18.2.21.tgz#b8c81715cebdebb2994378616a8d54ace54f043a"
integrity sha512-gnvBA/21SA4xxqNXEwNiVcP0xSGHh/gi1VhWv9Bl46a0ItbTT5nFY+G9VSQpaG/8N/qdJpJ+vftQ4zflTtnjLw==
"@types/react-dom@*", "@types/react-dom@^18.2.15", "@types/react-dom@^18.x":
version "18.3.0"
resolved "https://registry.yarnpkg.com/@types/react-dom/-/react-dom-18.3.0.tgz#0cbc818755d87066ab6ca74fbedb2547d74a82b0"
integrity sha512-EhwApuTmMBmXuFOikhQLIBUn6uFg81SwLMOAUgodJF14SOBOCMdU04gDoYi0WOJJHD144TL32z4yDqCW3dnkQg==
dependencies:
"@types/react" "*"

Expand All @@ -2050,13 +2050,12 @@
dependencies:
"@types/react" "*"

"@types/react@*", "@types/react@^18.2.37":
version "18.2.64"
resolved "https://registry.yarnpkg.com/@types/react/-/react-18.2.64.tgz#3700fbb6b2fa60a6868ec1323ae4cbd446a2197d"
integrity sha512-MlmPvHgjj2p3vZaxbQgFUQFvD8QiZwACfGqEdDSWou5yISWxDQ4/74nCAwsUiX7UFLKZz3BbVSPj+YxeoGGCfg==
"@types/react@*", "@types/react@^18.2.37", "@types/react@^18.x":
version "18.3.1"
resolved "https://registry.yarnpkg.com/@types/react/-/react-18.3.1.tgz#fed43985caa834a2084d002e4771e15dfcbdbe8e"
integrity sha512-V0kuGBX3+prX+DQ/7r2qsv1NsdfnCLnTgnRJ1pYnxykBhGMz+qj+box5lq7XsO5mtZsBqpjwwTu/7wszPfMBcw==
dependencies:
"@types/prop-types" "*"
"@types/scheduler" "*"
csstype "^3.0.2"

"@types/reactcss@*":
Expand All @@ -2066,11 +2065,6 @@
dependencies:
"@types/react" "*"

"@types/scheduler@*":
version "0.16.6"
resolved "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.6.tgz#eb26db6780c513de59bee0b869ef289ad3068711"
integrity sha512-Vlktnchmkylvc9SnwwwozTv04L/e1NykF5vgoQ0XTmI8DD+wxfjQuHuvHS3p0r2jz2x2ghPs2h1FVeDirIteWA==

"@types/semver@^7.5.0":
version "7.5.5"
resolved "https://registry.npmjs.org/@types/semver/-/semver-7.5.5.tgz#deed5ab7019756c9c90ea86139106b0346223f35"
Expand Down

0 comments on commit 63d18e5

Please sign in to comment.