[Wijmo入門]Menuコントロールの使い方 – 基本機能編 –

Wijmo(ウィジモ)」は業務アプリケーションの様々な要件に対応できるUI部品を備えたJavaScriptライブラリです。

Wijmoには、ドロップダウンメニューや任意のDOM要素に表示するコンテキストメニューを作成できる「Menu(メニュー)」コントロールが含まれています。この記事では、簡単なドロップダウンメニューとFlexChartコントロールやFlexGridコントロールに表示するコンテキストメニューを作成する方法を紹介します。

開発環境の準備とWijmoの参照

この記事では以下の開発環境を使用します。

作成するファイルは次の4つです。

index.htmlページ本体。ページの要素としてMenuコントロールとFlexChartコントロールおよびFlexGridコントロールを配置します
app.js各コントロールを作成するコードを記載します
data.jsFlexChartコントロールとFlexGridコントロールに設定するデータを記載します
styles.css各種ページ要素のスタイル定義を記載します

「data.js」に記載するデータは、G7各国の2000年、2010年、2020年のGDP(国民総生産)を10億USドル単位で表したものです。

function getData() {
    return[
        {'id': 0, 'country': 'カナダ', '2000': 744.631, '2010': 1617.35, '2020': 1647.60},
        {'id': 1, 'country': 'フランス', '2000': 1366.24, '2010': 2647.35, '2020': 2635.92},
        {'id': 2, 'country': 'ドイツ', '2000': 1948.84, '2010': 3402.44, '2020': 3886.56},
        {'id': 3, 'country': 'イタリア', '2000': 1147.18, '2010': 2137.85, '2020': 1895.69},
        {'id': 4, 'country': '日本', '2000': 4968.36, '2010': 5759.07, '2020': 5048.79},
        {'id': 5, 'country': 'イギリス', '2000': 1669.28, '2010': 2493.84, '2020': 2706.54},
        {'id': 6, 'country': 'アメリカ', '2000': 10250.95, '2010': 15048.98, '2020': 21060.45}
    ];
}

また、ページ上の要素のスタイルを「styles.css」で定義します。「.wj-menu」と「.wj-listbox.wj-menu-items」では「wijmo.min.css」ファイルに記載されているものを上書きして変更します。

/* FlexChartのスタイル */
#FlexChart{
    height: 320px;
    width: 780px;
}
/* FlexGridのスタイル */
#FlexGrid{
    border: none;
    height: 260px;
    width: 780px;
}
/* メニューバーのスタイル */
.menubar {
    background: lightgray;
    height: 30px;
}
/* メニューのスタイル */
.wj-menu {
    border: none;
    color: navy;
    background: transparent;
}
/* メニュー項目のスタイル */
.wj-listbox.wj-menu-items {
    border: none;
    background: lemonchiffon;
}
/* コンテキストメニューのスタイル */
.chart-menu {
    background: lightcyan !important;
}

ドロップダウンメニューを作成する

それでは「index.html」と「app.js」に次のようなコードを記述してMenuコントロールを作成しましょう。ここでは、メニューバー形式でドロップダウンメニューを表示する方法を紹介します。
※ ライセンスキーを設定しない場合トライアル版を示すメッセージが表示されます。ライセンスキーの入手や設定方法についてはこちらをご覧ください。

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <title>Wijmo Menu</title>
    <link href="css/wijmo.min.css" rel="stylesheet"/>
    <link href="css/styles.css" rel="stylesheet"/>
    <script src="scripts/wijmo.min.js"></script>
    <script src="scripts/wijmo.chart.min.js"></script>
    <script src="scripts/wijmo.grid.min.js"></script>
    <script src="scripts/wijmo.input.min.js"></script>
    <script src="scripts/cultures/wijmo.culture.ja.min.js"></script>
    <script src="scripts/app.js"></script>
    <script src="scripts/data.js"></script>
</head>
<body>
    <div class="menubar">
        <div id="menu-main"></div>
    </div>
    <div class="controls">
        <div id="FlexChart"></div>
        <div id="FlexGrid"></div>
    </div>
</body>
</html>
wijmo.setLicenseKey('ここにWijmoのライセンスキーを設定します');

