Skip to content

Commit

Permalink
Merge branch 'master' into legend-gap-removal
Browse files Browse the repository at this point in the history
  • Loading branch information
nickofthyme committed Jan 14, 2021
2 parents 9234f4a + 3df73d0 commit 47493e2
Show file tree
Hide file tree
Showing 28 changed files with 552 additions and 176 deletions.
5 changes: 3 additions & 2 deletions .eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,8 @@ module.exports = {
'global-require': 1,
'import/no-dynamic-require': 1,
'no-shadow': 1,
'no-param-reassign': 1,
'no-param-reassign': [1, { props: false }],
'@typescript-eslint/comma-spacing': 0,
'react/no-array-index-key': 1,
'react/prefer-stateless-function': 1,
'react/require-default-props': 'off',
Expand Down Expand Up @@ -342,7 +343,7 @@ module.exports = {
'prefer-destructuring': [
'warn',
{
array: true,
array: false,
object: true,
},
{
Expand Down
33 changes: 2 additions & 31 deletions .playground/playground.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -38,39 +38,10 @@

import React from 'react';

import { Chart, Settings, Partition, PartitionLayout } from '../src';
import { Example } from '../stories/icicle/01_unix_icicle';

export class Playground extends React.Component {
render() {
return (
<div className="chart">
<Chart className="story-chart">
<Settings showLegend flatLegend={false} />
<Partition
id="spec_1"
data={[
{ cat1: 'A', cat2: 'A', val: 1 },
{ cat1: 'A', cat2: 'B', val: 1 },
{ cat1: 'B', cat2: 'A', val: 1 },
{ cat1: 'B', cat2: 'B', val: 1 },
{ cat1: 'C', cat2: 'A', val: 1 },
{ cat1: 'C', cat2: 'B', val: 1 },
]}
valueAccessor={(d: any) => d.val as number}
layers={[
{
groupByRollup: (d: any) => d.cat1,
},
{
groupByRollup: (d: any) => d.cat2,
},
]}
config={{
partitionLayout: PartitionLayout.sunburst,
}}
/>
</Chart>
</div>
);
return <Example />;
}
}
6 changes: 4 additions & 2 deletions api/charts.api.md
Original file line number Diff line number Diff line change
Expand Up @@ -1258,6 +1258,8 @@ export interface PartitionLayer {
export const PartitionLayout: Readonly<{
sunburst: "sunburst";
treemap: "treemap";
icicle: "icicle";
flame: "flame";
}>;

// @public (undocumented)
Expand Down Expand Up @@ -1958,8 +1960,8 @@ export type YDomainRange = YDomainBase & DomainRange;
// src/chart_types/heatmap/layout/types/config_types.ts:28:13 - (ae-forgotten-export) The symbol "SizeRatio" needs to be exported by the entry point index.d.ts
// src/chart_types/heatmap/layout/types/config_types.ts:60:5 - (ae-forgotten-export) The symbol "TextAlign" needs to be exported by the entry point index.d.ts
// src/chart_types/heatmap/layout/types/config_types.ts:61:5 - (ae-forgotten-export) The symbol "TextBaseline" needs to be exported by the entry point index.d.ts
// src/chart_types/partition_chart/layout/types/config_types.ts:126:5 - (ae-forgotten-export) The symbol "TimeMs" needs to be exported by the entry point index.d.ts
// src/chart_types/partition_chart/layout/types/config_types.ts:127:5 - (ae-forgotten-export) The symbol "AnimKeyframe" needs to be exported by the entry point index.d.ts
// src/chart_types/partition_chart/layout/types/config_types.ts:128:5 - (ae-forgotten-export) The symbol "TimeMs" needs to be exported by the entry point index.d.ts
// src/chart_types/partition_chart/layout/types/config_types.ts:129:5 - (ae-forgotten-export) The symbol "AnimKeyframe" needs to be exported by the entry point index.d.ts
// src/chart_types/partition_chart/specs/index.ts:48:13 - (ae-forgotten-export) The symbol "NodeColorAccessor" needs to be exported by the entry point index.d.ts
// src/commons/series_id.ts:39:3 - (ae-forgotten-export) The symbol "SeriesKey" needs to be exported by the entry point index.d.ts

Expand Down
2 changes: 2 additions & 0 deletions src/chart_types/partition_chart/layout/types/config_types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ import { Font, FontFamily, PartialFont } from './types';
export const PartitionLayout = Object.freeze({
sunburst: 'sunburst' as const,
treemap: 'treemap' as const,
icicle: 'icicle' as const,
flame: 'flame' as const,
});

/** @public */
Expand Down
35 changes: 20 additions & 15 deletions src/chart_types/partition_chart/layout/utils/group_by_rollup.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,9 @@ interface MapNode extends NodeDescriptor {

export type PrimitiveValue = string | number | null; // there could be more but sufficient for now
type Key = PrimitiveValue;
type Sorter = (a: number, b: number) => number;

export type Sorter = (a: number, b: number) => number;

type NodeSorter = (a: ArrayEntry, b: ArrayEntry) => number;

export const entryKey = ([key]: ArrayEntry) => key;
Expand Down Expand Up @@ -99,7 +101,7 @@ export function groupByRollup(
const statistics: Statistics = {
globalAggregate: NaN,
};
const reductionMap = factTable.reduce((p: HierarchyOfMaps, n, index) => {
const reductionMap: HierarchyOfMaps = factTable.reduce((p: HierarchyOfMaps, n, index) => {
const keyCount = keyAccessors.length;
let pointer: HierarchyOfMaps = p;
keyAccessors.forEach((keyAccessor, i) => {
Expand Down Expand Up @@ -132,22 +134,22 @@ export function groupByRollup(

function getRootArrayNode(): ArrayNode {
const children: HierarchyOfArrays = [];
const bootstrap = {
const bootstrap: Omit<ArrayNode, typeof PARENT_KEY> = {
[AGGREGATE_KEY]: NaN,
[DEPTH_KEY]: NaN,
[CHILDREN_KEY]: children,
[INPUT_KEY]: [] as number[],
[PATH_KEY]: [] as number[],
[SORT_INDEX_KEY]: 0,
[STATISTICS_KEY]: { globalAggregate: 0 },
};
Object.assign(bootstrap, { [PARENT_KEY]: bootstrap });
const result: ArrayNode = bootstrap as ArrayNode;
return result;
return { ...bootstrap, [PARENT_KEY]: bootstrap } as ArrayNode; // TS doesn't yet handle bootstrapping but the `Omit` above retains guarantee for all props except `[PARENT_KEY`
}

/** @internal */
export function mapsToArrays(root: HierarchyOfMaps, sorter: NodeSorter): HierarchyOfArrays {
const groupByMap = (node: HierarchyOfMaps, parent: ArrayNode) =>
Array.from(
export function mapsToArrays(root: HierarchyOfMaps, sorter: NodeSorter | null): HierarchyOfArrays {
const groupByMap = (node: HierarchyOfMaps, parent: ArrayNode) => {
const items = Array.from(
node,
([key, value]: [Key, MapNode]): ArrayEntry => {
const valueElement = value[CHILDREN_KEY];
Expand All @@ -168,12 +170,15 @@ export function mapsToArrays(root: HierarchyOfMaps, sorter: NodeSorter): Hierarc
);
return [key, newValue];
},
)
.sort(sorter)
.map((n: ArrayEntry, i) => {
entryValue(n).sortIndex = i;
return n;
}); // with the current algo, decreasing order is important
);
if (sorter !== null) {
items.sort(sorter);
}
return items.map((n: ArrayEntry, i) => {
entryValue(n).sortIndex = i;
return n;
});
}; // with the current algo, decreasing order is important
const tree = groupByMap(root, getRootArrayNode());
const buildPaths = ([, mapNode]: ArrayEntry, currentPath: number[]) => {
const newPath = [...currentPath, mapNode[SORT_INDEX_KEY]];
Expand Down
13 changes: 7 additions & 6 deletions src/chart_types/partition_chart/layout/utils/sunburst.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,12 @@ import { ArrayEntry, childrenAccessor, HierarchyOfArrays } from './group_by_roll

/** @internal */
export function sunburst(
nodes: HierarchyOfArrays,
outerNodes: HierarchyOfArrays,
areaAccessor: (e: ArrayEntry) => number,
{ x0, y0 }: Origin,
{ x0: outerX0, y0: outerY0 }: Origin,
clockwiseSectors: boolean,
specialFirstInnermostSector: boolean,
heightStep: number = 1,
): Array<Part> {
const result: Array<Part> = [];
const laySubtree = (nodes: HierarchyOfArrays, { x0, y0 }: Origin, depth: number) => {
Expand All @@ -36,14 +37,14 @@ export function sunburst(
const index = clockwiseSectors ? i : nodeCount - i - 1;
const node = nodes[depth === 1 && specialFirstInnermostSector ? (index + 1) % nodeCount : index];
const area = areaAccessor(node);
result.push({ node, x0: currentOffsetX, y0, x1: currentOffsetX + area, y1: y0 + 1 });
result.push({ node, x0: currentOffsetX, y0, x1: currentOffsetX + area, y1: y0 + heightStep });
const children = childrenAccessor(node);
if (children && children.length) {
laySubtree(children, { x0: currentOffsetX, y0: y0 + 1 }, depth + 1);
if (children.length > 0) {
laySubtree(children, { x0: currentOffsetX, y0: y0 + heightStep }, depth + 1);
}
currentOffsetX += area;
}
};
laySubtree(nodes, { x0, y0 }, 0);
laySubtree(outerNodes, { x0: outerX0, y0: outerY0 }, 0);
return result;
}
19 changes: 12 additions & 7 deletions src/chart_types/partition_chart/layout/utils/treemap.ts
Original file line number Diff line number Diff line change
Expand Up @@ -101,20 +101,25 @@ export function treemap(
areaAccessor: (e: ArrayEntry) => number,
topPaddingAccessor: (e: ArrayEntry) => number,
paddingAccessor: (e: ArrayEntry) => number,
{ x0, y0, width, height }: { x0: number; y0: number; width: number; height: number },
{
x0: outerX0,
y0: outerY0,
width: outerWidth,
height: outerHeight,
}: { x0: number; y0: number; width: number; height: number },
): Array<Part> {
if (nodes.length === 0) return [];
// some bias toward horizontal rectangles with a golden ratio of width to height
const vertical = width / GOLDEN_RATIO <= height;
const independentSize = vertical ? width : height;
const vertical = outerWidth / GOLDEN_RATIO <= outerHeight;
const independentSize = vertical ? outerWidth : outerHeight;
const vectorElements = bestVector(nodes, independentSize, areaAccessor);
const vector = vectorNodeCoordinates(vectorElements, x0, y0, vertical);
const vector = vectorNodeCoordinates(vectorElements, outerX0, outerY0, vertical);
const { dependentSize } = vectorElements;
return vector
.concat(
...vector.map(({ node, x0, y0, x1, y1 }) => {
const childrenNodes = entryValue(node)[CHILDREN_KEY];
if (!childrenNodes || !childrenNodes.length) {
if (childrenNodes.length === 0) {
return [];
}
const fullWidth = x1 - x0;
Expand Down Expand Up @@ -148,8 +153,8 @@ export function treemap(
topPaddingAccessor,
paddingAccessor,
vertical
? { x0, y0: y0 + dependentSize, width, height: height - dependentSize }
: { x0: x0 + dependentSize, y0, width: width - dependentSize, height },
? { x0: outerX0, y0: outerY0 + dependentSize, width: outerWidth, height: outerHeight - dependentSize }
: { x0: outerX0 + dependentSize, y0: outerY0, width: outerWidth - dependentSize, height: outerHeight },
),
);
}
Original file line number Diff line number Diff line change
Expand Up @@ -28,12 +28,14 @@ import {
groupByRollup,
mapEntryValue,
mapsToArrays,
Sorter,
} from '../utils/group_by_rollup';

export function getHierarchyOfArrays(
rawFacts: Relation,
valueAccessor: ValueAccessor,
groupByRollupAccessors: IndexedAccessorFn[],
sorter: Sorter | null = childOrders.descending,
): HierarchyOfArrays {
const aggregator = aggregators.sum;

Expand All @@ -52,6 +54,6 @@ export function getHierarchyOfArrays(
// size as data value vs size as number of pixels in the rectangle
return mapsToArrays(
groupByRollup(groupByRollupAccessors, valueAccessor, aggregator, facts),
aggregateComparator(mapEntryValue, childOrders.descending),
sorter && aggregateComparator(mapEntryValue, sorter),
);
}
Loading

0 comments on commit 47493e2

Please sign in to comment.