読者です 読者をやめる 読者になる 読者になる

Chart JS V2.0 Bar Chart Pattern Sample

chartjs

目的

bar chart は標準で1色でのベタ塗りだが、 モノクロでも識別できるようにパターンを使って塗りつぶすようにする。

最終結果

f:id:katogiso-tech:20161010182453p:plain

解決方法

元々, backgroundColor にパターンを渡すとそれで塗りつぶせるようになっているので、 パターンをどこかで作って渡すだけで可能となる。

npm が使えて、使うことに抵抗がなければ

patternomaly

$ npm install patternomaly

でインストールすれば良い。

私は単純な事に npm を使うのがあまり好きではないので、 勉強がてら [patternomaly] を参考に少し javascript を記述してパターンを作成した。

主な修正点

修正点は

  1. パターン作成用の javascript を追加しbackgroundColorに指定し、
  2. borderWidth を 2 にした

こととなる。

パターン作成用 Javascript

少し長いですが、javascript を読めればそんなに大したことはやっていません。 そしてほとんど patternomaly と同じです。

主な違いは 2 点で、

  1. パターンの塗りつぶしが背景色に白をアルファブレンドしていたのを、白で塗りつぶしたこと
  2. pattern メソッド内部で shapeType で形を選択して、実行するあたり

です。 2 の方の違いは元のソースコードと見比べるとわかりますが、単純にしてしまいました。 Javascript は勉強中で、あまり正確に把握していないので問題があれば元のように書きなおしてください。

 function generateShape (size) {
     var canvas  = document.createElement('canvas');
     var context = canvas.getContext('2d');
     
     canvas.width  = size;
     canvas.height = size;
     
     return { canvas, context };
 }
 
 function square (width) {
     var shape  = generateShape(width);
     var height = width;
     
     shape.context.fillStyle = 'rgb(255, 255, 255)';
     shape.context.fillRect(0, 0, width / 2, height / 2);
     shape.context.fillRect(width / 2, height / 2, width / 2, height / 2);
     
     return shape.canvas;
 }

 function lineHorizontal (width) {
     var thickness = width / 4;
     var shape = generateShape(width);
     
     shape.context.fillStyle = 'rgb(255, 255, 255)';
     shape.context.fillRect(0, 0, width, thickness);
     shape.context.fillRect(0, thickness * 2, width, thickness);
     
     return shape.canvas;
 }

 function lineVertical (width) {
     let thickness = width / 4;
     let shape = generateShape(width);
     
     shape.context.fillStyle = 'rgb(255, 255, 255)';
     shape.context.fillRect(0, 0, thickness, width);
     shape.context.fillRect(thickness * 2, 0, thickness, width);
     
     return shape.canvas;
 }

 var shapes = {
     sq: square,
     lh: lineHorizontal,
     lv: lineVertical,
 };

 function pattern( bgColor, shape ){
     var patternCanvas  = document.createElement('canvas');
     var patternContext = patternCanvas.getContext('2d');
     var size           = 20;
     var outerSize      = size * 2;
     var shapeType      = shapes[shape];
     
     patternCanvas.width      = outerSize;
     patternCanvas.height     = outerSize;
     patternContext.fillStyle = bgColor;
     patternContext.fillRect(0, 0, patternCanvas.width, patternCanvas.height);

     pattern                  = patternContext.createPattern( shapeType(size, bgColor), 'repeat');
     patternContext.fillStyle = pattern;
     patternContext.fillRect(0, 0, outerSize, outerSize);

     patternFill           = patternContext.createPattern(patternCanvas, 'repeat');
     patternFill.shapeType = shapeType;

     return patternFill;
 }

backgroundColor への指定

必要なところを抜き出すと以下ように、

  1. backgroundColor に 上記の pattern メソッドを指定し、
  2. パターンだけだと境界が曖昧になるので、borderWidthで境界を表示する

だけです。

また、パターンは

  1. 四角
  2. 水平線
  3. 垂直線

を選択できるようになっていて、それぞれ

  1. pattern( '#color', 'sq')
  2. pattern( '#color', 'lh')
  3. pattern( '#color', 'lv')

と指定すると切り替わります。

 var myChart = new Chart(ctx, {
     type: 'bar',
     data: {
         labels: [ "Day1", "Day2", "Day3" ],
         datasets: [
             <...>
             {
                 <...>
                 backgroundColor: pattern( '#' + pal[5], 'lh' ),
                 borderWidth:     2,
             }
         ]
     },
})

全体

gist13805da2122499a00f0369fd714a6e43