FazBrowse GitHub Viewer | Trending |
URL:
| Home
Tools: [Download Repo ZIP]   [Original HTTPS Page]

refactor(graph): move the viewport translation members to PanningMixin by redfish4ktc · Pull Request #1132 · maxGraph/maxGraph · GitHub

forked from jgraph/mxgraph
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension .md  (1) .ts  (3) All 2 file types selected
Viewed files
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Unified
Split
Hide whitespace
Diff view
Unified
Split
Hide whitespace
5 changes: 5 additions & 0 deletions CHANGELOG.md
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,11 @@ _**Note:** Yet to be released breaking changes appear here._
- The dispatch methods `createHandler` and `createEdgeHandler` are now defined on `SelectionCellsHandler`. If you were overriding them to change the dispatch logic itself (and not only the instantiated class), extend `SelectionCellsHandler` and pass your subclass in the `plugins` option.
- `SelectionCellsHandler.createHandler` returns a non-nullable `CellHandler` (the new `EdgeHandler | VertexHandler` union type exported from the package), whereas `AbstractGraph.createHandler` was typed as nullable. TypeScript users can drop the now-useless null checks on the returned value.

- `AbstractGraph.isIgnoreScrollbars` and `AbstractGraph.isTranslateToScrollPosition` are now regular methods instead of arrow function properties, following the move of the scrolling members to `PanningMixin`.
Calling them on the graph is unaffected: `graph.isIgnoreScrollbars()` keeps working. Only detached references break, because the functions are no longer bound to their instance.
If you pass one of them as a callback, for instance `someArray.some(graph.isIgnoreScrollbars)` or `const isIgnored = graph.isIgnoreScrollbars`, bind it explicitly with `graph.isIgnoreScrollbars.bind(graph)` or wrap it in an arrow function.
Note that TypeScript does not report this, both forms have the same type, so the failure only appears at runtime.

