From 0d629142e57bc26443c92336ec6dbc7fee65a3e0 Mon Sep 17 00:00:00 2001 From: viruspc Date: Sun, 17 Sep 2023 00:43:17 +0800 Subject: [PATCH 1/5] fix(CONTRIBUTING.md): fix incorrect file path --- CONTRIBUTING.md | 2 +- CONTRIBUTING.zh-CN.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index ced842c48f..487d27f597 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -69,7 +69,7 @@ $ npm run dev The preview page can preview all chart cases under `__tests__/plots` and switch through the drop-down box according to different focus points. Chart cases are divided into the following categories based on different focus points: - animation - Animation-related cases, placed under `__tests__/plots/animation`. -- api - Chart API-related cases, placed under `__tests__/plots/tooltip`. +- api - Chart API-related cases, placed under `__tests__/plots/api`. - interaction - Interaction-related cases, placed under `__tests__/plots/interaction`. - static - Static drawing-related cases, placed under `__tests__/plots/static`. - tooltip - Tooltip-related cases, placed under `__tests__/plots/tooltip`. diff --git a/CONTRIBUTING.zh-CN.md b/CONTRIBUTING.zh-CN.md index 11ccb3ae5d..c168d1d823 100644 --- a/CONTRIBUTING.zh-CN.md +++ b/CONTRIBUTING.zh-CN.md @@ -70,7 +70,7 @@ $ npm run dev 预览界面可以预览 [`__tests__/plots`](./__tests__/plots) 下面的所有图表案例,并且通过下拉框进行切换。图表案例根据关注点不同,分为以下几类: - **animation** - 动画相关的案例,放在 [`__tests__/plots/animation`](./__tests__/plots/animation/) 下面。 -- **api** - Chart API 相关的案例,放在 [`__tests__/plots/tooltip`](./__tests__/plots/tooltip) 下面。 +- **api** - Chart API 相关的案例,放在 [`__tests__/plots/api`](./__tests__/plots/api) 下面。 - **interaction** - 交互相关的案例,放在 [`__tests__/plots/interaction`](./__tests__/plots/interaction) 下面。 - **static** - 静态绘制相关的案例,放在 [`__tests__/plots/static`](./__tests__/plots/static/) 下面。 - **tooltip** - tooltip 相关的案例,放在 [`__tests__/plots/tooltip`](./__tests__/plots/tooltip/) 下面。 From 0d0af262f053fc3e0f509108d8554bcc6873997c Mon Sep 17 00:00:00 2001 From: viruspc Date: Mon, 18 Sep 2023 09:12:12 +0800 Subject: [PATCH 2/5] feat(api): interval3D --- .../chart-render-3d-bar-chart-perspective.ts | 76 +++++++++++++ .../plots/api/chart-render-3d-bar-chart.ts | 75 +++++++++++++ __tests__/plots/api/index.ts | 2 + src/lib/threed.ts | 3 +- src/mark/index.ts | 1 + src/mark/interval3D.ts | 103 ++++++++++++++++++ src/shape/index.ts | 3 +- src/shape/interval3D/cube.ts | 71 ++++++++++++ 8 files changed, 332 insertions(+), 2 deletions(-) create mode 100644 __tests__/plots/api/chart-render-3d-bar-chart-perspective.ts create mode 100644 __tests__/plots/api/chart-render-3d-bar-chart.ts create mode 100644 src/mark/interval3D.ts create mode 100644 src/shape/interval3D/cube.ts diff --git a/__tests__/plots/api/chart-render-3d-bar-chart-perspective.ts b/__tests__/plots/api/chart-render-3d-bar-chart-perspective.ts new file mode 100644 index 0000000000..d6b7415106 --- /dev/null +++ b/__tests__/plots/api/chart-render-3d-bar-chart-perspective.ts @@ -0,0 +1,76 @@ +import { CameraType } from '@antv/g'; +import { Renderer as WebGLRenderer } from '@antv/g-webgl'; +import { Plugin as ThreeDPlugin, DirectionalLight } from '@antv/g-plugin-3d'; +import { Plugin as ControlPlugin } from '@antv/g-plugin-control'; +import { Runtime, extend } from '../../../src/api'; +import { corelib, threedlib } from '../../../src/lib'; + +export function chartRender3dBarChartPerspective(context) { + const { container } = context; + + // Create a WebGL renderer. + const renderer = new WebGLRenderer(); + renderer.registerPlugin(new ThreeDPlugin()); + renderer.registerPlugin(new ControlPlugin()); + + const Chart = extend(Runtime, { ...corelib(), ...threedlib() }); + const chart = new Chart({ + container, + renderer, + depth: 400, + }); + + const data: { x: string; z: string; y: number; color: number }[] = []; + for (let x = 0; x < 5; ++x) { + for (let z = 0; z < 5; ++z) { + data.push({ + x: `x-${x}`, + z: `z-${z}`, + y: 10 - x - z, + color: Math.random() < 0.33 ? 0 : Math.random() < 0.67 ? 1 : 2, + }); + } + } + + chart + .interval3D() + .data({ + type: 'inline', + value: data, + }) + .encode('x', 'x') + .encode('y', 'y') + .encode('z', 'z') + .encode('color', 'color') + .encode('shape', 'cube') + .coordinate({ type: 'cartesian3D' }) + .scale('x', { nice: true }) + .scale('y', { nice: true }) + .scale('z', { nice: true }) + .legend(false) + .axis('x', { gridLineWidth: 2 }) + .axis('y', { gridLineWidth: 2, titleBillboardRotation: -Math.PI / 2 }) + .axis('z', { gridLineWidth: 2 }); + + const finished = chart.render().then(() => { + const { canvas } = chart.getContext(); + const camera = canvas!.getCamera(); + camera.setPerspective(0.1, 5000, 80, 1280 / 960); + camera.setType(CameraType.ORBITING); + camera.rotate(-20, -20, 0); + + // Add a directional light into scene. + const light = new DirectionalLight({ + style: { + intensity: 2.5, + fill: 'white', + direction: [-1, 0, 1], + }, + }); + canvas!.appendChild(light); + }); + + return { finished }; +} + +chartRender3dBarChartPerspective.skip = true; diff --git a/__tests__/plots/api/chart-render-3d-bar-chart.ts b/__tests__/plots/api/chart-render-3d-bar-chart.ts new file mode 100644 index 0000000000..43010fa103 --- /dev/null +++ b/__tests__/plots/api/chart-render-3d-bar-chart.ts @@ -0,0 +1,75 @@ +import { CameraType } from '@antv/g'; +import { Renderer as WebGLRenderer } from '@antv/g-webgl'; +import { Plugin as ThreeDPlugin, DirectionalLight } from '@antv/g-plugin-3d'; +import { Plugin as ControlPlugin } from '@antv/g-plugin-control'; +import { Runtime, extend } from '../../../src/api'; +import { corelib, threedlib } from '../../../src/lib'; + +export function chartRender3dBarChart(context) { + const { container } = context; + + // Create a WebGL renderer. + const renderer = new WebGLRenderer(); + renderer.registerPlugin(new ThreeDPlugin()); + renderer.registerPlugin(new ControlPlugin()); + + const Chart = extend(Runtime, { ...corelib(), ...threedlib() }); + const chart = new Chart({ + container, + renderer, + depth: 400, + }); + + const data: { x: string; z: string; y: number; color: number }[] = []; + for (let x = 0; x < 5; ++x) { + for (let z = 0; z < 5; ++z) { + data.push({ + x: `x-${x}`, + z: `z-${z}`, + y: 10 - x - z, + color: Math.random() < 0.33 ? 0 : Math.random() < 0.67 ? 1 : 2, + }); + } + } + + chart + .interval3D() + .data({ + type: 'inline', + value: data, + }) + .encode('x', 'x') + .encode('y', 'y') + .encode('z', 'z') + .encode('color', 'color') + .encode('shape', 'cube') + .coordinate({ type: 'cartesian3D' }) + .scale('x', { nice: true }) + .scale('y', { nice: true }) + .scale('z', { nice: true }) + .legend(false) + .axis('x', { gridLineWidth: 2 }) + .axis('y', { gridLineWidth: 2, titleBillboardRotation: -Math.PI / 2 }) + .axis('z', { gridLineWidth: 2 }); + + const finished = chart.render().then(() => { + const { canvas } = chart.getContext(); + const camera = canvas!.getCamera(); + camera.setType(CameraType.ORBITING); + camera.rotate(-20, -20, 0); + + // Add a directional light into scene. + const light = new DirectionalLight({ + style: { + intensity: 2.5, + fill: 'white', + direction: [-1, 0, 1], + }, + }); + canvas!.appendChild(light); + }); + + return { finished }; +} + +chartRender3dBarChart.skip = true; diff --git a/__tests__/plots/api/index.ts b/__tests__/plots/api/index.ts index 69937a1608..12754ac91d 100644 --- a/__tests__/plots/api/index.ts +++ b/__tests__/plots/api/index.ts @@ -43,6 +43,8 @@ export { chartOnTextClick } from './chart-on-text-click'; export { chartOnComponentClick } from './chart-on-component-click'; export { chartRenderEvent } from './chart-render-event'; export { chartRender3dScatterPlot } from './chart-render-3d-scatter-plot'; +export { chartRender3dBarChart } from './chart-render-3d-bar-chart'; +export { chartRender3dBarChartPerspective } from './chart-render-3d-bar-chart-perspective'; export { chartRender3dScatterPlotPerspective } from './chart-render-3d-scatter-plot-perspective'; export { chartRender3dScatterPlotLegend } from './chart-render-3d-scatter-plot-legend'; export { chartRender3dLinePlot } from './chart-render-3d-line-plot'; diff --git a/src/lib/threed.ts b/src/lib/threed.ts index 4c55355361..94bb307bd9 100644 --- a/src/lib/threed.ts +++ b/src/lib/threed.ts @@ -1,6 +1,6 @@ import { Cartesian3D } from '../coordinate'; import { AxisZ } from '../component'; -import { Point3D, Line3D } from '../mark'; +import { Point3D, Line3D, Interval3D } from '../mark'; export function threedlib() { return { @@ -8,5 +8,6 @@ export function threedlib() { 'component.axisZ': AxisZ, 'mark.point3D': Point3D, 'mark.line3D': Line3D, + 'mark.interval3D': Interval3D, } as const; } diff --git a/src/mark/index.ts b/src/mark/index.ts index 05160b8a7d..8a47de62e8 100644 --- a/src/mark/index.ts +++ b/src/mark/index.ts @@ -4,6 +4,7 @@ export { Line } from './line'; export { Line3D } from './line3D'; export { Point } from './point'; export { Point3D } from './point3D'; +export { Interval3D } from './interval3D'; export { Text } from './text'; export { Cell } from './cell'; export { Area } from './area'; diff --git a/src/mark/interval3D.ts b/src/mark/interval3D.ts new file mode 100644 index 0000000000..b23f5a246d --- /dev/null +++ b/src/mark/interval3D.ts @@ -0,0 +1,103 @@ +import { Coordinate3D } from '@antv/coord'; +import { Band } from '@antv/scale'; +import { MarkComponent as MC, Vector3 } from '../runtime'; +import { PointMark } from '../spec'; +import { + MaybeZeroX, + MaybeZeroY, + MaybeZeroZ, + MaybeSize, + MaybeZeroY1, +} from '../transform'; +import { Sphere, IntervalCube } from '../shape'; +import { + baseGeometryChannels, + basePostInference, + basePreInference, + tooltip3d, +} from './utils'; + +export type PointOptions = Omit; + +/** + * Convert value for each channel to rect shapes. + * return bounding box and scale + */ +export const Interval3D: MC = (options) => { + console.log('interval3D_0 input - options', options); + return (index, scale, value, coordinate) => { + const { + x: X, + y: Y, + y1: Y1, + z: Z, + size: SZ, + dx: DX, + dy: DY, + dz: DZ, + } = value; + + // The scales for x and series channels must be band scale. + const x = scale.x as Band; + const z = scale.x as Band; + const [width, height, depth] = ( + coordinate as unknown as Coordinate3D + ).getSize(); + const x1x2 = (x: number, w: number, i: number) => [x, x + w]; + + console.log(coordinate.getSize()); + + // Calc the points of bounding box for the interval. + // They are start from left-top corner in clock wise order. + // TODO: series support + const P = Array.from(index, (i) => { + const groupWidthX = bandWidth(x, X[i]); + const groupWidthZ = bandWidth(z, Z[i]); + const x0 = +X[i]; + const z0 = +Z[i]; + const [x1, x2] = x1x2(x0, groupWidthX, i); + const [z1, z2] = x1x2(z0, groupWidthZ, i); + const y1 = +Y[i]; + const y2 = +Y1[i]; + + const p1 = [x1, y1, z1]; + const p2 = [x2, y2, z2]; + + return [ + (coordinate as unknown as Coordinate3D).map([...p1]), + (coordinate as unknown as Coordinate3D).map([...p2]), + ]; + }); + return [index, P]; + }; +}; + +function bandWidth(scale: Band, xz: any): number { + return scale.getBandWidth(scale.invert(xz)); +} + +const shape = { + cube: IntervalCube, +}; + +Interval3D.props = { + defaultShape: 'cube', + defaultLabelShape: 'label', + composite: false, + shape, + channels: [ + ...baseGeometryChannels({ shapes: Object.keys(shape) }), + { name: 'x', scale: 'band', required: true }, + { name: 'z', scale: 'band', required: true }, + { name: 'y', required: true }, + { name: 'series', scale: 'band' }, + { name: 'size' }, + ], + preInference: [ + ...basePreInference(), + { type: MaybeZeroX }, + { type: MaybeZeroY1 }, + { type: MaybeZeroZ }, + ], + postInference: [...basePostInference(), { type: MaybeSize }, ...tooltip3d()], +}; diff --git a/src/shape/index.ts b/src/shape/index.ts index 02f09af52f..9dce519918 100644 --- a/src/shape/index.ts +++ b/src/shape/index.ts @@ -32,6 +32,7 @@ export { Triangle as PointTriangle } from './point/triangle'; export { TriangleDown as PointTriangleDown } from './point/triangleDown'; export { Sphere } from './point3D/sphere'; export { Cube } from './point3D/cube'; +export { Cube as IntervalCube } from './interval3D/cube'; export { Vector as VectorShape } from './vector/vector'; export { Text as TextShape } from './text/text'; export { Badge as TextBadge } from './text/badge'; @@ -65,7 +66,7 @@ export { Liquid as LiquidShape } from './liquid/liquid'; export type { RectOptions as IntervalShapeOptions } from './interval/rect'; export type { HollowOptions as IntervalHollowOptions } from './interval/hollow'; export type { FunnelOptions as IntervalFunnelOptions } from './interval/funnel'; -export type { PyramidOptions as IntervalPyramidOptions } from './interval/pyramid'; +export type { PyramidOptions as IntervalPyline3DramidOptions } from './interval/pyramid'; export type { LineOptions as LineShapeOptions } from './line/line'; export type { SmoothOptions as LineSmoothOptions } from './line/smooth'; export type { HVOptions as LineHVOptions } from './line/hv'; diff --git a/src/shape/interval3D/cube.ts b/src/shape/interval3D/cube.ts new file mode 100644 index 0000000000..b09dab8506 --- /dev/null +++ b/src/shape/interval3D/cube.ts @@ -0,0 +1,71 @@ +import { MeshLambertMaterial, CubeGeometry, Mesh } from '@antv/g-plugin-3d'; +import { applyStyle, getOrigin, toOpacityKey } from '../utils'; +import { ShapeComponent as SC, Vector3 } from '../../runtime'; +import { select } from '../../utils/selection'; + +export type CubeOptions = Record; + +/** + * @see https://g.antv.antgroup.com/api/3d/geometry#cubegeometry + */ +export const Cube: SC = (options, context) => { + // Render border only when colorAttribute is stroke. + const { ...style } = options; + + // @ts-ignore + if (!context.cubeGeometry) { + const renderer = context.canvas.getConfig().renderer; + const plugin = renderer.getPlugin('device-renderer'); + const device = plugin.getDevice(); + // create a cube geometry + // @ts-ignore + context.cubeGeometry = new CubeGeometry(device, { + width: 1, + height: 1, + depth: 1, + }); + // create a material with Phong lighting model + // @ts-ignore + context.cubeMaterial = new MeshLambertMaterial(device); + } + + return (_points, value, defaults) => { + const points = _points as unknown as Vector3[]; + const { color: defaultColor } = defaults; + const { color = defaultColor, transform, opacity } = value; + const [cx, cy, cz] = getOrigin(points); + // value.co + const width = Math.abs(points[1][0] - points[0][0]); + const height = Math.abs(points[1][1] - points[0][1]); + const depth = Math.abs(points[1][2] - points[0][2]); + + const cube = new Mesh({ + style: { + x: cx, + y: cy, + z: cz, + // @ts-ignore + geometry: context.cubeGeometry, + // @ts-ignore + material: context.cubeMaterial, + }, + }); + cube.setOrigin(0, 0, 0); + cube.scale([width, height, depth]); + console.log({ scale: points[2], cx, cy, cz, width, height, depth }); + + const selection = select(cube) + .call(applyStyle, defaults) + .style('fill', color) + .style('transform', transform) + .style(toOpacityKey(options), opacity) + .call(applyStyle, style) + .node(); + console.log('Cube output', { selection }); + return selection; + }; +}; + +Cube.props = { + defaultMarker: 'cube', +}; From fe55ca49df02f0985c22b7ff2e8729f93b06ef9f Mon Sep 17 00:00:00 2001 From: viruspc Date: Tue, 19 Sep 2023 00:14:14 +0800 Subject: [PATCH 3/5] docs(interval3D): init docs --- .../chart-render-3d-bar-chart-perspective.ts | 4 +- .../plots/api/chart-render-3d-bar-chart.ts | 3 +- site/docs/api/chart.zh.md | 4 + site/docs/spec/threed/intervalThreed.en.md | 6 + site/docs/spec/threed/intervalThreed.zh.md | 106 ++++++++++++++++++ src/mark/interval3D.ts | 5 +- src/shape/interval3D/cube.ts | 6 +- 7 files changed, 124 insertions(+), 10 deletions(-) create mode 100644 site/docs/spec/threed/intervalThreed.en.md create mode 100644 site/docs/spec/threed/intervalThreed.zh.md diff --git a/__tests__/plots/api/chart-render-3d-bar-chart-perspective.ts b/__tests__/plots/api/chart-render-3d-bar-chart-perspective.ts index d6b7415106..b56182eb18 100644 --- a/__tests__/plots/api/chart-render-3d-bar-chart-perspective.ts +++ b/__tests__/plots/api/chart-render-3d-bar-chart-perspective.ts @@ -50,7 +50,9 @@ export function chartRender3dBarChartPerspective(context) { .legend(false) .axis('x', { gridLineWidth: 2 }) .axis('y', { gridLineWidth: 2, titleBillboardRotation: -Math.PI / 2 }) - .axis('z', { gridLineWidth: 2 }); + .axis('z', { gridLineWidth: 2 }) + .style('opacity', 0.7) + .style('cursor', 'pointer'); const finished = chart.render().then(() => { const { canvas } = chart.getContext(); diff --git a/__tests__/plots/api/chart-render-3d-bar-chart.ts b/__tests__/plots/api/chart-render-3d-bar-chart.ts index 43010fa103..2114c306af 100644 --- a/__tests__/plots/api/chart-render-3d-bar-chart.ts +++ b/__tests__/plots/api/chart-render-3d-bar-chart.ts @@ -50,7 +50,8 @@ export function chartRender3dBarChart(context) { .legend(false) .axis('x', { gridLineWidth: 2 }) .axis('y', { gridLineWidth: 2, titleBillboardRotation: -Math.PI / 2 }) - .axis('z', { gridLineWidth: 2 }); + .axis('z', { gridLineWidth: 2 }) + .style('opacity', 0.7); const finished = chart.render().then(() => { const { canvas } = chart.getContext(); diff --git a/site/docs/api/chart.zh.md b/site/docs/api/chart.zh.md index 3c4fcca131..6164466551 100644 --- a/site/docs/api/chart.zh.md +++ b/site/docs/api/chart.zh.md @@ -199,6 +199,10 @@ chart.render(); 添加 point3D 图形,具体见 [3d](/spec/threed/point-threed)。 +### `chart.interval3D` + +添加 interval3D 图形,具体见 [3d](/spec/threed/interval-threed)。 + ### `chart.line3D` 添加 line3D 图形,具体见 [3d](/spec/threed/line-threed)。 diff --git a/site/docs/spec/threed/intervalThreed.en.md b/site/docs/spec/threed/intervalThreed.en.md new file mode 100644 index 0000000000..0892beb548 --- /dev/null +++ b/site/docs/spec/threed/intervalThreed.en.md @@ -0,0 +1,6 @@ +--- +title: interval3D +order: 3 +--- + + diff --git a/site/docs/spec/threed/intervalThreed.zh.md b/site/docs/spec/threed/intervalThreed.zh.md new file mode 100644 index 0000000000..11427f10a7 --- /dev/null +++ b/site/docs/spec/threed/intervalThreed.zh.md @@ -0,0 +1,106 @@ +--- +title: interval3D +order: 3 +--- + +主要用于绘制 3D 条形图。 + +## 开始使用 + +首先需要使用 [@antv/g-webgl](https://g.antv.antgroup.com/api/renderer/webgl) 作为渲染器并注册以下两个插件: + +- [g-plugin-3d](https://g.antv.antgroup.com/plugins/3d) 提供 3D 场景下的几何、材质和光照 +- [g-plugin-control](https://g.antv.antgroup.com/plugins/control) 提供 3D 场景下的相机交互 + +然后设置 z 通道、scale 和 z 坐标轴,最后在场景中添加光源。 + +```js | ob +(() => { + // Create a WebGL renderer. + const renderer = new gWebgl.Renderer(); + renderer.registerPlugin(new gPluginControl.Plugin()); + renderer.registerPlugin(new gPlugin3d.Plugin()); + + const Chart = G2.extend(G2.Runtime, { ...G2.corelib(), ...G2.threedlib() }); + + // 初始化图表实例 + const chart = new Chart({ + container, + renderer, + width: 500, + height: 500, + depth: 400, + }); + + const data = []; + for (let x = 0; x < 5; ++x) { + for (let z = 0; z < 5; ++z) { + data.push({ + x: `x-${x}`, + z: `z-${z}`, + y: 10 - x - z, + color: Math.random() < 0.33 ? 0 : Math.random() < 0.67 ? 1 : 2, + }); + } + } + + chart + .interval3D() + .data({ + type: 'inline', + value: data, + }) + .encode('x', 'x') + .encode('y', 'y') + .encode('z', 'z') + .encode('color', 'color') + .encode('shape', 'cube') + .coordinate({ type: 'cartesian3D' }) + .scale('x', { nice: true }) + .scale('y', { nice: true }) + .scale('z', { nice: true }) + .legend(false) + .axis('x', { gridLineWidth: 2 }) + .axis('y', { gridLineWidth: 2, titleBillboardRotation: -Math.PI / 2 }) + .axis('z', { gridLineWidth: 2 }); + + chart.render().then(() => { + const { canvas } = chart.getContext(); + const camera = canvas.getCamera(); + camera.setPerspective(0.1, 5000, 80, 1280 / 960); + camera.setType(CameraType.ORBITING); + camera.rotate(-20, -20, 0); + + // Add a directional light into scene. + const light = new DirectionalLight({ + style: { + intensity: 2.5, + fill: 'white', + direction: [-1, 0, 1], + }, + }); + canvas.appendChild(light); + }); + + return chart.getContainer(); +})(); +``` + +更多的案例,可以查看[图表示例](/examples)页面。 + +## 选项 + +目前 interval3D 有以下一个内置 shape 图形: + +| 图形 | 描述 | 示例 | +| ------ | ---------- | ---- | +| cube | 绘制立方体 | | + +### cube + +| 属性 | 描述 | 类型 | 默认值 | +| ------- | --------------------------------------------- | ------------------------------ | --------- | +| fill | 图形的填充色 | `string` \| `Function` | - | +| opacity | 图形的整体透明度 | `number` \| `Function` | - | +| cursor | 鼠标样式。同 css 的鼠标样式,默认 'default'。 | `string` \| `Function` | 'default' | + diff --git a/src/mark/interval3D.ts b/src/mark/interval3D.ts index b23f5a246d..f1db9468ac 100644 --- a/src/mark/interval3D.ts +++ b/src/mark/interval3D.ts @@ -21,10 +21,9 @@ export type PointOptions = Omit; /** * Convert value for each channel to rect shapes. - * return bounding box and scale + * return two 3D points, which represents the bounding box of a rect. */ export const Interval3D: MC = (options) => { - console.log('interval3D_0 input - options', options); return (index, scale, value, coordinate) => { const { x: X, @@ -45,8 +44,6 @@ export const Interval3D: MC = (options) => { ).getSize(); const x1x2 = (x: number, w: number, i: number) => [x, x + w]; - console.log(coordinate.getSize()); - // Calc the points of bounding box for the interval. // They are start from left-top corner in clock wise order. // TODO: series support diff --git a/src/shape/interval3D/cube.ts b/src/shape/interval3D/cube.ts index b09dab8506..93a4425cd4 100644 --- a/src/shape/interval3D/cube.ts +++ b/src/shape/interval3D/cube.ts @@ -24,7 +24,7 @@ export const Cube: SC = (options, context) => { height: 1, depth: 1, }); - // create a material with Phong lighting model + // create a material with Lambert lighting model // @ts-ignore context.cubeMaterial = new MeshLambertMaterial(device); } @@ -34,7 +34,7 @@ export const Cube: SC = (options, context) => { const { color: defaultColor } = defaults; const { color = defaultColor, transform, opacity } = value; const [cx, cy, cz] = getOrigin(points); - // value.co + const width = Math.abs(points[1][0] - points[0][0]); const height = Math.abs(points[1][1] - points[0][1]); const depth = Math.abs(points[1][2] - points[0][2]); @@ -52,7 +52,6 @@ export const Cube: SC = (options, context) => { }); cube.setOrigin(0, 0, 0); cube.scale([width, height, depth]); - console.log({ scale: points[2], cx, cy, cz, width, height, depth }); const selection = select(cube) .call(applyStyle, defaults) @@ -61,7 +60,6 @@ export const Cube: SC = (options, context) => { .style(toOpacityKey(options), opacity) .call(applyStyle, style) .node(); - console.log('Cube output', { selection }); return selection; }; }; From 4f76ae53d7a0f5f77dd6b3f9bfd6827ef324b07d Mon Sep 17 00:00:00 2001 From: viruspc Date: Tue, 19 Sep 2023 00:21:24 +0800 Subject: [PATCH 4/5] fix: fix the bug in the example of intervalThree.zh.md --- site/.dumi/tsconfig.json | 6 ++++++ site/docs/spec/threed/intervalThreed.zh.md | 1 - 2 files changed, 6 insertions(+), 1 deletion(-) create mode 100644 site/.dumi/tsconfig.json diff --git a/site/.dumi/tsconfig.json b/site/.dumi/tsconfig.json new file mode 100644 index 0000000000..79711a82bb --- /dev/null +++ b/site/.dumi/tsconfig.json @@ -0,0 +1,6 @@ +{ + "extends": "../tsconfig.json", + "include": [ + "**/*" + ] +} \ No newline at end of file diff --git a/site/docs/spec/threed/intervalThreed.zh.md b/site/docs/spec/threed/intervalThreed.zh.md index 11427f10a7..caaa42c711 100644 --- a/site/docs/spec/threed/intervalThreed.zh.md +++ b/site/docs/spec/threed/intervalThreed.zh.md @@ -25,7 +25,6 @@ order: 3 // 初始化图表实例 const chart = new Chart({ - container, renderer, width: 500, height: 500, From acc5c1ea9ef99947574ab8e90e93d89930971f8a Mon Sep 17 00:00:00 2001 From: viruspc Date: Wed, 20 Sep 2023 00:23:13 +0800 Subject: [PATCH 5/5] feat(interval3D test): beautify test plots --- .../plots/api/chart-render-3d-bar-chart-perspective.ts | 8 +++++--- __tests__/plots/api/chart-render-3d-bar-chart.ts | 6 ++++-- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/__tests__/plots/api/chart-render-3d-bar-chart-perspective.ts b/__tests__/plots/api/chart-render-3d-bar-chart-perspective.ts index b56182eb18..30b1d7905f 100644 --- a/__tests__/plots/api/chart-render-3d-bar-chart-perspective.ts +++ b/__tests__/plots/api/chart-render-3d-bar-chart-perspective.ts @@ -18,6 +18,7 @@ export function chartRender3dBarChartPerspective(context) { container, renderer, depth: 400, + // padding: 10, }); const data: { x: string; z: string; y: number; color: number }[] = []; @@ -56,8 +57,9 @@ export function chartRender3dBarChartPerspective(context) { const finished = chart.render().then(() => { const { canvas } = chart.getContext(); - const camera = canvas!.getCamera(); - camera.setPerspective(0.1, 5000, 80, 1280 / 960); + if (!canvas) return; + const camera = canvas.getCamera(); + camera.setPerspective(0.1, 5000, 50, 1280 / 960); camera.setType(CameraType.ORBITING); camera.rotate(-20, -20, 0); @@ -69,7 +71,7 @@ export function chartRender3dBarChartPerspective(context) { direction: [-1, 0, 1], }, }); - canvas!.appendChild(light); + canvas.appendChild(light); }); return { finished }; diff --git a/__tests__/plots/api/chart-render-3d-bar-chart.ts b/__tests__/plots/api/chart-render-3d-bar-chart.ts index 2114c306af..40d3230f57 100644 --- a/__tests__/plots/api/chart-render-3d-bar-chart.ts +++ b/__tests__/plots/api/chart-render-3d-bar-chart.ts @@ -18,6 +18,7 @@ export function chartRender3dBarChart(context) { container, renderer, depth: 400, + padding: 50, }); const data: { x: string; z: string; y: number; color: number }[] = []; @@ -55,7 +56,8 @@ export function chartRender3dBarChart(context) { const finished = chart.render().then(() => { const { canvas } = chart.getContext(); - const camera = canvas!.getCamera(); + if (!canvas) return; + const camera = canvas.getCamera(); camera.setType(CameraType.ORBITING); camera.rotate(-20, -20, 0); @@ -67,7 +69,7 @@ export function chartRender3dBarChart(context) { direction: [-1, 0, 1], }, }); - canvas!.appendChild(light); + canvas.appendChild(light); }); return { finished };