123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283 |
- import { Point } from '@antv/x6-geometry';
- import { Dom, FunctionExt, NumberExt, ObjectExt } from '@antv/x6-common';
- import { ToolsView } from '../../view/tool';
- import { Util } from '../../util';
- export class CellEditor extends ToolsView.ToolItem {
- constructor() {
- super(...arguments);
- this.labelIndex = -1;
- this.distance = 0.5;
- this.dblClick = this.onCellDblClick.bind(this);
- }
- onRender() {
- const cellView = this.cellView;
- if (cellView) {
- cellView.on('cell:dblclick', this.dblClick);
- }
- }
- createElement() {
- const classNames = [
- this.prefixClassName(`${this.cell.isEdge() ? 'edge' : 'node'}-tool-editor`),
- this.prefixClassName('cell-tool-editor'),
- ];
- this.editor = ToolsView.createElement('div', false);
- this.addClass(classNames, this.editor);
- this.editor.contentEditable = 'true';
- this.container.appendChild(this.editor);
- }
- removeElement() {
- this.undelegateDocumentEvents();
- if (this.editor) {
- this.container.removeChild(this.editor);
- this.editor = null;
- }
- }
- updateEditor() {
- const { cell, editor } = this;
- if (!editor) {
- return;
- }
- const { style } = editor;
- if (cell.isNode()) {
- this.updateNodeEditorTransform();
- }
- else if (cell.isEdge()) {
- this.updateEdgeEditorTransform();
- }
- // set font style
- const { attrs } = this.options;
- style.fontSize = `${attrs.fontSize}px`;
- style.fontFamily = attrs.fontFamily;
- style.color = attrs.color;
- style.backgroundColor = attrs.backgroundColor;
- // set init value
- const text = this.getCellText() || '';
- editor.innerText = text;
- this.setCellText(''); // clear display value when edit status because char ghosting.
- return this;
- }
- updateNodeEditorTransform() {
- const { graph, cell, editor } = this;
- if (!editor) {
- return;
- }
- let pos = Point.create();
- let minWidth = 20;
- let translate = '';
- let { x, y } = this.options;
- const { width, height } = this.options;
- if (typeof x !== 'undefined' && typeof y !== 'undefined') {
- const bbox = cell.getBBox();
- x = NumberExt.normalizePercentage(x, bbox.width);
- y = NumberExt.normalizePercentage(y, bbox.height);
- pos = bbox.topLeft.translate(x, y);
- minWidth = bbox.width - x * 2;
- }
- else {
- const bbox = cell.getBBox();
- pos = bbox.center;
- minWidth = bbox.width - 4;
- translate = 'translate(-50%, -50%)';
- }
- const scale = graph.scale();
- const { style } = editor;
- pos = graph.localToGraph(pos);
- style.left = `${pos.x}px`;
- style.top = `${pos.y}px`;
- style.transform = `scale(${scale.sx}, ${scale.sy}) ${translate}`;
- style.minWidth = `${minWidth}px`;
- if (typeof width === 'number') {
- style.width = `${width}px`;
- }
- if (typeof height === 'number') {
- style.height = `${height}px`;
- }
- }
- updateEdgeEditorTransform() {
- if (!this.event) {
- return;
- }
- const { graph, editor } = this;
- if (!editor) {
- return;
- }
- let pos = Point.create();
- let minWidth = 20;
- const { style } = editor;
- const target = this.event.target;
- const parent = target.parentElement;
- const isEdgeLabel = parent && Dom.hasClass(parent, this.prefixClassName('edge-label'));
- if (isEdgeLabel) {
- const index = parent.getAttribute('data-index') || '0';
- this.labelIndex = parseInt(index, 10);
- const matrix = parent.getAttribute('transform');
- const { translation } = Dom.parseTransformString(matrix);
- pos = new Point(translation.tx, translation.ty);
- minWidth = Util.getBBox(target).width;
- }
- else {
- if (!this.options.labelAddable) {
- return this;
- }
- pos = graph.clientToLocal(Point.create(this.event.clientX, this.event.clientY));
- const view = this.cellView;
- const d = view.path.closestPointLength(pos);
- this.distance = d;
- this.labelIndex = -1;
- }
- pos = graph.localToGraph(pos);
- const scale = graph.scale();
- style.left = `${pos.x}px`;
- style.top = `${pos.y}px`;
- style.minWidth = `${minWidth}px`;
- style.transform = `scale(${scale.sx}, ${scale.sy}) translate(-50%, -50%)`;
- }
- onDocumentMouseUp(e) {
- if (this.editor && e.target !== this.editor) {
- const value = this.editor.innerText.replace(/\n$/, '') || '';
- // set value, when value is null, we will remove label in edge
- this.setCellText(value !== '' ? value : null);
- // remove tool
- this.removeElement();
- }
- }
- onCellDblClick({ e }) {
- if (!this.editor) {
- e.stopPropagation();
- this.removeElement();
- this.event = e;
- this.createElement();
- this.updateEditor();
- this.autoFocus();
- this.delegateDocumentEvents(this.options.documentEvents);
- }
- }
- onMouseDown(e) {
- e.stopPropagation();
- }
- autoFocus() {
- setTimeout(() => {
- if (this.editor) {
- this.editor.focus();
- this.selectText();
- }
- });
- }
- selectText() {
- if (window.getSelection && this.editor) {
- const range = document.createRange();
- const selection = window.getSelection();
- range.selectNodeContents(this.editor);
- selection.removeAllRanges();
- selection.addRange(range);
- }
- }
- getCellText() {
- const { getText } = this.options;
- if (typeof getText === 'function') {
- return FunctionExt.call(getText, this.cellView, {
- cell: this.cell,
- index: this.labelIndex,
- });
- }
- if (typeof getText === 'string') {
- if (this.cell.isNode()) {
- return this.cell.attr(getText);
- }
- if (this.cell.isEdge()) {
- if (this.labelIndex !== -1) {
- return this.cell.prop(`labels/${this.labelIndex}/attrs/${getText}`);
- }
- }
- }
- }
- setCellText(value) {
- const setText = this.options.setText;
- if (typeof setText === 'function') {
- FunctionExt.call(setText, this.cellView, {
- cell: this.cell,
- value,
- index: this.labelIndex,
- distance: this.distance,
- });
- return;
- }
- if (typeof setText === 'string') {
- if (this.cell.isNode()) {
- if (value !== null) {
- this.cell.attr(setText, value);
- }
- return;
- }
- if (this.cell.isEdge()) {
- const edge = this.cell;
- if (this.labelIndex === -1) {
- if (value) {
- const newLabel = {
- position: {
- distance: this.distance,
- },
- attrs: {},
- };
- ObjectExt.setByPath(newLabel, `attrs/${setText}`, value);
- edge.appendLabel(newLabel);
- }
- }
- else {
- if (value !== null) {
- edge.prop(`labels/${this.labelIndex}/attrs/${setText}`, value);
- }
- else if (typeof this.labelIndex === 'number') {
- edge.removeLabelAt(this.labelIndex);
- }
- }
- }
- }
- }
- onRemove() {
- const cellView = this.cellView;
- if (cellView) {
- cellView.off('cell:dblclick', this.dblClick);
- }
- this.removeElement();
- }
- }
- (function (CellEditor) {
- CellEditor.config({
- tagName: 'div',
- isSVGElement: false,
- events: {
- mousedown: 'onMouseDown',
- touchstart: 'onMouseDown',
- },
- documentEvents: {
- mouseup: 'onDocumentMouseUp',
- touchend: 'onDocumentMouseUp',
- touchcancel: 'onDocumentMouseUp',
- },
- });
- })(CellEditor || (CellEditor = {}));
- (function (CellEditor) {
- CellEditor.NodeEditor = CellEditor.define({
- attrs: {
- fontSize: 14,
- fontFamily: 'Arial, helvetica, sans-serif',
- color: '#000',
- backgroundColor: '#fff',
- },
- getText: 'text/text',
- setText: 'text/text',
- });
- CellEditor.EdgeEditor = CellEditor.define({
- attrs: {
- fontSize: 14,
- fontFamily: 'Arial, helvetica, sans-serif',
- color: '#000',
- backgroundColor: '#fff',
- },
- labelAddable: true,
- getText: 'label/text',
- setText: 'label/text',
- });
- })(CellEditor || (CellEditor = {}));
- //# sourceMappingURL=editor.js.map
|