mirror of
https://gitee.com/antv/g6.git
synced 2024-11-29 18:28:19 +08:00
docs: add element api interactive demos (#5719)
* docs: add element api interactive demos * fix: fix cr issues * refactor: adjust locales in docs
This commit is contained in:
parent
80ed0b9cc3
commit
ad30bd97d2
@ -7,7 +7,7 @@ export const elementNodeDonut: TestCase = async (context) => {
|
||||
{
|
||||
id: 'donut',
|
||||
style: {
|
||||
innerRadius: '60%',
|
||||
innerR: '60%',
|
||||
donuts: [
|
||||
{
|
||||
color: 'orange',
|
||||
@ -65,14 +65,14 @@ export const elementNodeDonut: TestCase = async (context) => {
|
||||
{
|
||||
id: 'donut-inactive',
|
||||
style: {
|
||||
innerRadius: 0,
|
||||
innerR: 0,
|
||||
donuts: [{ fill: 'red' }, { fill: 'green' }],
|
||||
},
|
||||
},
|
||||
{
|
||||
id: 'donut-disabled',
|
||||
style: {
|
||||
innerRadius: '50%',
|
||||
innerR: '50%',
|
||||
donuts: [{ color: 'green' }, { color: 'red' }],
|
||||
},
|
||||
},
|
||||
@ -86,7 +86,7 @@ export const elementNodeDonut: TestCase = async (context) => {
|
||||
type: 'donut', // 👈🏻 Node shape type.
|
||||
style: {
|
||||
size: 40,
|
||||
innerRadius: (d: any) => d.style.innerRadius ?? '50%',
|
||||
innerR: (d: any) => d.style.innerR ?? '50%',
|
||||
labelText: (d) => d.id,
|
||||
iconHeight: 20,
|
||||
iconWidth: 20,
|
||||
|
@ -20,8 +20,6 @@ export interface CircleComboStyleProps extends BaseComboStyleProps {}
|
||||
* <zh/> 圆形组合
|
||||
*
|
||||
* <en/> Circle combo
|
||||
* @remarks
|
||||
* <img width="300" src="https://mdn.alipayobjects.com/huamei_qa8qxu/afts/img/A*WJhpRJCcFLAAAAAAAAAAAAAADmJ7AQ/original" />
|
||||
*/
|
||||
export class CircleCombo extends BaseCombo<CircleComboStyleProps> {
|
||||
constructor(options: DisplayObjectConfig<CircleComboStyleProps>) {
|
||||
|
@ -34,8 +34,6 @@ export interface CubicHorizontalStyleProps extends BaseEdgeStyleProps {
|
||||
* <zh/> 特别注意,计算控制点时主要考虑 x 轴上的距离,忽略 y 轴的变化
|
||||
*
|
||||
* <en/> Please note that when calculating the control points, the distance on the x-axis is mainly considered, and the change on the y-axis is ignored
|
||||
*
|
||||
* <img width="300" src="https://mdn.alipayobjects.com/huamei_qa8qxu/afts/img/A*6Gj2R50AJ8AAAAAAAAAAAAAADmJ7AQ/original" /
|
||||
*/
|
||||
export class CubicHorizontal extends Cubic {
|
||||
static defaultStyleProps: Partial<CubicHorizontalStyleProps> = {
|
||||
|
@ -34,8 +34,6 @@ export interface CubicVerticalStyleProps extends BaseEdgeStyleProps {
|
||||
* <zh/> 特别注意,计算控制点时主要考虑 y 轴上的距离,忽略 x 轴的变化
|
||||
*
|
||||
* <en/> Please note that when calculating the control points, the distance on the y-axis is mainly considered, and the change on the x-axis is ignored
|
||||
*
|
||||
* <img width="300" src="https://mdn.alipayobjects.com/huamei_qa8qxu/afts/img/A*wrDlQKxNHNEAAAAAAAAAAAAADmJ7AQ/original" />
|
||||
*/
|
||||
export class CubicVertical extends Cubic {
|
||||
static defaultStyleProps: Partial<CubicVerticalStyleProps> = {
|
||||
|
@ -40,8 +40,6 @@ type ParsedCubicStyleProps = Required<CubicStyleProps>;
|
||||
* <zh/> 三次贝塞尔曲线
|
||||
*
|
||||
* <en/> Cubic Bezier curve
|
||||
* @remarks
|
||||
* <img width="300" src="https://mdn.alipayobjects.com/huamei_qa8qxu/afts/img/A*cVd-TLQWujYAAAAAAAAAAAAADmJ7AQ/original" />
|
||||
*/
|
||||
export class Cubic extends BaseEdge {
|
||||
static defaultStyleProps: Partial<CubicStyleProps> = {
|
||||
|
@ -59,8 +59,6 @@ type ParsedPolylineStyleProps = Required<PolylineStyleProps>;
|
||||
* <zh/> 折线
|
||||
*
|
||||
* <en/> Polyline
|
||||
* @remarks
|
||||
* <img width="300" src="https://mdn.alipayobjects.com/huamei_qa8qxu/afts/img/A*LeBUQKp9QD0AAAAAAAAAAAAADmJ7AQ/original" />
|
||||
*/
|
||||
export class Polyline extends BaseEdge {
|
||||
static defaultStyleProps: Partial<PolylineStyleProps> = {
|
||||
|
@ -40,8 +40,6 @@ type ParsedQuadraticStyleProps = Required<QuadraticStyleProps>;
|
||||
* <zh/> 二次贝塞尔曲线
|
||||
*
|
||||
* <en/> Quadratic Bezier curve
|
||||
* @remarks
|
||||
* <img width="300" src="https://mdn.alipayobjects.com/huamei_qa8qxu/afts/img/A*CLx6RqrqMvMAAAAAAAAAAAAADmJ7AQ/original" />
|
||||
*/
|
||||
export class Quadratic extends BaseEdge {
|
||||
static defaultStyleProps: Partial<QuadraticStyleProps> = {
|
||||
|
@ -2,7 +2,7 @@ import type { DisplayObjectConfig } from '@antv/g';
|
||||
import type { Point } from '../../types';
|
||||
import { getDiamondPoints } from '../../utils/element';
|
||||
import { getPolygonIntersectPoint } from '../../utils/point';
|
||||
import type { PolygonStyleProps } from '../shapes/polygon';
|
||||
import type { PolygonStyleProps } from '../shapes';
|
||||
import { Polygon } from '../shapes/polygon';
|
||||
|
||||
/**
|
||||
|
@ -6,6 +6,7 @@ import { parseSize } from '../../utils/size';
|
||||
import { Circle } from './circle';
|
||||
|
||||
import type { BaseStyleProps, DisplayObjectConfig, Group } from '@antv/g';
|
||||
import type { CategoricalPalette } from '../../palettes/types';
|
||||
import type { DonutRound, Prefix } from '../../types';
|
||||
import type { CircleStyleProps } from './circle';
|
||||
|
||||
@ -21,7 +22,7 @@ export interface DonutStyleProps extends CircleStyleProps, Prefix<'donut', BaseS
|
||||
* <en/> Inner ring radius, using percentage or pixel value.
|
||||
* @defaultValue '50%'
|
||||
*/
|
||||
innerRadius?: string | number;
|
||||
innerR?: string | number;
|
||||
/**
|
||||
* <zh/> 圆环数据
|
||||
*
|
||||
@ -34,7 +35,7 @@ export interface DonutStyleProps extends CircleStyleProps, Prefix<'donut', BaseS
|
||||
* <en/> Color or palette.
|
||||
* @defaultValue 'tableau'
|
||||
*/
|
||||
colors?: string | string[];
|
||||
donutPalette?: string | CategoricalPalette;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -44,33 +45,43 @@ export interface DonutStyleProps extends CircleStyleProps, Prefix<'donut', BaseS
|
||||
*/
|
||||
export class Donut extends Circle {
|
||||
static defaultStyleProps: Partial<DonutStyleProps> = {
|
||||
innerRadius: '50%',
|
||||
innerR: '50%',
|
||||
donuts: [],
|
||||
colors: 'tableau',
|
||||
donutPalette: 'tableau',
|
||||
};
|
||||
|
||||
constructor(options: DisplayObjectConfig<DonutStyleProps>) {
|
||||
super(deepMix({}, { style: Donut.defaultStyleProps }, options));
|
||||
}
|
||||
|
||||
private parseOuterR() {
|
||||
const { size } = this.parsedAttributes as Required<DonutStyleProps>;
|
||||
return Math.min(...parseSize(size)) / 2;
|
||||
}
|
||||
|
||||
private parseInnerR() {
|
||||
const { innerR } = this.parsedAttributes as Required<DonutStyleProps>;
|
||||
return isString(innerR) ? (parseInt(innerR) / 100) * this.parseOuterR() : innerR;
|
||||
}
|
||||
|
||||
protected drawDonutShape(attributes: Required<DonutStyleProps>, container: Group): void {
|
||||
const { donuts, innerRadius = 0, size } = attributes;
|
||||
const { donuts } = attributes;
|
||||
if (!donuts?.length) return;
|
||||
|
||||
const parsedDonuts = donuts.map((round) => (isNumber(round) ? { value: round } : round) as DonutRound);
|
||||
|
||||
const style = subStyleProps<BaseStyleProps>(this.getGraphicStyle(attributes), 'donut');
|
||||
|
||||
const colors = getPaletteColors(attributes.colors);
|
||||
const colors = getPaletteColors(attributes.donutPalette);
|
||||
if (!colors) return;
|
||||
|
||||
const sum = parsedDonuts.reduce((acc, cur) => acc + (cur.value ?? 0), 0);
|
||||
const outerR = this.parseOuterR();
|
||||
const innerR = this.parseInnerR();
|
||||
|
||||
let start = 0;
|
||||
parsedDonuts.forEach((round, index) => {
|
||||
const { value = 0, color = colors[index % colors.length], ...roundStyle } = round;
|
||||
const outerR = parseSize(size)[0] / 2;
|
||||
const innerR = isString(innerRadius) ? (outerR * parseInt(innerRadius)) / 100 : innerRadius;
|
||||
const angle = (sum === 0 ? 1 / parsedDonuts.length : value / sum) * 360;
|
||||
|
||||
this.upsert(
|
||||
|
@ -2,8 +2,7 @@ import type { DisplayObjectConfig } from '@antv/g';
|
||||
import { ICON_SIZE_RATIO } from '../../constants/element';
|
||||
import type { Point } from '../../types';
|
||||
import { getHexagonPoints } from '../../utils/element';
|
||||
import type { IconStyleProps } from '../shapes';
|
||||
import type { PolygonStyleProps } from '../shapes/polygon';
|
||||
import type { IconStyleProps, PolygonStyleProps } from '../shapes';
|
||||
import { Polygon } from '../shapes/polygon';
|
||||
|
||||
/**
|
||||
@ -13,9 +12,9 @@ import { Polygon } from '../shapes/polygon';
|
||||
*/
|
||||
export interface HexagonStyleProps extends PolygonStyleProps {
|
||||
/**
|
||||
* <zh/> 外半径
|
||||
* <zh/> 外半径,默认为宽高的最小值的一半
|
||||
*
|
||||
* <en/> outer radius
|
||||
* <en/> outer radius, default is half of the minimum value of width and height
|
||||
*/
|
||||
outerR?: number;
|
||||
}
|
||||
|
@ -2,8 +2,7 @@ import type { DisplayObjectConfig } from '@antv/g';
|
||||
import { ICON_SIZE_RATIO } from '../../constants/element';
|
||||
import type { NodePortStyleProps, Point, StarPortPlacement } from '../../types';
|
||||
import { getPortXYByPlacement, getStarPoints, getStarPorts } from '../../utils/element';
|
||||
import type { IconStyleProps } from '../shapes';
|
||||
import type { PolygonStyleProps } from '../shapes/polygon';
|
||||
import type { IconStyleProps, PolygonStyleProps } from '../shapes';
|
||||
import { Polygon } from '../shapes/polygon';
|
||||
|
||||
/**
|
||||
|
@ -5,8 +5,8 @@ import type { NodePortStyleProps, Point, TriangleDirection, TrianglePortPlacemen
|
||||
import { getIncircleRadius, getTriangleCenter } from '../../utils/bbox';
|
||||
import { getPortXYByPlacement, getTrianglePoints, getTrianglePorts } from '../../utils/element';
|
||||
import { subStyleProps } from '../../utils/prefix';
|
||||
import type { PolygonStyleProps } from '../shapes';
|
||||
import { IconStyleProps } from '../shapes';
|
||||
import type { PolygonStyleProps } from '../shapes/polygon';
|
||||
import { Polygon } from '../shapes/polygon';
|
||||
|
||||
/**
|
||||
@ -19,6 +19,7 @@ export interface TriangleStyleProps extends PolygonStyleProps {
|
||||
* <zh/> 三角形的方向
|
||||
*
|
||||
* <en/> The direction of the triangle
|
||||
* @defaultValue 'up'
|
||||
*/
|
||||
direction?: TriangleDirection;
|
||||
}
|
||||
|
@ -15,3 +15,4 @@ export type { BaseShapeStyleProps } from './base-shape';
|
||||
export type { ContourStyleProps } from './contour';
|
||||
export type { IconStyleProps } from './icon';
|
||||
export type { LabelStyleProps } from './label';
|
||||
export type { PolygonStyleProps } from './polygon';
|
||||
|
@ -12,11 +12,12 @@ import { BaseNode } from '../nodes/base-node';
|
||||
*/
|
||||
export interface PolygonStyleProps extends BaseNodeStyleProps {
|
||||
/**
|
||||
* <zh/>.多边形的顶点坐标
|
||||
* <zh/> 多边形的顶点坐标
|
||||
*
|
||||
* <en/> The vertex coordinates of the polygon
|
||||
* @internal
|
||||
*/
|
||||
points: ([number, number] | [number, number, number])[];
|
||||
points?: ([number, number] | [number, number, number])[];
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -141,7 +141,13 @@ export type {
|
||||
StarStyleProps,
|
||||
TriangleStyleProps,
|
||||
} from './elements/nodes';
|
||||
export type { BadgeStyleProps, BaseShapeStyleProps, IconStyleProps, LabelStyleProps } from './elements/shapes';
|
||||
export type {
|
||||
BadgeStyleProps,
|
||||
BaseShapeStyleProps,
|
||||
IconStyleProps,
|
||||
LabelStyleProps,
|
||||
PolygonStyleProps,
|
||||
} from './elements/shapes';
|
||||
export type { ContourLabelStyleProps, ContourStyleProps } from './elements/shapes/contour';
|
||||
export type { AnimationOptions, BaseLayoutOptions, WebWorkerLayoutOptions } from './layouts/types';
|
||||
export type { CategoricalPalette } from './palettes/types';
|
||||
@ -223,6 +229,7 @@ export type {
|
||||
Size,
|
||||
State,
|
||||
TransformOptions,
|
||||
TriangleDirection,
|
||||
Vector2,
|
||||
Vector3,
|
||||
ViewportAnimationEffectTiming,
|
||||
|
@ -3,13 +3,13 @@ createGraph(
|
||||
{
|
||||
data: {
|
||||
nodes: [
|
||||
{ id: 'node1', style: { x: 250, y: 150, parentId: 'combo1' } },
|
||||
{ id: 'node2', style: { x: 350, y: 150, parentId: 'combo1' } },
|
||||
{ id: 'node3', style: { x: 250, y: 300, parentId: 'combo2' } },
|
||||
{ id: 'node1', combo: 'combo1', style: { x: 250, y: 150 } },
|
||||
{ id: 'node2', combo: 'combo1', style: { x: 350, y: 150 } },
|
||||
{ id: 'node3', combo: 'combo2', style: { x: 250, y: 300 } },
|
||||
],
|
||||
edges: [],
|
||||
combos: [
|
||||
{ id: 'combo1', style: { parentId: 'combo2' } },
|
||||
{ id: 'combo1', combo: 'combo2' },
|
||||
{ id: 'combo2', style: {} },
|
||||
],
|
||||
},
|
||||
|
@ -3,13 +3,13 @@ createGraph(
|
||||
{
|
||||
data: {
|
||||
nodes: [
|
||||
{ id: 'node1', style: { x: 250, y: 150, parentId: 'combo1' } },
|
||||
{ id: 'node2', style: { x: 350, y: 150, parentId: 'combo1' } },
|
||||
{ id: 'node3', style: { x: 250, y: 300, parentId: 'combo2' } },
|
||||
{ id: 'node1', combo: 'combo1', style: { x: 250, y: 150 } },
|
||||
{ id: 'node2', combo: 'combo1', style: { x: 350, y: 150 } },
|
||||
{ id: 'node3', combo: 'combo2', style: { x: 250, y: 300 } },
|
||||
],
|
||||
edges: [],
|
||||
combos: [
|
||||
{ id: 'combo1', style: { parentId: 'combo2' } },
|
||||
{ id: 'combo1', combo: 'combo2' },
|
||||
{ id: 'combo2', style: {} },
|
||||
],
|
||||
},
|
||||
|
@ -3,13 +3,13 @@ createGraph(
|
||||
{
|
||||
data: {
|
||||
nodes: [
|
||||
{ id: 'node1', style: { x: 250, y: 150, parentId: 'combo1' } },
|
||||
{ id: 'node2', style: { x: 350, y: 150, parentId: 'combo1' } },
|
||||
{ id: 'node3', style: { x: 250, y: 300, parentId: 'combo2' } },
|
||||
{ id: 'node1', combo: 'combo1', style: { x: 250, y: 150 } },
|
||||
{ id: 'node2', combo: 'combo1', style: { x: 350, y: 150 } },
|
||||
{ id: 'node3', combo: 'combo2', style: { x: 250, y: 300 } },
|
||||
],
|
||||
edges: [],
|
||||
combos: [
|
||||
{ id: 'combo1', style: { parentId: 'combo2' } },
|
||||
{ id: 'combo1', combo: 'combo2' },
|
||||
{ id: 'combo2', style: {} },
|
||||
],
|
||||
},
|
||||
|
71
packages/site/common/api/elements/combos/base-combo.md
Normal file
71
packages/site/common/api/elements/combos/base-combo.md
Normal file
@ -0,0 +1,71 @@
|
||||
```js | ob { pin: false }
|
||||
createGraph(
|
||||
{
|
||||
data: {
|
||||
nodes: [
|
||||
{ id: 'node1', combo: 'combo1', style: { x: 250, y: 150 } },
|
||||
{ id: 'node2', combo: 'combo1', style: { x: 350, y: 150 } },
|
||||
{ id: 'node3', combo: 'combo2', style: { x: 250, y: 300 } },
|
||||
],
|
||||
combos: [
|
||||
{ id: 'combo1', combo: 'combo2' },
|
||||
{ id: 'combo2', style: {} },
|
||||
],
|
||||
},
|
||||
combo: {
|
||||
style: {
|
||||
labelText: (d) => d.id,
|
||||
labelPadding: [1, 5],
|
||||
labelFill: '#fff',
|
||||
labelBackground: true,
|
||||
labelBackgroundRadius: 10,
|
||||
labelBackgroundFill: '#7863FF',
|
||||
},
|
||||
},
|
||||
behaviors: ['collapse-expand'],
|
||||
plugins: ['grid-line'],
|
||||
animation: true,
|
||||
},
|
||||
{ width: 600, height: 400 },
|
||||
(gui, graph) => {
|
||||
const options = {
|
||||
collapsed: false,
|
||||
collapsedSize: 32,
|
||||
collapsedOrigin: [0.5, 0.5],
|
||||
collapsedMarker: true,
|
||||
collapsedMarkerFontSize: 12,
|
||||
collapsedMarkerType: 'child-count',
|
||||
};
|
||||
|
||||
const optionFolder = gui.addFolder('combo2.style');
|
||||
|
||||
optionFolder.add(options, 'collapsed');
|
||||
optionFolder.add(options, 'collapsedSize', 0, 100, 1);
|
||||
optionFolder.add(options, 'collapsedOrigin', [
|
||||
[0.5, 0.5],
|
||||
'left',
|
||||
'right',
|
||||
'top',
|
||||
'bottom',
|
||||
'left-top',
|
||||
'left-bottom',
|
||||
'right-top',
|
||||
'right-bottom',
|
||||
'top-left',
|
||||
'top-right',
|
||||
'bottom-left',
|
||||
'bottom-right',
|
||||
'center',
|
||||
]);
|
||||
|
||||
optionFolder.add(options, 'collapsedMarker');
|
||||
optionFolder.add(options, 'collapsedMarkerFontSize', 12, 20, 1);
|
||||
optionFolder.add(options, 'collapsedMarkerType', ['child-count', 'descendant-count', 'node-count']);
|
||||
|
||||
optionFolder.onChange(({ property, value }) => {
|
||||
graph.updateComboData([{ id: 'combo2', style: { [property]: value } }]);
|
||||
graph.render();
|
||||
});
|
||||
},
|
||||
);
|
||||
```
|
24
packages/site/common/api/elements/combos/circle-combo.md
Normal file
24
packages/site/common/api/elements/combos/circle-combo.md
Normal file
@ -0,0 +1,24 @@
|
||||
```js | ob { pin: false }
|
||||
createGraph(
|
||||
{
|
||||
data: {
|
||||
nodes: [
|
||||
{ id: 'node1', combo: 'combo1', style: { x: 250, y: 150 } },
|
||||
{ id: 'node2', combo: 'combo1', style: { x: 350, y: 150 } },
|
||||
{ id: 'node3', combo: 'combo2', style: { x: 250, y: 300 } },
|
||||
],
|
||||
combos: [
|
||||
{ id: 'combo1', combo: 'combo2' },
|
||||
{ id: 'combo2', style: {} },
|
||||
],
|
||||
},
|
||||
behaviors: ['collapse-expand'],
|
||||
plugins: ['grid-line'],
|
||||
animation: true,
|
||||
},
|
||||
{ width: 600, height: 400 },
|
||||
(gui, graph) => {
|
||||
gui.add({ type: 'circle' }, 'type').disable();
|
||||
},
|
||||
);
|
||||
```
|
25
packages/site/common/api/elements/combos/rect-combo.md
Normal file
25
packages/site/common/api/elements/combos/rect-combo.md
Normal file
@ -0,0 +1,25 @@
|
||||
```js | ob { pin: false }
|
||||
createGraph(
|
||||
{
|
||||
data: {
|
||||
nodes: [
|
||||
{ id: 'node1', combo: 'combo1', style: { x: 250, y: 150 } },
|
||||
{ id: 'node2', combo: 'combo1', style: { x: 350, y: 150 } },
|
||||
{ id: 'node3', combo: 'combo2', style: { x: 250, y: 300 } },
|
||||
],
|
||||
combos: [
|
||||
{ id: 'combo1', combo: 'combo2' },
|
||||
{ id: 'combo2', style: {} },
|
||||
],
|
||||
},
|
||||
combo: { type: 'rect' },
|
||||
behaviors: ['collapse-expand'],
|
||||
plugins: ['grid-line'],
|
||||
animation: true,
|
||||
},
|
||||
{ width: 600, height: 400 },
|
||||
(gui, graph) => {
|
||||
gui.add({ type: 'rect' }, 'type').disable();
|
||||
},
|
||||
);
|
||||
```
|
122
packages/site/common/api/elements/edges/base-edge.md
Normal file
122
packages/site/common/api/elements/edges/base-edge.md
Normal file
@ -0,0 +1,122 @@
|
||||
```js | ob { pin: false }
|
||||
createGraph(
|
||||
{
|
||||
data: {
|
||||
nodes: [
|
||||
{ id: 'node1', style: { x: 150, y: 250 } },
|
||||
{ id: 'node2', style: { x: 400, y: 250 } },
|
||||
],
|
||||
edges: [{ id: 'edge1', source: 'node1', target: 'node2', style: { labelText: 'node1 👉 node2' } }],
|
||||
},
|
||||
node: { style: { labelText: (d) => d.id } },
|
||||
behaviors: ['drag-canvas', 'drag-element'],
|
||||
plugins: ['grid-line'],
|
||||
},
|
||||
{ width: 600, height: 500 },
|
||||
(gui, graph) => {
|
||||
const options = {
|
||||
lineWidth: 1,
|
||||
opacity: 1,
|
||||
stroke: '#99add1',
|
||||
|
||||
startArrow: false,
|
||||
startArrowSize: 8,
|
||||
startArrowType: 'triangle',
|
||||
|
||||
endArrow: false,
|
||||
endArrowSize: 8,
|
||||
endArrowType: 'triangle',
|
||||
|
||||
label: true,
|
||||
labelAutoRotate: true,
|
||||
labelMaxWidth: '80%',
|
||||
labelOffsetX: 0,
|
||||
labelOffsetY: 0,
|
||||
labelPadding: 0,
|
||||
labelPlacement: 'center',
|
||||
labelText: 'node1 👉 node2',
|
||||
|
||||
labelBackground: false,
|
||||
labelBackgroundFill: '#fff',
|
||||
labelBackgroundStroke: '#fff',
|
||||
labelBackgroundLineDash: 0,
|
||||
labelBackgroundLineWidth: 0,
|
||||
labelBackgroundOpacity: 0.5,
|
||||
labelBackgroundRadius: 0,
|
||||
|
||||
halo: false,
|
||||
haloLineDash: 0,
|
||||
haloLineWidth: 12,
|
||||
haloStrokeOpacity: 0.25,
|
||||
};
|
||||
const optionFolder = gui.addFolder('edge.style');
|
||||
|
||||
optionFolder.add(options, 'lineWidth', 0, 20);
|
||||
optionFolder.add(options, 'opacity', 0, 1);
|
||||
optionFolder.addColor(options, 'stroke');
|
||||
|
||||
// startArrow
|
||||
optionFolder.add(options, 'startArrow').onChange((v) => {
|
||||
startArrowSize.show(v);
|
||||
startArrowType.show(v);
|
||||
});
|
||||
const startArrowSize = optionFolder.add(options, 'startArrowSize', 0, 20).hide();
|
||||
const startArrowType = optionFolder
|
||||
.add(options, 'startArrowType', ['triangle', 'circle', 'diamond', 'vee', 'rect', 'triangleRect', 'simple'])
|
||||
.hide();
|
||||
|
||||
// endArrow
|
||||
optionFolder.add(options, 'endArrow').onChange((v) => {
|
||||
endArrowSize.show(v);
|
||||
endArrowType.show(v);
|
||||
});
|
||||
const endArrowSize = optionFolder.add(options, 'endArrowSize', 0, 20).hide();
|
||||
const endArrowType = optionFolder
|
||||
.add(options, 'endArrowType', ['triangle', 'circle', 'diamond', 'vee', 'rect', 'triangleRect', 'simple'])
|
||||
.hide();
|
||||
|
||||
// label
|
||||
optionFolder.add(options, 'label').onChange((v) => {
|
||||
[labelAutoRotate, labelMaxWidth, labelOffsetX, labelOffsetY, labelPadding, labelPlacement, labelText].forEach(
|
||||
(i) => i.show(v),
|
||||
);
|
||||
});
|
||||
const labelAutoRotate = optionFolder.add(options, 'labelAutoRotate');
|
||||
const labelMaxWidth = optionFolder.add(options, 'labelMaxWidth', ['80%', '20px', '200%']);
|
||||
const labelOffsetX = optionFolder.add(options, 'labelOffsetX', 0, 50);
|
||||
const labelOffsetY = optionFolder.add(options, 'labelOffsetY', 0, 50);
|
||||
const labelPadding = optionFolder.add(options, 'labelPadding', 0, 20);
|
||||
const labelPlacement = optionFolder.add(options, 'labelPlacement', ['start', 'center', 'end', 0.2, 0.8]);
|
||||
const labelText = optionFolder.add(options, 'labelText');
|
||||
|
||||
const labelBackground = optionFolder.add(options, 'labelBackground').onChange((v) => {
|
||||
[
|
||||
labelBackgroundFill,
|
||||
labelBackgroundStroke,
|
||||
labelBackgroundLineDash,
|
||||
labelBackgroundLineWidth,
|
||||
labelBackgroundOpacity,
|
||||
labelBackgroundRadius,
|
||||
].forEach((i) => i.show(v));
|
||||
});
|
||||
const labelBackgroundFill = optionFolder.addColor(options, 'labelBackgroundFill').hide();
|
||||
const labelBackgroundStroke = optionFolder.addColor(options, 'labelBackgroundStroke').hide();
|
||||
const labelBackgroundLineDash = optionFolder.add(options, 'labelBackgroundLineDash', 0, 10).hide();
|
||||
const labelBackgroundLineWidth = optionFolder.add(options, 'labelBackgroundLineWidth', 0, 10).hide();
|
||||
const labelBackgroundOpacity = optionFolder.add(options, 'labelBackgroundOpacity', 0, 1).hide();
|
||||
const labelBackgroundRadius = optionFolder.add(options, 'labelBackgroundRadius', 0, 30).hide();
|
||||
|
||||
const halo = optionFolder.add(options, 'halo').onChange((v) => {
|
||||
[haloStrokeOpacity, haloLineDash, haloLineWidth].forEach((i) => i.show(v));
|
||||
});
|
||||
const haloStrokeOpacity = optionFolder.addColor(options, 'haloStrokeOpacity', 0, 1).hide();
|
||||
const haloLineDash = optionFolder.add(options, 'haloLineDash', 0, 10).hide();
|
||||
const haloLineWidth = optionFolder.add(options, 'haloLineWidth', 0, 10).hide();
|
||||
|
||||
optionFolder.onChange(({ property, value }) => {
|
||||
graph.updateEdgeData([{ id: 'edge1', style: { [property]: value } }]);
|
||||
graph.render();
|
||||
});
|
||||
},
|
||||
);
|
||||
```
|
46
packages/site/common/api/elements/edges/cubic-horizontal.md
Normal file
46
packages/site/common/api/elements/edges/cubic-horizontal.md
Normal file
@ -0,0 +1,46 @@
|
||||
```js | ob { pin: false }
|
||||
createGraph(
|
||||
{
|
||||
data: {
|
||||
nodes: [{ id: 'node1' }, { id: 'node2' }, { id: 'node3' }, { id: 'node4' }, { id: 'node5' }, { id: 'node6' }],
|
||||
edges: [
|
||||
{ source: 'node1', target: 'node2' },
|
||||
{ source: 'node1', target: 'node3' },
|
||||
{ source: 'node1', target: 'node4' },
|
||||
{ source: 'node1', target: 'node5' },
|
||||
{ source: 'node1', target: 'node6' },
|
||||
],
|
||||
},
|
||||
node: {
|
||||
style: { port: true, ports: [{ placement: 'left' }, { placement: 'right' }] },
|
||||
},
|
||||
edge: { type: 'cubic-horizontal' },
|
||||
behaviors: ['drag-canvas', 'drag-element'],
|
||||
plugins: ['grid-line'],
|
||||
layout: {
|
||||
type: 'antv-dagre',
|
||||
begin: [100, 50],
|
||||
rankdir: 'LR',
|
||||
nodesep: 15,
|
||||
ranksep: 100,
|
||||
},
|
||||
},
|
||||
{ width: 600, height: 400 },
|
||||
(gui, graph) => {
|
||||
gui.add({ type: 'cubic-horizontal' }, 'type').disable();
|
||||
|
||||
const options = {
|
||||
curveOffset: 20,
|
||||
curvePosition: 0.5,
|
||||
};
|
||||
const optionFolder = gui.addFolder('cubic-horizontal.style');
|
||||
optionFolder.add(options, 'curveOffset', 0, 100);
|
||||
optionFolder.add(options, 'curvePosition', 0, 1);
|
||||
|
||||
optionFolder.onChange(({ property, value }) => {
|
||||
graph.updateEdgeData((prev) => prev.map((edge) => ({ ...edge, style: { [property]: value } })));
|
||||
graph.render();
|
||||
});
|
||||
},
|
||||
);
|
||||
```
|
46
packages/site/common/api/elements/edges/cubic-vertical.md
Normal file
46
packages/site/common/api/elements/edges/cubic-vertical.md
Normal file
@ -0,0 +1,46 @@
|
||||
```js | ob { pin: false }
|
||||
createGraph(
|
||||
{
|
||||
data: {
|
||||
nodes: [{ id: 'node1' }, { id: 'node2' }, { id: 'node3' }, { id: 'node4' }, { id: 'node5' }, { id: 'node6' }],
|
||||
edges: [
|
||||
{ source: 'node1', target: 'node2' },
|
||||
{ source: 'node1', target: 'node3' },
|
||||
{ source: 'node1', target: 'node4' },
|
||||
{ source: 'node1', target: 'node5' },
|
||||
{ source: 'node1', target: 'node6' },
|
||||
],
|
||||
},
|
||||
node: {
|
||||
style: { port: true, ports: [{ placement: 'bottom' }, { placement: 'top' }] },
|
||||
},
|
||||
edge: { type: 'cubic-vertical' },
|
||||
behaviors: ['drag-canvas', 'drag-element'],
|
||||
plugins: ['grid-line'],
|
||||
layout: {
|
||||
type: 'antv-dagre',
|
||||
begin: [100, 50],
|
||||
rankdir: 'TB',
|
||||
nodesep: 25,
|
||||
ranksep: 80,
|
||||
},
|
||||
},
|
||||
{ width: 600, height: 300 },
|
||||
(gui, graph) => {
|
||||
gui.add({ type: 'cubic-vertical' }, 'type').disable();
|
||||
|
||||
const options = {
|
||||
curveOffset: 20,
|
||||
curvePosition: 0.5,
|
||||
};
|
||||
const optionFolder = gui.addFolder('cubic-vertical.style');
|
||||
optionFolder.add(options, 'curveOffset', 0, 100);
|
||||
optionFolder.add(options, 'curvePosition', 0, 1);
|
||||
|
||||
optionFolder.onChange(({ property, value }) => {
|
||||
graph.updateEdgeData((prev) => prev.map((edge) => ({ ...edge, style: { [property]: value } })));
|
||||
graph.render();
|
||||
});
|
||||
},
|
||||
);
|
||||
```
|
33
packages/site/common/api/elements/edges/cubic.md
Normal file
33
packages/site/common/api/elements/edges/cubic.md
Normal file
@ -0,0 +1,33 @@
|
||||
```js | ob { pin: false }
|
||||
createGraph(
|
||||
{
|
||||
data: {
|
||||
nodes: [
|
||||
{ id: 'node1', style: { x: 150, y: 150 } },
|
||||
{ id: 'node2', style: { x: 350, y: 150 } },
|
||||
],
|
||||
edges: [{ id: 'edge1', source: 'node1', target: 'node2' }],
|
||||
},
|
||||
edge: { type: 'cubic' },
|
||||
behaviors: ['drag-canvas', 'drag-element'],
|
||||
plugins: ['grid-line'],
|
||||
},
|
||||
{ width: 600, height: 300 },
|
||||
(gui, graph) => {
|
||||
gui.add({ type: 'cubic' }, 'type').disable();
|
||||
|
||||
const options = {
|
||||
curveOffset: 20,
|
||||
curvePosition: 0.5,
|
||||
};
|
||||
const optionFolder = gui.addFolder('cubic.style');
|
||||
optionFolder.add(options, 'curveOffset', 0, 100, 1);
|
||||
optionFolder.add(options, 'curvePosition', 0, 1, 0.1);
|
||||
|
||||
optionFolder.onChange(({ property, value }) => {
|
||||
graph.updateEdgeData([{ id: 'edge1', style: { [property]: value } }]);
|
||||
graph.render();
|
||||
});
|
||||
},
|
||||
);
|
||||
```
|
19
packages/site/common/api/elements/edges/line.md
Normal file
19
packages/site/common/api/elements/edges/line.md
Normal file
@ -0,0 +1,19 @@
|
||||
```js | ob { pin: false }
|
||||
createGraph(
|
||||
{
|
||||
data: {
|
||||
nodes: [
|
||||
{ id: 'node1', style: { x: 150, y: 150 } },
|
||||
{ id: 'node2', style: { x: 350, y: 150 } },
|
||||
],
|
||||
edges: [{ id: 'edge1', source: 'node1', target: 'node2' }],
|
||||
},
|
||||
behaviors: ['drag-canvas', 'drag-element'],
|
||||
plugins: ['grid-line'],
|
||||
},
|
||||
{ width: 600, height: 300 },
|
||||
(gui, graph) => {
|
||||
gui.add({ type: 'line' }, 'type').disable();
|
||||
},
|
||||
);
|
||||
```
|
82
packages/site/common/api/elements/edges/polyline.md
Normal file
82
packages/site/common/api/elements/edges/polyline.md
Normal file
@ -0,0 +1,82 @@
|
||||
```js | ob { pin: false }
|
||||
createGraph(
|
||||
{
|
||||
data: {
|
||||
nodes: [
|
||||
{
|
||||
id: 'node1',
|
||||
style: { x: 150, y: 150 },
|
||||
},
|
||||
{
|
||||
id: 'node2',
|
||||
style: {
|
||||
x: 400,
|
||||
y: 150,
|
||||
labelText: 'Drag Me!',
|
||||
labelPadding: [1, 5],
|
||||
labelBackground: true,
|
||||
labelBackgroundRadius: 10,
|
||||
labelBackgroundFill: '#99add1',
|
||||
},
|
||||
},
|
||||
],
|
||||
edges: [
|
||||
{
|
||||
id: 'edge1',
|
||||
source: 'node1',
|
||||
target: 'node2',
|
||||
type: 'polyline',
|
||||
style: {
|
||||
router: true,
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
behaviors: ['drag-canvas', 'drag-element'],
|
||||
plugins: ['grid-line'],
|
||||
},
|
||||
{ width: 600, height: 300 },
|
||||
(gui, graph) => {
|
||||
gui.add({ type: 'polyline' }, 'type').disable();
|
||||
|
||||
let index = 3;
|
||||
const options = {
|
||||
radius: 0,
|
||||
router: true,
|
||||
random: () => {
|
||||
const x = Math.floor(Math.random() * 600);
|
||||
const y = Math.floor(Math.random() * 300);
|
||||
graph.addNodeData([
|
||||
{
|
||||
id: `node-${index}`,
|
||||
style: {
|
||||
size: 5,
|
||||
fill: '#D580FF',
|
||||
x,
|
||||
y,
|
||||
},
|
||||
},
|
||||
]);
|
||||
index++;
|
||||
graph.updateEdgeData((prev) => {
|
||||
const targetEdgeData = prev.find((edge) => edge.id === 'edge1');
|
||||
const controlPoints = [...(targetEdgeData.style.controlPoints || [])];
|
||||
controlPoints.push([x, y]);
|
||||
return [{ ...targetEdgeData, style: { ...targetEdgeData.style, controlPoints } }];
|
||||
});
|
||||
graph.render();
|
||||
},
|
||||
};
|
||||
const optionFolder = gui.addFolder('polyline.style');
|
||||
optionFolder.add(options, 'radius', 0, 100, 1);
|
||||
optionFolder.add(options, 'router');
|
||||
optionFolder.add(options, 'random').name('Add random node as control points');
|
||||
|
||||
optionFolder.onChange(({ property, value }) => {
|
||||
if (property === 'random') return;
|
||||
graph.updateEdgeData([{ id: 'edge1', style: { [property]: value } }]);
|
||||
graph.render();
|
||||
});
|
||||
},
|
||||
);
|
||||
```
|
33
packages/site/common/api/elements/edges/quadratic.md
Normal file
33
packages/site/common/api/elements/edges/quadratic.md
Normal file
@ -0,0 +1,33 @@
|
||||
```js | ob { pin: false }
|
||||
createGraph(
|
||||
{
|
||||
data: {
|
||||
nodes: [
|
||||
{ id: 'node1', style: { x: 150, y: 150 } },
|
||||
{ id: 'node2', style: { x: 350, y: 150 } },
|
||||
],
|
||||
edges: [{ id: 'edge1', source: 'node1', target: 'node2' }],
|
||||
},
|
||||
edge: { type: 'quadratic' },
|
||||
behaviors: ['drag-canvas', 'drag-element'],
|
||||
plugins: ['grid-line'],
|
||||
},
|
||||
{ width: 600, height: 300 },
|
||||
(gui, graph) => {
|
||||
gui.add({ type: 'quadratic' }, 'type').disable();
|
||||
|
||||
const options = {
|
||||
curveOffset: 30,
|
||||
curvePosition: 0.5,
|
||||
};
|
||||
const optionFolder = gui.addFolder('quadratic.style');
|
||||
optionFolder.add(options, 'curveOffset', 0, 100);
|
||||
optionFolder.add(options, 'curvePosition', 0, 1);
|
||||
|
||||
optionFolder.onChange(({ property, value }) => {
|
||||
graph.updateEdgeData([{ id: 'edge1', style: { [property]: value } }]);
|
||||
graph.render();
|
||||
});
|
||||
},
|
||||
);
|
||||
```
|
249
packages/site/common/api/elements/nodes/base-node.md
Normal file
249
packages/site/common/api/elements/nodes/base-node.md
Normal file
@ -0,0 +1,249 @@
|
||||
```js | ob { pin: false }
|
||||
createGraph(
|
||||
{
|
||||
data: {
|
||||
nodes: [
|
||||
{
|
||||
id: 'node1',
|
||||
style: {
|
||||
x: 300,
|
||||
y: 150,
|
||||
size: 40,
|
||||
label: false,
|
||||
labelText: 'node',
|
||||
icon: false,
|
||||
iconSrc: 'https://gw.alipayobjects.com/zos/basement_prod/012bcf4f-423b-4922-8c24-32a89f8c41ce.svg',
|
||||
donuts: [30, 30, 20, 20],
|
||||
donutPalette: ['#1783FF', '#00C9C9', '#F08F56', '#D580FF'],
|
||||
badge: false,
|
||||
badges: [{ text: 'Important' }],
|
||||
port: false,
|
||||
ports: [
|
||||
{ key: 'left', placement: [0, 0.5] },
|
||||
{ key: 'right', placement: [1, 0.5] },
|
||||
],
|
||||
portFill: '#00C9C9',
|
||||
portR: 3,
|
||||
portStroke: '#00C9C9',
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
plugins: ['grid-line'],
|
||||
},
|
||||
{ width: 600, height: 600 },
|
||||
(gui, graph) => {
|
||||
const global = { type: 'circle' };
|
||||
gui
|
||||
.add(global, 'type', ['circle', 'diamond', 'donut', 'ellipse', 'hexagon', 'image', 'rect', 'star', 'triangle'])
|
||||
.onChange((v) => {
|
||||
graph.updateNodeData([{ id: 'node1', type: v }]);
|
||||
graph.render();
|
||||
});
|
||||
|
||||
const options = {
|
||||
x: 300,
|
||||
y: 150,
|
||||
fill: '#1783FF',
|
||||
fillOpacity: 1,
|
||||
lineWidth: 0,
|
||||
'size[0]': 40,
|
||||
'size[1]': 40,
|
||||
stroke: '#000000',
|
||||
strokeOpacity: 1,
|
||||
|
||||
label: false,
|
||||
labelFill: '000000d9',
|
||||
labelMaxWidth: '200%',
|
||||
labelPadding: 0,
|
||||
labelPlacement: 'bottom',
|
||||
labelText: 'node',
|
||||
labelWordWrap: false,
|
||||
labelOpacity: 1,
|
||||
|
||||
labelBackground: false,
|
||||
labelBackgroundFill: '#fff',
|
||||
labelBackgroundLineDash: 0,
|
||||
labelBackgroundLineWidth: 0,
|
||||
labelBackgroundOpacity: 0.5,
|
||||
labelBackgroundRadius: 0,
|
||||
labelBackgroundStroke: '#fff',
|
||||
|
||||
halo: false,
|
||||
haloLineDash: 0,
|
||||
haloLineWidth: 12,
|
||||
haloStrokeOpacity: 0.25,
|
||||
|
||||
icon: false,
|
||||
iconFill: '#fff',
|
||||
iconFontSize: 16,
|
||||
iconOpacity: 1,
|
||||
iconSrc: 'https://gw.alipayobjects.com/zos/basement_prod/012bcf4f-423b-4922-8c24-32a89f8c41ce.svg',
|
||||
iconText: '',
|
||||
iconWidth: 20,
|
||||
iconHeight: 20,
|
||||
|
||||
badge: false,
|
||||
badgeFill: '000000d9',
|
||||
badgeMaxWidth: '200%',
|
||||
badgeOpacity: 1,
|
||||
badgePadding: 0,
|
||||
badgePlacement: 'top',
|
||||
badgeText: 'Important',
|
||||
badgeWordWrap: false,
|
||||
|
||||
badgeBackground: true,
|
||||
badgeBackgroundFill: '#fff',
|
||||
badgeBackgroundLineDash: 0,
|
||||
badgeBackgroundLineWidth: 0,
|
||||
badgeBackgroundOpacity: 0.5,
|
||||
badgeBackgroundRadius: 0,
|
||||
badgeBackgroundStroke: '#fff',
|
||||
|
||||
port: false,
|
||||
portFill: '#00C9C9',
|
||||
portR: 3,
|
||||
portStroke: '#00C9C9',
|
||||
};
|
||||
const optionFolder = gui.addFolder('node.style');
|
||||
|
||||
optionFolder.add(options, 'x', 0, 600, 1);
|
||||
optionFolder.add(options, 'y', 0, 300, 1);
|
||||
optionFolder.add(options, 'size[0]', 0, 100).name('width(size[0])');
|
||||
optionFolder.add(options, 'size[1]', 0, 100).name('height(size[1])');
|
||||
optionFolder.add(options, 'lineWidth', 0, 20);
|
||||
optionFolder.addColor(options, 'fill');
|
||||
optionFolder.add(options, 'fillOpacity', 0, 1);
|
||||
optionFolder.addColor(options, 'stroke');
|
||||
optionFolder.add(options, 'strokeOpacity', 0, 1);
|
||||
|
||||
optionFolder.add(options, 'label').onChange((v) => {
|
||||
[labelFill, labelMaxWidth, labelWordWrap, labelPadding, labelPlacement, labelText, labelOpacity].forEach((i) =>
|
||||
i.show(v),
|
||||
);
|
||||
});
|
||||
const labelFill = optionFolder.addColor(options, 'labelFill').hide();
|
||||
const labelMaxWidth = optionFolder.add(options, 'labelMaxWidth', ['200%', '20px', '80%']).hide();
|
||||
const labelWordWrap = optionFolder.add(options, 'labelWordWrap').hide();
|
||||
const labelPadding = optionFolder.add(options, 'labelPadding', 0, 20).hide();
|
||||
const labelPlacement = optionFolder
|
||||
.add(options, 'labelPlacement', [
|
||||
'left',
|
||||
'right',
|
||||
'top',
|
||||
'bottom',
|
||||
'left-top',
|
||||
'left-bottom',
|
||||
'right-top',
|
||||
'right-bottom',
|
||||
'top-left',
|
||||
'top-right',
|
||||
'bottom-left',
|
||||
'bottom-right',
|
||||
'center',
|
||||
])
|
||||
.hide();
|
||||
const labelText = optionFolder.add(options, 'labelText').hide();
|
||||
const labelOpacity = optionFolder.add(options, 'labelOpacity', 0, 1).hide();
|
||||
|
||||
const labelBackground = optionFolder.add(options, 'labelBackground').onChange((v) => {
|
||||
[
|
||||
labelBackgroundFill,
|
||||
labelBackgroundStroke,
|
||||
labelBackgroundLineDash,
|
||||
labelBackgroundLineWidth,
|
||||
labelBackgroundOpacity,
|
||||
labelBackgroundRadius,
|
||||
].forEach((i) => i.show(v));
|
||||
});
|
||||
const labelBackgroundFill = optionFolder.addColor(options, 'labelBackgroundFill').hide();
|
||||
const labelBackgroundStroke = optionFolder.addColor(options, 'labelBackgroundStroke').hide();
|
||||
const labelBackgroundLineDash = optionFolder.add(options, 'labelBackgroundLineDash', 0, 10).hide();
|
||||
const labelBackgroundLineWidth = optionFolder.add(options, 'labelBackgroundLineWidth', 0, 10).hide();
|
||||
const labelBackgroundOpacity = optionFolder.add(options, 'labelBackgroundOpacity', 0, 1).hide();
|
||||
const labelBackgroundRadius = optionFolder.add(options, 'labelBackgroundRadius', 0, 30).hide();
|
||||
|
||||
const halo = optionFolder.add(options, 'halo').onChange((v) => {
|
||||
[haloStrokeOpacity, haloLineDash, haloLineWidth].forEach((i) => i.show(v));
|
||||
});
|
||||
const haloStrokeOpacity = optionFolder.add(options, 'haloStrokeOpacity', 0, 1).hide();
|
||||
const haloLineDash = optionFolder.add(options, 'haloLineDash', 0, 10).hide();
|
||||
const haloLineWidth = optionFolder.add(options, 'haloLineWidth', 0, 10).hide();
|
||||
|
||||
const icon = optionFolder.add(options, 'icon').onChange((v) => {
|
||||
[iconSrc, iconText, iconFill, iconFontSize, iconOpacity, iconWidth, iconHeight].forEach((i) => i.show(v));
|
||||
});
|
||||
const iconSrc = optionFolder.add(options, 'iconSrc').hide();
|
||||
const iconText = optionFolder.add(options, 'iconText').hide();
|
||||
const iconFill = optionFolder.addColor(options, 'iconFill').hide();
|
||||
const iconFontSize = optionFolder.add(options, 'iconFontSize', 12, 20, 1).hide();
|
||||
const iconOpacity = optionFolder.add(options, 'iconOpacity', 0, 1).hide();
|
||||
const iconWidth = optionFolder.add(options, 'iconWidth', 0, 100, 1).hide();
|
||||
const iconHeight = optionFolder.add(options, 'iconHeight', 0, 100, 1).hide();
|
||||
|
||||
const badge = optionFolder.add(options, 'badge').onChange((v) => {
|
||||
[badgeFill, badgeMaxWidth, badgeWordWrap, badgePadding, badgePlacement, badgeText, badgeOpacity].forEach((i) =>
|
||||
i.show(v),
|
||||
);
|
||||
});
|
||||
const badgeFill = optionFolder.addColor(options, 'badgeFill').hide();
|
||||
const badgeMaxWidth = optionFolder.add(options, 'badgeMaxWidth', ['200%', '20px', '80%']).hide();
|
||||
const badgeWordWrap = optionFolder.add(options, 'badgeWordWrap').hide();
|
||||
const badgePadding = optionFolder.add(options, 'badgePadding', 0, 20).hide();
|
||||
const badgePlacement = optionFolder
|
||||
.add(options, 'badgePlacement', [
|
||||
'left',
|
||||
'right',
|
||||
'top',
|
||||
'bottom',
|
||||
'left-top',
|
||||
'left-bottom',
|
||||
'right-top',
|
||||
'right-bottom',
|
||||
'top-left',
|
||||
'top-right',
|
||||
'bottom-left',
|
||||
'bottom-right',
|
||||
])
|
||||
.hide();
|
||||
const badgeText = optionFolder.add(options, 'badgeText').hide();
|
||||
const badgeOpacity = optionFolder.add(options, 'badgeOpacity', 0, 1).hide();
|
||||
|
||||
const badgeBackground = optionFolder.add(options, 'badgeBackground').onChange((v) => {
|
||||
[
|
||||
badgeBackgroundFill,
|
||||
badgeBackgroundStroke,
|
||||
badgeBackgroundLineDash,
|
||||
badgeBackgroundLineWidth,
|
||||
badgeBackgroundOpacity,
|
||||
badgeBackgroundRadius,
|
||||
].forEach((i) => i.show(v));
|
||||
});
|
||||
const badgeBackgroundFill = optionFolder.addColor(options, 'badgeBackgroundFill').hide();
|
||||
const badgeBackgroundStroke = optionFolder.addColor(options, 'badgeBackgroundStroke').hide();
|
||||
const badgeBackgroundLineDash = optionFolder.add(options, 'badgeBackgroundLineDash', 0, 10).hide();
|
||||
const badgeBackgroundLineWidth = optionFolder.add(options, 'badgeBackgroundLineWidth', 0, 10).hide();
|
||||
const badgeBackgroundOpacity = optionFolder.add(options, 'badgeBackgroundOpacity', 0, 1).hide();
|
||||
const badgeBackgroundRadius = optionFolder.add(options, 'badgeBackgroundRadius', 0, 30).hide();
|
||||
|
||||
const port = optionFolder.add(options, 'port').onChange((v) => {
|
||||
[portR, portFill, portStroke].forEach((i) => i.show(v));
|
||||
});
|
||||
const portR = optionFolder.add(options, 'portR', 0, 20, 1).hide();
|
||||
const portFill = optionFolder.addColor(options, 'portFill').hide();
|
||||
const portStroke = optionFolder.addColor(options, 'portStroke').hide();
|
||||
|
||||
optionFolder.onChange(({ property, value, object }) => {
|
||||
let updateStyle = { [property]: value };
|
||||
if (['size[0]', 'size[1]'].includes(property)) {
|
||||
updateStyle.size = [object['size[0]'], object['size[1]']];
|
||||
} else if (['badgePlacement', 'badgeText'].includes(property)) {
|
||||
const nodeData = graph.getNodeData('node1').badges;
|
||||
updateStyle.badges = [{ text: object.badgeText, placement: object.badgePlacement }];
|
||||
}
|
||||
graph.updateNodeData([{ id: 'node1', style: updateStyle }]);
|
||||
graph.render();
|
||||
});
|
||||
},
|
||||
);
|
||||
```
|
22
packages/site/common/api/elements/nodes/circle.md
Normal file
22
packages/site/common/api/elements/nodes/circle.md
Normal file
@ -0,0 +1,22 @@
|
||||
```js | ob { pin: false }
|
||||
createGraph(
|
||||
{
|
||||
data: { nodes: [{ id: 'node1', style: { x: 300, y: 110, size: 40 } }] },
|
||||
node: { type: 'circle' },
|
||||
plugins: ['grid-line'],
|
||||
},
|
||||
{ width: 600, height: 220 },
|
||||
(gui, graph) => {
|
||||
gui.add({ type: 'circle' }, 'type').disable();
|
||||
|
||||
const options = { size: 40 };
|
||||
const optionFolder = gui.addFolder('circle.style');
|
||||
optionFolder.add(options, 'size', 0, 100, 1);
|
||||
|
||||
optionFolder.onChange(({ property, value }) => {
|
||||
graph.updateNodeData([{ id: 'node1', style: { [property]: value } }]);
|
||||
graph.render();
|
||||
});
|
||||
},
|
||||
);
|
||||
```
|
22
packages/site/common/api/elements/nodes/diamond.md
Normal file
22
packages/site/common/api/elements/nodes/diamond.md
Normal file
@ -0,0 +1,22 @@
|
||||
```js | ob { pin: false }
|
||||
createGraph(
|
||||
{
|
||||
data: { nodes: [{ id: 'node1', style: { x: 300, y: 110, size: 40 } }] },
|
||||
node: { type: 'diamond' },
|
||||
plugins: ['grid-line'],
|
||||
},
|
||||
{ width: 600, height: 220 },
|
||||
(gui, graph) => {
|
||||
gui.add({ type: 'diamond' }, 'type').disable();
|
||||
|
||||
const options = { size: 40 };
|
||||
const optionFolder = gui.addFolder('diamond.style');
|
||||
optionFolder.add(options, 'size', 0, 100, 1);
|
||||
|
||||
optionFolder.onChange(({ property, value }) => {
|
||||
graph.updateNodeData([{ id: 'node1', style: { [property]: value } }]);
|
||||
graph.render();
|
||||
});
|
||||
},
|
||||
);
|
||||
```
|
43
packages/site/common/api/elements/nodes/donut.md
Normal file
43
packages/site/common/api/elements/nodes/donut.md
Normal file
@ -0,0 +1,43 @@
|
||||
```js | ob { pin: false }
|
||||
createGraph(
|
||||
{
|
||||
data: {
|
||||
nodes: [
|
||||
{
|
||||
id: 'node1',
|
||||
style: {
|
||||
x: 300,
|
||||
y: 110,
|
||||
fill: 'transparent',
|
||||
size: 60,
|
||||
donuts: [30, 30, 20, 20],
|
||||
donutPalette: ['#1783FF', '#00C9C9', '#F08F56', '#D580FF'],
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
node: { type: 'donut' },
|
||||
plugins: ['grid-line'],
|
||||
},
|
||||
{ width: 600, height: 220 },
|
||||
(gui, graph) => {
|
||||
gui.add({ type: 'donut' }, 'type').disable();
|
||||
|
||||
const options = {
|
||||
size: 60,
|
||||
innerR: 50,
|
||||
donutPalette: ['#1783FF', '#00C9C9', '#F08F56', '#D580FF'],
|
||||
};
|
||||
const optionFolder = gui.addFolder('donut.style');
|
||||
optionFolder.add(options, 'size', 0, 100, 1);
|
||||
optionFolder.add(options, 'innerR', 0, 100, 1).name('innerR(%)');
|
||||
optionFolder.add(options, 'donutPalette', ['spectral', 'tableau', ['#1783FF', '#00C9C9', '#F08F56', '#D580FF']]);
|
||||
|
||||
optionFolder.onChange(({ property, value }) => {
|
||||
if (property === 'innerR') value = value + '%';
|
||||
graph.updateNodeData([{ id: 'node1', style: { [property]: value } }]);
|
||||
graph.render();
|
||||
});
|
||||
},
|
||||
);
|
||||
```
|
24
packages/site/common/api/elements/nodes/ellipse.md
Normal file
24
packages/site/common/api/elements/nodes/ellipse.md
Normal file
@ -0,0 +1,24 @@
|
||||
```js | ob { pin: false }
|
||||
createGraph(
|
||||
{
|
||||
data: { nodes: [{ id: 'node1', style: { x: 300, y: 110 } }] },
|
||||
node: { type: 'ellipse' },
|
||||
plugins: ['grid-line'],
|
||||
},
|
||||
{ width: 600, height: 220 },
|
||||
(gui, graph) => {
|
||||
gui.add({ type: 'ellipse' }, 'type').disable();
|
||||
|
||||
const options = { 'size[0]': 80, 'size[1]': 40 };
|
||||
|
||||
const optionFolder = gui.addFolder('ellipse.style');
|
||||
optionFolder.add(options, 'size[0]', 0, 100, 1);
|
||||
optionFolder.add(options, 'size[1]', 0, 100, 1);
|
||||
|
||||
optionFolder.onChange(({ object }) => {
|
||||
graph.updateNodeData([{ id: 'node1', style: { size: [object['size[0]'], object['size[1]']] } }]);
|
||||
graph.render();
|
||||
});
|
||||
},
|
||||
);
|
||||
```
|
26
packages/site/common/api/elements/nodes/hexagon.md
Normal file
26
packages/site/common/api/elements/nodes/hexagon.md
Normal file
@ -0,0 +1,26 @@
|
||||
```js | ob { pin: false }
|
||||
createGraph(
|
||||
{
|
||||
data: { nodes: [{ id: 'node1', style: { x: 300, y: 110, size: 40 } }] },
|
||||
node: { type: 'hexagon' },
|
||||
plugins: ['grid-line'],
|
||||
},
|
||||
{ width: 600, height: 220 },
|
||||
(gui, graph) => {
|
||||
gui.add({ type: 'hexagon' }, 'type').disable();
|
||||
|
||||
const options = {
|
||||
size: 40,
|
||||
outerR: 0,
|
||||
};
|
||||
const optionFolder = gui.addFolder('hexagon.style');
|
||||
optionFolder.add(options, 'size', 0, 100, 1);
|
||||
optionFolder.add(options, 'outerR', 0, 100);
|
||||
|
||||
optionFolder.onChange(({ property, value }) => {
|
||||
graph.updateNodeData([{ id: 'node1', style: { [property]: value } }]);
|
||||
graph.render();
|
||||
});
|
||||
},
|
||||
);
|
||||
```
|
48
packages/site/common/api/elements/nodes/html.md
Normal file
48
packages/site/common/api/elements/nodes/html.md
Normal file
@ -0,0 +1,48 @@
|
||||
```js | ob { pin: false }
|
||||
createGraph(
|
||||
{
|
||||
data: {
|
||||
nodes: [
|
||||
{
|
||||
id: 'node1',
|
||||
style: {
|
||||
x: 300,
|
||||
y: 110,
|
||||
size: [120, 40],
|
||||
innerHTML: `
|
||||
<div style="width: 100%; height: 100%; background: #7863FF; display: flex; justify-content: center; align-items: center;">
|
||||
<span style="color: #fff; font-size: 12px;">
|
||||
HTML Node
|
||||
</span>
|
||||
</div>`,
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
node: { type: 'html' },
|
||||
plugins: ['grid-line'],
|
||||
},
|
||||
{ width: 600, height: 220 },
|
||||
(gui, graph) => {
|
||||
gui.add({ type: 'html' }, 'type').disable();
|
||||
|
||||
const options = {
|
||||
size: 50,
|
||||
innerHTML: `
|
||||
<div style="width: 100%; height: 100%; background: #7863FF; display: flex; justify-content: center; align-items: center;">
|
||||
<span style="color: #fff; font-size: 20px;">
|
||||
'HTML Node'
|
||||
</span>
|
||||
</div>`,
|
||||
};
|
||||
const optionFolder = gui.addFolder('html.style');
|
||||
optionFolder.add(options, 'size', 0, 100, 1);
|
||||
optionFolder.add(options, 'innerHTML');
|
||||
|
||||
optionFolder.onChange(({ property, value }) => {
|
||||
graph.updateNodeData([{ id: 'node1', style: { [property]: value } }]);
|
||||
graph.render();
|
||||
});
|
||||
},
|
||||
);
|
||||
```
|
37
packages/site/common/api/elements/nodes/image.md
Normal file
37
packages/site/common/api/elements/nodes/image.md
Normal file
@ -0,0 +1,37 @@
|
||||
```js | ob { pin: false }
|
||||
createGraph(
|
||||
{
|
||||
data: {
|
||||
nodes: [
|
||||
{
|
||||
id: 'node1',
|
||||
style: {
|
||||
x: 300,
|
||||
y: 110,
|
||||
src: 'https://gw.alipayobjects.com/mdn/rms_6ae20b/afts/img/A*N4ZMS7gHsUIAAAAAAAAAAABkARQnAQ',
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
node: { type: 'image' },
|
||||
plugins: ['grid-line'],
|
||||
},
|
||||
{ width: 600, height: 220 },
|
||||
(gui, graph) => {
|
||||
gui.add({ type: 'image' }, 'type').disable();
|
||||
|
||||
const options = {
|
||||
size: 50,
|
||||
src: 'https://gw.alipayobjects.com/mdn/rms_6ae20b/afts/img/A*N4ZMS7gHsUIAAAAAAAAAAABkARQnAQ',
|
||||
};
|
||||
const optionFolder = gui.addFolder('image.style');
|
||||
optionFolder.add(options, 'size', 0, 100, 1);
|
||||
optionFolder.add(options, 'src');
|
||||
|
||||
optionFolder.onChange(({ property, value }) => {
|
||||
graph.updateNodeData([{ id: 'node1', style: { [property]: value } }]);
|
||||
graph.render();
|
||||
});
|
||||
},
|
||||
);
|
||||
```
|
24
packages/site/common/api/elements/nodes/rect.md
Normal file
24
packages/site/common/api/elements/nodes/rect.md
Normal file
@ -0,0 +1,24 @@
|
||||
```js | ob { pin: false }
|
||||
createGraph(
|
||||
{
|
||||
data: { nodes: [{ id: 'node1', style: { x: 300, y: 110 } }] },
|
||||
node: { type: 'rect' },
|
||||
plugins: ['grid-line'],
|
||||
},
|
||||
{ width: 600, height: 220 },
|
||||
(gui, graph) => {
|
||||
gui.add({ type: 'rect' }, 'type').disable();
|
||||
|
||||
const options = { 'size[0]': 48, 'size[1]': 24 };
|
||||
|
||||
const optionFolder = gui.addFolder('rect.style');
|
||||
optionFolder.add(options, 'size[0]', 0, 100, 1);
|
||||
optionFolder.add(options, 'size[1]', 0, 100, 1);
|
||||
|
||||
optionFolder.onChange(({ object }) => {
|
||||
graph.updateNodeData([{ id: 'node1', style: { size: [object['size[0]'], object['size[1]']] } }]);
|
||||
graph.render();
|
||||
});
|
||||
},
|
||||
);
|
||||
```
|
26
packages/site/common/api/elements/nodes/star.md
Normal file
26
packages/site/common/api/elements/nodes/star.md
Normal file
@ -0,0 +1,26 @@
|
||||
```js | ob { pin: false }
|
||||
createGraph(
|
||||
{
|
||||
data: { nodes: [{ id: 'node1', style: { x: 300, y: 110, size: 40 } }] },
|
||||
node: { type: 'star' },
|
||||
plugins: ['grid-line'],
|
||||
},
|
||||
{ width: 600, height: 220 },
|
||||
(gui, graph) => {
|
||||
gui.add({ type: 'star' }, 'type').disable();
|
||||
|
||||
const options = {
|
||||
size: 40,
|
||||
innerR: 0,
|
||||
};
|
||||
const optionFolder = gui.addFolder('star.style');
|
||||
optionFolder.add(options, 'size', 0, 100, 1);
|
||||
optionFolder.add(options, 'innerR', 0, 100);
|
||||
|
||||
optionFolder.onChange(({ property, value }) => {
|
||||
graph.updateNodeData([{ id: 'node1', style: { [property]: value } }]);
|
||||
graph.render();
|
||||
});
|
||||
},
|
||||
);
|
||||
```
|
26
packages/site/common/api/elements/nodes/triangle.md
Normal file
26
packages/site/common/api/elements/nodes/triangle.md
Normal file
@ -0,0 +1,26 @@
|
||||
```js | ob { pin: false }
|
||||
createGraph(
|
||||
{
|
||||
data: { nodes: [{ id: 'node1', style: { x: 300, y: 110 } }] },
|
||||
node: { type: 'triangle' },
|
||||
plugins: ['grid-line'],
|
||||
},
|
||||
{ width: 600, height: 220 },
|
||||
(gui, graph) => {
|
||||
gui.add({ type: 'triangle' }, 'type').disable();
|
||||
|
||||
const options = {
|
||||
size: 40,
|
||||
direction: 'up',
|
||||
};
|
||||
const optionFolder = gui.addFolder('triangle.style');
|
||||
optionFolder.add(options, 'size', 0, 100, 1);
|
||||
optionFolder.add(options, 'direction', ['up', 'left', 'right', 'down']);
|
||||
|
||||
optionFolder.onChange(({ property, value }) => {
|
||||
graph.updateNodeData([{ id: 'node1', style: { [property]: value } }]);
|
||||
graph.render();
|
||||
});
|
||||
},
|
||||
);
|
||||
```
|
@ -22,7 +22,7 @@ const graph = new Graph({
|
||||
type: 'donut', // 👈🏻 Node shape type.
|
||||
size: 80,
|
||||
fill: '#DB9D0D',
|
||||
innerRadius: 0.5,
|
||||
innerR: 0.5,
|
||||
donuts: (v, index) => {
|
||||
if (index === 0) return [1, 2, 3];
|
||||
|
||||
|
@ -1,8 +1,34 @@
|
||||
/**
|
||||
* @file Generate API Markdown documentation from the API Document Model files
|
||||
*/
|
||||
import { MarkdownAction } from '../src/MarkdownAction';
|
||||
import { ApiModel } from '@microsoft/api-extractor-model';
|
||||
import { FileSystem } from '@rushstack/node-core-library';
|
||||
import * as path from 'path';
|
||||
import { MarkdownDocumenter } from '../src/MarkdownDocumenter';
|
||||
|
||||
(function runApiDocumenter() {
|
||||
new MarkdownAction().onExecute();
|
||||
const inputFolder = 'support/api';
|
||||
const outputFolder = 'docs/api';
|
||||
|
||||
(async function runApiDocumenter() {
|
||||
const apiModel: ApiModel = new ApiModel();
|
||||
|
||||
if (!FileSystem.exists(inputFolder)) {
|
||||
throw new Error('The input folder does not exist: ' + inputFolder);
|
||||
}
|
||||
FileSystem.ensureFolder(outputFolder);
|
||||
|
||||
for (const filename of FileSystem.readFolderItemNames(inputFolder)) {
|
||||
if (filename.match(/\.api\.json$/i)) {
|
||||
console.log(`Reading ${filename}`);
|
||||
const filenamePath: string = path.join(inputFolder, filename);
|
||||
apiModel.loadPackage(filenamePath);
|
||||
}
|
||||
}
|
||||
|
||||
const markdownDocumenter: MarkdownDocumenter = new MarkdownDocumenter({
|
||||
apiModel,
|
||||
outputFolder,
|
||||
});
|
||||
|
||||
await markdownDocumenter.generateFiles();
|
||||
})();
|
||||
|
@ -1,112 +0,0 @@
|
||||
import type { ApiItem, IResolveDeclarationReferenceResult } from '@microsoft/api-extractor-model';
|
||||
import { ApiDocumentedItem, ApiItemContainerMixin, ApiModel } from '@microsoft/api-extractor-model';
|
||||
import type * as tsdoc from '@microsoft/tsdoc';
|
||||
import { FileSystem } from '@rushstack/node-core-library';
|
||||
import * as path from 'path';
|
||||
import { MarkdownDocumenter } from './MarkdownDocumenter';
|
||||
import { inputFolder, outputFolder } from './setting';
|
||||
|
||||
interface IBuildApiModelResult {
|
||||
apiModel: ApiModel;
|
||||
inputFolder: string;
|
||||
outputFolder: string;
|
||||
}
|
||||
|
||||
export class MarkdownAction {
|
||||
public async onExecute(): Promise<void> {
|
||||
const { apiModel, outputFolder } = this.buildApiModel();
|
||||
|
||||
const markdownDocumenter: MarkdownDocumenter = new MarkdownDocumenter({
|
||||
apiModel,
|
||||
outputFolder,
|
||||
});
|
||||
|
||||
await markdownDocumenter.generateFiles();
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds the ApiModel by loading all .api.json files from the input folder.
|
||||
* @returns The ApiModel and the input/output folders.
|
||||
*/
|
||||
protected buildApiModel(): IBuildApiModelResult {
|
||||
const apiModel: ApiModel = new ApiModel();
|
||||
|
||||
if (!FileSystem.exists(inputFolder)) {
|
||||
throw new Error('The input folder does not exist: ' + inputFolder);
|
||||
}
|
||||
FileSystem.ensureFolder(outputFolder);
|
||||
|
||||
for (const filename of FileSystem.readFolderItemNames(inputFolder)) {
|
||||
if (filename.match(/\.api\.json$/i)) {
|
||||
console.log(`Reading ${filename}`);
|
||||
const filenamePath: string = path.join(inputFolder, filename);
|
||||
apiModel.loadPackage(filenamePath);
|
||||
}
|
||||
}
|
||||
|
||||
this._applyInheritDoc(apiModel, apiModel);
|
||||
|
||||
return { apiModel, inputFolder, outputFolder };
|
||||
}
|
||||
|
||||
// TODO: This is a temporary workaround. The long term plan is for API Extractor's DocCommentEnhancer
|
||||
// to apply all @inheritDoc tags before the .api.json file is written.
|
||||
// See DocCommentEnhancer._applyInheritDoc() for more info.
|
||||
private _applyInheritDoc(apiItem: ApiItem, apiModel: ApiModel): void {
|
||||
if (apiItem instanceof ApiDocumentedItem) {
|
||||
if (apiItem.tsdocComment) {
|
||||
const inheritDocTag: tsdoc.DocInheritDocTag | undefined = apiItem.tsdocComment.inheritDocTag;
|
||||
|
||||
if (inheritDocTag && inheritDocTag.declarationReference) {
|
||||
// Attempt to resolve the declaration reference
|
||||
const result: IResolveDeclarationReferenceResult = apiModel.resolveDeclarationReference(
|
||||
inheritDocTag.declarationReference,
|
||||
apiItem,
|
||||
);
|
||||
|
||||
if (result.errorMessage) {
|
||||
console.log(`Warning: Unresolved @inheritDoc tag for ${apiItem.displayName}: ` + result.errorMessage);
|
||||
} else {
|
||||
if (
|
||||
result.resolvedApiItem instanceof ApiDocumentedItem &&
|
||||
result.resolvedApiItem.tsdocComment &&
|
||||
result.resolvedApiItem !== apiItem
|
||||
) {
|
||||
this._copyInheritedDocs(apiItem.tsdocComment, result.resolvedApiItem.tsdocComment);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Recurse members
|
||||
if (ApiItemContainerMixin.isBaseClassOf(apiItem)) {
|
||||
for (const member of apiItem.members) {
|
||||
this._applyInheritDoc(member, apiModel);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Copy the content from `sourceDocComment` to `targetDocComment`.
|
||||
* This code is borrowed from DocCommentEnhancer as a temporary workaround.
|
||||
* @param targetDocComment - The target doc comment to copy into
|
||||
* @param sourceDocComment - The source doc comment to copy from
|
||||
* @internal
|
||||
*/
|
||||
private _copyInheritedDocs(targetDocComment: tsdoc.DocComment, sourceDocComment: tsdoc.DocComment): void {
|
||||
targetDocComment.summarySection = sourceDocComment.summarySection;
|
||||
targetDocComment.remarksBlock = sourceDocComment.remarksBlock;
|
||||
|
||||
targetDocComment.params.clear();
|
||||
for (const param of sourceDocComment.params) {
|
||||
targetDocComment.params.add(param);
|
||||
}
|
||||
for (const typeParam of sourceDocComment.typeParams) {
|
||||
targetDocComment.typeParams.add(typeParam);
|
||||
}
|
||||
targetDocComment.returnsBlock = sourceDocComment.returnsBlock;
|
||||
|
||||
targetDocComment.inheritDocTag = undefined;
|
||||
}
|
||||
}
|
@ -50,8 +50,9 @@ import { FileSystem, NewlineKind, PackageName } from '@rushstack/node-core-libra
|
||||
import { camelCase, isBoolean, kebabCase, upperFirst } from 'lodash';
|
||||
import * as path from 'path';
|
||||
import prettier from 'prettier';
|
||||
import { Keyword, LocaleLanguage, getApiCategoryIntl, getHelperIntl, getKeywordIntl } from './constants';
|
||||
import { intl } from './constants';
|
||||
import { links } from './constants/link';
|
||||
import { Keyword, LocaleLanguage, LocaleType } from './constants/locales/enum';
|
||||
import { CustomMarkdownEmitter } from './markdown/CustomMarkdownEmitter';
|
||||
import { CustomDocNodes } from './nodes/CustomDocNodeKind';
|
||||
import { DocContainer } from './nodes/DocContainer';
|
||||
@ -65,7 +66,6 @@ import { DocTableCell } from './nodes/DocTableCell';
|
||||
import { DocTableRow } from './nodes/DocTableRow';
|
||||
import { DocText } from './nodes/DocText';
|
||||
import { DocUnorderedList } from './nodes/DocUnorderedList';
|
||||
import { outputFolder, referenceFoldername } from './setting';
|
||||
import { Utilities } from './utils/Utilities';
|
||||
import {
|
||||
ICustomExcerptToken,
|
||||
@ -73,11 +73,17 @@ import {
|
||||
liftPrefixExcerptTokens,
|
||||
parseExcerptTokens,
|
||||
} from './utils/excerpt-token';
|
||||
import { initGitignore, syncToGitignore } from './utils/gitignore';
|
||||
import { getBlockTagByName } from './utils/parser';
|
||||
|
||||
const referenceFoldername = 'reference';
|
||||
|
||||
const supportedApiItems = [ApiItemKind.Interface, ApiItemKind.Enum, ApiItemKind.Class, ApiItemKind.TypeAlias];
|
||||
|
||||
const hyperlinkReferences = ['BaseNodeStyleProps'];
|
||||
// 需要跳过解析的复杂类型 | Complex types that need to be skipped for parsing
|
||||
export const interfacesToSkipParsing = ['BaseNodeStyleProps', 'BaseEdgeStyleProps', 'BaseComboStyleProps'];
|
||||
|
||||
const typesToSkipParsing = ['CallableValue'];
|
||||
|
||||
/**
|
||||
* A page and its associated API items.
|
||||
@ -130,7 +136,7 @@ export class MarkdownDocumenter {
|
||||
}
|
||||
|
||||
public async generateFiles() {
|
||||
this._initGitignore();
|
||||
initGitignore(this._outputFolder);
|
||||
|
||||
const collectedData = this._initPageData(this._apiModel);
|
||||
|
||||
@ -466,10 +472,11 @@ export class MarkdownDocumenter {
|
||||
const isBase = pageData.name.startsWith('Base');
|
||||
|
||||
if (apiClass && !isBase) {
|
||||
this._writeSummarySection(output, apiClass);
|
||||
this._writeRemarksSection(output, apiClass);
|
||||
}
|
||||
|
||||
this._assertDemo(output, pageData);
|
||||
|
||||
if (apiInterface) {
|
||||
this._writeElementOptions(output, apiInterface, pageData, isBase);
|
||||
}
|
||||
@ -482,31 +489,26 @@ export class MarkdownDocumenter {
|
||||
/**
|
||||
* Special for Element options, which needs to handle `Prefix`
|
||||
*/
|
||||
private _writeElementOptions(
|
||||
output: DocSection,
|
||||
apiInterface: ApiInterface,
|
||||
pageData: IPageData,
|
||||
includeExcerptTokens: boolean,
|
||||
) {
|
||||
private _writeElementOptions(output: DocSection, apiInterface: ApiInterface, pageData: IPageData, isBase: boolean) {
|
||||
const configuration: TSDocConfiguration = this._tsdocConfiguration;
|
||||
|
||||
if (!includeExcerptTokens) {
|
||||
if (!isBase) {
|
||||
const elementType = pageData.group.split('/')[1].slice(0, -1);
|
||||
const baseStyleFileName = upperFirst(camelCase(`base ${elementType}`));
|
||||
output.appendNode(
|
||||
new DocContainer({ configuration, status: 'info', title: getHelperIntl('remarks', this.locale) }, [
|
||||
new DocParagraph({ configuration }, [
|
||||
new DocPlainText({
|
||||
configuration,
|
||||
text:
|
||||
getHelperIntl('basePropsStyleHelper', this.locale) + `(./${baseStyleFileName}.${this._getLang()}.md)`,
|
||||
}),
|
||||
]),
|
||||
new DocParagraph({ configuration }, [
|
||||
new DocText({
|
||||
configuration,
|
||||
text:
|
||||
'> ' +
|
||||
intl(LocaleType.HELPER, 'basePropsStyleHelper', this.locale) +
|
||||
` [${baseStyleFileName}](./${baseStyleFileName}.${this._getLang()}.md)`,
|
||||
}),
|
||||
]),
|
||||
);
|
||||
}
|
||||
|
||||
this._writeOptions(output, apiInterface, { showTitle: false, includeExcerptTokens });
|
||||
this._writeOptions(output, apiInterface, { showTitle: false, includeExcerptTokens: true });
|
||||
}
|
||||
|
||||
private _getLinkFromExcerptToken(excerptToken: ICustomExcerptToken): string | undefined {
|
||||
@ -569,7 +571,7 @@ export class MarkdownDocumenter {
|
||||
|
||||
const filterTokens = (tokens: ICustomExcerptToken[]): ICustomExcerptToken[] => {
|
||||
return tokens
|
||||
.filter((token) => token.type !== 'Prefix')
|
||||
.filter((token) => token.type !== 'Prefix' && !interfacesToSkipParsing.includes(token.text))
|
||||
.map((token) => ({
|
||||
...token,
|
||||
children: token.children ? filterTokens(token.children) : [],
|
||||
@ -653,13 +655,6 @@ export class MarkdownDocumenter {
|
||||
private _writeExcerptTokens(output: DocSection, customExcerptTokens: ICustomExcerptToken[]) {
|
||||
const configuration: TSDocConfiguration = this._tsdocConfiguration;
|
||||
|
||||
customExcerptTokens.forEach((customExcerptToken) => {
|
||||
if (hyperlinkReferences.includes(customExcerptToken.text)) {
|
||||
delete customExcerptToken.children;
|
||||
delete customExcerptToken.interface;
|
||||
}
|
||||
});
|
||||
|
||||
for (const customExcerptToken of customExcerptTokens) {
|
||||
const textNodes: DocPlainText[] = [];
|
||||
|
||||
@ -704,7 +699,7 @@ export class MarkdownDocumenter {
|
||||
const helper = (key: string) =>
|
||||
linkMd +
|
||||
this._intl(Keyword.LEFT_PARENTHESIS) +
|
||||
getHelperIntl(key, this.locale) +
|
||||
intl(LocaleType.HELPER, key, this.locale) +
|
||||
' ' +
|
||||
fieldString +
|
||||
' ' +
|
||||
@ -740,7 +735,7 @@ export class MarkdownDocumenter {
|
||||
new DocParagraph({ configuration }, [
|
||||
new DocPlainText({
|
||||
configuration,
|
||||
text: getHelperIntl('advancedPropsHelper', this.locale) + this._intl(Keyword.COLON),
|
||||
text: intl(LocaleType.HELPER, 'advancedPropsHelper', this.locale) + this._intl(Keyword.COLON),
|
||||
}),
|
||||
...textNodes
|
||||
.map((node) => [node, new DocPlainText({ configuration, text: ', ' })])
|
||||
@ -755,7 +750,9 @@ export class MarkdownDocumenter {
|
||||
new DocParagraph({ configuration }, [
|
||||
new DocPlainText({
|
||||
configuration,
|
||||
text: getHelperIntl('prefixHelper', this.locale) + `(../../reference/g6.prefix.${this._getLang()}.md)`,
|
||||
text:
|
||||
intl(LocaleType.HELPER, 'prefixHelper', this.locale) +
|
||||
`(../../reference/g6.prefix.${this._getLang()}.md)`,
|
||||
}),
|
||||
]),
|
||||
);
|
||||
@ -763,7 +760,7 @@ export class MarkdownDocumenter {
|
||||
|
||||
if (content.length > 0) {
|
||||
output.appendNode(
|
||||
new DocContainer({ configuration, status: 'info', title: getHelperIntl('remarks', this.locale) }, content),
|
||||
new DocContainer({ configuration, status: 'info', title: this._intl(Keyword.REMARKS) }, content),
|
||||
);
|
||||
}
|
||||
|
||||
@ -836,7 +833,7 @@ export class MarkdownDocumenter {
|
||||
|
||||
Object.entries(groupMembers).forEach(([category, apiMembers]) => {
|
||||
if (category !== 'undeclared' && showSubTitle) {
|
||||
const title = getApiCategoryIntl(category, this.locale);
|
||||
const title = intl(LocaleType.API_CATEGORY, category, this.locale);
|
||||
output.appendNode(new DocHeading({ configuration, title, level: 1 }));
|
||||
}
|
||||
if (apiMembers.length > 0) {
|
||||
@ -959,38 +956,7 @@ export class MarkdownDocumenter {
|
||||
convertLineEndings: NewlineKind.CrLf,
|
||||
});
|
||||
|
||||
this._syncToGitignore(filename);
|
||||
}
|
||||
|
||||
private _syncToGitignore(filename: string) {
|
||||
const gitignoreUrl = outputFolder + '/.gitignore';
|
||||
const relativeFilename = filename.replace(`${outputFolder}/`, '');
|
||||
|
||||
if (FileSystem.exists(gitignoreUrl)) {
|
||||
const gitignoreContent = FileSystem.readFile(gitignoreUrl);
|
||||
if (relativeFilename.includes(referenceFoldername)) {
|
||||
const hasReference = gitignoreContent.includes(referenceFoldername);
|
||||
if (!hasReference) FileSystem.appendToFile(gitignoreUrl, `\n${referenceFoldername}`);
|
||||
return;
|
||||
}
|
||||
if (!gitignoreContent.includes(relativeFilename)) {
|
||||
FileSystem.appendToFile(gitignoreUrl, `\n${relativeFilename}`);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private _initGitignore() {
|
||||
const splitLine = '# auto-generated by api-documenter';
|
||||
const gitignoreUrl = outputFolder + '/.gitignore';
|
||||
if (FileSystem.exists(gitignoreUrl)) {
|
||||
let gitignoreContent = FileSystem.readFile(gitignoreUrl);
|
||||
const index = gitignoreContent.indexOf(splitLine);
|
||||
if (index !== -1) gitignoreContent = gitignoreContent.substring(0, index);
|
||||
gitignoreContent += splitLine;
|
||||
FileSystem.writeFile(gitignoreUrl, gitignoreContent);
|
||||
} else {
|
||||
FileSystem.writeFile(gitignoreUrl, splitLine);
|
||||
}
|
||||
syncToGitignore(this._outputFolder, filename);
|
||||
}
|
||||
|
||||
private _writeHeritageTypes(output: DocSection, apiItem: ApiDeclaredItem): void {
|
||||
@ -1828,15 +1794,15 @@ export class MarkdownDocumenter {
|
||||
}
|
||||
}
|
||||
|
||||
private _parseTypeAliasTokens(excerptTokens: ExcerptToken[]): ExcerptToken[] {
|
||||
const tokens = excerptTokens.flatMap((token) => {
|
||||
private _parseTypeAliasTokens(apiTypeAlias: ApiTypeAlias): ExcerptToken[] {
|
||||
const tokens = apiTypeAlias.excerptTokens.slice(1, -1).flatMap((token) => {
|
||||
if (token.kind === ExcerptTokenKind.Reference && token.canonicalReference) {
|
||||
const apiItemResult: IResolveDeclarationReferenceResult = this._apiModel.resolveDeclarationReference(
|
||||
token.canonicalReference,
|
||||
undefined,
|
||||
);
|
||||
if (apiItemResult.resolvedApiItem instanceof ApiTypeAlias) {
|
||||
return this._parseTypeAliasTokens(apiItemResult.resolvedApiItem.excerptTokens.slice(1, -1));
|
||||
return this._parseTypeAliasTokens(apiItemResult.resolvedApiItem);
|
||||
}
|
||||
}
|
||||
return token;
|
||||
@ -1860,13 +1826,16 @@ export class MarkdownDocumenter {
|
||||
);
|
||||
|
||||
if (apiItemResult.resolvedApiItem) {
|
||||
if (apiItemResult.resolvedApiItem.kind === ApiItemKind.TypeAlias && this.referenceLevel > 0) {
|
||||
const excerptTokens = (apiItemResult.resolvedApiItem as ApiTypeAlias).excerptTokens.slice(1, -1);
|
||||
const typeAliasTokens = this._parseTypeAliasTokens(excerptTokens);
|
||||
if (
|
||||
apiItemResult.resolvedApiItem.kind === ApiItemKind.TypeAlias &&
|
||||
this.referenceLevel > 0 &&
|
||||
!typesToSkipParsing.includes(apiItemResult.resolvedApiItem.displayName)
|
||||
) {
|
||||
const typeAliasTokens = this._parseTypeAliasTokens(apiItemResult.resolvedApiItem as ApiTypeAlias);
|
||||
// If the type alias is a simple single-line type alias, then render it as plain text
|
||||
// Otherwise, render it as a hyperlink
|
||||
if (typeAliasTokens.every((token) => !token.text.includes('\n') && !token.text.includes('\r'))) {
|
||||
return docNodeContainer.appendNode(
|
||||
docNodeContainer.appendNode(
|
||||
new DocPlainText({
|
||||
configuration,
|
||||
text: typeAliasTokens
|
||||
@ -1877,6 +1846,7 @@ export class MarkdownDocumenter {
|
||||
.join(' | '),
|
||||
}),
|
||||
);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
@ -2177,7 +2147,11 @@ export class MarkdownDocumenter {
|
||||
private _appendPageTitle(output: DocSection, key: string, order?: number): void {
|
||||
const configuration: TSDocConfiguration = this._tsdocConfiguration;
|
||||
|
||||
output.appendNode(new DocPageTitle({ configuration, key, locale: this.locale, order }));
|
||||
const en = intl(LocaleType.PAGE_NAME, key, LocaleLanguage.EN);
|
||||
const zh = intl(LocaleType.PAGE_NAME, key, LocaleLanguage.ZH);
|
||||
const title = this.locale === LocaleLanguage.ZH && en !== zh ? `${en} ${zh}` : en;
|
||||
|
||||
output.appendNode(new DocPageTitle({ configuration, title, order }));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -2374,7 +2348,7 @@ export class MarkdownDocumenter {
|
||||
}
|
||||
|
||||
private _intl(keyword: Keyword) {
|
||||
return getKeywordIntl(keyword, this.locale);
|
||||
return intl(LocaleType.KEYWORD, keyword, this.locale);
|
||||
}
|
||||
|
||||
private _getLang() {
|
||||
|
17
packages/site/src/constants/locales/api-category.json
Normal file
17
packages/site/src/constants/locales/api-category.json
Normal file
@ -0,0 +1,17 @@
|
||||
{
|
||||
"option": ["Option", "图配置项"],
|
||||
"render": ["Render", "渲染"],
|
||||
"data": ["Data", "数据"],
|
||||
"instance": ["Instance", "图实例"],
|
||||
"canvas": ["Canvas", "画布"],
|
||||
"viewport": ["Viewport", "视口"],
|
||||
"element": ["Element", "元素"],
|
||||
"animation": ["Animation", "动画"],
|
||||
"layout": ["Layout", "布局"],
|
||||
"behavior": ["Behavior", "交互"],
|
||||
"event": ["Event", "事件"],
|
||||
"theme": ["Theme", "主题"],
|
||||
"transform": ["Transform", "数据转换"],
|
||||
"plugin": ["plugin", "插件"],
|
||||
"exportImage": ["Export Image", "导出图片"]
|
||||
}
|
@ -1,27 +0,0 @@
|
||||
import { getIntl } from './common';
|
||||
|
||||
const apiCategoryNames: Record<string, string[]> = {
|
||||
option: ['Option', '图配置项'],
|
||||
render: ['Render', '渲染'],
|
||||
data: ['Data', '数据'],
|
||||
instance: ['Instance', '图实例'],
|
||||
canvas: ['Canvas', '画布'],
|
||||
viewport: ['Viewport', '视口'],
|
||||
element: ['Element', '元素'], //包括元素配置项设置 API 和元素操纵 API
|
||||
animation: ['Animation', '动画'],
|
||||
layout: ['Layout', '布局'],
|
||||
behavior: ['Behavior', '交互'],
|
||||
event: ['Event', '事件'],
|
||||
theme: ['Theme', '主题'],
|
||||
transform: ['Transform', '数据转换'],
|
||||
plugin: ['plugin', '插件'],
|
||||
exportImage: ['Export Image', '导出图片'],
|
||||
};
|
||||
|
||||
/**
|
||||
* 获取 API 分类名称
|
||||
* @param categoryKey 分类 key
|
||||
* @param locale 语言
|
||||
* @returns 分类名称
|
||||
*/
|
||||
export const getApiCategoryIntl = getIntl(apiCategoryNames);
|
@ -1,11 +0,0 @@
|
||||
export enum LocaleLanguage {
|
||||
EN = 'en-US',
|
||||
ZH = 'zh-CN',
|
||||
}
|
||||
|
||||
export const getIntl = (obj: Record<string, string[]>) => {
|
||||
return (key: string, language: LocaleLanguage) => {
|
||||
const [en, zh] = obj[key];
|
||||
return language === LocaleLanguage.EN ? en : zh;
|
||||
};
|
||||
};
|
5
packages/site/src/constants/locales/element.json
Normal file
5
packages/site/src/constants/locales/element.json
Normal file
@ -0,0 +1,5 @@
|
||||
{
|
||||
"node": ["Node", "节点"],
|
||||
"edge": ["Edge", "边"],
|
||||
"combo": ["Combo", "组合"]
|
||||
}
|
61
packages/site/src/constants/locales/enum.ts
Normal file
61
packages/site/src/constants/locales/enum.ts
Normal file
@ -0,0 +1,61 @@
|
||||
export enum LocaleType {
|
||||
API_CATEGORY = 'api-category',
|
||||
ELEMENT = 'element',
|
||||
HELPER = 'helper',
|
||||
KEYWORD = 'keyword',
|
||||
PAGE_NAME = 'page-name',
|
||||
}
|
||||
|
||||
export enum LocaleLanguage {
|
||||
EN = 'en-US',
|
||||
ZH = 'zh-CN',
|
||||
}
|
||||
|
||||
export enum Keyword {
|
||||
ABSTRACT_CLASS = 'abstract-class',
|
||||
ABSTRACT_CLASSES = 'abstract-classes',
|
||||
CLASS = 'class',
|
||||
CLASSES = 'classes',
|
||||
COLON = 'colon',
|
||||
COMMA = 'comma',
|
||||
CONSTRUCTOR = 'constructor',
|
||||
CONSTRUCTORS = 'constructors',
|
||||
DECORATOR = 'decorator',
|
||||
DEFAULT_VALUE = 'defaultValue',
|
||||
DESCRIPTION = 'description',
|
||||
ENUMERATION = 'enumeration',
|
||||
ENUMERATION_MEMBERS = 'enumeration-members',
|
||||
ENUMERATIONS = 'enumerations',
|
||||
EVENTS = 'events',
|
||||
EXAMPLE = 'example',
|
||||
EXCEPTIONS = 'exceptions',
|
||||
EXTENDS = 'extends',
|
||||
FUNCTION = 'function',
|
||||
FUNCTIONS = 'functions',
|
||||
IMPLEMENTS = 'implements',
|
||||
INTERFACE = 'interface',
|
||||
INTERFACES = 'interfaces',
|
||||
LEFT_PARENTHESIS = 'leftParenthesis',
|
||||
METHOD = 'method',
|
||||
METHODS = 'methods',
|
||||
MODIFIERS = 'modifiers',
|
||||
NAMESPACE = 'namespace',
|
||||
NAMESPACES = 'namespaces',
|
||||
OPTIONAL = 'optional',
|
||||
OPTIONS = 'options',
|
||||
PACKAGE = 'package',
|
||||
PACKAGES = 'packages',
|
||||
PARAMETER = 'parameter',
|
||||
PROPERTIES = 'properties',
|
||||
PROPERTY = 'property',
|
||||
REFERENCES = 'references',
|
||||
REMARKS = 'remarks',
|
||||
RETURNS = 'returns',
|
||||
RIGHT_PARENTHESIS = 'rightParenthesis',
|
||||
TYPE = 'type',
|
||||
TYPE_ALIAS = 'type-alias',
|
||||
TYPE_ALIASES = 'type-aliases',
|
||||
VARIABLE = 'variable',
|
||||
VARIABLES = 'variables',
|
||||
VIEW_PARAMETERS = 'view-parameters',
|
||||
}
|
13
packages/site/src/constants/locales/helper.json
Normal file
13
packages/site/src/constants/locales/helper.json
Normal file
@ -0,0 +1,13 @@
|
||||
{
|
||||
"prefixHelper": ["More about `Prefix` generic usage, see [Prefix]", "关于 `Prefix` 泛型的使用信息,见 [Prefix]"],
|
||||
"basePropsStyleHelper": [
|
||||
"If the element has its specific properties, we will list them below. For all generic style attributes, see",
|
||||
"如果元素有其特定的属性,我们将在下面列出。对于所有的通用样式属性,见"
|
||||
],
|
||||
"advancedPropsHelper": [
|
||||
"Except for the properties explicitly listed below, other supported properties are seen",
|
||||
"除了下面显式列出的属性,其他支持属性见"
|
||||
],
|
||||
"includes": ["Includes", "其中的"],
|
||||
"excludes": ["Excludes", "除了"]
|
||||
}
|
@ -1,15 +0,0 @@
|
||||
import { getIntl } from './index';
|
||||
|
||||
export const helpers = {
|
||||
prefixHelper: ['More about `Prefix` generic usage, see [Prefix]', '关于 `Prefix` 泛型的使用信息,见 [Prefix]'],
|
||||
basePropsStyleHelper: ['More about base style configuration, please check [here]', '了解通用样式配置,请点击[这里]'],
|
||||
advancedPropsHelper: [
|
||||
'Except for the properties explicitly listed below, other supported properties are seen',
|
||||
'除了下面显式列出的属性,其他支持属性见',
|
||||
],
|
||||
includes: ['Includes', '其中的'],
|
||||
excludes: ['Excludes', '除了'],
|
||||
remarks: ['Remarks', '说明'],
|
||||
};
|
||||
|
||||
export const getHelperIntl = getIntl(helpers);
|
@ -1,5 +1,18 @@
|
||||
export * from './api-category';
|
||||
export * from './common';
|
||||
export * from './helper';
|
||||
export * from './keywords';
|
||||
export * from './page';
|
||||
import { FileSystem } from '@rushstack/node-core-library';
|
||||
import * as path from 'path';
|
||||
import type { LocaleType } from './enum';
|
||||
import { LocaleLanguage } from './enum';
|
||||
|
||||
const localeMap = new Map<LocaleType, Record<string, string[]>>();
|
||||
|
||||
export const intl = (type: LocaleType, key: string, lang: LocaleLanguage): string => {
|
||||
if (!localeMap.has(type)) {
|
||||
const filePath = path.join(__dirname, `${type}.json`);
|
||||
if (!FileSystem.exists(filePath)) {
|
||||
throw new Error(`The locale file does not exist: ${filePath}`);
|
||||
}
|
||||
localeMap.set(type, JSON.parse(FileSystem.readFile(filePath)));
|
||||
}
|
||||
const [en, zh] = localeMap.get(type)?.[key] || [key, key];
|
||||
return lang === LocaleLanguage.EN ? en : zh;
|
||||
};
|
||||
|
48
packages/site/src/constants/locales/keyword.json
Normal file
48
packages/site/src/constants/locales/keyword.json
Normal file
@ -0,0 +1,48 @@
|
||||
{
|
||||
"abstract-class": ["Abstract Class", "抽象类"],
|
||||
"abstract-classes": ["Abstract Classes", "抽象类"],
|
||||
"class": ["Class", "类"],
|
||||
"classes": ["Classes", "类"],
|
||||
"colon": [": ", ":"],
|
||||
"comma": [", ", ","],
|
||||
"constructor": ["Constructor", "构造函数"],
|
||||
"constructors": ["Constructors", "构造函数"],
|
||||
"decorator": ["Decorator", "装饰器"],
|
||||
"defaultValue": ["Default Value", "默认值"],
|
||||
"description": ["Description", "描述"],
|
||||
"enumeration-members": ["Enumeration Members", "枚举成员"],
|
||||
"enumeration": ["Enumeration", "枚举"],
|
||||
"enumerations": ["Enumerations", "枚举"],
|
||||
"events": ["Events", "事件"],
|
||||
"example": ["Example", "示例"],
|
||||
"exceptions": ["Exceptions", "异常"],
|
||||
"extends": ["Extends", "继承自"],
|
||||
"function": ["Function", "函数"],
|
||||
"functions": ["Functions", "函数"],
|
||||
"implements": ["Implements", "实现自"],
|
||||
"interface": ["Interface", "接口"],
|
||||
"interfaces": ["Interfaces", "接口"],
|
||||
"leftParenthesis": ["(", "("],
|
||||
"method": ["Method", "方法"],
|
||||
"methods": ["Methods", "方法"],
|
||||
"modifiers": ["Modifiers", "修饰符"],
|
||||
"namespace": ["Namespace", "命名空间"],
|
||||
"namespaces": ["Namespaces", "命名空间"],
|
||||
"optional": ["Optional", "可选"],
|
||||
"options": ["Options", "配置项"],
|
||||
"package": ["Package", "包"],
|
||||
"packages": ["Packages", "包"],
|
||||
"parameter": ["Parameter", "参数"],
|
||||
"properties": ["Properties", "属性"],
|
||||
"property": ["Property", "属性"],
|
||||
"references": ["References", "引用"],
|
||||
"remarks": ["Remarks", "附注"],
|
||||
"returns": ["Returns", "返回值"],
|
||||
"rightParenthesis": [")", ")"],
|
||||
"type": ["Type", "类型"],
|
||||
"type-alias": ["Type Alias", "类型别名"],
|
||||
"type-aliases": ["Type Aliases", "类型别名"],
|
||||
"variable": ["Variable", "变量"],
|
||||
"variables": ["Variables", "变量"],
|
||||
"view-parameters": ["View Parameters", "相关参数"]
|
||||
}
|
@ -1,101 +0,0 @@
|
||||
import { getIntl } from './index';
|
||||
|
||||
export enum Keyword {
|
||||
ABSTRACT_CLASS = 'abstract-class',
|
||||
ABSTRACT_CLASSES = 'abstract-classes',
|
||||
CLASS = 'class',
|
||||
CLASSES = 'classes',
|
||||
COLON = 'colon',
|
||||
COMMA = 'comma',
|
||||
CONSTRUCTOR = 'constructor',
|
||||
CONSTRUCTORS = 'constructors',
|
||||
DECORATOR = 'decorator',
|
||||
DEFAULT_VALUE = 'defaultValue',
|
||||
DESCRIPTION = 'description',
|
||||
ENUMERATION = 'enumeration',
|
||||
ENUMERATION_MEMBERS = 'enumeration-members',
|
||||
ENUMERATIONS = 'enumerations',
|
||||
EVENTS = 'events',
|
||||
EXAMPLE = 'example',
|
||||
EXCEPTIONS = 'exceptions',
|
||||
EXTENDS = 'extends',
|
||||
FUNCTION = 'function',
|
||||
FUNCTIONS = 'functions',
|
||||
IMPLEMENTS = 'implements',
|
||||
INTERFACE = 'interface',
|
||||
INTERFACES = 'interfaces',
|
||||
LEFT_PARENTHESIS = 'leftParenthesis',
|
||||
METHOD = 'method',
|
||||
METHODS = 'methods',
|
||||
MODIFIERS = 'modifiers',
|
||||
NAMESPACE = 'namespace',
|
||||
NAMESPACES = 'namespaces',
|
||||
OPTIONAL = 'optional',
|
||||
OPTIONS = 'options',
|
||||
PACKAGE = 'package',
|
||||
PACKAGES = 'packages',
|
||||
PARAMETER = 'parameter',
|
||||
PROPERTIES = 'properties',
|
||||
PROPERTY = 'property',
|
||||
REFERENCES = 'references',
|
||||
REMARKS = 'remarks',
|
||||
RETURNS = 'returns',
|
||||
RIGHT_PARENTHESIS = 'rightParenthesis',
|
||||
TYPE = 'type',
|
||||
TYPE_ALIAS = 'type-alias',
|
||||
TYPE_ALIASES = 'type-aliases',
|
||||
VARIABLE = 'variable',
|
||||
VARIABLES = 'variables',
|
||||
VIEW_PARAMETERS = 'view-parameters',
|
||||
}
|
||||
|
||||
export const KeywordMapping: Record<Keyword, string[]> = {
|
||||
[Keyword.ABSTRACT_CLASS]: ['Abstract Class', '抽象类'],
|
||||
[Keyword.ABSTRACT_CLASSES]: ['Abstract Classes', '抽象类'],
|
||||
[Keyword.CLASS]: ['Class', '类'],
|
||||
[Keyword.CLASSES]: ['Classes', '类'],
|
||||
[Keyword.COLON]: [': ', ':'],
|
||||
[Keyword.COMMA]: [', ', ','],
|
||||
[Keyword.CONSTRUCTOR]: ['Constructor', '构造函数'],
|
||||
[Keyword.CONSTRUCTORS]: ['Constructors', '构造函数'],
|
||||
[Keyword.DECORATOR]: ['Decorator', '装饰器'],
|
||||
[Keyword.DEFAULT_VALUE]: ['Default Value', '默认值'],
|
||||
[Keyword.DESCRIPTION]: ['Description', '描述'],
|
||||
[Keyword.ENUMERATION_MEMBERS]: ['Enumeration Members', '枚举成员'],
|
||||
[Keyword.ENUMERATION]: ['Enumeration', '枚举'],
|
||||
[Keyword.ENUMERATIONS]: ['Enumerations', '枚举'],
|
||||
[Keyword.EVENTS]: ['Events', '事件'],
|
||||
[Keyword.EXAMPLE]: ['Example', '示例'],
|
||||
[Keyword.EXCEPTIONS]: ['Exceptions', '异常'],
|
||||
[Keyword.EXTENDS]: ['Extends', '继承自'],
|
||||
[Keyword.FUNCTION]: ['Function', '函数'],
|
||||
[Keyword.FUNCTIONS]: ['Functions', '函数'],
|
||||
[Keyword.IMPLEMENTS]: ['Implements', '实现自'],
|
||||
[Keyword.INTERFACE]: ['Interface', '接口'],
|
||||
[Keyword.INTERFACES]: ['Interfaces', '接口'],
|
||||
[Keyword.LEFT_PARENTHESIS]: ['(', '('],
|
||||
[Keyword.METHOD]: ['Method', '方法'],
|
||||
[Keyword.METHODS]: ['Methods', '方法'],
|
||||
[Keyword.MODIFIERS]: ['Modifiers', '修饰符'],
|
||||
[Keyword.NAMESPACE]: ['Namespace', '命名空间'],
|
||||
[Keyword.NAMESPACES]: ['Namespaces', '命名空间'],
|
||||
[Keyword.OPTIONAL]: ['Optional', '可选'],
|
||||
[Keyword.OPTIONS]: ['Options', '配置项'],
|
||||
[Keyword.PACKAGE]: ['Package', '包'],
|
||||
[Keyword.PACKAGES]: ['Packages', '包'],
|
||||
[Keyword.PARAMETER]: ['Parameter', '参数'],
|
||||
[Keyword.PROPERTIES]: ['Properties', '属性'],
|
||||
[Keyword.PROPERTY]: ['Property', '属性'],
|
||||
[Keyword.REFERENCES]: ['References', '引用'],
|
||||
[Keyword.REMARKS]: ['Remarks', '备注'],
|
||||
[Keyword.RETURNS]: ['Returns', '返回值'],
|
||||
[Keyword.RIGHT_PARENTHESIS]: [')', ')'],
|
||||
[Keyword.TYPE_ALIAS]: ['Type Alias', '类型别名'],
|
||||
[Keyword.TYPE_ALIASES]: ['Type Aliases', '类型别名'],
|
||||
[Keyword.TYPE]: ['Type', '类型'],
|
||||
[Keyword.VARIABLE]: ['Variable', '变量'],
|
||||
[Keyword.VARIABLES]: ['Variables', '变量'],
|
||||
[Keyword.VIEW_PARAMETERS]: ['View Parameters', '相关参数'],
|
||||
};
|
||||
|
||||
export const getKeywordIntl = getIntl(KeywordMapping);
|
66
packages/site/src/constants/locales/page-name.json
Normal file
66
packages/site/src/constants/locales/page-name.json
Normal file
@ -0,0 +1,66 @@
|
||||
{
|
||||
"GraphOptions": ["Options", "配置项"],
|
||||
"GraphMethods": ["API", "方法"],
|
||||
"GraphProperties": ["Properties", "属性"],
|
||||
"ElementMethods": ["API", "方法"],
|
||||
"BaseNode": ["BaseNode", "节点通用样式"],
|
||||
"Circle": ["Circle", "圆形"],
|
||||
"Diamond": ["Diamond", "菱形"],
|
||||
"Donut": ["Donut", "甜甜圈"],
|
||||
"Ellipse": ["Ellipse", "椭圆形"],
|
||||
"Hexagon": ["Hexagon", "六边形"],
|
||||
"Html": ["Html", "HTML"],
|
||||
"Image": ["Image", "图片"],
|
||||
"Rect": ["Rect", "矩形"],
|
||||
"Star": ["Star", "五角形"],
|
||||
"Triangle": ["Triangle", "三角形"],
|
||||
"BaseEdge": ["BaseEdge", "边通用样式"],
|
||||
"Cubic": ["Cubic", "三次贝塞尔曲线"],
|
||||
"CubicHorizontal": ["CubicHorizontal", "水平三次贝塞尔曲线"],
|
||||
"CubicVertical": ["CubicVertical", "垂直三次贝塞尔曲线"],
|
||||
"Line": ["Line", "直线"],
|
||||
"Polyline": ["Polyline", "折线"],
|
||||
"Quadratic": ["Quadratic", "二次贝塞尔曲线"],
|
||||
"BaseCombo": ["BaseCombo", "组合基础样式"],
|
||||
"CircleCombo": ["Circle", "圆形"],
|
||||
"RectCombo": ["Rect", "矩形"],
|
||||
"AntvDagreLayout": ["AntvDagre", "布局"],
|
||||
"CircularLayout": ["Circular", "环形布局"],
|
||||
"ComboCombinedLayout": ["ComboCombined", "复合布局"],
|
||||
"ConcentricLayout": ["Concentric", "同心圆布局"],
|
||||
"D3Force3DLayout": ["D3Force3D", "3D 力导向布局"],
|
||||
"D3ForceLayout": ["D3Force", "力导向布局"],
|
||||
"DagreLayout": ["Dagre", "层次布局"],
|
||||
"ForceAtlas2Layout": ["ForceAtlas2", "力导向布局"],
|
||||
"ForceLayout": ["Force", "力导向布局"],
|
||||
"FruchtermanLayout": ["Fruchterman", "力导向布局"],
|
||||
"GridLayout": ["Grid", "网格布局"],
|
||||
"MdsLayout": ["Mds", "高维数据降维布局"],
|
||||
"RadialLayout": ["Radial", "镭射布局"],
|
||||
"RandomLayout": ["Random", "随机布局"],
|
||||
"BaseBehavior": ["BaseBehavior", "基础交互"],
|
||||
"BrushSelect": ["BrushSelect", "框选"],
|
||||
"ClickElement": ["ClickElement", "点击选中"],
|
||||
"CollapseExpand": ["CollapseExpand", "展开折叠Combo"],
|
||||
"CreateEdge": ["CreateEdge", "创建边"],
|
||||
"DragCanvas": ["DragCanvas", "拖拽画布"],
|
||||
"DragElement": ["DragElement", "拖拽元素"],
|
||||
"DragElementForce": ["DragElementForce", "力导向拖拽元素"],
|
||||
"FocusElement": ["FocusElement", "聚焦元素"],
|
||||
"HoverElement": ["HoverElement", "悬停激活"],
|
||||
"LassoSelect": ["LassoSelect", "套索选择"],
|
||||
"ScrollCanvas": ["ScrollCanvas", "滚动画布"],
|
||||
"ZoomCanvas": ["ZoomCanvas", "缩放画布"],
|
||||
"BubbleSets": ["BubbleSets", "气泡集"],
|
||||
"CameraSetting": ["CameraSetting", "相机设置"],
|
||||
"ContextMenu": ["ContextMenu", "右键菜单"],
|
||||
"GridLine": ["GridLine", "网格线"],
|
||||
"History": ["History", "历史记录"],
|
||||
"Hull": ["Hull", "轮廓包围"],
|
||||
"Legend": ["Legend", "图例"],
|
||||
"Toolbar": ["Toolbar", "工具栏"],
|
||||
"Tooltip": ["Tooltip", "提示框"],
|
||||
"Watermark": ["Watermark", "水印"],
|
||||
"Timebar": ["Timebar", "时间条"],
|
||||
"Contextmenu": ["Contextmenu", "上下文菜单"]
|
||||
}
|
@ -1,85 +0,0 @@
|
||||
import { getIntl } from './common';
|
||||
|
||||
export const PageTitle: Record<string, string[]> = {
|
||||
// graph
|
||||
GraphOptions: ['Options', '配置项'],
|
||||
GraphMethods: ['API', '方法'],
|
||||
GraphProperties: ['Properties', '属性'],
|
||||
// element
|
||||
ElementMethods: ['API', '方法'],
|
||||
// element/node
|
||||
BaseNode: ['BaseNode', '节点通用样式属性'],
|
||||
Circle: ['Circle', '圆形'],
|
||||
Diamond: ['Diamond', '菱形'],
|
||||
Donut: ['Donut', '甜甜圈'],
|
||||
Ellipse: ['Ellipse', '椭圆形'],
|
||||
Hexagon: ['Hexagon', '六边形'],
|
||||
Html: ['Html', 'HTML'],
|
||||
Image: ['Image', '图片'],
|
||||
Rect: ['Rect', '矩形'],
|
||||
Star: ['Star', '五角形'],
|
||||
Triangle: ['Triangle', '三角形'],
|
||||
// element/edge
|
||||
BaseEdge: ['BaseEdge', '边通用样式属性'],
|
||||
Cubic: ['Cubic', '三次贝塞尔曲线'],
|
||||
CubicHorizontal: ['CubicHorizontal', '水平三次贝塞尔曲线'],
|
||||
CubicVertical: ['CubicVertical', '垂直三次贝塞尔曲线'],
|
||||
Line: ['Line', '直线'],
|
||||
Polyline: ['Polyline', '折线'],
|
||||
Quadratic: ['Quadratic', '二次贝塞尔曲线'],
|
||||
// element/combo
|
||||
BaseCombo: ['BaseCombo', '组合基础样式属性'],
|
||||
CircleCombo: ['Circle', '圆形'],
|
||||
RectCombo: ['Rect', '矩形'],
|
||||
// layout
|
||||
AntvDagreLayout: ['AntvDagre', '布局'],
|
||||
CircularLayout: ['Circular', '环形布局'],
|
||||
ComboCombinedLayout: ['ComboCombined', '复合布局'],
|
||||
ConcentricLayout: ['Concentric', '同心圆布局'],
|
||||
D3Force3DLayout: ['D3Force3D', '3D 力导向布局'],
|
||||
D3ForceLayout: ['D3Force', '力导向布局'],
|
||||
DagreLayout: ['Dagre', '层次布局'],
|
||||
ForceAtlas2Layout: ['ForceAtlas2', '力导向布局'],
|
||||
ForceLayout: ['Force', '力导向布局'],
|
||||
FruchtermanLayout: ['Fruchterman', '力导向布局'],
|
||||
GridLayout: ['Grid', '网格布局'],
|
||||
MdsLayout: ['Mds', '高维数据降维布局'],
|
||||
RadialLayout: ['Radial', '镭射布局'],
|
||||
RandomLayout: ['Random', '随机布局'],
|
||||
// behaviors
|
||||
BaseBehavior: ['BaseBehavior', '基础交互'],
|
||||
BrushSelect: ['BrushSelect', '框选'],
|
||||
ClickElement: ['ClickElement', '点击选中'],
|
||||
CollapseExpand: ['CollapseExpand', '展开折叠Combo'],
|
||||
CreateEdge: ['CreateEdge', '创建边'],
|
||||
DragCanvas: ['DragCanvas', '拖拽画布'],
|
||||
DragElement: ['DragElement', '拖拽元素'],
|
||||
DragElementForce: ['DragElementForce', '力导向拖拽元素'],
|
||||
FocusElement: ['FocusElement', '聚焦元素'],
|
||||
HoverElement: ['HoverElement', '悬停激活'],
|
||||
LassoSelect: ['LassoSelect', '套索选择'],
|
||||
ScrollCanvas: ['ScrollCanvas', '滚动画布'],
|
||||
ZoomCanvas: ['ZoomCanvas', '缩放画布'],
|
||||
// plugins
|
||||
BubbleSets: ['BubbleSets', '气泡集'],
|
||||
CameraSetting: ['CameraSetting', '相机设置'],
|
||||
ContextMenu: ['ContextMenu', '右键菜单'],
|
||||
GridLine: ['GridLine', '网格线'],
|
||||
History: ['History', '历史记录'],
|
||||
Hull: ['Hull', '轮廓包围'],
|
||||
Legend: ['Legend', '图例'],
|
||||
Toolbar: ['Toolbar', '工具栏'],
|
||||
Tooltip: ['Tooltip', '提示框'],
|
||||
Watermark: ['Watermark', '水印'],
|
||||
Timebar: ['Timebar', '时间条'],
|
||||
Contextmenu: ['Contextmenu', '上下文菜单'],
|
||||
};
|
||||
|
||||
// 节点、边、Combo 的中英文对照
|
||||
export const ElementLocale: Record<string, string[]> = {
|
||||
node: ['Node', '节点'],
|
||||
edge: ['Edge', '边'],
|
||||
combo: ['Combo', '组合'],
|
||||
};
|
||||
|
||||
export const getElementIntl = getIntl(ElementLocale);
|
@ -1,14 +1,12 @@
|
||||
import type { IDocNodeParameters } from '@microsoft/tsdoc';
|
||||
import { DocNode } from '@microsoft/tsdoc';
|
||||
import { LocaleLanguage, PageTitle } from '../constants/locales';
|
||||
import { CustomDocNodeKind } from './CustomDocNodeKind';
|
||||
|
||||
/**
|
||||
* Constructor parameters for {@link DocPageTitle}.
|
||||
*/
|
||||
export interface IDocPageTitleParameters extends IDocNodeParameters {
|
||||
key: string;
|
||||
locale: string;
|
||||
title: string;
|
||||
order?: number;
|
||||
}
|
||||
|
||||
@ -27,10 +25,8 @@ export class DocPageTitle extends DocNode {
|
||||
|
||||
public constructor(parameters: IDocPageTitleParameters) {
|
||||
super(parameters);
|
||||
const { key, locale, order } = parameters;
|
||||
const arr = PageTitle[key];
|
||||
this.title = arr ? (locale === LocaleLanguage.EN ? arr[0] : arr.join(' ')) : key;
|
||||
this.order = order;
|
||||
this.title = parameters.title;
|
||||
this.order = parameters.order;
|
||||
}
|
||||
|
||||
/** @override */
|
||||
|
@ -1,3 +0,0 @@
|
||||
export const inputFolder = 'support/api';
|
||||
export const outputFolder = 'docs/api';
|
||||
export const referenceFoldername = 'reference';
|
@ -1,5 +1,6 @@
|
||||
import { ApiInterface, ApiModel, ExcerptTokenKind, type ExcerptToken } from '@microsoft/api-extractor-model';
|
||||
import { camelCase } from 'lodash';
|
||||
import { interfacesToSkipParsing } from '../MarkdownDocumenter';
|
||||
|
||||
export type BaseExcerptToken = {
|
||||
text: string;
|
||||
@ -94,6 +95,8 @@ export const liftPrefixExcerptTokens = (items: ICustomExcerptToken[]): ICustomEx
|
||||
let topLevelPrefixes: ICustomExcerptToken[] = [];
|
||||
|
||||
for (const item of items) {
|
||||
if (interfacesToSkipParsing.includes(item.text)) continue;
|
||||
|
||||
if (item.type === 'Prefix') {
|
||||
const newItem = { ...item, prefix: getAccessorExcerptTokensPrefixes(item) };
|
||||
topLevelPrefixes.push(newItem);
|
||||
|
30
packages/site/src/utils/gitignore.ts
Normal file
30
packages/site/src/utils/gitignore.ts
Normal file
@ -0,0 +1,30 @@
|
||||
import { FileSystem } from '@rushstack/node-core-library';
|
||||
import * as path from 'path';
|
||||
|
||||
/**
|
||||
* Get the path to the .gitignore file
|
||||
* @param outputFolder - The output folder
|
||||
* @returns The path to the .gitignore file
|
||||
*/
|
||||
function getGitignorePath(outputFolder: string): string {
|
||||
return path.join(outputFolder, '.gitignore');
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize the .gitignore file
|
||||
* @param outputFolder - The output folder
|
||||
*/
|
||||
export function initGitignore(outputFolder: string) {
|
||||
const gitPath = getGitignorePath(outputFolder);
|
||||
FileSystem.writeFile(gitPath, '');
|
||||
}
|
||||
|
||||
/**
|
||||
* Sync the filename to the .gitignore file
|
||||
* @param outputFolder - The output folder
|
||||
* @param filename - The filename to sync
|
||||
*/
|
||||
export function syncToGitignore(outputFolder: string, filename: string) {
|
||||
const gitPath = getGitignorePath(outputFolder);
|
||||
FileSystem.appendToFile(gitPath, `\n${filename.replace(outputFolder, '')}`);
|
||||
}
|
Loading…
Reference in New Issue
Block a user