ساخت یک ActivityRenderer – انجمن DEV

رندر فعالیت Gantt رندر اصلی ScheduleJS Viewer است. در این مقاله نحوه ساخت آن و ویژگی های این رندر اکتیویتی بحث خواهد شد.
چگونه یک کلاس رندر سفارشی بسازیم
اولین قدم برای ساختن یک کلاس رندر، به ارث بردن ویژگی ها و متدها با گسترش یک کلاس فریمورک مرتبه بالاتر است.
ما می خواهیم وظایف را فقط از طریق ابعاد زمان شروع و پایان آنها نشان دهیم. کلاس رندر پایه ScheduleJS برای انجام این کار است ActivityBarRenderer کلاس
ما باید آرگومان های نوع سفارشی را برای آن ارائه کنیم ActivityBarRenderer کلاس بنابراین ویژگی ها و روش های ارائه شده توسط سفارشی ما ردیف و فعالیت کلاس ها با استفاده از API کلاس پایه قابل دسترسی خواهند بود.
بیایید ایجاد کنیم ScheduleJsViewerTaskActivityRenderer کلاس برای ترسیم هر ScheduleJsViewerTaskActivity مربوط به خود ScheduleJsViewerTaskRow.
// 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 ActivityBarRendererScheduleJsViewerTaskActivity, ScheduleJsViewerTaskRow> { }
همانطور که هست، رندر از قبل میتواند برای ترسیم فعالیتهای ما با استفاده از رفتار پیشفرض ثبت شده باشد ActivityBarRenderer. حالا بیایید به نحوه سفارشی کردن آن بپردازیم.
معماری پایه
در ScheduleJS، یک ActivityRenderer کلاسی است که ما به صورت برنامه نویسی با استفاده از Graphics API برای ترسیم یک کلاس خاص ثبت می کنیم فعالیت روی آن ردیف. برای سازماندهی ما ScheduleJsViewerTaskActivityRenderer، کد آن را به سه بخش تقسیم می کنیم:
- ویژگیها متغیرهایی را در خود نگه میدارند که به ما اجازه میدهند رفتار یک رویه ترسیمی خاص را تغییر دهیم.
- سازنده به ما اجازه می دهد یک حالت پیش فرض برای رندر تعریف کنیم.
- روش های ترسیم تمام دستورالعمل های طراحی فعالیت های ما را روی بوم نگه می دارند.
ویژگی های
ویژگی ها ثابت هایی هستند که در سراسر رندر مورد استفاده مجدد قرار می گیرند. همانطور که هست، این ویژگی ها فقط مستقیماً در کد رندر ویرایش می شوند. ما می توانیم صفحه خاصی را تصور کنیم که در آن کاربر می تواند این تنظیمات را مستقیماً در UI تغییر دهد.
// 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;
سازنده
سازنده به شدت با روش چرخه حیات رندر ما همراه است. در ScheduleJS Viewer، ما تصمیم گرفتیم هر زمان که کاربر صفحهها را تغییر میدهد تا ویژگیها را مشخص کند و در هر برگهای که این رندر را پیادهسازی میکند، دوباره از کد ما استفاده کند، رندر را نمونهسازی کنیم. این بدان معناست که عملکرد سازنده هر بار که کاربر صفحهای با این رندر را انتخاب میکند اجرا میشود.
// Constructor
// The renderer requires the graphics and the current tab variable
constructor(graphics: GraphicsBaseScheduleJsViewerTaskRow>,
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
، سetStroke
، setFillHover
، setStrokeHover
، setLineWidth
، و setBarHeight
به ارث برده می شوند و برای تغییر ویژگی های رندر پیش فرض کلاس ActivityBarRenderer استفاده می شوند.
ویژگی های پیش فرض این رندر به شرح زیر است:
- یک رنگ سفارشی هنگام شناور کردن فعالیتها
- یک خط مشکی (برای مرزهای فعالیت)
- ضخامت خط سکته مغزی 0.5 پیکسل
- ارتفاع نوار فعالیت 8 پیکسل
- رنگ پر مشروط: آبی برای کودکان و قهوه ای برای والدین در برگه WBS سبز برای کودکان و خاکستری برای والدین در برگه های دیگر
طراحی
فریم ورک به طور خودکار فراخوانی می کند drawActivity
روشی برای ارائه فعالیت های ما بر روی بوم. تمام پارامترهای آن به صورت پویا پر شده است و به شما امکان می دهد در زمان واقعی به وضعیت فعلی فعالیت های خود واکنش نشان دهید.
// Main drawing method
drawActivity(activityRef: ActivityRefScheduleJsViewerTaskActivity>,
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);
}
ترسیم به این صورت انجام می شود:
- دریافت اطلاعات در مورد جریان فعالیت و ردیف با استفاده از ActivityRef API
- با استفاده از ما رنگ ها را به صورت پویا تنظیم کنید
_setActivityColor
روش - رسم متن فعالیت با استفاده از ما
_drawActivityText
روش - خود فعالیت را با استفاده از دو روش ترسیم کنید: The
_drawParentActivity
روش ترسیم والدین Thesuper.drawActivity
روش پیشفرض ActivityBarRenderer برای ترسیم کودکان
روش های طراحی فعالیت های سفارشی
بیایید نگاهی دقیقتر به نحوه ترسیم آزادانه فعالیتهای خود با طراحی روشهای خود با استفاده کنیم _drawParentActivity
روش.
// Draw the parent activity
private _drawParentActivity(activityRef: ActivityRefScheduleJsViewerTaskActivity>,
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);
}
در اینجا ما مستقیماً از HTMLCanvas API برای تعریف استراتژی ترسیم خود با تنظیم CanvasRenderingContex2D. تنها عملیات مربوط به چارچوب انجام شده در این روش، ایجاد برخی موارد جدید است محدوده فعالیت برای والدین فعلی فعالیت.
چارچوب با استفاده از یک نقشه ایجاد می کند محدوده فعالیت زیر کاپوت برای ثبت تمام فعالیت ها بر روی صفحه نمایش. این نقشه با ارائه یک منطق عنصر مانند به توسعه دهنده کمک می کند تا تجربیات کاربری پیشرفته ای را بر اساس اطلاعات دقیق ایجاد کند و در عین حال از عملکرد HTMLCanvas API.
روش عناصر ترسیم مانند _drawParentActivityStartTriangle
تکیه بر CanvasRenderingContext2D API برای ترسیم در سطح پیکسل
// 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();
}
نتیجه نهایی
برای ثبت رندر جدید خود، از graphics.setActivityRenderer
روش:
// Register the renderer
graphics.setActivityRenderer(ScheduleJsViewerTaskActivity, GanttLayout, new ScheduleJsViewerTaskActivityRenderer(graphics, currentRibbonMenuTab));
برای دیدن ویدیوی نتیجه نهایی می توانید به بخش ساختن ActivityRenderer مراجعه کنید