You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

112 lines
3.3 KiB

import React from "react";
import classNames from "classnames";
import { Icon } from "@antv/x6-components";
import { Graph, Dnd } from "@antv/x6";
import { data, DataItem, isGroup } from "./data";
import { addNode } from "./util";
export class Sidebar extends React.Component<Sidebar.Props> {
private container: HTMLDivElement;
refContainer = (container: HTMLDivElement) => {
this.container = container;
};
componentDidMount() {
this.container.childNodes.forEach((elem: HTMLElement) => {
const type = elem.getAttribute("data-type") || "";
const itemData = data.map[type];
const dnd = new Dnd<DataItem>(elem, {
data: itemData,
getGraph: () => this.props.graph,
getTargetCell: ({ graph, graphX, graphY }) => {
const cell = graph.getCellAt(graphX, graphY);
if (cell != null && cell.data != null && isGroup(cell.data.type)) {
return cell;
}
return null;
},
createDragElement: ({ element }) => {
const elem = document.createElement("div") as HTMLDivElement;
const w = element.offsetWidth;
const h = element.offsetHeight;
elem.style.width = `${w}px`;
elem.style.height = `${h}px`;
elem.style.border = "1px dashed #000";
elem.style.cursor = "move";
return elem;
},
createPreviewElement: ({ graph, element }) => {
const elem = document.createElement("div") as HTMLDivElement;
const w = element.offsetWidth;
const h = element.offsetHeight;
const s = graph.view.scale;
elem.style.width = `${w * s}px`;
elem.style.height = `${h * s}px`;
elem.style.border = "1px dashed #000";
elem.style.cursor = "move";
return elem;
}
});
dnd.on("dragPrepare", ({ dragElement }) => {
dragElement.style.margin = "0";
});
dnd.on("drop", ({ data, graph, targetCell, targetPosition }) => {
if (data != null) {
const group = isGroup(data.data.type);
const parent = targetCell || undefined;
let x = targetPosition.x;
let y = targetPosition.y;
// relative parent position
if (parent != null) {
const geom = parent.getGeometry()!;
x -= geom.bounds.x;
y -= geom.bounds.y;
}
const cell = addNode(
graph,
data,
x,
y,
group ? 200 : null,
group ? 160 : null,
null,
parent
);
graph.unSelectCells(graph.getSelectedCells()).selectCell(cell);
}
});
});
}
render() {
return (
<div className="flowchart-source-nodes" ref={this.refContainer}>
{data.items.map(({ data, width, height }) => (
<div
key={data.type}
data-type={data.type}
style={{ width, height }}
className={classNames("flowchart-node-wrap", data.type)}
>
<div className={classNames("flowchart-node", data.type)}>
{data.icon && <Icon type={data.icon} svg={true} />}
<span className="text">{data.title}</span>
</div>
</div>
))}
</div>
);
}
}
export namespace Sidebar {
export interface Props {
graph: Graph;
}
}