**Other Changes**:
- The order of the child elements produced by the XML serialization of `<Graph>` and `<BaseGraph>` has changed: `pageFormat` and `warningImage` are now emitted right after `options`, instead of last.
This is not a breaking change, decoding matches elements by their `as` attribute and is order-independent, so existing documents keep decoding identically and previously exported documents are still valid.
Expand Down
156 changes: 1 addition & 155 deletions packages/core/src/view/AbstractGraph.ts
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ import type PanningHandler from './plugin/PanningHandler.js';
import GraphView from './GraphView.js';
import CellRenderer from './cell/CellRenderer.js';
import Point from './geometry/Point.js';
import { getCurrentStyle, hasScrollbars, parseCssNumber } from '../util/styleUtils.js';
import { getCurrentStyle, parseCssNumber } from '../util/styleUtils.js';
import Cell from './cell/Cell.js';
import GraphDataModel from './GraphDataModel.js';
import { Stylesheet } from './style/Stylesheet.js';
Expand Down Expand Up @@ -280,22 +280,6 @@ export abstract class AbstractGraph extends EventSource {
*/
importEnabled = true;

/**
* Specifies if the graph should automatically scroll regardless of the
* scrollbars. This will scroll the container using positive values for
* scroll positions (ie usually only rightwards and downwards). To avoid
* possible conflicts with panning, set {@link translateToScrollPosition} to `true`.
*/
ignoreScrollbars = false;

/**
* Specifies if the graph should automatically convert the current scroll
* position to a translate in the graph view when a mouseUp event is received.
* This can be used to avoid conflicts when using {@link autoScroll} and
* {@link ignoreScrollbars} with no scrollbars in the container.
*/
translateToScrollPosition = false;

/**
* {@link Rectangle} that specifies the area in which all cells in the diagram
* should be placed. Uses in {@link getMaximumGraphBounds}. Use a width or height of
Expand Down Expand Up @@ -473,8 +457,6 @@ export abstract class AbstractGraph extends EventSource {
getPageScale = () => this.pageScale;
isExportEnabled = () => this.exportEnabled;
isImportEnabled = () => this.importEnabled;
isIgnoreScrollbars = () => this.ignoreScrollbars;
isTranslateToScrollPosition = () => this.translateToScrollPosition;

getMinimumGraphSize = () => this.minimumGraphSize;
setMinimumGraphSize = (size: Rectangle | null) => (this.minimumGraphSize = size);
Expand Down Expand Up @@ -644,89 +626,6 @@ export abstract class AbstractGraph extends EventSource {
}
}

/**
* Scrolls the graph to the given point, extending the graph container if
* specified.
*/
scrollPointToVisible(x: number, y: number, extend = false, border = 20) {
const panningHandler = this.getPlugin<PanningHandler>('PanningHandler');

if (
!this.isTimerAutoScroll() &&
(this.ignoreScrollbars || hasScrollbars(this.container))
) {
const c = <HTMLElement>this.container;

if (
x >= c.scrollLeft &&
y >= c.scrollTop &&
x <= c.scrollLeft + c.clientWidth &&
y <= c.scrollTop + c.clientHeight
) {
let dx = c.scrollLeft + c.clientWidth - x;

if (dx < border) {
const old = c.scrollLeft;
c.scrollLeft += border - dx;

// Automatically extends the canvas size to the bottom, right
// if the event is outside of the canvas and the edge of the
// canvas has been reached. Notes: Needs fix for IE.
if (extend && old === c.scrollLeft) {
// @ts-ignore
const root = this.view.getDrawPane().ownerSVGElement;
const width = c.scrollWidth + border - dx;

// Updates the clipping region. This is an expensive
// operation that should not be executed too often.
// @ts-ignore
root.style.width = `${width}px`;

c.scrollLeft += border - dx;
}
} else {
dx = x - c.scrollLeft;

if (dx < border) {
c.scrollLeft -= border - dx;
}
}

let dy = c.scrollTop + c.clientHeight - y;

if (dy < border) {
const old = c.scrollTop;
c.scrollTop += border - dy;

if (old == c.scrollTop && extend) {
// @ts-ignore
const root = this.view.getDrawPane().ownerSVGElement;
const height = c.scrollHeight + border - dy;

// Updates the clipping region. This is an expensive
// operation that should not be executed too often.
// @ts-ignore
root.style.height = `${height}px`;

c.scrollTop += border - dy;
}
} else {
dy = y - c.scrollTop;

if (dy < border) {
c.scrollTop -= border - dy;
}
}
}
} else if (
this.isAllowAutoPanning() &&
panningHandler &&
!panningHandler.isActive()
) {
panningHandler.getPanningManager().panTo(x + this.getPanDx(), y + this.getPanDy());
}
}

/**
* Returns the size of the border and padding on all four sides of the
* container. The left, top, right and bottom borders are stored in the x, y,
Expand Down Expand Up @@ -909,59 +808,6 @@ export abstract class AbstractGraph extends EventSource {
this.fireEvent(new EventObject(InternalEvent.REFRESH));
}

/**
* Centers the graph in the container.
*
* @param horizontal Optional boolean that specifies if the graph should be centered
* horizontally. Default is `true`.
* @param vertical Optional boolean that specifies if the graph should be centered
* vertically. Default is `true`.
* @param cx Optional float that specifies the horizontal center. Default is `0.5`.
* @param cy Optional float that specifies the vertical center. Default is `0.5`.
*/
center(horizontal = true, vertical = true, cx = 0.5, cy = 0.5): void {
const container = <HTMLElement>this.container;
const _hasScrollbars = hasScrollbars(this.container);
const padding = 2 * this.getBorder();
const cw = container.clientWidth - padding;
const ch = container.clientHeight - padding;
const bounds = this.getGraphBounds();

const t = this.view.translate;
const s = this.view.scale;

let dx = horizontal ? cw - bounds.width : 0;
let dy = vertical ? ch - bounds.height : 0;

if (!_hasScrollbars) {
this.view.setTranslate(
horizontal ? Math.floor(t.x - bounds.x / s + (dx * cx) / s) : t.x,
vertical ? Math.floor(t.y - bounds.y / s + (dy * cy) / s) : t.y
);
} else {
bounds.x -= t.x;
bounds.y -= t.y;

const sw = container.scrollWidth;
const sh = container.scrollHeight;

if (sw > cw) {
dx = 0;
}

if (sh > ch) {
dy = 0;
}

this.view.setTranslate(
Math.floor(dx / 2 - bounds.x),
Math.floor(dy / 2 - bounds.y)
);
container.scrollLeft = (sw - cw) / 2;
container.scrollTop = (sh - ch) / 2;
}
}

/**
* Returns `true` if perimeter points should be computed such that the resulting edge has only horizontal or vertical segments.
*
Expand Down
143 changes: 142 additions & 1 deletion packages/core/src/view/mixin/PanningMixin.ts
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ import type SelectionCellsHandler from '../plugin/SelectionCellsHandler.js';

type PartialGraph = Pick<
AbstractGraph,
'getContainer' | 'getView' | 'getPlugin' | 'fireEvent'
'getContainer' | 'getView' | 'getPlugin' | 'fireEvent' | 'getBorder' | 'getGraphBounds'
>;
type PartialPanning = Pick<
AbstractGraph,
Expand All @@ -34,17 +34,23 @@ type PartialPanning = Pick<
| 'useScrollbarsForPanning'
| 'timerAutoScroll'
| 'allowAutoPanning'
| 'ignoreScrollbars'
| 'translateToScrollPosition'
| 'panDx'
| 'panDy'
| 'isUseScrollbarsForPanning'
| 'isTimerAutoScroll'
| 'isAllowAutoPanning'
| 'isIgnoreScrollbars'
| 'isTranslateToScrollPosition'
| 'getPanDx'
| 'setPanDx'
| 'getPanDy'
| 'setPanDy'
| 'panGraph'
| 'center'
| 'scrollCellToVisible'
| 'scrollPointToVisible'
| 'scrollRectToVisible'
| 'setPanning'
>;
Expand Down Expand Up @@ -73,6 +79,18 @@ export const PanningMixin: PartialType = {
return this.allowAutoPanning;
},

ignoreScrollbars: false,

isIgnoreScrollbars() {
return this.ignoreScrollbars;
},

translateToScrollPosition: false,

isTranslateToScrollPosition() {
return this.translateToScrollPosition;
},

panDx: 0,

getPanDx() {
Expand Down Expand Up @@ -193,6 +211,129 @@ export const PanningMixin: PartialType = {
}
},

scrollPointToVisible(x, y, extend = false, border = 20) {
const panningHandler = this.getPlugin<PanningHandler>('PanningHandler');
const container = this.getContainer();

if (
!this.isTimerAutoScroll() &&
(this.ignoreScrollbars || hasScrollbars(container))
) {
const c = container;

if (
x >= c.scrollLeft &&
y >= c.scrollTop &&
x <= c.scrollLeft + c.clientWidth &&
y <= c.scrollTop + c.clientHeight
) {
let dx = c.scrollLeft + c.clientWidth - x;

if (dx < border) {
const old = c.scrollLeft;
c.scrollLeft += border - dx;

// Automatically extends the canvas size to the bottom, right
// if the event is outside of the canvas and the edge of the
// canvas has been reached. Notes: Needs fix for IE.
if (extend && old === c.scrollLeft) {
// @ts-ignore
const root = this.getView().getDrawPane().ownerSVGElement;
const width = c.scrollWidth + border - dx;

// Updates the clipping region. This is an expensive
// operation that should not be executed too often.
// @ts-ignore
root.style.width = `${width}px`;

c.scrollLeft += border - dx;
}
} else {
dx = x - c.scrollLeft;

if (dx < border) {
c.scrollLeft -= border - dx;
}
}

let dy = c.scrollTop + c.clientHeight - y;

if (dy < border) {
const old = c.scrollTop;
c.scrollTop += border - dy;

if (old == c.scrollTop && extend) {
// @ts-ignore
const root = this.getView().getDrawPane().ownerSVGElement;
const height = c.scrollHeight + border - dy;

// Updates the clipping region. This is an expensive
// operation that should not be executed too often.
// @ts-ignore
root.style.height = `${height}px`;

c.scrollTop += border - dy;
}
} else {
dy = y - c.scrollTop;

if (dy < border) {
c.scrollTop -= border - dy;
}
}
}
} else if (
this.isAllowAutoPanning() &&
panningHandler &&
!panningHandler.isActive()
) {
panningHandler.getPanningManager().panTo(x + this.getPanDx(), y + this.getPanDy());
}
},

center(horizontal = true, vertical = true, cx = 0.5, cy = 0.5) {
const container = this.getContainer();
const _hasScrollbars = hasScrollbars(container);
const padding = 2 * this.getBorder();
const cw = container.clientWidth - padding;
const ch = container.clientHeight - padding;
const bounds = this.getGraphBounds();

const t = this.getView().translate;
const s = this.getView().scale;

let dx = horizontal ? cw - bounds.width : 0;
let dy = vertical ? ch - bounds.height : 0;

if (!_hasScrollbars) {
this.getView().setTranslate(
horizontal ? Math.floor(t.x - bounds.x / s + (dx * cx) / s) : t.x,
vertical ? Math.floor(t.y - bounds.y / s + (dy * cy) / s) : t.y
);
} else {
bounds.x -= t.x;
bounds.y -= t.y;

const sw = container.scrollWidth;
const sh = container.scrollHeight;

if (sw > cw) {
dx = 0;
}

if (sh > ch) {
dy = 0;
}

this.getView().setTranslate(
Math.floor(dx / 2 - bounds.x),
Math.floor(dy / 2 - bounds.y)
);
container.scrollLeft = (sw - cw) / 2;
container.scrollTop = (sh - ch) / 2;
}
},

scrollCellToVisible(cell, center = false) {
const x = -this.getView().translate.x;
const y = -this.getView().translate.y;
Expand Down
Loading

Back | FazBrowse Home | New Git URL