Refactored more.

- image-related classes
 - event-related classes
development
Junsik Shim 2021-07-24 10:33:24 +09:00
parent 0453da274f
commit 49b307a557
10 changed files with 109 additions and 88 deletions

View File

@ -1,4 +1,5 @@
import type Cell from './view/cell/datatypes/Cell';
import Shape from './view/geometry/shape/Shape';
export type CellMap = {
[id: string]: Cell;
@ -48,14 +49,18 @@ export type CellStateStyles = {
gradientColor: ColorValue;
gradientDirection: DirectionValue;
horizontal: boolean;
image: string;
imageAlign: AlignValue;
imageAspect: boolean;
imageBackground: ColorValue;
imageBorder: ColorValue;
imageHeight: number;
imageWidth: number;
indicatorWidth: number;
indicatorColor: ColorValue;
indicatorHeight: number;
indicatorImage: string;
indicatorShape: Shape;
indicatorWidth: number;
labelBorderColor: ColorValue;
labelPosition: AlignValue;
margin: number;

View File

@ -665,6 +665,20 @@ class AbstractCanvas2D {
rotation = 0,
dir: TextDirectionValue
) {}
updateText(
x: number,
y: number,
w: number,
h: number,
align: AlignValue,
valign: VAlignValue,
wrap: boolean,
overflow: OverflowValue,
clip: boolean,
rotation = 0,
node: SVGElement
) {}
}
export default AbstractCanvas2D;

View File

@ -12,7 +12,7 @@ import GraphView from '../../view/GraphView';
import Shape from '../../geometry/shape/Shape';
import TextShape from '../../geometry/shape/node/TextShape';
import Dictionary from '../../../util/Dictionary';
import { ALIGN_MIDDLE, NONE } from '../../../util/Constants';
import { NONE } from '../../../util/Constants';
import type { CellStateStyles } from '../../../types';
@ -461,7 +461,7 @@ class CellState extends Rectangle {
* returned.
*/
getVerticalAlign() {
return this.style.verticalAlign ?? ALIGN_MIDDLE;
return this.style.verticalAlign;
}
/**
@ -472,8 +472,8 @@ class CellState extends Rectangle {
isTransparentState() {
let result = false;
const stroke = this.style.strokeColor ?? NONE;
const fill = this.style.fillColor ?? NONE;
const stroke = this.style.strokeColor;
const fill = this.style.fillColor;
result = stroke === NONE && fill === NONE && !this.getImageSrc();
@ -488,7 +488,7 @@ class CellState extends Rectangle {
* @param state {@link mxCellState} whose image URL should be returned.
*/
getImageSrc() {
return this.style.image ?? null;
return this.style.image;
}
/**
@ -500,7 +500,7 @@ class CellState extends Rectangle {
* returned.
*/
getIndicatorColor() {
return this.style.indicatorColor ?? null;
return this.style.indicatorColor;
}
/**
@ -512,7 +512,7 @@ class CellState extends Rectangle {
* returned.
*/
getIndicatorGradientColor() {
return this.style.gradientColor ?? null;
return this.style.gradientColor;
}
/**
@ -523,7 +523,7 @@ class CellState extends Rectangle {
* @param state {@link mxCellState} whose indicator shape should be returned.
*/
getIndicatorShape() {
return this.style.indicatorShape ?? null;
return this.style.indicatorShape;
}
/**
@ -534,7 +534,7 @@ class CellState extends Rectangle {
* @param state {@link mxCellState} whose indicator image should be returned.
*/
getIndicatorImageSrc() {
return this.style.indicatorImage ?? null;
return this.style.indicatorImage;
}
}

View File

@ -5,6 +5,8 @@
* Type definitions from the typed-mxgraph project
*/
type EventProperties = Record<string, any>;
/**
* Class: mxEventObject
*
@ -29,9 +31,9 @@
* (end)
*/
class EventObject {
constructor(name: string, ...args: any[]) {
constructor(name = '', ...args: any[]) {
this.name = name;
this.properties = [];
this.properties = {};
if (!!args[0] && args[0].constructor === Object) {
// A literal object ({})
@ -41,7 +43,7 @@ class EventObject {
} else {
// two-values [key, value, key, value, ...]
for (let i = 0; i < args.length; i += 2) {
if (args[i + 1] != null) {
if (args[i + 1] !== null) {
this.properties[args[i]] = args[i + 1];
}
}
@ -53,14 +55,14 @@ class EventObject {
*
* Holds the name.
*/
name: string = '';
name: string;
/**
* Variable: properties
*
* Holds the properties as an associative array.
*/
properties: any = null;
properties: EventProperties;
/**
* Variable: consumed
@ -74,7 +76,7 @@ class EventObject {
*
* Returns <name>.
*/
getName(): string {
getName() {
return this.name;
}
@ -83,7 +85,7 @@ class EventObject {
*
* Returns <properties>.
*/
getProperties(): any {
getProperties() {
return this.properties;
}
@ -92,7 +94,7 @@ class EventObject {
*
* Returns the property for the given key.
*/
getProperty(key: string): any {
getProperty(key: string) {
return this.properties[key];
}
@ -101,7 +103,7 @@ class EventObject {
*
* Returns true if the event has been consumed.
*/
isConsumed(): boolean {
isConsumed() {
return this.consumed;
}
@ -110,7 +112,7 @@ class EventObject {
*
* Consumes the event.
*/
consume(): void {
consume() {
this.consumed = true;
}
}

View File

@ -7,6 +7,11 @@
import EventObject from './EventObject';
type EventListener = {
funct: Function;
name: string;
};
/**
* Class: mxEventSource
*
@ -30,7 +35,7 @@ import EventObject from './EventObject';
* Constructs a new event source.
*/
class EventSource {
constructor(eventSource: EventSource | null=null) {
constructor(eventSource: EventSource | null = null) {
this.eventSource = eventSource;
}
@ -41,14 +46,14 @@ class EventSource {
* contains the event name followed by the respective listener for each
* registered listener.
*/
eventListeners: ({funct: Function, name: string})[] = [];
eventListeners: EventListener[] = [];
/**
* Variable: eventsEnabled
*
* Specifies if events can be fired. Default is true.
*/
eventsEnabled: boolean = true;
eventsEnabled = true;
/**
* Variable: eventSource
@ -62,7 +67,7 @@ class EventSource {
*
* Returns <eventsEnabled>.
*/
isEventsEnabled(): boolean {
isEventsEnabled() {
return this.eventsEnabled;
}
@ -71,7 +76,7 @@ class EventSource {
*
* Sets <eventsEnabled>.
*/
setEventsEnabled(value: boolean): void {
setEventsEnabled(value: boolean) {
this.eventsEnabled = value;
}
@ -80,7 +85,7 @@ class EventSource {
*
* Returns <eventSource>.
*/
getEventSource(): EventSource | null {
getEventSource() {
return this.eventSource;
}
@ -89,7 +94,7 @@ class EventSource {
*
* Sets <eventSource>.
*/
setEventSource(value: EventSource): void {
setEventSource(value: EventSource) {
this.eventSource = value;
}
@ -101,13 +106,8 @@ class EventSource {
*
* The parameters of the listener are the sender and an <mxEventObject>.
*/
addListener(name: string,
funct: (...args: any[]) => any): void {
if (this.eventListeners == null) {
this.eventListeners = [];
}
this.eventListeners.push({name, funct});
addListener(name: string, funct: (...args: any[]) => any) {
this.eventListeners.push({ name, funct });
}
/**
@ -115,16 +115,14 @@ class EventSource {
*
* Removes all occurrences of the given listener from <eventListeners>.
*/
removeListener(funct: (...args: any[]) => any): void {
if (this.eventListeners != null) {
let i = 0;
removeListener(funct: (...args: any[]) => any) {
let i = 0;
while (i < this.eventListeners.length) {
if (this.eventListeners[i].funct === funct) {
this.eventListeners.splice(i, 1);
} else {
i += 1;
}
while (i < this.eventListeners.length) {
if (this.eventListeners[i].funct === funct) {
this.eventListeners.splice(i, 1);
} else {
i += 1;
}
}
}
@ -148,21 +146,21 @@ class EventSource {
* sender - Optional sender to be passed to the listener. Default value is
* the return value of <getEventSource>.
*/
fireEvent(evt: EventObject, sender: any = null): void {
if (this.eventListeners != null && this.isEventsEnabled()) {
if (evt == null) {
fireEvent(evt: EventObject, sender: any = null) {
if (this.isEventsEnabled()) {
if (!evt) {
evt = new EventObject('');
}
if (sender == null) {
if (!sender) {
sender = this.getEventSource();
}
if (sender == null) {
if (!sender) {
sender = this;
}
for (const eventListener of this.eventListeners) {
if (eventListener.name == null || eventListener.name === evt.getName()) {
if (eventListener.name === null || eventListener.name === evt.getName()) {
eventListener.funct.apply(this, [sender, evt]);
}
}

View File

@ -7,7 +7,7 @@
import Point from './Point';
import Rectangle from './Rectangle';
import utils, { equalPoints, getRotatedPoint, toRadians } from '../../util/Utils';
import { equalPoints, getRotatedPoint, toRadians } from '../../util/Utils';
import { clone } from '../../util/CloneUtils';
/**
@ -74,12 +74,7 @@ import { clone } from '../../util/CloneUtils';
* defines the absolute offset for the label inside the vertex or group.
*/
class Geometry extends Rectangle {
constructor(
x: number = 0,
y: number = 0,
width: number = 0,
height: number = 0
) {
constructor(x = 0, y = 0, width = 0, height = 0) {
super(x, y, width, height);
}

View File

@ -31,7 +31,7 @@ import {
} from '../../../../util/Constants';
import { getAlignmentAsPoint, getBoundingBox } from '../../../../util/Utils';
import Point from '../../Point';
import AbstractCanvas2D from '../../../../util/canvas/SvgCanvas2D';
import AbstractCanvas2D from '../../../../util/canvas/AbstractCanvas2D';
import Shape from '../Shape';
import Rectangle from '../../Rectangle';
import CellState from '../../../cell/datatypes/CellState';
@ -48,6 +48,7 @@ import {
TextDirectionValue,
VAlignValue,
} from 'packages/core/src/types';
import SvgCanvas2D from 'packages/core/src/util/canvas/SvgCanvas2D';
/**
* Extends mxShape to implement a text shape.
@ -688,7 +689,7 @@ class TextShape extends Shape {
const margin = <Point>this.margin;
const node = this.node;
AbstractCanvas2D.createCss(
SvgCanvas2D.createCss(
w + 2,
h,
this.align,

View File

@ -1,6 +1,5 @@
import Graph from "../Graph";
import ImageBundle from "../../util/image/ImageBundle";
import ImageBundle from "./ImageBundle";
import Graph from '../Graph';
import ImageBundle from './ImageBundle';
class GraphImage {
constructor(graph: Graph) {
@ -19,14 +18,14 @@ class GraphImage {
/**
* Adds the specified {@link ImageBundle}.
*/
addImageBundle(bundle: ImageBundle): void {
addImageBundle(bundle: ImageBundle) {
this.imageBundles.push(bundle);
}
/**
* Removes the specified {@link ImageBundle}.
*/
removeImageBundle(bundle: ImageBundle): void {
removeImageBundle(bundle: ImageBundle) {
const tmp = [];
for (let i = 0; i < this.imageBundles.length; i += 1) {
if (this.imageBundles[i] !== bundle) {
@ -40,11 +39,11 @@ class GraphImage {
* Searches all {@link imageBundles} for the specified key and returns the value
* for the first match or null if the key is not found.
*/
getImageFromBundles(key: string): string {
if (key != null) {
getImageFromBundles(key: string) {
if (key) {
for (let i = 0; i < this.imageBundles.length; i += 1) {
const image = this.imageBundles[i].getImage(key);
if (image != null) {
if (image) {
return image;
}
}

View File

@ -5,6 +5,13 @@
* Type definitions from the typed-mxgraph project
*/
type ImageMap = {
[key: string]: {
value: string;
fallback: Function;
};
};
/**
* Class: mxImageBundle
*
@ -51,9 +58,9 @@
* all data URIs should be limited to 32 KB.
*/
class ImageBundle {
constructor(alt) {
this.images = [];
this.alt = alt != null ? alt : false;
constructor(alt = false) {
this.images = {};
this.alt = alt;
}
/**
@ -61,14 +68,14 @@ class ImageBundle {
*
* Maps from keys to images.
*/
images: { [key: string]: { value: string; fallback: Function } } | null = null;
images: ImageMap;
/**
* Variable: alt
*
* Specifies if the fallback representation should be returned.
*/
alt: boolean = null;
alt: boolean;
/**
* Function: putImage
@ -87,13 +94,13 @@ class ImageBundle {
* or fallback, depending on <alt>. The fallback is returned if
* <alt> is true, the value is returned otherwise.
*/
getImage(key: string): string {
getImage(key: string) {
let result = null;
if (key != null) {
if (key) {
const img = this.images[key];
if (img != null) {
if (img) {
result = this.alt ? img.fallback : img.value;
}
}

View File

@ -5,7 +5,7 @@
* Type definitions from the typed-mxgraph project
*/
import mxAbstractCanvas2D from '../../util/canvas/AbstractCanvas2D';
import AbstractCanvas2D from '../../util/canvas/AbstractCanvas2D';
import CellState from '../cell/datatypes/CellState';
import Shape from '../geometry/shape/Shape';
@ -41,13 +41,13 @@ class ImageExport {
/**
* Specifies if overlays should be included in the export. Default is false.
*/
includeOverlays: boolean = false;
includeOverlays = false;
/**
* Draws the given state and all its descendants to the given canvas.
*/
drawState(state: CellState, canvas: mxAbstractCanvas2D): void {
if (state != null) {
drawState(state: CellState, canvas: AbstractCanvas2D): void {
if (state) {
this.visitStatesRecursive(state, canvas, () => {
this.drawCellState(state, canvas);
});
@ -66,8 +66,8 @@ class ImageExport {
*
* Visits the given state and all its descendants to the given canvas recursively.
*/
visitStatesRecursive(state: CellState, canvas: mxAbstractCanvas2D, visitor: Function) {
if (state != null) {
visitStatesRecursive(state: CellState, canvas: AbstractCanvas2D, visitor: Function) {
if (state) {
visitor(state, canvas);
const { graph } = state.view;
@ -83,18 +83,18 @@ class ImageExport {
/**
* Returns the link for the given cell state and canvas. This returns null.
*/
getLinkForCellState(state: CellState, canvas: mxAbstractCanvas2D): any {
getLinkForCellState(state: CellState, canvas: AbstractCanvas2D): any {
return null;
}
/**
* Draws the given state to the given canvas.
*/
drawCellState(state: CellState, canvas: mxAbstractCanvas2D): void {
drawCellState(state: CellState, canvas: AbstractCanvas2D): void {
// Experimental feature
const link = this.getLinkForCellState(state, canvas);
if (link != null) {
if (link) {
canvas.setLink(link);
}
@ -102,7 +102,7 @@ class ImageExport {
this.drawShape(state, canvas);
this.drawText(state, canvas);
if (link != null) {
if (link) {
canvas.setLink(null);
}
}
@ -112,7 +112,7 @@ class ImageExport {
*
* Draws the shape of the given state.
*/
drawShape(state: CellState, canvas: mxAbstractCanvas2D): void {
drawShape(state: CellState, canvas: AbstractCanvas2D): void {
if (state.shape instanceof Shape && state.shape.checkBounds()) {
canvas.save();
@ -127,8 +127,8 @@ class ImageExport {
/**
* Draws the text of the given state.
*/
drawText(state: CellState, canvas: mxAbstractCanvas2D): void {
if (state.text != null && state.text.checkBounds()) {
drawText(state: CellState, canvas: AbstractCanvas2D): void {
if (state.text && state.text.checkBounds()) {
canvas.save();
state.text.beforePaint(canvas);
@ -145,7 +145,7 @@ class ImageExport {
* Draws the overlays for the given state. This is called if <includeOverlays>
* is true.
*/
drawOverlays(state: CellState, canvas: mxAbstractCanvas2D): void {
drawOverlays(state: CellState, canvas: AbstractCanvas2D): void {
if (state.overlays != null) {
state.overlays.visit((id, shape) => {
if (shape instanceof Shape) {