«Если рабочий хочет хорошо выполнять свою работу, он должен сначала заточить свои инструменты» — Конфуций, «Аналитики Конфуция. Лу Лингун»
титульная страница > программирование > Создание ActivityRenderer

Создание ActivityRenderer

Опубликовано 5 августа 2024 г.
Просматривать:471

Средство визуализации действий Ганта является основным средством визуализации ScheduleJS Viewer. В этой статье будет обсуждаться, как он устроен и каковы особенности этого средства визуализации действий.

Как создать собственный класс рендеринга

Первым шагом к созданию класса средства рендеринга является наследование атрибутов и методов путем расширения класса платформы более высокого порядка.

Мы хотим представлять задачи только через их время начала и окончания. Базовым классом рендеринга ScheduleJS для этого является класс ActivityBarRenderer.

Нам необходимо предоставить аргументы пользовательского типа классу ActivityBarRenderer, чтобы атрибуты и методы, предоставляемые нашими пользовательскими классами Row и Activity, были доступны используя 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 для рисования определенного Activity в его Row. Чтобы организовать наш ScheduleJsViewerTaskActivityRenderer, мы разделим его код на три секции:

  • Атрибуты будут содержать переменные, которые позволят нам изменить поведение конкретной процедуры рисования.
  • Конструктор позволит нам определить состояние по умолчанию для средства рендеринга.
  • Методы рисования будут содержать все инструкции по рисованию наших действий на холсте.

Атрибуты

Атрибуты — это константы, которые будут повторно использоваться в средстве рендеринга. Как есть, эти свойства будут редактироваться только непосредственно в коде средства визуализации. Мы можем представить себе конкретный экран, на котором пользователь может изменять эти настройки непосредственно в пользовательском интерфейсе.

// 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: 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
  • Динамическая установка цветов с помощью нашего метода _setActivityColor
  • Нарисуйте текст активности, используя наш метод _drawActivityText
  • Нарисуйте само действие двумя способами: Метод _drawParentActivity для рисования родителей. Метод ActivityBarRenderer по умолчанию super.drawActivity для рисования дочерних элементов

Пользовательские методы рисования действий

Давайте подробнее рассмотрим, как свободно рисовать вашу активность, разрабатывая собственные методы с помощью метода _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. Единственная операция, связанная с платформой, выполняемая в этом методе, — это создание новых ActivityBounds для текущего родительского Activity.

Фреймворк создает карту, используя ActivityBounds под капотом для регистрации всех действий на экране. Эта карта помогает разработчику, предоставляя элементную логику для создания расширенного пользовательского интерфейса на основе точной информации, используя при этом преимущества производительности HTMLCanvas API.

Методы рисования элементов, такие как _drawParentActivityStartTriangle, используют API CanvasRenderingContext2D для рисования на уровне пикселей.

// 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