サポート > Wagby Developer Network(R8) > 画面のカスタマイズ > 一覧表示グラフのカスタマイズ

一覧表示画面にグラフを表示する機能のカスタマイズ方法を説明します。

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

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

グラフ出力のカスタマイズは、MyShowList<モデルID>.js に行います。カスタマイズしたファイルを customize/webapp/<モデル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 による追加コードの記述が必要です。散布図を含んだ表示例を示します。

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

Designerの設定

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

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

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

図5 チャートの設定

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 でご利用ください。

Wagby Developer Day 2018