برنامه نویسی

ساخت یک 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 روش ترسیم والدین The super.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 مراجعه کنید

نوشته های مشابه

دیدگاهتان را بنویسید

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *

دکمه بازگشت به بالا