maxGraph/packages/html/stories/Control.stories.js

199 lines
4.9 KiB
JavaScript
Raw Normal View History

2021-04-21 11:36:38 +00:00
import mxgraph from '@mxgraph/core';
import { globalTypes } from '../.storybook/preview';
export default {
title: 'Icon_Images/Control',
argTypes: {
...globalTypes,
rubberBand: {
type: 'boolean',
defaultValue: true
}
}
};
const Template = ({ label, ...args }) => {
const {
mxGraph,
mxEvent,
mxRubberband,
mxDomHelpers,
mxImageShape,
mxRectangle,
mxCellRenderer,
mxImage
} = mxgraph;
const div = document.createElement('div');
const container = document.createElement('div');
container.style.position = 'relative';
container.style.overflow = 'hidden';
container.style.width = `${args.width}px`;
container.style.height = `${args.height}px`;
container.style.background = 'url(/images/grid.gif)';
container.style.cursor = 'default';
div.appendChild(container);
// Specifies the URL and size of the new control
const deleteImage = new mxImage(
'/images/forbidden.png',
16,
16
);
class MyCustomCellRenderer extends mxCellRenderer {
createControl(state) {
super.createControl(state);
const { graph } = state.view;
if (state.cell.isVertex()) {
2021-04-21 11:36:38 +00:00
if (state.deleteControl == null) {
const b = new mxRectangle(
0,
0,
deleteImage.width,
deleteImage.height
);
state.deleteControl = new mxImageShape(b, deleteImage.src);
state.deleteControl.dialect = graph.dialect;
state.deleteControl.preserveImageAspect = false;
this.initControl(state, state.deleteControl, false, function(evt) {
if (graph.isEnabled()) {
graph.removeCells([state.cell]);
mxEvent.consume(evt);
}
});
}
} else if (state.deleteControl != null) {
state.deleteControl.destroy();
state.deleteControl = null;
}
}
getDeleteControlBounds(state) {
// Helper function to compute the bounds of the control
if (state.deleteControl != null) {
const oldScale = state.deleteControl.scale;
const w = state.deleteControl.bounds.width / oldScale;
const h = state.deleteControl.bounds.height / oldScale;
const s = state.view.scale;
return state.cell.isEdge()
2021-04-21 11:36:38 +00:00
? new mxRectangle(
state.x + state.width / 2 - (w / 2) * s,
state.y + state.height / 2 - (h / 2) * s,
w * s,
h * s
)
: new mxRectangle(
state.x + state.width - w * s,
state.y,
w * s,
h * s
);
}
return null;
}
redrawControl(state) {
// Overridden to update the scale and bounds of the control
super.redrawControl(state);
if (state.deleteControl != null) {
const bounds = this.getDeleteControlBounds(state);
const s = state.view.scale;
if (
state.deleteControl.scale !== s ||
!state.deleteControl.bounds.equals(bounds)
) {
state.deleteControl.bounds = bounds;
state.deleteControl.scale = s;
state.deleteControl.redraw();
}
}
}
destroy(state) {
// Overridden to remove the control if the state is destroyed
super.destroy(state);
if (state.deleteControl != null) {
state.deleteControl.destroy();
state.deleteControl = null;
}
}
}
class MyCustomGraph extends mxGraph {
createCellRenderer() {
return new MyCustomCellRenderer();
}
}
// Creates the graph inside the given container
const graph = new MyCustomGraph(container);
graph.setPanning(true);
// Uncomment the following if you want the container
// to fit the size of the graph
// graph.setResizeContainer(true);
// Enables rubberband selection
if (args.rubberBand)
new mxRubberband(graph);
// Gets the default parent for inserting new cells. This
// is normally the first child of the root (ie. layer 0).
const parent = graph.getDefaultParent();
// Adds cells to the model in a single step
graph.getModel().beginUpdate();
try {
const v1 = graph.insertVertex({
parent,
value: 'Hello,',
position: [20, 20],
size: [80, 30],
});
const v2 = graph.insertVertex({
parent,
value: 'World!',
position: [200, 150],
size: [80, 30],
});
const e1 = graph.insertEdge({
parent,
source: v1,
target: v2,
});
} finally {
// Updates the display
graph.getModel().endUpdate();
}
graph.centerZoom = false;
const buttons = document.createElement('div');
div.appendChild(buttons);
buttons.appendChild(
mxDomHelpers.button('Zoom In', () => {
graph.zoomIn();
})
);
buttons.appendChild(
mxDomHelpers.button('Zoom Out', () => {
graph.zoomOut();
})
);
return div;
}
export const Default = Template.bind({});