出典:ArcGIS Experience Builder - Guide - Jimu
Jimuは、ArcGIS Experience Builder の根幹となる JavaScript フレームワークです。Experience Builder を拡張可能かつカスタマイズ可能にする基盤です。Jimu は以下の機能を提供します。
Jimuはモジュール性を重視して設計されており、必要なものだけを使用して、アプリケーション間で一貫性を維持できます。
Jimu を使って次のものを作成できます。
Experience Builder の機能を拡張するウィジェット Experience Builder の機能を強化するエクステンション エクスペリエンスに適用できるテーマ エクスペリエンスの動作や外観をカスタマイズする構成
Jimu は以下の主要な原則に基づくモジュール型アーキテクチャー パターンを採用しています:
Jimuは、機能ごとに分けられたパッケージで構成されるモジュール型アーキテクチャを採用しています。この設計により、開発者は必要なパッケージのみを使用しながら、アプリケーション間で一貫性を維持できます。
| パッケージ | 説明 |
|---|---|
| jimu-core | ユーティリティー、状態管理、データソース、基底クラス |
| jimu-ui | コンポーネントとテーマ |
| jimu-arcgis | ArcGIS機能と地図の統合 |
| jimu-for-builder | ビルダー コンポーネントとユーティリティー |
| jimu-theme | テーマ管理とスタイル |
| jimu-layouts | レイアウト管理とコンポーネント |
| jimu-for-test | テスト用ユーティリティー |
| jimu-icons | アイコン管理とSVG |
Jimu は、機能を拡張する上で、一貫したパターンを採用しています。カスタム ウィジェットを作成するコード例は次の通りです。
// Example: Creating a custom widget
import { type AllWidgetProps } from 'jimu-core'
const Widget = (props: AllWidgetProps<any>) => {
return (
<div className="my-widget jimu-widget ">
<p>My Widget</p>
</div>
)
}
export default Widget
メッセージ アクション と データ アクション は JavaScript クラスであり、AbstractDataAction および AbstractMessageAction クラスを継承することが推奨されます。
export default class MyDataAction extends AbstractDataAction {}
export default class MyMessageAction extends AbstractMessageAction {}
Jimu の拡張機能は JavaScript クラスとして実装されますが、その種類によって異なるインターフェイスを持ちます。それぞれの機能に合わせたインターフェイスを実装することが推奨されます。
export default class MyExtension implements extensionSpec.SomeExtensionInterface {}
Jimu アプリケーションは構成駆動型であり、実行時のカスタマイズが可能です。以下はウィジェットの構成ファイルの例です:
{
"widgets": {
"my-widget": {
"label": "My Widget",
"uri": "widgets/my-widget",
"config": {
"title": "Custom Title"
}
}
}
}
Jimu は、開発ニーズに応じてパッケージとして構成されています。以下は各パッケージの概要です。
jimu-core パッケージによって、エクスペリエンス構築のためのユーティリティと基底クラスを利用できます。
| コンポーネント | 説明 |
|---|---|
| 基底クラスとインターフェイス | Message、MessageAction、DataAction、BaseExtension、DataSourceなど |
| マネージャー | WidgetManager、MessageManager、DataActionManager、ExtensionManager、DataSourceManager、SessionManagerなど |
| Reduxアクション | 状態管理のためのappActionsなど |
| ユーティリティー関数 | utils、urlUtils、portalUrlUtils、appConfigUtils、dataSourceUtils、geometryUtilsなど |
| コンポーネント | DataSourceComponent、ExpressionResolverComponentなど |
| モジュール ローダー | moduleLoader、loadArcGISJSAPIModules |
jimu-ui パッケージによって、エクスペリエンス構築のためのすべての UI コンポーネントを利用できます。スタイリングには emotion-js を使用し、コンポーネントは index、basic、advanced のいずれかのカテゴリーに分類されます。
| コンポーネント | 説明 |
|---|---|
| index | Button、TextInput、Modalなどの一般的な UI コンポーネント |
| Basic | DatePicker、ColorPickerなどの特定機能に特化したコンポーネント |
| Advanced | ExpressionBuilder、DataSourceSelectorなど Experience Builder 特有の複雑なコンポーネント |
UI コンポーネントを作成する推奨方法は styled component を使用することです。詳細は jimu-ui パッケージのドキュメントに記載されています。
以下は UI コンポーネントの使用例です:
import { Button, TextInput, Modal } from 'jimu-ui';
import { css } from 'jimu-core';
import { React } from 'jimu-core';
// Example: Using UI components with theming
const widgetStyle = css`
background: var(--background-color);
color: var(--text-color);
padding: 1rem;
`;
export default function MyWidget() {
const [isModalOpen, setIsModalOpen] = React.useState(false);
return (
<div css={widgetStyle}>
<TextInput placeholder="Enter data..." />
<Button type="primary" onClick={() => setIsModalOpen(true)}>Submit</Button>
<Modal isOpen={isModalOpen}>
<div>Modal content</div>
</Modal>
</div>
);
}
jimu-arcgis パッケージには、ArcGIS Maps SDK for JavaScriptを扱うためのコンポーネント、インターフェイス、クラス、プロパティ、メソッドが含まれています。
jimu-arcgis パッケージに含まれるクラスとコンポーネントは以下の通りです。
| コンポーネント | 説明 | | JimuMapView | MapView や SceneView インスタンスにアクセスするためのクラス | | JimuMapViewComponent | マップ ウィジェットとビューを統合するためのコンポーネント | | JimuLayerView | レイヤー ビューを扱うためのクラス | | JimuLayerViewComponent | レイヤー ビューを操作するためのコンポーネント |
以下にマップ コンポーネントの使用例を示します。
import { JimuMapViewComponent } from 'jimu-arcgis';
// Example: Map integration
<JimuMapViewComponent
useMapWidgetId={useMapWidgetId}
onActiveViewChange={(jmv) => {
// Handle map view changes
jmv.view.when(() => {
console.log('Map view ready');
});
}}
/>
jimu-for-builder パッケージは、ウィジェット設定ページの開発をサポートするために設計されています。設定ページは、エクスペリエンス作成者がウィジェット構成を追加するビルダー内のセクションです。
このパッケージの主なコンポーネントは、builderAppSync、appBuilderSync、WidgetSettingManager です。Redux ストアを拡張し、appStateInBuilder や builder などのビルダー状態を追加するにはこのパッケージを使用します。
jimu-theme パッケージによって、エクスペリエンス構築のためのテーマ管理とスタイルを利用できます。このパッケージには以下が含まれます。
styledwithThemetheme にアクセスするためのReactフックとなる useThemeThemeVariable、ThemeOptions などのテーマに関連したインターフェイス| コンポーネント | 説明 |
|---|---|
| styled | styled componet を作成するメソッド |
| useTheme | theme 変数にアクセスする React フック |
| withTheme | コンポーネントにテーマ情報を付与するメソッド |
| ThemeVariable | テーマ変数のインターフェイス |
| RawThemeOptions | JSON 形式のテーマ オプションのインターフェイス (theme フォルダ内の variables.json ) |
jimu-layouts パッケージによって、レイアウト管理とコンポーネントの利用が可能となります。2つのエントリー ポイントがあります。
layout-runtime。レイアウト ツリー検索機能を提供する selectors や、ウィジェット レイアウト機能のための LayoutEntry コンポーネントをエクスポートします。layout-entry。searchUtils。jimu-data-sources パッケージによって、データ ソースを実装することができます。ただ、ほとんどのケースではこのパッケージを直接使うより、jimu-core からエクスポートされる DataSourceComponent を使用することが推奨されます。
jimu-for-test パッケージは、テスト用のユーティリティーを提供します。ユーティリティ関数には、wrapWidget、withThemeRender、withIntlRender、withStoreRender、mockService、mockItem、initGlobal、getInitState、widgetRender があります。
以下はテスト ユーティリティの使用例として示した、チェックボックス コンポーネントをテストするコードです。
import * as React from 'react'
import { render } from '@testing-library/react'
import { Checkbox } from 'jimu-ui'
describe('checkbox component test', () => {
it('test mount', () => {
const { container } = render(<Checkbox />)
expect(container.firstChild).not.toBeNull()
})
it('test default jimu class name', () => {
const { container } = render(<Checkbox />)
expect(container.querySelector('.jimu-checkbox')).toBeTruthy()
})
it('test "checked" attribute', () => {
const { container } = render(<Checkbox checked />)
expect(container.querySelector('.jimu-checked')).toBeTruthy()
})
it('test "indeterminate" attribute', () => {
const { container } = render(<Checkbox indeterminate />)
expect(container.querySelector('.indeterminate')).toBeTruthy()
})
it('test "disabled" attribute', () => {
const { container } = render(<Checkbox disabled />)
expect(container.querySelector('.jimu-disabled')).toBeTruthy()
})
})
テスト用ユーティリティの別の使用例として、ボタン コンポーネントをテストするコードを示します。この例は次のファイルでも確認することができます:<Experience Builder Developer Edition のインストールパス>/client/dist/widgets/common/button/tests/button.test.tsx
import { React, Immutable, getAppStore, appActions } from 'jimu-core'
import ButtonWidget from '../src/runtime/widget'
import { wrapWidget, widgetRender, getInitState, getDefaultAppConfig } from 'jimu-for-test'
import '@testing-library/jest-dom'
getAppStore().dispatch(appActions.updateStoreState(getInitState().merge({ appConfig: getDefaultAppConfig() })))
const render = widgetRender(false)
const Widget = wrapWidget(ButtonWidget)
describe('button widget test', function () {
describe('default config', function () {
const config = Immutable({
functionConfig: {
text: 'Please configure link',
toolTip: '',
linkParam: {
}
},
styleConfig: {
themeStyle: {
quickStyleType: 'default'
}
}
})
it('button widget should be render', () => {
const { queryBySelector } = render(<Widget config={config}/>)
expect(queryBySelector('.widget-button-link')).not.toBeNull()
})
})
describe('test value config', function () {
const config = Immutable({
functionConfig: {
text: 'textTest',
toolTip: 'testToolTip',
linkParam: {
value: 'detail-page',
linkType: 'PAGE'
}
},
styleConfig: {
themeStyle: {
quickStyleType: 'default'
}
}
})
it('button widget should be render', () => {
const renderResult = render(<Widget config={config}/>)
expect(renderResult.queryBySelector('.widget-button-link')).toBeInTheDocument()
expect(renderResult.queryByText('textTest')).toBeInTheDocument() //text ok
expect(renderResult.queryByTitle('testToolTip')).toBeInTheDocument() // toolTip ok
// renderResult.queryBySelector('.widget-button-link').getAttribute('href'); // link ok
})
})
})
jimu のパッケージについての詳細は、API Reference をご確認ください。