Der Gantt-Aktivitätsrenderer ist der Hauptrenderer des ScheduleJS Viewer. In diesem Artikel wird erläutert, wie er aufgebaut ist und was die Besonderheiten dieses Aktivitätsrenderers sind.
Der erste Schritt zum Aufbau einer Renderer-Klasse besteht darin, Attribute und Methoden zu erben, indem eine Framework-Klasse höherer Ordnung erweitert wird.
Wir möchten Aufgaben nur durch ihre Start- und Endzeitdimensionen darstellen. Die ScheduleJS-Basis-Renderer-Klasse hierfür ist die Klasse ActivityBarRenderer.
Wir müssen die benutzerdefinierten Argumente für die Klasse ActivityBarRenderer bereitstellen, damit auf die Attribute und Methoden unserer benutzerdefinierten Klassen Row und Activity zugegriffen werden kann unter Verwendung der Basisklassen-API.
Lassen Sie uns die Klasse ScheduleJsViewerTaskActivityRenderer erstellen, um jede ScheduleJsViewerTaskActivity in ihrer jeweiligen ScheduleJsViewerTaskRow zu zeichnen.
// Import the base ActivityBarRenderer class from ScheduleJS import {ActivityBarRenderer} from "schedule"; // Import our custom Activity and Row types import {ScheduleJsViewerTaskActivity} from "..."; import {ScheduleJsViewerTaskRow} from "..."; // Create our custom renderer by extending the ActivityBarRenderer class export class ScheduleJsViewerTaskActivityRenderer extends ActivityBarRenderer<ScheduleJsViewerTaskActivity, ScheduleJsViewerTaskRow> { }
So wie es ist, kann der Renderer bereits registriert werden, um unsere Aktivitäten mit dem Standardverhalten des ActivityBarRenderer zu zeichnen. Lassen Sie uns nun näher darauf eingehen, wie Sie es anpassen können.
In ScheduleJS ist ein ActivityRenderer eine Klasse, die wir programmgesteuert mithilfe der Grafik-API registrieren, um eine bestimmte Aktivität in ihrer Zeile zu zeichnen. Um unseren ScheduleJsViewerTaskActivityRenderer zu organisieren, unterteilen wir seinen Code in drei Abschnitte:
Attribute sind Konstanten, die im gesamten Renderer wiederverwendet werden. So wie sie sind, werden diese Eigenschaften nur direkt im Renderer-Code bearbeitet. Wir können uns einen speziellen Bildschirm vorstellen, auf dem der Benutzer diese Einstellungen direkt in der Benutzeroberfläche ändern kann.
// Attributes // Pixels sizings private readonly _parentActivityTrianglesWidthPx: number = 5; private readonly _parentActivityTrianglesHeightPx: number = 8; private readonly _defaultLineWidthPx: number = 0.5; // Colors palette private readonly _parentActivityColor: string = Color.GRAY.toCssString(); private readonly _strokeColor: string = Color.BLACK.toCssString(); private readonly _defaultActivityGreen: Color = Color.rgb(28, 187, 158); private readonly _defaultActivityBlue: Color = Color.rgb(53, 152, 214); private readonly _onHoverFillColor: string = Color.ORANGE.toCssString(); // Opacity ratio for baseline activities private readonly _baselineOpacityRatio: number = 0.6;
Der Konstruktor ist eng an unsere Renderer-Lebenszyklusmethode gekoppelt. Im ScheduleJS Viewer haben wir beschlossen, den Renderer immer dann zu instanziieren, wenn der Benutzer den Bildschirm wechselt, um Besonderheiten zu definieren und unseren Code in jeder Registerkarte wiederzuverwenden, die diesen Renderer implementiert. Dies bedeutet, dass die Konstruktorfunktion jedes Mal ausgeführt wird, wenn der Benutzer einen Bildschirm mit diesem Renderer auswählt.
// Constructor // The renderer requires the graphics and the current tab variable constructor(graphics: GraphicsBase<ScheduleJsViewerTaskRow>, private _currentRibbonMenuTab: ScheduleJsViewerRibbonMenuTabsEnum) { // The ActivityBarRenderer class requires the graphics and a name for the renderer super(graphics, ScheduleJsViewerRenderingConstants.taskActivityRendererName); // Default fill color when hovering an activity this.setFillHover(Color.web(this._onHoverFillColor)); // Default stroke color when hovering an activity this.setStrokeHover(Color.BLACK); // Default stroke color this.setStroke(Color.BLACK); // Default thickness this.setLineWidth(this._defaultLineWidthPx); // Default bar height this.setBarHeight(8); // Default fill color based on current tab switch (_currentRibbonMenuTab) { // Change color for the WBS tab case ScheduleJsViewerRibbonMenuTabsEnum.WBS: this._parentActivityColor = ScheduleJsViewerColors.brown; this.setFill(this._defaultActivityBlue); break; default: this._parentActivityColor = Color.GRAY.toCssString(); this.setFill(this._defaultActivityGreen); break; } }
setFill, setStroke, setFillHover, setStrokeHover, setLineWidth und setBarHeight werden geerbt und verwendet, um die Standard-Rendering-Eigenschaften der ActivityBarRenderer-Klasse zu ändern.
Die Standardfunktionen dieses Renderers sind die folgenden:
Das Framework ruft automatisch die Methode drawActivity auf, um unsere Aktivitäten auf der Leinwand darzustellen. Alle Parameter werden dynamisch gefüllt, sodass Sie in Echtzeit auf den aktuellen Stand Ihrer Aktivitäten reagieren können.
// Main drawing method drawActivity(activityRef: ActivityRef<ScheduleJsViewerTaskActivity>, position: ViewPosition, ctx: CanvasRenderingContext2D, x: number, y: number, w: number, h: number, selected: boolean, hover: boolean, highlighted: boolean, pressed: boolean ): ActivityBounds { // This method has to return ActivityBounds // True if current activity includes a comparison task const hasModifications = !!activityRef.getActivity().diffTask; // True if current row has children const isParent = activityRef.getRow().getChildren().length; // Set colors dynamically this._setActivityColor(activityRef, hasModifications); // Draw text this._drawActivityText(activityRef, ctx, x, y, w, h, hasModifications); // Run a custom method to draw parent activities or delegate to the default method return isParent ? this._drawParentActivity(activityRef, ctx, x, y, w, h, hover, hasModifications) : super.drawActivity(activityRef, position, ctx, x, y, w, h, selected, hover, highlighted, pressed); }
Die Zeichnung erfolgt folgendermaßen:
Sehen wir uns genauer an, wie Sie Ihre Aktivität frei zeichnen können, indem Sie Ihre eigenen Methoden mit der _drawParentActivity-Methode entwerfen.
// Draw the parent activity private _drawParentActivity(activityRef: ActivityRef<ScheduleJsViewerTaskActivity>, ctx: CanvasRenderingContext2D, x: number, y: number, w: number, h: number, hover: boolean, hasModifications: boolean ): ActivityBounds { // Set padding const topPadding = h / 3.5; const leftPadding = 1; // Set CanvasRenderingContext2D ctx.lineWidth = this._defaultLineWidthPx; if (hover) { ctx.fillStyle = this._onHoverFillColor; ctx.strokeStyle = ScheduleJsViewerColors.brown; } else if (hasModifications) { ctx.fillStyle = Color.web(this._parentActivityColor).withOpacity(this._baselineOpacityRatio).toCssString(); ctx.strokeStyle = `rgba(0,0,0,${this._baselineOpacityRatio})`; } else { ctx.fillStyle = this._parentActivityColor; ctx.strokeStyle = this._strokeColor; } // Draw elements ScheduleJsViewerTaskActivityRenderer._drawParentActivityStartTriangle(ctx, x + leftPadding, y + topPadding, this._parentActivityTrianglesWidthPx, this._parentActivityTrianglesHeightPx); ScheduleJsViewerTaskActivityRenderer._drawParentActivityBody(ctx, x + leftPadding, y + topPadding, w, this._parentActivityTrianglesWidthPx, this._parentActivityTrianglesHeightPx); ScheduleJsViewerTaskActivityRenderer._drawParentActivityEndTriangle(ctx, x + leftPadding, y + topPadding, w, this._parentActivityTrianglesWidthPx, this._parentActivityTrianglesHeightPx); // Return positions to update where your activity should be responsive return new ActivityBounds(activityRef, x, y, w, h); }
Hier verwenden wir direkt die HTMLCanvas-API, um unsere Zeichenstrategie zu definieren, indem wir den CanvasRenderingContex2D einrichten. Der einzige Framework-bezogene Vorgang, der in dieser Methode ausgeführt wird, ist das Erstellen einiger neuer ActivityBounds für die aktuelle übergeordnete Activity.
Das Framework erstellt mithilfe von ActivityBounds unter der Haube eine Karte, um alle Aktivitäten auf dem Bildschirm zu registrieren. Diese Karte hilft dem Entwickler, indem sie eine elementartige Logik bereitstellt, um erweiterte Benutzererfahrungen auf der Grundlage genauer Informationen zu erstellen und gleichzeitig die Leistung der HTMLCanvas-API zu nutzen.
The draw elements methods like _drawParentActivityStartTriangle rely on the CanvasRenderingContext2D API to draw at the pixel level.
// Draw the start triangle element of the parent activity private static _drawParentActivityStartTriangle(ctx: CanvasRenderingContext2D, x: number, y: number, triangleWidth: number, triangleHeight: number): void { ctx.beginPath(); ctx.moveTo(x, y); ctx.lineTo(x , y + triangleHeight); ctx.lineTo(x + triangleWidth, y); ctx.lineTo(x, y); ctx.fill(); ctx.stroke(); ctx.closePath(); }
To register your brand-new renderer, use the graphics.setActivityRenderer method:
// Register the renderer graphics.setActivityRenderer(ScheduleJsViewerTaskActivity, GanttLayout, new ScheduleJsViewerTaskActivityRenderer(graphics, currentRibbonMenuTab));
To see the video of the final result you can go to see: Building an ActivityRenderer
Das obige ist der detaillierte Inhalt vonErstellen eines ActivityRenderers. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!