Skip to content

Commit

Permalink
refactor(runtime): simplfy library param
Browse files Browse the repository at this point in the history
  • Loading branch information
pearmini committed Jul 11, 2024
1 parent a169d5c commit 2b1e103
Show file tree
Hide file tree
Showing 6 changed files with 59 additions and 95 deletions.
14 changes: 4 additions & 10 deletions src/runtime/mark.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,11 @@ import {
G2Mark,
G2TransformOptions,
G2EncodeOptions,
G2Context,
} from './types/options';
import { MarkProps } from './types/mark';
import { NormalizedEncodeSpec, EncodeComponent, Encode } from './types/encode';
import {
ColumnOf,
TransformContext,
Transform,
TransformComponent,
} from './types/transform';
import { ColumnOf, Transform, TransformComponent } from './types/transform';
import {
applyDefaults,
applyDataTransform,
Expand All @@ -33,11 +29,9 @@ import {
export async function initializeMark(
partialMark: G2Mark,
partialProps: MarkProps,
library: G2Library,
createCanvas: () => HTMLCanvasElement,
context: G2Library,
): Promise<[G2Mark, G2MarkState]> {
// Apply transform to mark to derive indices, data, encode, etc,.
const context = { library, createCanvas };
const [I, transformedMark] = await applyMarkTransform(
partialMark,
partialProps,
Expand Down Expand Up @@ -144,7 +138,7 @@ export function createColumnOf(library: G2Library): ColumnOf {
async function applyMarkTransform(
mark: G2Mark,
props: MarkProps,
context: TransformContext,
context: G2Context,
): Promise<[number[], G2Mark]> {
const { library } = context;
const [useTransform] = useLibrary<
Expand Down
96 changes: 37 additions & 59 deletions src/runtime/plot.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { Vector2 } from '@antv/coord';
import { DisplayObject, IAnimation as GAnimation, HTML, Rect } from '@antv/g';
import { DisplayObject, IAnimation as GAnimation, Rect } from '@antv/g';
import { deepMix, upperFirst, isArray } from '@antv/util';
import { group, groups } from 'd3-array';
import { format } from 'd3-format';
Expand Down Expand Up @@ -96,9 +96,10 @@ type Store = Map<any, (options: G2ViewTree) => G2ViewTree>;
export async function plot<T extends G2ViewTree>(
options: T,
selection: Selection,
library: G2Library,
context: G2Context,
): Promise<any> {
const { library } = context;

const [useComposition] = useLibrary<
G2CompositionOptions,
CompositionComponent,
Expand All @@ -122,8 +123,6 @@ export async function plot<T extends G2ViewTree>(
.filter(defined),
);

const { createCanvas } = context;

const typeOf = (node: G2ViewTree) => {
const { type } = node;
if (typeof type === 'function') {
Expand Down Expand Up @@ -170,7 +169,7 @@ export async function plot<T extends G2ViewTree>(
const state = nodeState.get(node);
const [view, children] = state
? initializeState(state, node, library)
: await initializeView(node, library, createCanvas);
: await initializeView(node, context);
viewNode.set(view, node);
views.push(view);

Expand All @@ -185,9 +184,7 @@ export async function plot<T extends G2ViewTree>(
// should sync position scales among facets normally.
if (transformedNodes.every(isStandardView)) {
const states = await Promise.all(
transformedNodes.map((d) =>
initializeMarks(d, library, createCanvas),
),
transformedNodes.map((d) => initializeMarks(d, context)),
);
// Note!!!
// This will mutate scales for marks.
Expand All @@ -202,9 +199,7 @@ export async function plot<T extends G2ViewTree>(
// Apply transform to get data in advance for non-mark composition
// node, which makes sure that composition node can preprocess the
// data to produce more nodes based on it.
const n = isMark(node)
? node
: await applyTransform(node, library, createCanvas);
const n = isMark(node) ? node : await applyTransform(node, context);
const N = transform(n);
if (Array.isArray(N)) discovered.push(...N);
else if (typeof N === 'function') nodeGenerators.push(N());
Expand All @@ -228,12 +223,12 @@ export async function plot<T extends G2ViewTree>(
.attr('id', (view) => view.key)
.call(applyTranslate)
.each(function (view, i, element) {
plotView(view, select(element), transitions, library, context);
plotView(view, select(element), transitions, context);
enterContainer.set(view, element);
}),
(update) =>
update.call(applyTranslate).each(function (view, i, element) {
plotView(view, select(element), transitions, library, context);
plotView(view, select(element), transitions, context);
updateContainer.set(view, element);
}),
(exit) =>
Expand Down Expand Up @@ -266,12 +261,7 @@ export async function plot<T extends G2ViewTree>(
oldStore || new Map<any, (options: G2ViewTree) => G2ViewTree>();
const setState = (key, reducer = (x) => x) => store.set(key, reducer);
const options = viewNode.get(view);
const update = createUpdateView(
select(container),
options,
library,
context,
);
const update = createUpdateView(select(container), options, context);
return {
view,
container,
Expand Down Expand Up @@ -378,7 +368,7 @@ export async function plot<T extends G2ViewTree>(
const keyframe = new Promise<void>(async (resolve) => {
for (const node of nodeGenerator) {
const sizedNode = { width, height, ...node };
await plot(sizedNode, selection, library, context);
await plot(sizedNode, selection, context);
}
resolve();
});
Expand Down Expand Up @@ -430,9 +420,9 @@ function definedInteraction(library: G2Library) {
function createUpdateView(
selection: Selection,
options: G2ViewTree,
library: G2Library,
context: G2Context,
): G2ViewInstance['update'] {
const { library } = context;
const createDefinedInteraction = definedInteraction(library);
const filter = (d) => d[1] && d[1].props && d[1].props.reapplyWhenUpdate;
const interactions = inferInteraction(options);
Expand All @@ -443,20 +433,16 @@ function createUpdateView(

return async (newOptions, source, callback) => {
const transitions = [];
const [newView, newChildren] = await initializeView(
newOptions,
library,
context.createCanvas,
);
plotView(newView, selection, transitions, library, context);
const [newView, newChildren] = await initializeView(newOptions, context);
plotView(newView, selection, transitions, context);

// Update interaction need to reapply when update.
for (const name of updates.filter((d) => d !== source)) {
updateInteraction(name, selection, newOptions, newView, library, context);
updateInteraction(name, selection, newOptions, newView, context);
}

for (const child of newChildren) {
plot(child, selection, library, context);
plot(child, selection, context);
}
callback();
return { options: newOptions, view: newView };
Expand All @@ -468,9 +454,10 @@ function updateInteraction(
selection: Selection,
options: G2ViewTree,
view: G2ViewDescriptor,
library: G2Library,
context: G2Context,
) {
const { library } = context;

const [useInteraction] = useLibrary<
G2InteractionOptions,
InteractionComponent,
Expand Down Expand Up @@ -510,10 +497,11 @@ function updateInteraction(

async function initializeView(
options: G2View,
library: G2Library,
createCanvas: () => HTMLCanvasElement,
context: G2Context,
): Promise<[G2ViewDescriptor, G2ViewTree[]]> {
const flattenOptions = await transformMarks(options, library, createCanvas);
const { library } = context;

const flattenOptions = await transformMarks(options, context);

const mergedOptions = bubbleOptions(flattenOptions);

Expand All @@ -526,7 +514,7 @@ async function initializeView(
options.marks = [...mergedOptions.marks, ...mergedOptions.components];

const transformedOptions = coordinate2Transform(mergedOptions, library);
const state = await initializeMarks(transformedOptions, library);
const state = await initializeMarks(transformedOptions, context);
return initializeState(state, transformedOptions, library);
}

Expand Down Expand Up @@ -564,9 +552,10 @@ function bubbleOptions(options: G2View): G2View {

async function transformMarks(
options: G2View,
library: G2Library,
createCanvas: () => HTMLCanvasElement,
context: G2Context,
): Promise<G2View> {
const { library } = context;

const [useMark, createMark] = useLibrary<G2MarkOptions, MarkComponent, Mark>(
'mark',
library,
Expand All @@ -582,13 +571,13 @@ async function transformMarks(
const components = [];
const discovered = [...marks];
const { width, height } = computeRoughPlotSize(options);
const context = { options, width, height };
const markOptions = { options, width, height };

// Pre order traversal.
while (discovered.length) {
const [node] = discovered.splice(0, 1);
// Apply data transform to get data.
const mark = (await applyTransform(node, library, createCanvas)) as G2Mark;
const mark = (await applyTransform(node, context)) as G2Mark;
const { type = error('G2Mark type is required.'), key } = mark;

// For components.
Expand All @@ -607,7 +596,7 @@ async function transformMarks(
};

// Convert composite mark to marks.
const marks = await useMark(newMark, context);
const marks = await useMark(newMark, markOptions);
const M = Array.isArray(marks) ? marks : [marks];
discovered.unshift(...M.map((d, i) => ({ ...d, key: `${key}-${i}` })));
}
Expand All @@ -619,9 +608,10 @@ async function transformMarks(

async function initializeMarks(
options: G2View,
library: G2Library,
createCanvas?: () => HTMLCanvasElement,
context: G2Context,
): Promise<Map<G2Mark, G2MarkState>> {
const { library } = context;

const [useTheme] = useLibrary<G2ThemeOptions, ThemeComponent, Theme>(
'theme',
library,
Expand All @@ -643,12 +633,7 @@ async function initializeMarks(
for (const markOptions of partialMarks) {
const { type } = markOptions;
const { props = {} } = createMark(type);
const markAndState = await initializeMark(
markOptions,
props,
library,
createCanvas,
);
const markAndState = await initializeMark(markOptions, props, context);
if (markAndState) {
const [initializedMark, state] = markAndState;
markState.set(initializedMark, state);
Expand Down Expand Up @@ -880,9 +865,9 @@ async function plotView(
view: G2ViewDescriptor,
selection: Selection,
transitions: GAnimation[],
library: G2Library,
context: G2Context,
): Promise<void> {
const { library } = context;
const {
components,
theme,
Expand Down Expand Up @@ -1040,13 +1025,7 @@ async function plotView(
const { data } = state;
const { key, class: cls, type } = mark;
const viewNode = selection.select(`#${key}`);
const shapeFunction = createMarkShapeFunction(
mark,
state,
view,
library,
context,
);
const shapeFunction = createMarkShapeFunction(mark, state, view, context);
const enterFunction = createEnterFunction(mark, state, view, library);
const updateFunction = createUpdateFunction(mark, state, view, library);
const exitFunction = createExitFunction(mark, state, view, library);
Expand Down Expand Up @@ -1506,13 +1485,14 @@ function createMarkShapeFunction(
mark: G2Mark,
state: G2MarkState,
view: G2ViewDescriptor,
library: G2Library,
context: G2Context,
): (
data: Record<string, any>,
index: number,
element?: DisplayObject,
) => DisplayObject {
const { library } = context;

const [useShape] = useLibrary<G2ShapeOptions, ShapeComponent, Shape>(
'shape',
library,
Expand Down Expand Up @@ -1710,10 +1690,8 @@ function inferInteraction(

async function applyTransform<T extends G2ViewTree>(
node: T,
library: G2Library,
createCanvas: () => HTMLCanvasElement,
context: G2Context,
): Promise<G2ViewTree> {
const context = { library, createCanvas };
const { data, ...rest } = node;
if (data == undefined) return node;
const [, { data: newData }] = await applyDataTransform([], { data }, context);
Expand Down
6 changes: 2 additions & 4 deletions src/runtime/render.ts
Original file line number Diff line number Diff line change
Expand Up @@ -92,9 +92,7 @@ export function render<T extends G2ViewTree = G2ViewTree>(
// Make sure that plot chart after container is ready for every time.
const selection = select(canvas.document.documentElement);
canvas.ready
.then(() =>
plot<T>({ ...keyed, width, height, depth }, selection, library, context),
)
.then(() => plot<T>({ ...keyed, width, height, depth }, selection, context))
.then(() => {
// Place the center of whole scene at z axis' origin.
if (depth) {
Expand Down Expand Up @@ -147,7 +145,7 @@ export function renderToMountedElement<T extends G2ViewTree = G2ViewTree>(
emitter.emit(ChartEvent.BEFORE_RENDER);
// Plot the chart and mutate context.
// Make sure that plot chart after container is ready for every time.
plot<T>({ ...keyed, width, height }, selection, library, context)
plot<T>({ ...keyed, width, height }, selection, context)
.then(() => {
context.canvas?.requestAnimationFrame(() => {
emitter.emit(ChartEvent.AFTER_RENDER);
Expand Down
Loading

0 comments on commit 2b1e103

Please sign in to comment.