「労働者が自分の仕事をうまくやりたいなら、まず自分の道具を研ぎ澄まさなければなりません。」 - 孔子、「論語。陸霊公」
表紙 > プログラミング > ActivityRenderer の構築

ActivityRenderer の構築

2024 年 8 月 5 日に公開
ブラウズ:426

ガント アクティビティ レンダラは、ScheduleJS ビューアのメイン レンダラです。この記事では、このアクティビティ レンダラーの構築方法とその特徴について説明します。

カスタムレンダラークラスを構築する方法

レンダラー クラスを構築する最初のステップは、上位フレームワーク クラスを拡張して属性とメソッドを継承することです。

タスクの開始時間と終了時間のディメンションのみでタスクを表現したいと考えています。これを行うための ScheduleJS の基本レンダラー クラスは、ActivityBarRenderer クラスです。

カスタム Row クラスと Activity クラスによって提供される属性とメソッドにアクセスできるように、カスタム タイプの引数を 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 ActivityBarRenderer { }

そのままでは、ActivityBarRenderer のデフォルトの動作を使用してアクティビティを描画するためにレンダラーをすでに登録できます。それでは、カスタマイズ方法を見ていきましょう。

基本アーキテクチャ

ScheduleJS の ActivityRenderer は、Graphics API を使用してプログラムで登録し、Row に特定の Activity を描画するクラスです。 ScheduleJsViewerTaskActivityRenderer を整理するために、コードを 3 つのセクションに分割します:

  • 属性には、特定の描画手順の動作を変更できる変数が保持されます。
  • コンストラクターを使用すると、レンダラーのデフォルト状態を定義できます。
  • 描画メソッドには、キャンバス上にアクティビティを描画するためのすべての命令が含まれます。

属性

属性はレンダラー全体で再利用される定数です。現状では、これらのプロパティはレンダラー コード内でのみ直接編集されます。ユーザーがこれらの設定を 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 ビューアでは、ユーザーが画面を切り替えるたびにレンダラーをインスタンス化して詳細を定義し、このレンダラーを実装するすべてのタブでコードを再利用することにしました。これは、ユーザーがこのレンダラーを備えた画面を選択するたびにコンストラクター関数が実行されることを意味します。

// Constructor

// The renderer requires the graphics and the current tab variable
constructor(graphics: GraphicsBase,
            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、および setBarHeight は継承され、ActivityBarRenderer クラスのデフォルトのレンダリング特性を変更するために使用されます。

このレンダラーのデフォルトの機能は次のとおりです:

  • アクティビティをホバーするときのカスタムカラー
  • 黒い線のストローク (アクティビティの境界線用)
  • ストローク線の太さ 0.5 ピクセル
  • アクティビティ バーの高さは 8 ピクセル
  • 条件付き塗りつぶし色: WBS タブの子供は青、親は茶色 他のタブの子供は緑色、親は灰色

描画

フレームワークは自動的にdrawActivityメソッドを呼び出して、キャンバス上にアクティビティをレンダリングします。すべてのパラメータは動的に入力されるため、アクティビティの現在の状態にリアルタイムで反応できます。

// Main drawing method

drawActivity(activityRef: ActivityRef,
             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 を使用して、現在の Activity および Row に関する情報を取得します
  • _setActivityColor メソッドを使用して動的に色を設定します
  • _drawActivityText メソッドを使用してアクティビティ テキストを描画します
  • 次の 2 つの方法を使用してアクティビティ自体を描画します。 親を描画する _drawParentActivity メソッド 子を描画するための super.drawActivity のデフォルトの ActivityBarRenderer メソッド

カスタムアクティビティの描画方法

_drawParentActivity メソッドを使用して独自のメソッドを設計し、アクティビティを自由に描画する方法を詳しく見てみましょう。

// Draw the parent activity

private _drawParentActivity(activityRef: ActivityRef,
                            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を設定することで描画戦略を定義します。このメソッドで行われる唯一のフレームワーク関連の操作は、現在の親 Activity に対して新しい ActivityBounds を作成することです。

フレームワークは、内部で ActivityBounds を使用してマップを作成し、画面上のすべてのアクティビティを登録します。このマップは、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));

brand-new renderer

最終結果のビデオを見るには、「ActivityRenderer の構築」を参照してください。

リリースステートメント この記事は次の場所に転載されています: https://dev.to/lenormor/building-an-activityrenderer-3o0?1 侵害がある場合は、[email protected] に連絡して削除してください。
最新のチュートリアル もっと>

免責事項: 提供されるすべてのリソースの一部はインターネットからのものです。お客様の著作権またはその他の権利および利益の侵害がある場合は、詳細な理由を説明し、著作権または権利および利益の証拠を提出して、電子メール [email protected] に送信してください。 できるだけ早く対応させていただきます。

Copyright© 2022 湘ICP备2022001581号-3