ビジュアルパーツを実装する

このチュートリアルでは、例として、値を表示するだけのシンプルなビジュアルパーツを作成します。

../_images/my-sensor-value.png

図 12 現在の値を表示するビジュアルパーツ

ディレクトリを作成する

ワークスペース内にビジュアルパーツのディレクトリを作成します。

$ mkdir src/entrypoint/my-project/my-sensor-value

$ cd src/entrypoint/my-project/my-sensor-value

注釈

  • 1つのワークスペースに複数のビジュアルパーツを含めることができます。

  • 1つのワークスペースに含まれるビジュアルパーツは、ビルド作業によりまとめられ、1つの app.js ファイルになります。 デプロイ(サーバーへの設置)は app.js ごとに行うため、ビジュアルパーツを個別にデプロイしたい場合は、ワークスペースを個別に作成する必要があります。

ビジュアルパーツ本体を実装する

ビジュアルパーツ本体を実装します。

以下のコードを index.tsx として保存してください。

注釈

コード内でインポートされる style.tsxthumbnail.svg は後で作成します。

// src/entrypoint/my-project/my-sensor-value/index.tsx

// Visual Parts SDK 関連の Import
import {
  expose,
  Renderer,
  Metadata,
  ExposerEvent,
} from '@aptpod/data-viz-visual-parts-sdk'

// React 関連の Import
import React, { useEffect, useState } from 'react'
import { createRoot, Root } from 'react-dom/client'

// Shadow DOM に適用するStyle
import { StyledShadowStyle } from '../../../styles/shadow'
// Styled Components を Shadow DOM 以下で適用するための Utility
import { StyleSheetManagerWrapper } from '../../../utils/components/style/stylesheet-manager-wrapper'
// React Profiler から描画処理に要した時間を取得するための Utility
import { ReactProfilerWrapper } from '../../../utils/components/profiler/react-profiler-wrapper'

import * as S from './style'
import thumbnailSrc from 'src/assets/images/my-project/my-sensor-value/thumbnail.svg'

// Metadata 作成
const metadata: Metadata = {
  partsType: '@my-project/my-sensor-value',
  partsName: 'My Sensor Value',
  groupName: 'My Project',
  panelTagName: 'x-my-project-my-sensor-value',
  getThumbnailURL: (baseURL: string) => `${baseURL}${thumbnailSrc}`,
  panelViewConfig: {
    displayTimestamp: true,
  },
  panelOptionConfig: {
    rangeAtMost: 1,
    canEditColor: false,
    bindDataCountMax: 1,
    extensionConfigs: [],
  },
}

// React を使用した描画
type Props = {
  comm: ExposerEvent
}
const App: React.FC<Props> = (props) => {
  const [baseURL, setBaseURL] = useState('')
  const [value, setValue] = useState<any>()

  // ExposerEvent から受信したデータを React Hooks の state に更新します。
  useEffect(() => {
    props.comm.baseURL.on(setBaseURL)
    props.comm.currentData.on((data) => setValue(data.data))
    props.comm.loaded.emit()
  }, [props.comm])

  // React Hooks の state を使用して描画します。
  return (
    <S.Section>
      <div>{String(value)}</div>
    </S.Section>
  )
}

// Renderer を作成
// - render で描画の初期設定
// - dispose で描画の終了処理を適用します
class PluginRenderer extends Renderer {
  private root: Root | undefined

  /**
   * 描画を実行します。 1回だけコールします。
   * 状態を変更する場合は、 ExposerEvent のイベントを利用し、 element のDOMを再描画します。
   */
  render(el: HTMLElement, comm: ExposerEvent) {
    this.root = createRoot(el)
    this.root.render(
      <StyleSheetManagerWrapper>
        {/* comm.renderingProfile は Data Visualizer v3.3.0 以降で利用可能です。 */}
        <ReactProfilerWrapper onProfile={comm.renderingProfile?.emit}>
          <>
            <StyledShadowStyle />
            <App comm={comm} />
          </>
        </ReactProfilerWrapper>
      </StyleSheetManagerWrapper>,
    )
  }