document.addEventListener("DOMContentLoaded", function () {
    const chart = InitializeChart();
    const grid = InitializeGrid();
    InitializeMenuBar();
});

// チャートの作成
function InitializeChart(){
    const chart = new wijmo.chart.FlexChart('#FlexChart', {
        header: 'G7のGDP (単位:10億USドル)',
        itemsSource: getData(),
        bindingX: 'country',
        series: [
            {binding: '2000', name: '2000年'},
            {binding: '2010', name: '2010年'},
            {binding: '2020', name: '2020年'}
        ]
    });
    return chart;
}

// グリッドの作成
function InitializeGrid(){
    const grid = new wijmo.grid.FlexGrid('#FlexGrid', {
        autoGenerateColumns: false,
        columns: [
            {binding: 'id', header: 'ID'},
            {binding: 'country', header: '国名', width: 153},
            {binding: '2000', header: '2000年', width: 153},
            {binding: '2010', header: '2010年', width: 153},
            {binding: '2020', header: '2020年', width: 153}
        ],
        itemsSource: getData()
    });
    return grid;
}

// メニューバーの作成
function InitializeMenuBar(){
    const menu = new wijmo.input.Menu('#menu-main', {
        header: 'コントロールの配置変更',
        openOnHover: true,
        isAnimated: true,
        itemsSource: ['チャートを最上部に配置', '-', 'グリッドを最上部に配置'],
        showDropDownButton: false,
        itemClicked: (sender) => {
            const controls = document.querySelector('.controls');
            if(sender.selectedIndex == 0){
                const fc = document.querySelector('#FlexChart');
                controls.insertBefore(fc, controls.firstChild);
            }else if(sender.selectedIndex == 2){
                const fg = document.querySelector('#FlexGrid');
                controls.insertBefore(fg, controls.firstChild);
            }
        }
    });
}

Menuクラスのコンストラクタで設定しているプロパティの機能は次のとおりです。

プロパティ名説明
headerメニューの標題を表す文字列
openOnHoverマウスホーバーによるメニューのオープン
isAnimatedアニメーション効果の有無
itemsSourceメニュー項目
showDropDownButtonドロップダウンボタンの表示/非表示

openOnHoverプロパティをtrueに設定するとMenuコントロール上にマウスポインタがきたときにドロップダウンメニューが自動的に表示されます。また、itemsSourceプロパティの要素として半角ハイフン「-」を追加するとその部分が区切り線として描画されます。なお、ここではMenuコントロールをメニューバーの形で表示するのでshowDropDownButtonプロパティをfalseに設定してドロップダウンボタンを非表示にしています。

コンストラクタではitemClickedイベントのハンドラも実装しています。メニュー項目の「グリッドを最上部に配置」をクリックするとグリッドが上部に配置され、チャートは下部に移動します。どのメニュー項目がクリックされたかはMenuクラスのselectedIndexプロパティで判別しています。

作成したページのメニューにマウスポインタを置くとドロップダウンメニューが表示されます。

ドロップダウンメニュー

メニュー項目の「グリッドを最上部に配置」をクリックすると以下のようにグリッドの位置が入れ替わります。

グリッドを最上部に配置

FlexGridコントロールとFlexChartコントロールの使用方法については以下の記事もご参考下さい。

FlexChartコントロールにコンテキストメニューを設定する

次に、先ほどのFlexChartコントロールにコンテキストメニューを追加しましょう。

このコンテキストメニューを使ってFlexChartコントロールに設定されている3つの棒グラフ(2000年、2010年、2020年)の表示と非表示を切り替えられるようにします。

「app.js」のdocument.DOMContentLoadedイベントにInitializeChartMenu(chart);を追加し、新たにInitializeChartMenu関数を記述します。

wijmo.setLicenseKey('ここにWijmoのライセンスキーを設定します');

document.addEventListener("DOMContentLoaded", function () {
    const chart = InitializeChart();
    const grid = InitializeGrid();
    InitializeMenuBar();
    InitializeChartMenu(chart);
});
・・・(中略)・・・

