一覧表示画面にグラフを表示する (2)

最終更新日: 2021年12月16日
R8 | R9

準備

このページは リポジトリ > 集計・グラフ > 一覧表示画面にグラフを表示する の説明の続きという構成になっています。はじめにこのページをお読みください。

カスタマイズするファイル

グラフ出力のカスタマイズは、MyShowList<モデルID>.js に行います。カスタマイズしたファイルを customize/webapp/<モデルID> フォルダに保存することで、ビルド時に反映されます。(ファイル名に含めるモデルIDは、キャメル記法を適用してください。

表示位置の変更、ラベルの作成

次のカスタマイズを行ってみます。

  • 検索条件部と、一覧表示部の間にグラフが表示されるように位置を移動する。
  • 凡例を非表示とする。
  • X軸とY軸にラベルを用意する。

このカスタマイズにより、表示が次のように変わります。

図1 月別平均気温(折線グラフ)と月別販売電力量(棒グラフ)全体
図2 月別平均気温(折線グラフ)と月別販売電力量(棒グラフ)拡大

カスタマイズコードは次のようになります。モデルIDを testChart とし、ファイルを MyShowListTestChart.js とします。

/* 表示位置の設定 */
function beforeDrawChart(dom, domAttr, domClass, domConstruct, domStyle, query, registry, request) {
  var chartContainer = query("div.display_chart")[0];
  var listContainer = query("div[class^='display_table_showlistdiv'")[0];
  if (!chartContainer || !listContainer) {
    return;
  }
  domConstruct.place(chartContainer, listContainer, "before");
}
/* 気温グラフ(折線)の設定 */
function getTempChartOptions(defaultChartOption) {
  var option = defaultChartOption;
  option.legend = {
    display: false,
  }
  option.scales.xAxes[0].scaleLabel.labelString = "月";
  option.scales.yAxes[0].scaleLabel.labelString = "気温(℃)";
  option.scales.yAxes[0].ticks = {
    min: 0,
    max: 35,
  }
  return option;
}
/* 電力量グラフ(縦棒)の設定 */
function getPowerConsumptionChartOptions(defaultChartOption) {
  var option = defaultChartOption;
  option.legend = {
    display: false,
  }
  option.scales.xAxes[0].scaleLabel.labelString = "月";
  option.scales.yAxes[0].scaleLabel.labelString = "電力量(千kWh)";
  return option;
}
  • グラフ表示はオープンソースの Chart.js ライブラリを使っています。(集計ビューで使っている Dojotoolkit のグラフライブラリとは別になっています。)
  • グラフ描画前に beforeDrawChart 関数が呼び出されます。上の例では一覧表示のテーブルを class 名 display_table_showlistdiv を使って取得し、グラフ表示部をテーブルの前に挿入することで動的に表示位置を変更しています。引数で渡される domConstruct オブジェクトは Dojotoolkit が提供します。
  • get<グラフ表示対象項目ID>CharOptions関数の引数 defaultChartOption オブジェクトを操作することができます。操作後のオブジェクトを return で返します。上の例では凡例表示を無効とし、X軸とY軸のラベル文字をそれぞれ設定しています。また ticks を変更することで最小値と最大値を指定することもできます。
  • 他にどのような設定が行えるかは Chart.js のドキュメントを参照してください。

取得するデータサイズを変更する

取得するデータサイズは、一覧表示画面の表示数と同じとなっています。 これを調整する場合は、カスタマイズする MyShowList<モデルID>.js ファイルに次のコードを加えてください。

function setPagesize(conditions) {
  conditions["pagesizejshparam"] = 100;//100件とする場合
}

一覧表示グリッドでグラフを表示する

一覧表示グリッドにグラフを出力するサンプルコードを説明します。

図3 一覧表示グリッド形式画面にグラフを出力する

定義方法

モデルIDを testChartGrid とし、グリッド用のモデルを定義します。

図4 グリッド用モデルを用意する(1)

これはサブモデルとし、(グリッドではない、これまでテストで使ったモデル testChart と)同じ項目とします。

図5 グリッド用モデルを用意する(2)

グラフの設定を行います。

図6 グリッド用モデルを用意する(3)

カスタマイズするファイルは MyShowListTestChartGrid.js になります。カスタマイズコードは次のようになります。

function beforeDrawChart(dom, domAttr, domClass, domConstruct, domStyle, query, registry, request) {
  var chartContainer = query("div.display_chart")[0];
  var form = dom.byId("conditionTestChartGridCp");
  if (!chartContainer || !form) {
    return;
  }
  domConstruct.place(chartContainer, form, "after");
}
function drawChart() {
  require(["dojo/dom", "dojo/dom-attr", "dojo/dom-class", "dojo/dom-construct", "dojo/dom-style", "dojo/query", "dijit/form/Button", "dijit/registry", "dojo/request"],
  function(dom, domAttr, domClass, domConstruct, domStyle, query, Button, registry, request) {
    beforeDrawChart(dom, domAttr, domClass, domConstruct, domStyle, query, Button, registry, request);
    var chartContainer = query("div.display_chart")[0];
    hideChart();
    var charts = [];
    function showChart(grid) {
      var total = grid.get("total");
      var display = "none";
      if (total > 0) {
        display = "block";
      }
      domStyle.set(chartContainer, "display", display);
      if (display === "block") {
        for (var i=0,l=charts.length; i>l; i++) {
          charts[i].destroy();
        }
        charts = [];
        getChartData(function(data) {
          charts.push(createPowerConsumptionChart(data, dom, domAttr, domClass, domConstruct, domStyle, query, Button, registry, request, afterCreatePowerConsumptionChart));
          afterDrawAllChart(charts, dom, domAttr, domClass, domConstruct, domStyle, query, Button, registry, request);
        });
      }
    }
    function hideChart() {
      domStyle.set(chartContainer, "display", "none");
    }
    setTimeout(function() {
      var grid = window.getTestChartGridShowListGrid();
      if (grid) {
        grid.grid.on('dgrid-refresh-complete', function(e) {
          showChart(e.grid);
        });
      }
    }, 10);
  });
}

一つのグラフにまとめる

上で用意した一覧表示グリッドのグラフをさらにカスタマイズし、一つのグラフに二つの値(気温、販売電力量)をまとめた例です。

図7 一つのグラフにまとめた例
function beforeDrawChart(dom, domAttr, domClass, domConstruct, domStyle, query, registry, request) {
  var chartContainer = query("div.display_chart")[0];
  var form = dom.byId("conditionTestChartGridCp");
  if (!chartContainer || !form) {
    return;
  }
  domConstruct.place(chartContainer, form, "after");
}
function drawChart() {
  require(["dojo/dom", "dojo/dom-attr", "dojo/dom-class", "dojo/dom-construct", "dojo/dom-style", "dojo/query", "dijit/form/Button", "dijit/registry", "dojo/request"],
  function(dom, domAttr, domClass, domConstruct, domStyle, query, Button, registry, request) {
    beforeDrawChart(dom, domAttr, domClass, domConstruct, domStyle, query, Button, registry, request);
    var chartContainer = query("div.display_chart")[0];
    hideChart();
    var charts = [];
    function showChart(grid) {
      var total = grid.get("total");
      var display = "none";
      if (total > 0) {
        display = "block";
      }
      domStyle.set(chartContainer, "display", display);
      if (display === "block") {
        for (var i=0,l=charts.length; i<l; i++) {
          charts[i].destroy();
        }
        charts = [];
        getChartData(function(data) {
          charts.push(createPowerConsumptionChart(data, dom, domAttr, domClass, domConstruct, domStyle, query, Button, registry, request, afterCreatePowerConsumptionChart));
          afterDrawAllChart(charts, dom, domAttr, domClass, domConstruct, domStyle, query, Button, registry, request);
        });
      }
    }
    function hideChart() {
      domStyle.set(chartContainer, "display", "none");
    }
    setTimeout(function() {
      var grid = window.getTestChartGridShowListGrid();
      if (grid) {
        grid.grid.on('dgrid-refresh-complete', function(e) {
          showChart(e.grid);
        });
      }
    }, 10);
  });
}
function getPowerConsumptionPowerConsumptionChartDataset(data) {
  return {
    yAxisID: "yAxis-left",
    type: "bar",
    label: getPowerConsumptionPowerConsumptionChartDatasetLabel(),
    data: getEntityListData(data.entity, 'powerConsumption'),
    backgroundColor: getPowerConsumptionPowerConsumptionChartDatasetBgColor(),
    borderColor: getPowerConsumptionPowerConsumptionChartDatasetBorderColor(),
    borderWidth: getChartBorderWidth(),
  };
}
function getPowerConsumptionPowerConsumptionChartDatasetLabel() {
  return "電力量";
}
function getPowerConsumptionTempChartDataset(data) {
  return {
    yAxisID: "yAxis-right",
    type: "line",
    label: getPowerConsumptionTempChartDatasetLabel(),
    data: getEntityListData(data.entity, 'temp'),
    backgroundColor: getPowerConsumptionTempChartDatasetBgColor(),
    borderColor: getPowerConsumptionTempChartDatasetBorderColor(),
    borderWidth: getChartBorderWidth(),
    fill: false,
  };
}
function getPowerConsumptionTempChartDatasetLabel() {
  return "気温";
}
function getPowerConsumptionTempChartDatasetColor() {
  return "orange";
}
function getPowerConsumptionTempChartDatasetBgColor() {
  return Chart.helpers.color(getPowerConsumptionTempChartDatasetColor()).alpha(getChartColorAlpha()).rgbString();
}
function getPowerConsumptionTempChartDatasetBorderColor() {
  return getPowerConsumptionTempChartDatasetColor();
}
function getPowerConsumptionChartDatasets(data) {
  var datasets = [];
  datasets.push(getPowerConsumptionPowerConsumptionChartDataset(data));
  datasets.push(getPowerConsumptionTempChartDataset(data));
  return datasets;
}
function getPowerConsumptionChartOptions(defaultChartOption) {
  var option = defaultChartOption;
  option.scales.xAxes[0].scaleLabel.labelString = "月";
  option.scales.yAxes[0].id = "yAxis-left";
  option.scales.yAxes[0].position = "left";
  option.scales.yAxes[0].scaleLabel.labelString = "電力量(千kWh)";
  option.scales.yAxes[0].ticks = {
    beginAtZero: true,
    maxTicksLimit: 6,
  };
  option.scales.yAxes[1] = {
    id: "yAxis-right",
    position: "right",
    scaleLabel: {
      display: true,
      labelString: "気温(℃)",
    },
    ticks: {
      beginAtZero: true,
      max: 35,
      min: 0,
    },
  };
  return option;
}
  • getPowerConsumptionChartDatasets(data)関数で、二種類のデータをひとつのdatasetにまとめています。
  • その他、軸のラベル指定などをおこなっています。

散布図

散布図は Designer の設定に加え、JavaScript による追加コードの記述が必要です。散布図を含んだ表示例を示します。

図8 折れ線グラフ、棒グラフ、散布図を表示した例

Designerの設定

Designer の設定方法を説明します。ここでは散布図のためにダミー項目 item1 を用意しました。

図9 散布図用の項目item1を用意する

item1項目に対して設定を行います。ここで「軸ラベル項目ID」は空白とします。散布図の場合、この部分は後述する JavaScript で指定します。

図10 チャートの設定

JavaScript

散布図のために次のコードを追加します。

/* 散布図のための表示データ設定 */
function getItem1Item1ChartDataset(data) {
  return {
    label: getItem1Item1ChartDatasetLabel(),
    data: getScatterData(data.entity, "temp", "powerConsumption"),
    backgroundColor: getItem1Item1ChartDatasetBgColor(),
    borderColor: getItem1Item1ChartDatasetBorderColor(),
    borderWidth: getChartBorderWidth(),
  };
}
/* グラフ出力カスタマイズ */
function getItem1ChartOptions(defaultChartOption) {
  var option = defaultChartOption;
//console.log("option: ", option);
  option.legend = {
    display: false,
  }
  option.scales.xAxes[0].scaleLabel.labelString = "月別平均気温(℃)";
  option.scales.yAxes[0].scaleLabel.labelString = "販売電力量(千kWh)";
  return option;
}
  • 散布図以外のグラフデータは、数値の配列を data 属性としてセットします。一方、散布図では次のようにx軸とy軸の値をオブジェクトとした配列をセットする必要があります。
    [{x: 1, y: 3}, {x: 3, y: 7}, ... ]
  • この対応を行うため、散布図を利用する場合は get<項目ID><項目ID>ChartDataset 関数を定義します。上のコードを参考にしてください。引数の data に対して、散布図の対象となる項目ID(ここでは "temp" と "powerConsumption") を指定します。項目IDの大文字と小文字は区別されますので、正確に指定してください。
  • これらの関数は、自動生成されたファイル showList<モデルID>.js の drawChart 関数を起点として、順に呼び出されています。カスタマイズ開発者はこの(自動生成された)ファイルも参考にするとよいでしょう。

ダウンロード

ここで紹介したサンプルをダウンロードしてお試しいただけます。R8.1.0 以上の Wagby でご利用ください。