maxGraph/packages/html/stories/HoverIcons.stories.js

215 lines
5.2 KiB
JavaScript

import mxgraph from '@mxgraph/core';
import { globalTypes } from '../.storybook/preview';
export default {
title: 'Icon_Images/HoverIcons',
argTypes: {
...globalTypes,
rubberBand: {
type: 'boolean',
defaultValue: true
}
}
};
const Template = ({ label, ...args }) => {
const {
mxGraph,
mxEvent,
mxRubberband,
mxImage,
mxRectangle,
mxUtils,
mxConnectionHandler
} = mxgraph;
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';
// Defines an icon for creating new connections in the connection handler.
// This will automatically disable the highlighting of the source vertex.
mxConnectionHandler.prototype.connectImage = new mxImage(
'images/connector.gif',
16,
16
);
// Defines a new class for all icons
class mxIconSet {
constructor(state) {
this.images = [];
const { graph } = state.view;
// Icon1
let img = mxUtils.createImage('images/copy.png');
img.setAttribute('title', 'Duplicate');
Object.assign(img.style, {
cursor: 'pointer',
width: '16px',
height: '16px',
position: 'absolute',
left: `${state.x + state.width}px`,
top: `${state.y + state.height}px`,
});
mxEvent.addGestureListeners(img, evt => {
const s = graph.gridSize;
graph.setSelectionCells(graph.moveCells([state.cell], s, s, true));
mxEvent.consume(evt);
this.destroy();
});
state.view.graph.container.appendChild(img);
this.images.push(img);
// Delete
img = mxUtils.createImage('images/delete2.png');
img.setAttribute('title', 'Delete');
Object.assign(img.style, {
cursor: 'pointer',
width: '16px',
height: '16px',
position: 'absolute',
left: `${state.x + state.width}px`,
top: `${state.y - 16}px`,
});
mxEvent.addGestureListeners(img, evt => {
// Disables dragging the image
mxEvent.consume(evt);
});
mxEvent.addListener(img, 'click', evt => {
graph.removeCells([state.cell]);
mxEvent.consume(evt);
this.destroy();
});
state.view.graph.container.appendChild(img);
this.images.push(img);
}
destroy() {
if (this.images != null) {
for (const img of this.images) {
img.parentNode.removeChild(img);
}
}
this.images = null;
}
}
// Creates the graph inside the given container
const graph = new mxGraph(container);
graph.setConnectable(true);
// Enables rubberband selection
if (args.rubberBand)
new mxRubberband(graph);
// Defines the tolerance before removing the icons
const ICON_TOLERANCE = 20;
// Shows icons if the mouse is over a cell
graph.addMouseListener({
currentState: null,
currentIconSet: null,
mouseDown(sender, me) {
// Hides icons on mouse down
if (this.currentState != null) {
this.dragLeave(me.getEvent(), this.currentState);
this.currentState = null;
}
},
mouseMove(sender, me) {
if (
this.currentState != null &&
(me.getState() === this.currentState || me.getState() == null)
) {
const tol = ICON_TOLERANCE;
const tmp = new mxRectangle(
me.getGraphX() - tol,
me.getGraphY() - tol,
2 * tol,
2 * tol
);
if (mxUtils.intersects(tmp, this.currentState)) {
return;
}
}
let tmp = graph.view.getState(me.getCell());
// Ignore everything but vertices
if (
graph.isMouseDown ||
(tmp != null && !tmp.cell.isVertex())
) {
tmp = null;
}
if (tmp !== this.currentState) {
if (this.currentState != null) {
this.dragLeave(me.getEvent(), this.currentState);
}
this.currentState = tmp;
if (this.currentState != null) {
this.dragEnter(me.getEvent(), this.currentState);
}
}
},
mouseUp(sender, me) {},
dragEnter(evt, state) {
if (this.currentIconSet == null) {
this.currentIconSet = new mxIconSet(state);
}
},
dragLeave(evt, state) {
if (this.currentIconSet != null) {
this.currentIconSet.destroy();
this.currentIconSet = null;
}
},
});
// 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.batchUpdate(() => {
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,
});
});
return container;
}
export const Default = Template.bind({});