// チャート用コンテキストメニューの作成
function InitializeChartMenu(chart){
    const menuChart = new wijmo.input.Menu(document.createElement('div'), {
        displayMemberPath: 'header',
        selectedValuePath: 'cmd',
        dropDownCssClass: 'chart-menu',
        itemsSource: [
            {header: '2000年の非表示', cmd: '2000'},
            {header: '2010年の非表示', cmd: '2010'},
            {header: '2020年の非表示', cmd: '2020'}
        ],
        itemClicked: (sender) => {
            if(sender.selectedValue == '2000'){
                // 2000年のデータの表示切り替え
                const series0 = chart.series[0];
                if(series0.visibility == wijmo.chart.SeriesVisibility.Visible){
                    series0.visibility = wijmo.chart.SeriesVisibility.Hidden;
                    sender.itemsSource = [
                        {header: '2000年の表示', cmd: '2000'}, 
                        sender.itemsSource[1], 
                        sender.itemsSource[2]
                    ];
                }else{
                    series0.visibility = wijmo.chart.SeriesVisibility.Visible;
                    sender.itemsSource = [
                        {header: '2000年の非表示', cmd: '2000'}, 
                        sender.itemsSource[1], 
                        sender.itemsSource[2]
                    ];
                }
            }else if(sender.selectedValue == '2010'){
                // 2010年のデータの表示切り替え
                const series1 = chart.series[1];
                if(series1.visibility == wijmo.chart.SeriesVisibility.Visible){
                    series1.visibility = wijmo.chart.SeriesVisibility.Hidden;
                    sender.itemsSource = [
                        sender.itemsSource[0],
                        {header: '2010年の表示', cmd: '2010'}, 
                        sender.itemsSource[2]
                    ];
                }else{
                    series1.visibility = wijmo.chart.SeriesVisibility.Visible;
                    sender.itemsSource = [
                        sender.itemsSource[0], 
                        {header: '2010年の非表示', cmd: '2010'}, 
                        sender.itemsSource[2]
                    ];
                }
            }else if(sender.selectedValue == '2020'){
                // 2020年のデータの表示切り替え
                const series2 = chart.series[2];
                if(series2.visibility == wijmo.chart.SeriesVisibility.Visible){
                    series2.visibility = wijmo.chart.SeriesVisibility.Hidden;
                    sender.itemsSource = [
                        sender.itemsSource[0], 
                        sender.itemsSource[1], 
                        {header: '2020年の表示', cmd: '2020'}
                    ];
                }else{
                    series2.visibility = wijmo.chart.SeriesVisibility.Visible;
                    sender.itemsSource = [
                        sender.itemsSource[0], 
                        sender.itemsSource[1], 
                        {header: '2020年の非表示', cmd: '2020'},
                    ];
                }
            }
        }
    });
    // コンテキストメニューの表示
    const fc = document.querySelector('#FlexChart');
    fc.addEventListener('contextmenu', e => {
        e.preventDefault();
        menuChart.show(e);
    }, true);
}

コンテキストメニューでは、Menuクラスのコンストラクタの第1引数として新規に生成したdiv要素を設定します。このdiv要素にはitemsSourceプロパティで設定したメニュー項目が表示されます。作成したコンテキストメニューを表示するには、FlexChartコントロールのdiv要素のcontextmenuイベントでMenuクラスのshowメソッドを呼び出します。

Menuクラスのコンストラクタで設定しているプロパティの機能は次のとおりです。

プロパティ名説明
displayMemberPath項目名として使うプロパティの名称
selectedValuePathselectedValueの取得に使うプロパティの名称
dropDownCssClassドロップダウン要素のCSSクラス名
itemsSourceメニュー項目

itemsSourceプロパティに含まれる各項目の「header(displayMemberPathで指定)」に設定した文字列が項目名として表示され、「cmd(selectedValuePathで指定)」に設定した文字列がMenuクラスのselectedValueプロパティで取得されます。

dropDownCssClassプロパティを指定しない場合にはCSSの「.wj-listbox.wj-menu-items」で設定されたスタイルが適用されます。

また、itemClickedイベントでは、本来の処理に加えてクリックされた項目の文字列を切り替える処理も行っています。これにより、非表示になった棒グラフに対応する文字列は「~の非表示」から「~の表示」に変更されます。

FlexChartコントロールを右クリックすると、各棒グラフの表示/非表示を切り替えるためのコンテキストメニューが表示されます。

FlexChartにコンテキストメニュー追加

