見出し画像

【GAS】直近2週間の支出がリンク付き棒グラフで自動表示される家計簿アプリ・・・クリックすると日別の帳票が開いて便利!(解説編2)WEBページに座標を指定してリンク文字を埋め込むには

GoogleスプレッドシートをうまくGoogle Apps Script(GAS)と組み合わせると、WEBページを通じてシートへ読み書きできる、簡易なWEBアプリとして利用することが可能です

GASで作るWEBアプリのページは、「テンプレート」と呼ばれるモジュールにHTMLコードを記述して作成しますが、文字ベースのWEB画面だけでなく、グラフィカルなページにすることもできます。

そこで、簡単なグラフィックを活用したWEBアプリを、GASで作った一例として、集計グラフ付きの家計簿アプリを作ってみました。以下の記事で機能をご紹介しています。


長い名前ですが「直近2週間グラフ目次付き 家計簿アプリ」と題することにしました。

このアプリは、アクセスすると、目次代わりの直近2週間の支出を日毎の棒グラフで示したページ表れます。この棒グラフの下にはリンク文字が埋め込まれています。

このリンク文字をクリックすると、その日の明細が日別の帳票で判る様になっています。


この帳簿から支出項目を追加したり編集が可能で、編集結果はスプレッドシートに自動挿入される日別のシートに反映されます。

Googleスプレッドシートを直接編集するのと変わらなように見えますが、WEBページを介するとアクセスが最小限のため、通信時以外の操作がキビキビしていて快適です。

また、WEBページには必要な情報だけがディスプレイに表示されるので、スプレッドシートを直接操作するよりも集中して操作できます。

WEBページを介して、Googleスプレッドシートとインタラクティブなデータ編集ができるWEBアプリの作り方については、以下にて簡単に解説しています。宜しければどうぞ。


さて、テンプレートで作るWEBページには、テキストばかりでなく、冒頭の棒グラフの様に、図形を表示することもできます。

色々な方法がありますが、ライブラリなどを使わない方法を記事ではご紹介しており、先回に続いてHTMLとJavaScriptによる図形表示について解説します。

先回記事の振り返り・・・GASのテンプレートを使った、図形のあるWEBページを作り方



GASに備わっているテンプレートは、記述するHTMLコードを工夫することで、文字情報だけでなく、以下の様な図形を含んだWEBページも表現可能であることを、先回の記事でご説明しました。

記事ではまず、棒グラフの素になっている長方形の描き方をご説明しました。


先回の記事で解説した事を少し振り返ります。

図形を表現するには、テンプレート内に以下の様に、領域を示す<DIV>要素をおいて、その中に<CANVAS>要素を記述します。

<div  id=”描画エリア” >
 <canvas id=”キャンバス要素” width= 巾 height=高さ></canvas>
</div>

キャンバス要素の中に描画する図形は、JavaScriptの中の関数のコードとして記述していきます。

コードの記述は次の様にします。

まず、キャンバス要素を取得し、次いで2D図形の為のペン(2Dコンテキスト)をgetContext('2d')で取得します。コードは以下の様になります。

  var キャンバス = document.getElementById('キャンバス要素');
   
  //2D描画要素を描画するためのハンドルを取得
  var 2Dペン = キャンバス.getContext('2d');

  //2D描画要素を描画するためのペンを初期化
  2Dペン.save();  // 定型処理


次に、2Dペン(2Dコンテキスト)を走らせます(パスを作ります)。

beginPath()で描き始め、stroke()で書き終わりますが、その間に図形や塗りつぶしに関するコードを以下の様に記述していきます。

//長方形で棒グラフを描画する
  2Dペン.beginPath();
  2Dペン.rect(X座標、Y座標、巾、高さ);

  //長方形を塗りつぶし
  2Dペン.fillStyle = 'ライトグリーン';
  2Dペン.fill();

  2Dペン.stroke();

コード中の変数名は、判りやすくするため仮に日本語にしていますが、実際は英数字でコードします。

以上、簡単な振り返りでした。図形については、概ねこうしたコードの積み重ねで記述していきます。

次に文字についてご説明します。文字もこの様にキャンバス要素に描いていくべきでしょうか。


ちょっキャンバス要素に描いた文字は、単なる「絵」となってしまう・・・リンク属性など文字としての機能を保ったまま埋め込むには?


キャンバス要素に書かれた文字は単なるピクチャ画像



キャンバス要素には、図形だけでなく、文字を表示させる仕掛けも用意されており、上記のコードと似たコードで文字を表現する事が可能です。

ところが、キャンバス要素に書かれたテキストは、単なるピクチャ画像になってしまいますので、リンク機能などを持たせることは出来ません。

今回のWEBアプリでは、リンク文字を目次として使うことを狙っているので、キャンバスに文字を表現する方法は残念ながら使えません。

appendChild()関数を使えば、リンク機能などを保ったままの文字を、指定の座標に表示可能


文字を各種の属性を保ったまま、特定の位置に表示させる方法はないのでしょうか。

文字は通常、そのまま表記するだけで、WEBページに表示できますが、この方法では文字を指定の座標位置で表示させることは出来ません。

厳密に座標を指定して表示させるには、WEBページの要素に子要素を追加するappendChild( )という関数を利用し、追加する子要素に座標を指定します。そしてキャンバスの親要素となっているDIV要素に対し、座標を指定してテキスト要素を追加する様にします。

