Skip to content

Commit

Permalink
fix: ensure cell's type when defined it
Browse files Browse the repository at this point in the history
  • Loading branch information
bubkoo committed Jun 12, 2020
1 parent d5fdd65 commit a2cf40f
Show file tree
Hide file tree
Showing 17 changed files with 628 additions and 603 deletions.
11 changes: 8 additions & 3 deletions examples/x6-example-features/src/pages/shape/basic.tsx
Expand Up @@ -96,6 +96,7 @@ export default class Example extends React.Component {
})

const DecoratedRect = Node.define({
type: 'decorated-rect',
markup:
'<g class="rotatable"><g class="scalable"><rect/></g><image/><text/></g>',
size: { width: 100, height: 60 },
Expand Down Expand Up @@ -126,13 +127,14 @@ export default class Example extends React.Component {
y: 140,
width: 180,
height: 80,

attrs: {
text: { text: 'Decorated with image' },
image: { 'xlink:href': 'http://placehold.it/16x16' },
},
})

console.log(decoratedRect)

graph.addNode(decoratedRect)

graph.addNode({
Expand All @@ -145,7 +147,8 @@ export default class Example extends React.Component {
'Lorem ipsum dolor sit amet,\n consectetur adipiscing elit. Nulla vel porttitor est.',
})

const MyElementWithPorts = Node.define({
const NodeWithPorts = Node.define({
type: 'node-with-ports',
markup: [
'<g class="rotatable">',
'<g class="scalable">',
Expand Down Expand Up @@ -189,7 +192,7 @@ export default class Example extends React.Component {
},
})

const nodeWithPort = new MyElementWithPorts({
const nodeWithPort = new NodeWithPorts({
x: 90,
y: 300,
width: 80,
Expand Down Expand Up @@ -236,6 +239,8 @@ export default class Example extends React.Component {
token.appendTo(scalableNode)
}
}

console.log(graph.toJSON())
}

refContainer = (container: HTMLDivElement) => {
Expand Down
2 changes: 2 additions & 0 deletions examples/x6-example-features/src/pages/shape/standard.tsx
Expand Up @@ -205,6 +205,8 @@ export default class Example extends React.Component {
target: { x: 450, y: 520 },
vertices: [{ x: 500, y: 440 }],
})

console.log(graph.toJSON())
}

refContainer = (container: HTMLDivElement) => {
Expand Down
9 changes: 8 additions & 1 deletion packages/x6/src/graph/graph.ts
Expand Up @@ -111,7 +111,14 @@ export class Graph extends Basecoat<EventArgs> {
return this.model.toJSON()
}

fromJSON() {}
parseJSON(data: Model.FromJSONData) {
return this.model.parseJSON(data)
}

fromJSON(data: Model.FromJSONData, options: Model.FromJSONOptions = {}) {
this.model.fromJSON(data, options)
return this
}

getCellById(id: string) {
return this.model.getCell(id)
Expand Down
30 changes: 29 additions & 1 deletion packages/x6/src/model/cell.ts
Expand Up @@ -92,7 +92,9 @@ export class Cell<

const ctor = this.constructor as typeof Cell
const defaults = ctor.getDefaults(true)
const meta = ObjectExt.merge({}, defaults, metadata)
const meta = ObjectExt.merge({}, defaults, metadata, {
type: defaults.type || metadata.type,
})
const props = this.preprocess(meta)

this.id = metadata.id || StringExt.uuid()
Expand Down Expand Up @@ -1064,6 +1066,32 @@ export class Cell<
const defaults = ctor.getDefaults(true)
const defaultAttrs = defaults.attrs || {}
const finalAttrs: Attr.CellAttrs = {}
const toString = Object.prototype.toString
const cellType = this.isNode() ? 'node' : this.isEdge() ? 'edge' : 'cell'

if (!props.type) {
const ctor = this.constructor
throw new Error(
`Unable to serialize ${cellType} missing "type" prop, check the ${cellType} "${
ctor.name || toString.call(ctor)
}"`,
)
}

Object.keys(props).forEach((key) => {
const val = props[key]
if (
!Array.isArray(val) &&
typeof val === 'object' &&
!ObjectExt.isPlainObject(val)
) {
throw new Error(
`Can only serialize ${cellType} with plain-object props, but got a "${toString.call(
val,
)}" type of key "${key}" on ${cellType} "${this.id}"`,
)
}
})

Object.keys(attrs).forEach((key) => {
const attr = attrs[key]
Expand Down
19 changes: 17 additions & 2 deletions packages/x6/src/model/edge.ts
Expand Up @@ -1290,10 +1290,16 @@ export namespace Edge {
export function define(config: Config) {
const { name, ...others } = config
const shape = ObjectExt.createClass<Definition>(
getClassName(name),
getClassName(name || others.type),
this as Definition,
)

shape.config(others)

if (others.type) {
registry.register(others.type, shape)
}

return shape
}

Expand Down Expand Up @@ -1323,6 +1329,7 @@ export namespace Edge {
}

if (typeof options === 'function') {
options.config({ type: name })
return options
}

Expand All @@ -1341,9 +1348,17 @@ export namespace Edge {
others.name = name
}

return parent.define.call(parent, others)
const shape = parent.define.call(parent, others)
shape.config({ type: name })
return shape
},
})

Share.setEdgeRegistry(registry)
}

export namespace Edge {
const type = 'basic.edge'
Edge.config({ type })
registry.register(type, Edge)
}
26 changes: 12 additions & 14 deletions packages/x6/src/model/model.ts
Expand Up @@ -6,6 +6,7 @@ import { Collection } from './collection'
import { Cell } from './cell'
import { Edge } from './edge'
import { Node } from './node'
import { type } from 'jquery'

export class Model extends Basecoat<Model.EventArgs> {
public readonly collection: Collection
Expand Down Expand Up @@ -1045,16 +1046,14 @@ export class Model extends Basecoat<Model.EventArgs> {
return Model.toJSON(this.getCells())
}

parseJSON(data: Parameters<typeof Model.fromJSON>[0]) {
parseJSON(data: Model.FromJSONData) {
return Model.fromJSON(data)
}

fromJSON(
data: Parameters<typeof Model.fromJSON>[0],
options: Model.FromJSONOptions = {},
) {
fromJSON(data: Model.FromJSONData, options: Model.FromJSONOptions = {}) {
const cells = this.parseJSON(data)
this.resetCells(cells, options)
return this
}

// #endregion
Expand Down Expand Up @@ -1096,9 +1095,15 @@ export namespace Model {
export interface SetOptions extends Collection.SetOptions {}
export interface AddOptions extends Collection.AddOptions {}
export interface RemoveOptions extends Collection.RemoveOptions {}

export interface FromJSONOptions extends Collection.SetOptions {}

export type FromJSONData =
| (Node.Properties | Edge.Properties)[]
| (Partial<ReturnType<typeof toJSON>> & {
nodes?: Node.Properties[]
edges?: Edge.Properties[]
})

export interface GetCellsInAreaOptions {
strict?: boolean
}
Expand Down Expand Up @@ -1195,14 +1200,7 @@ export namespace Model {
}
}

export function fromJSON(
data:
| (Node.Properties | Edge.Properties)[]
| (Partial<ReturnType<typeof toJSON>> & {
nodes?: Node.Properties[]
edges?: Edge.Properties[]
}),
) {
export function fromJSON(data: FromJSONData) {
const cells: Cell.Properties[] = []
if (Array.isArray(data)) {
cells.push(...data)
Expand Down
13 changes: 11 additions & 2 deletions packages/x6/src/model/node.ts
Expand Up @@ -1050,10 +1050,16 @@ export namespace Node {
export function define(config: Config) {
const { name, ...others } = config
const shape = ObjectExt.createClass<Definition>(
getClassName(name),
getClassName(name || others.type),
this as Definition,
)

shape.config(others)

if (others.type) {
registry.register(others.type, shape)
}

return shape
}

Expand Down Expand Up @@ -1083,6 +1089,7 @@ export namespace Node {
}

if (typeof options === 'function') {
options.config({ type: name })
return options
}

Expand All @@ -1101,7 +1108,9 @@ export namespace Node {
others.name = name
}

return parent.define.call(parent, others)
const shape = parent.define.call(parent, others)
shape.config({ type: name })
return shape
},
})

Expand Down
3 changes: 1 addition & 2 deletions packages/x6/src/shape/basic/text-block.ts
Expand Up @@ -81,8 +81,8 @@ export namespace TextBlock {

export namespace TextBlock {
TextBlock.config({
type: registryName,
view: registryName,

markup: [
'<g class="rotatable">',
'<g class="scalable"><rect/></g>',
Expand All @@ -97,7 +97,6 @@ export namespace TextBlock {
: `<text class="${contentSelector.substr(1)}"/>`,
'</g>',
].join(''),

attrs: {
'.': {
fill: '#ffffff',
Expand Down
8 changes: 3 additions & 5 deletions packages/x6/src/shape/basic/util.ts
Expand Up @@ -81,9 +81,7 @@ export function createShape(
}

const base = options.parent || Base
const shape = base.define(ObjectExt.merge(defaults, config))

Node.registry.register(name, shape)

return shape as typeof Base
return base.define(
ObjectExt.merge(defaults, config, { type: name }),
) as typeof Base
}
5 changes: 1 addition & 4 deletions packages/x6/src/shape/standard/cylinder.ts
@@ -1,12 +1,11 @@
import { NumberExt } from '../../util'
import { bodyAttr } from './util'
import { Node } from '../../model/node'
import { Base } from '../base'

const CYLINDER_TILT = 10

export const Cylinder = Base.define({
name: 'cylinder',
type: 'cylinder',
markup: [
{
tagName: 'path',
Expand Down Expand Up @@ -113,5 +112,3 @@ export const Cylinder = Base.define({
},
},
})

Node.registry.register('cylinder', Cylinder)
3 changes: 2 additions & 1 deletion packages/x6/src/shape/standard/edge-doubled.ts
@@ -1,6 +1,7 @@
import { Edge } from '../../model/edge'

export const DoubleEdge = Edge.registry.register('double-edge', {
export const DoubleEdge = Edge.define({
type: 'double-edge',
markup: [
{
tagName: 'path',
Expand Down
3 changes: 2 additions & 1 deletion packages/x6/src/shape/standard/edge-shadow.ts
@@ -1,6 +1,7 @@
import { Edge } from '../../model/edge'

export const ShadowEdge = Edge.registry.register('shadow-edge', {
export const ShadowEdge = Edge.define({
type: 'shadow-edge',
markup: [
{
tagName: 'path',
Expand Down
3 changes: 2 additions & 1 deletion packages/x6/src/shape/standard/edge.ts
@@ -1,6 +1,7 @@
import { Edge as E } from '../../model/edge'

export const Edge = E.registry.register('edge', {
export const Edge = E.define({
type: 'edge',
markup: [
{
tagName: 'path',
Expand Down
3 changes: 2 additions & 1 deletion packages/x6/src/shape/standard/rect-headered.ts
@@ -1,7 +1,8 @@
import { bodyAttr, labelAttr } from './util'
import { Node } from '../../model/node'

export const HeaderedRect = Node.registry.register('rect-headered', {
export const HeaderedRect = Node.define({
type: 'rect-headered',
markup: [
{
tagName: 'rect',
Expand Down
5 changes: 1 addition & 4 deletions packages/x6/src/shape/standard/text-block.ts
@@ -1,11 +1,10 @@
import { Platform, Dom } from '../../util'
import { Attr } from '../../definition'
import { Node } from '../../model'
import { bodyAttr } from './util'
import { Base } from '../base'

export const TextBlock = Base.define({
name: 'text-block',
type: 'text-block',
markup: [
{
tagName: 'rect',
Expand Down Expand Up @@ -92,5 +91,3 @@ export const TextBlock = Base.define({
},
},
})

Node.registry.register('text-block', TextBlock)
4 changes: 1 addition & 3 deletions packages/x6/src/shape/standard/util.ts
Expand Up @@ -52,7 +52,5 @@ export function createShape(
}

const base = options.parent || Base
const shape = base.define(ObjectExt.merge(defaults, config))
Node.registry.register(type, shape)
return shape as typeof Base
return base.define(ObjectExt.merge(defaults, config, { type })) as typeof Base
}

0 comments on commit a2cf40f

Please sign in to comment.