メニュー項目の「2020年の非表示」をクリックすると2020年の棒グラフが非表示になります。その後でFlexChartコントロールを右クリックすると、3番目のメニュー項目が「2020年の表示」に変更されています。

コンテキストメニューからデータを非表示

FlexGridコントロールにコンテキストメニューを設定する

最後にFlexGridコントロールにコンテキストメニューを追加しましょう。

このコンテキストメニューを使ってFlexGridコントロールの選択セルの背景色を変更し、変更した背景色を解除できるようにします。

「app.js」のdocument.DOMContentLoadedイベントにInitializeGridMenu(grid);を追加し、新たにInitializeGridMenu関数を記述します。

wijmo.setLicenseKey('ここにWijmoのライセンスキーを設定します');

document.addEventListener("DOMContentLoaded", function () {
    const chart = InitializeChart();
    const grid = InitializeGrid();
    InitializeMenuBar();
    InitializeChartMenu(chart); 
    InitializeGridMenu(grid);
});
・・・(中略)・・・

// グリッド用コンテキストメニューの作成
function InitializeGridMenu(grid){
    const menuGrid = new wijmo.input.Menu(document.createElement('div'), {
        displayMemberPath: 'header',
        selectedValuePath: 'cmd',
        itemsSource: [
            {header: '背景色の設定', cmd: 'SetBackColor'},
            {header: '-', cmd: ''},
            {header: '設定の解除', cmd: 'ResetBackColor'}
        ],
        itemClicked: (sender) => {
            grid.itemFormatter = function (panel, r, c, cell) {
                if (panel.cellType == wijmo.grid.CellType.Cell) {
                    // 背景色と文字色のリセット
                    cell.style.backgroundColor = '';
                    cell.style.color = '';
                    // 背景色と文字色の設定
                    if(sender.selectedValue == 'SetBackColor'){
                        grid.selectedRanges.forEach(element => {
                            if(element.contains(r, c)){
                                cell.style.backgroundColor = 'lightpink';
                                cell.style.color = 'black';
                            }
                        });
                    }
                }
            }
        }
    });
    // コンテキストメニューの表示
    const fg = document.querySelector('#FlexGrid');
    fg.addEventListener('contextmenu', e => {
        e.preventDefault();
        menuGrid.show(e);
    }, true);
}

このコンテキストメニューではdropDownCssClassプロパティを設定していないので、「styles.css」ファイルに記載している下記のスタイルが使用されます。

・・・(中略)・・・
/* メニュー項目のスタイル */
.wj-listbox.wj-menu-items {
    border: none;
    background: lemonchiffon;
}
・・・(中略)・・・

FlexGridコントロールを右クリックすると、選択範囲の背景色を設定または解除するためのコンテキストメニューが表示されます。
※ FlexGridコントロールでセルのスタイルを変更する方法についてはこちらをご覧ください。

FlexGridにコンテキストメニュー追加

メニュー項目の「背景色の設定」をクリックすると選択範囲のセルの背景色が変更されます。
※ 背景色の変更後に別の選択範囲の背景色を変更すると、最初に変更した箇所の背景色の変更は解除されます。

コンテキストメニューから背景色設定

今回ご紹介した各種設定は以下のデモアプリケーションでも確認できます(“Run Project”をクリックするとデモが起動します)。

Menuコントロールの利用については以下のドキュメントも用意していますので、ここで紹介できなかった機能については、これらのドキュメントを参照していただければと思います。

さいごに

今回はWijmoに含まれているMenuコントロールの基本的な使用方法を紹介いたしました。Menuは、この他にも階層構造のメニューや独自のHTMLコンテンツを項目としたメニューも作成することができます。アプリケーションでのナビゲーション操作を洗練されたものにするMenuコントロールをご検討いただけますと幸いです。

この他にもWijmoの各種コントロールの基本的な使い方や応用的な使い方の解説を連載記事として公開しています。こちらも是非ご覧ください。

製品サイトでは、Wijmoの機能を手軽に体験できるデモアプリケーションやトライアル版も公開しておりますので、こちらもご確認ください。

また、ご導入前の製品に関するご相談、ご導入後の各種サービスに関するご質問など、お気軽にお問合せください。

\  この記事をシェアする  /