Chart.js 図全体背景色、グラフエリア背景色、イメージダウンロードの問題を解決する

Chart.js を使用して canvas に描画するグラフは、canvas の中のグラフエリアだけは、
以下 stackoverflow の返答にあるように、描画前に実行する関数プラグインを書き
option の chartArea で backgroundColor を指定すれば、グラフエリアだけは背景色が適用できる。
javascript - Chart area background color chartjs - Stack Overflow

Chart.js プラグインへの登録:beforeDraw (描画前に実行する関数)を記述して

Chart.pluginService.register({
    beforeDraw: function(c){
        if (c.config.options.chartArea && c.config.options.chartArea.backgroundColor) {
            var ctx = c.chart.ctx;
            var chartArea = c.chartArea;
            ctx.save();
            ctx.fillStyle = c.config.options.chartArea.backgroundColor;
            ctx.fillRect(chartArea.left, chartArea.top, chartArea.right - chartArea.left, chartArea.bottom - chartArea.top);
            ctx.restore();
        }
    }
});

この後で、canvas にグラフを描画する処理で指定する option の中で、chartArea に backgroundColor を指定する。

var options = {
    responsive: true,
    title:{ display:true,
        text:'Chart sample'
    },
    // グラフエリアのオプション
    chartArea: {
        backgroundColor: 'rgba(230, 238, 255, 0.6)'
    },
    scales: {
        xAxes: [{ display: true,
            scaleLabel: { display: true, labelString: 'Days' }
        }],
        yAxes: [{ display: true,
            scaleLabel: { display: true, labelString: 'Value' },
            ticks: { min: 0, max: 100, stepSize: 20 }
        }]
    },
};

var ctx = document.getElementById("myChart").getContext('2d');
var myChart = new Chart(ctx, {
    type: 'line',
    data: graph,
    options: options
});

canvas 全体の背景色を指定することをしたい場合。。
Chart.js はbackgrondColor 指定して塗りつぶす fill() fillRectangle() メソッドも組み込まれていないため、
以下のように、csnvas の context への CSS で指定することになる。

var canvas = document.getElementById("myChart");
canvas.style.backgroundColor = "rgba(255, 255, 220, 1)";
var ctx = canvas.getContext('2d');

var myChart = new Chart(ctx, {
    type: 'line',
    data: graph,
    options: options
});

しかしこれでは、このcanvas画像をダウンロードすれば判るが、
グラフエリアの外側の背景色は透過されたままだ。

外側の背景色を画像への変換(toDataURL()の使用)でも適用させるためには、
この方法ではなくて、上に書いた beforeDraw 関数プラグイン登録の記述で、書くべきだ。
背景色とグラフエリアの両方に各々の背景色を
指定しダウンロード画像にも適用させるには、、

Chart.pluginService.register({
    beforeDraw: function(c){
        if (c.config.options.chartArea && c.config.options.chartArea.backgroundColor) {
            var ctx = c.chart.ctx;
            var chartArea = c.chartArea;
            ctx.fillStyle = "rgba(153, 255, 221, 1)";           // 外側背景色の指定
            ctx.fillRect(0, 0, c.chart.width, c.chart.height);  // 外側背景色描画
            ctx.save();
            ctx.fillStyle = c.config.options.chartArea.backgroundColor;
            ctx.fillRect(chartArea.left, chartArea.top, chartArea.right - chartArea.left, chartArea.bottom - chartArea.top);
            ctx.restore();
        }
    }
});

背景色だけを指定する場合は、

Chart.plugins.register({
    beforeDraw: function(c){
        var ctx = c.chart.ctx;
        ctx.fillStyle = "rgba(153, 255, 221, 1)";
        ctx.fillRect(0, 0, c.chart.width, c.chart.height);
    }
});

ということになる。
すると、canvas から getContext して、new Chart の記述はマニュアルどおり

var canvas = document.getElementById("myChart");
var ctx = canvas.getContext('2d');
var myChart = new Chart(ctx, {
    type: 'line',
    data: graph,
    options: options
});

canvas 画像ダウンロードは、chrome では以下の方法ができる。IEではダメた。

例)id="createImg" のボタンclick で。

$('#createImg').click(function(){
    var png = document.getElementById('myChart').toDataURL();
    var a = document.createElement('a');
    var e = document.createEvent('MouseEvent');
    // 保存するファイル名
    a.download = "sample.png";
    a.href = png;
    e.initEvent("click", true, true, window, 1, 0, 0, 0, 0, false, false, false, false, 0, null);
    a.dispatchEvent(e);
});

Chart.js can't acquire context from the given item

www.chartjs.orgChart.js を使用しようとしたら、
Failed to create chart: can't acquire context from the given item 
描画の為の の後で、スクリプトを書かないとならない。

<script src="Chart.bundle.js"></script>
</head>
<body>
<canvas id="myChart"></canvas>
<script type="text/javascript">
     // ここで、canvas id="myChart" に対する Chart.js の処理を書く。