  /**
   * render メソッドで指定した element に紐づく子要素のDOMや子要素のイベントハンドラを解放します。
   *
   * ※ 引数の _el は React v18 に更新したことで、引数 el は使用しなくなりましたが、互換性を維持するため引数の定義は現状維持となっています。
   */
  dispose(_el: HTMLElement) {
    this.root?.unmount()
    this.root = undefined
  }
}

// 作成した metadata, renderer を公開します。
expose({
  metadata,
  renderer: PluginRenderer,
})

主な内容は以下です:

  • ビジュアルパーツの名前や設定を、Metadataインスタンスとして定義する。

  • ビジュアルパーツを描画するクラスを、Rendererのサブクラス(上の例ではPluginRenderer)として定義する。

  • 上記の2つを expose する。

Metadata、Renderer等のクラスの使い方についてはdata-viz-visual-parts-sdkの APIドキュメント を参照してください。

コンポーネントのスタイル(style.tsx)を作成する

上記コードにインポートされているスタイル ./style.tsx を作成します。

以下のコードを style.tsx として保存してください。

// src/entrypoint/my-project/my-sensor-value/style.tsx

import styled from 'styled-components'

const BG_COLOR = 'green'

export const Section = styled.section`
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  width: 100%;
  height: 100%;
  background-color: ${BG_COLOR};
`

この例では、背景色として green を指定しています。

サムネイルを作成する

ビジュアルパーツにはSVGまたはpng形式のサムネイルが必要です。

以下のSVG画像をダウンロードして、 src/assets/images/my-project/my-sensor-value/thumbnail.svg として保存してください。

../_images/thumbnail.svg

注釈

サムネイルは、Data Visualizer上でビジュアルパーツを一覧表示したときに使用されます。

  • サムネイルをSVG形式で作成する場合、サイズは幅150px x 高さ100pxとしてください。

  • サムネイルをpng形式で作成する場合、幅300px x 高さ200px以上とすることで、高解像度のディスプレイでもきれいに表示されます。

ビジュアルパーツをビルド対象に含める

新しく実装したビジュアルパーツをビルド対象に含めるには、webpackのエントリーポイント src/entrypoint/index.ts にディレクトリ名を追加します。

import './my-project/my-sensor-value'

注釈

付属のサンプルビジュアルパーツが不要な場合は、以下を行って削除してください。

  • src/entrypoint/index.ts から、 import './sample/...' の行を削除する。

  • ディレクトリ src/entrypoint/samples/ を削除する。

  • npm uninstall chart.js react-chartjs-2 d3 @types/chart.js @types/d3 binary-search-bound chartjs-adapter-date-fns date-fns を実行して、サンプルビジュアルパーツが使用していたパッケージをアンインストールする。

ローカルサーバーでビジュアルパーツをホストする

ローカルサーバーを起動して開発中のビジュアルパーツをホストし、Data Visualizerで読み込みます。

  1. ワークスペースで以下のコマンドを実行してローカルサーバーを起動します。

    $ npm run start
    

    ローカルサーバーが正しく起動すると、ローカルサーバーのURLが表示されます。

    --------------------------------
    
    Set the Plugin URL under development to Visual M2M Data Visualizer.
    Please set the following URL in Local Plugin URL Settings of Function Menu.
    
    - http://localhost:8080/app.js
    
    --------------------------------
    
  2. Data Visualizer画面下部の[Visual Parts]をクリックし、ビジュアルパーツ一覧に、いま作成したビジュアルパーツが表示されることを確認します。

    ../_images/my-sensor-value-visual-part.png

    図 13 使用できるビジュアルパーツの一覧

  3. ビジュアルパーツにデータをバインドして、動作を確認します。

ビジュアルパーツの開発は、以上のようにワークスペース内で行います。

ビジュアルパーツが完成したら、サーバーにデプロイします。 次の手順 ビジュアルパーツをビルドし、サーバーにデプロイする に進んでください。

注釈

ビジュアルパーツの実装方法の詳細については、ワークスペースに付属のサンプルビジュアルパーツのコードを参照してください(詳細なコメントが付いています)。 各サンプルビジュアルパーツの機能については 付属するビジュアルパーツのサンプルについて を参照してください。