具体的にどう使うのか、以下にご説明します。

テキストを狙った座標に配置するおよその手順

DIV要素の属性設定

まず、キャンバスの親要素となっているDIV要素にID名の他、座標に関するいくつかの属性をHTMLコードで指定しておきます。具体的には以下の様に記述します。

<body>

  <!--<DIV>要素内に<CNVAS>要素を設定-->

  <div id="親エリア" style="position:relative;white-space: nowrap;margin: 0;padding:0;">
    <canvas id="キャンバス" width= 巾 height= 高さ ></canvas>
  </div>

</body>


ポイントはスタイル属性です。
style="position:relative; white-space: nowrap; margin: 0; padding:0;

position: relative 座標は現在位置を基点とする
white-space: nowrap 文字は折り返さない
margin: 0 外側余白なし
padding:0; 内側余白なし

上記の指定により、キャンバス要素で同じ要領で親のDIV要素にも座標系が設定されます。また、文字を配置した際に意図せず折り返しによってレイアウトが乱れてしまうことを防げます。

キャンバス図形との微妙なズレは今のところ止むなし

ただし、DIV要素とキャンバス要素で本来は同じ座標を共有するはずなのですが、表示デバイスによっては微妙に両者の位置はずれてしまいます。以下で文字の位置が棒グラフの長方形と中心が微妙にずれているのが判りますか。

残念ながらどのデバイスでも丁度よく合わせる方法を筆者が見つけておらず、この点は目をつぶって頂ければと思います。

あまり大きなキャンバスを使わないのが1つの対処方法です。

scriptセクション内での記述

続いて、scriptセクション内の関数でコードを実装していきます。図形描画と同じ関数内に記述します。

まずは、さきほどの親DIV要素を取得します。

<Script type="text/javascript">  

・・・・
function 関数(){
・・・・

 //描画する<CANVAS>要素を含んだDIV要素を取得
  var 親エリア= document.getElementById("親エリア");


・・・・
</Script>  

続いて文字要素を生成させ、これを子要素として追加します。

まず文字要素(SPAN要素)の生成は以下です。
 var テキスト要素= createElement("span")

次いでappendChild()関数を使って、これを子要素としてDIV要素にぶら下げます。
 親エリア.appendChild(テキスト要素);

コード全体を下に示します。


//親エリアの中にテキスト要素を追加する
   
    //テキスト要素(<SPAN>要素)を生成する
      var テキスト要素= document.createElement("span");
      
      //生成結果を<CANVAS>を配置している<DIV>内に子要素として追加する 
      親エリア.appendChild(テキスト要素);

この子要素に座標などの属性を付与します。以下のコードを見てください。

    //テキスト要素の中に表示文字(テキスト・ノード)を追加する

      //テキスト要素の座標や属性を設定する
      テキスト要素.style.position   = "absolute"; 
      テキスト要素.style.left       = X座標+"px";
      テキスト要素.style.top        = Y座標+"px";
      テキスト要素.style.fontFamily = "Arial"; 
      テキスト要素.style.fontSize   = "12px";

      //「テキスト要素」内に文字データを流し込み子要素として実体化させる
      テキスト要素.appendChild(document.createTextNode(表示文字));

表示座標は、以下の3行で記述しています。

テキスト要素.style.position = "absolute";
テキスト要素.style.left = X座標+"px";
テキスト要素.style.top = Y座標+"px";

座標系として絶対座標(親の座標系)を指定し、座標値はpx付きの文字で設定します。

最後のコードで、再び.appendChild()を用いて、今度は文字そのものを追加します。「文字そのもの」は、createTextNode(表示文字)という記述をして生成させます。

上記のコードで、長方形の上側に集計値を表示させることが可能です。

リンク文字を表示させる



次いで、各日の帳票を開くためのリンク文字を配置します。文字の場合とほぼ同じです。

最初に要素の生成を以下の様に記述します。リンク文字は<A>要素とすればOKです。

//日別の帳票へのリンクをリンク要素として配置する  
  
     //リンク要素(<A>要素)を生成する
      var リンク文字= document.createElement("A");

      
      //生成結果を<CANVAS>を配置している<DIV>内に子要素として追加する
      親エリア.appendChild(リンク文字);
    

後は全く同様なので割愛しますが、2点属性指定で異なるところがあります。

この部分のコードは以下です。

    //リンク要素の属性を設定し、子として追加する

      //リンク要素の要素名とリンクURLを設定する
      リンク文字.href             = リンク先URL;

      //クラス指定によりスタイルを設定する
      if(表示文字の最後の1文字=="●"){
        リンク文字.className        = "myClass_Blink";      
      }else{
        リンク文字.className        = "myClass_Nowrap";
      }

以下はリンクを張るはめの処理です。
リンク文字.href = リンク先URL;

以下は、当日であれば、点滅させるための処理です。
リンク文字.className = "myClass_Blink";
または
リンク文字.className = "myClass__Nowrap";

点滅はクラス属性で対処しますが、キャンバスに描いた文字ではこうした動的な属性を与えることはできません。

次の記事では、こうした図形の座標値などをどう管理するかをご紹介します。プログラムで対応せず、スプレッドシートの表計算機能を利用しています。

前の記事はこちら

次の記事はこちら

この記事が気に入ったらサポートをしてみませんか?