var ctx = document.getElementById("myChart").getContext('2d');
var myChart = new Chart(ctx, {
    type: 'bar',
    data: {
   :
   :
</script>

必要な Chart.bundle.js は、https://github.com/chartjs から、Chart.js を辿って、
https://github.com/chartjs/Chart.js/releases から入手する。

GitHub ドキュメントのリンクの書き方メモ

GitHub ドキュメントのリンクの書き方

https://help.github.com/articles/basic-writing-and-formatting-syntax/#links

[ ] でリンク文字列を書いて続けて ( ) でURLパスを書く。
GitHub上のドキュメントなら、相対パスで書く

[GitHub help](https://help.github.com/)

[detail](/doc/description.md)

Wicket scheduleRequestHandlerAfterCurrent の実行を簡潔に

Wicket の RequestCycle の scheduleRequestHandlerAfterCurrent で IRequestHandler を指定して
応答としてファイル出力する方法は標準として昔から存在した。

以下のように WebPage で書いていたものだ。

@Inject Logic logic;

getRequestCycle().scheduleRequestHandlerAfterCurrent(new IRequestHandler(){
   @Override
      public void respond(IRequestCycle cycle){
         try(OutputStream out = cycle.getResponse().getOutputStream()){
            logic.printFile(out);
            out.flush();
         }catch(Exception e){
            throw new RuntimeException(e);
         }
      }
   }
);

すでに Wicket 8 では、IRequestHandler も @FunctionalInterface が付いており、1つのメソッドと
default メソッド1つしかないので、、

getRequestCycle().scheduleRequestHandlerAfterCurrent(cycle->{
   try(OutputStream out = cycle.getResponse().getOutputStream()){
      logic.printFile(out);
      out.flush();
   }catch(Exception e){
      throw new RuntimeException(e);
   }
});

で書ける。

応答としてファイル出力するメソッドが内部で例外捕捉するようにすれば、
例えば、メソッド名=printFileNoexception と適当に銘打って、、

getRequestCycle().scheduleRequestHandlerAfterCurrent(
  c->logic.printFileNoexception(c.getResponse().getOutputStream())
);

完全ではないがほぼ、普遍的なコード1行で書けるようになる。

Jasperreprts でサブレポートを使用する時のコレクションのテンプレート設定

Jasperreports でサブレポートを出力するときの jrxml を準備するのに、いつもデータを渡すコレクションのラップを
テンプレートで設定を書き込む方法を忘れて、後からどうやるんだっけと悩んでしまうので、手順メモです。
Jaspersoft Studio 上でテンプレート jrxml の先頭を Outline タブで選択します。
f:id:posturan:20180113202758j:plain
選択したら、プロパティで、import のところを入力します。
f:id:posturan:20180113202909j:plain

すると以下のようにテンプレート jrxml が Javaとしてインポートするクラス、パッケージ指定を設定するものが
出てきます。
f:id:posturan:20180113203045j:plain
[Add Class] をクリックして、コレクション渡しの目的の net.sf.jasperreports.engine.data.JRBeanCollectionDataSource
を選択します。
f:id:posturan:20180113203230j:plain
設定します。
f:id:posturan:20180113203304j:plain
この設定をしておくことで、sabreport の設定は、以下のように、JRBeanCollectionDataSource を 簡潔に new 演算子指定できます。
f:id:posturan:20180113203648j:plain

この import 設定をしなければ、new JRBeanCollectionDataSource( ) の記述はコンパイルエラーになり、
 import 設定をしなければ、 new net.sf.jasperreports.engine.data.JRBeanCollectionDataSource( ) と
書かなければなりません。

Javaのコードは気持ち悪いダサいコードですが、、

public class FareDatasource implements Serializable{
   public Collection<FareItem> farereports;

   public FareDatasource(Collection<FareItem> farereports){
      this.farereports = farereports;
   }
   public Collection<FareItem> getFarereports(){
      return farereports;
   }
}

Collection<FareDatasource> farereports = new ArrayList<>();
FareDatasource datasource = new FareDatasource(list);
farereports.add(datasource);

JRBeanCollectionDataSource dataSource = new JRBeanCollectionDataSource(farereports);

JasperPrint jasperPrint = JasperFillManager.fillReport(inputStream, parameters, dataSource);
inputStream.close();

こんな風になります。

Jasperreports NumberFormat は、cannot be resolved to a type

Jasperreports で、java.text.format.NumberFormat で、金額 format 出力しようと

<textFieldExpression>
<![CDATA[java.text.format.NumberFormat.getCurrencyInstance().format($P{total_money})]]>
</textFieldExpression>

と書いたら、JRException 発生
java.text.format.NumberFormat cannot be resolved to a type
になってしまう。

DecimalFormatを使わざる得ない、

<textFieldExpression>
<![CDATA[new DecimalFormat("\\###,###,###").format($P{total_money})]]>
</textFieldExpression>

Jasperreports でLocalDate をフォーマット出力

1年近く前、Jasperreports 5.6.0 で、Java8 LocalDate を出力するのに、Eclipseコンパイラを使う方法を書いたが、
  Jasperreports 5.6.0 で Java8 LocalDate を出力するには - Oboe吹きプログラマの黙示録
もう、Jasperreports 6.5.1 では、Jaspersoft Studio も Java8 対応でその必要はなく
以下のように TextField 出力の expression は、jrxml で以下のように書く。

<textFieldExpression>
<![CDATA[$F{access_date}.format(java.time.format.DateTimeFormatter.ofPattern("yyyy年 M月d日"))]]>
</textFieldExpression>