ブログ

Armadillo-400シリーズでWebページ上で表とグラフを表示するサンプルデモ

at_kazutaka.bito
2015年8月22日 14時28分

Armadillo-400シリーズで下記のようにWebページ上で表とグラフを表示するサンプルデモを作ってみた。

備考)Webブラウザはcanvasに対応している必要がある。 当方の確認では、Firefox、IE、Chromeのいずれも上記の写真のように表示されることを確認した。

1.まず、表の要素となるデータを出力するスクリプト"rand_data"を作成。

rand_data

rm -f /tmp/log.txt
rm -f /home/www-data/log20.txt
touch /tmp/log.txt
touch /home/www-data/log20.txt
 
for i in `seq 1 1000`
do
echo -n `date +"%Y/%m/%d %p %I:%M:%S"` >> /tmp/log.txt
echo -n ',' >> /tmp/log.txt
echo -n $((RANDOM % 100)) >> /tmp/log.txt
echo -n ',' >> /tmp/log.txt
echo $((RANDOM % 100)) >> /tmp/log.txt
tail -n 20 /tmp/log.txt > /home/www-data/log20.txt
sleep 1
done

このスクリプトは、1秒毎に  日付,乱数,乱数 という形式で、 /tmp/log.txt に1000回まで出力する。 うち、最新の20行が /home/www-data/log20.txt に出力される。

2.Webページに表を作るプログラムをCGIで作成。

ArmadilloをCGIで制御するサンプル(LED点灯) のredled.cを改造して、下記のような"graph_demo.c"を作成する。 graph_demo.c

#include <stdio.h>
#include <stdlib.h>
#include <string.h> 
 
int main(void)
{
    FILE *fp;
    char str[25][30];
    int val1[25], val2[25];
    char str1[10], str2[10];
    int ret;
    int i, j;
    int row_max;
    int x1, y1;
    char str0[30];
    int str_copy_len = 0;
 
/**** log read: begin ****/
    for(i = 0; i < 25; i++)
        for(j = 0; j < 30; j++)
            str[i][j] = '\0';
 
    fp = fopen("/home/www-data/log20.txt", "rt");
 
    if( fp == NULL ){
        printf( "cannot open /home/www-data/log20.txt\n");
        return -1;
    }
 
    i = 0;
 
    while((ret = fscanf( fp, "%[^,],%d,%d", str[i], &val1[i], &val2[i])) != EOF
            && i < 20) {
        fgetc(fp);
        i++;
    }
 
    row_max = i - 1;
 
    fclose(fp);
/**** log read: end ****/
 
        puts(
        "Content-type: text/html\n"
        "\n"
        "<HTML>\n"
        "<HEAD>\n"
        "<TITLE> Armadillo-440 </TITLE>\n"
        "</HEAD>\n"
        "<BODY>\n"
    );
 
//system("echo 1 > /sys/class/leds/red/brightness");
//system("sleep 1"); 
//system("echo 0 > /sys/class/leds/red/brightness");
 
/**** table: begin ****/
    puts(
        "<TABLE border=\\"1\\" align=\\"left\\">\n"
    );
 
    puts(
        "<TR>\n"
        "<TD>時刻</TD>\n"
        "<TD>乱数1</TD>\n"
        "<TD>乱数2</TD>\n"
        "</TR>\n"
    );
 
    for(i = 0; i < row_max && i < 20; i++) {
        sprintf(str1, "%d", val1[i]);
        sprintf(str2, "%d", val2[i]);
        puts(
            "<TR>\n"
            "<TD>"
        );
        puts(str[i]);
        puts(
            "</TD>\n"
            "<TD>"
        );
        puts(str1);
        puts(
            "</TD>\n"
            "<TD>"
        );
        puts(str2);
        puts(
            "</TD>\n"
            "</TR>\n"
        );
    }
 
    puts(
        "</TABLE>\n"
    );
/**** table: end ****/
 
/**** graph: begin ****/
    puts("<canvas width=\\"480\\" height=\\"480\\" id=\\"sample\\" style=\\"background-color:yellow;\\">\n");
    puts("</canvas>\n");
 
    puts(
        "<script type=\\"text/javascript\\">\n"
        "var canvas = document.getElementById('sample');\n"
        "if (canvas.getContext) {\n"
        "    var context = canvas.getContext('2d');\n"
        "    canvas.style.position = \\"absolute\\";\n"
        "    canvas.style.left = \\"300px\\";\n"
        "    canvas.style.top = \\"10px\\";\n"
 
        "    context.beginPath();\n"
 
/**** graph: graph area ****/
        "    context.moveTo(40, 50);\n"
        "    context.lineTo(40, 250);\n"
        "    context.lineTo(440, 250);\n"
        "    context.lineTo(440, 50);\n"
        "    context.closePath();\n"
        "    context.fillStyle = \\"rgb(255, 255, 255)\\";\n"
        "    context.strokeStyle = \\"rgb(0, 0, 0)\\";\n"
        "    context.fill();\n"
        "    context.stroke();\n"
 
/**** graph: y-axis value ****/
        "    context.font = \\"bold 12px Century Gothic\\";\n"
        "    context.fillStyle = \\"rgb(0, 0, 0)\\";\n"
        "    context.textAlign = \\"right\\";\n"
 
        "    context.fillText(\\"100\\", 35, 50);\n"
        "    context.fillText(\\"50\\", 35, 150);\n"
        "    context.fillText(\\"0\\", 35, 250);\n"
 
        "    context.textAlign = \\"left\\";\n"
        "    context.fillText(\\"100\\", 445, 50);\n"
        "    context.fillText(\\"50\\", 445, 150);\n"
        "    context.fillText(\\"0\\", 445, 250);\n"
        "    context.save();\n"
    );
 
/**** graph: x-axis value ****/
    puts(
        "    context.textAlign = \\"right\\";\n"
        "    context.rotate(270/180*Math.PI);\n"
    );
 
    for(i = 0; i < row_max && i < 20; i++) {
        y1 = 440 - (row_max - i) * 20;
        x1 = -250 - 5;
 
        sprintf(str1, "%d", x1);
        sprintf(str2, "%d", y1);
 
        for(j = 0; j < 30; j++) str0[j] = '\0';
 
        if(strlen(str[i]) > 25) str_copy_len = 25;
        else str_copy_len = strlen(str[i]);
 
        str0[0] = '\\"';
        for(j = 0; j < str_copy_len; j++) str0[j + 1] = str[i][j];
        str0[str_copy_len + 1] = '\\"';
 
        puts("context.fillText(");
        puts(str0);
        puts(", ");
        puts(str1);
        puts(", ");
        puts(str2);
        puts(");\n");
    }
 
/**** graph: line graph ****/
    puts(
        "    context.restore();\n"
        "    context.strokeStyle = 'rgb(0, 0, 255)';\n"
    );
 
    for(i = 0; i < row_max && i < 20; i++) {
        x1 = 440 - (row_max - i) * 20;
        y1 = 250 - (val1[i] * 2);
 
        sprintf(str1, "%d", x1);
        sprintf(str2, "%d", y1);
 
        if(i == 0) {
            puts("context.moveTo(");
            puts(str1);
            puts(", ");
            puts(str2);
            puts(");\n");
        }
        else {
            puts("context.lineTo(");
            puts(str1);
            puts(", ");
            puts(str2);
            puts(");\n");
        }
    }
 
    puts(
        "    context.stroke();\n"
        "}\n"
    );
 
    puts("</script>\n");
/**** graph: end ****/
 
    puts(
        "</BODY>\n"
        "</HTML>"
    );
 
    return 0;
}

備考) /**** log read: begin ****/ /**** log read: end ****/ で囲んだ箇所で、/home/www-data/log20.txtの内容を読み込んでいる。

/**** table: begin ****/ /**** table: end ****/ で囲んだ箇所で、表に表示している。

/**** graph: begin ****/ /**** graph: end ****/ で囲んだ箇所で、グラフに表示している。

/**** graph: graph area ****/ グラフの表示エリアの描画。

/**** graph: y-axis value ****/ Y軸(乱数)の目盛の描画。

/**** graph: x-axis value ****/ X軸(日付)の描画。

/**** graph: line graph ****/ 乱数1の変化を折れ線で表示。

3.ビルドをかける(実行ファイルは、graph_demo.cgiとする)

arm-linux-gnueabi-gcc graph_demo.c -o graph_demo.cgi

4.上記1,2のファイル"rand_data"、"graph_demo.cgi"をArmadilloに転送し、/home/www-dataに置く

5.実行権限をつける

[armadillo ~]# chmod +x /home/www-data/rand_data
[armadillo ~]# chmod +x /home/www-data/graph_demo.cgi

6.PCのWebブラウザで確認する。

まず、PCとArmadilloをネットワーク経由で接続し、ArmadilloのIPアドレスを確認する。

Armadillo上で

[armadillo ~]# /home/www-data/rand_data &

を実行後、PCのWebブラウザで [ArmadilloのIPアドレス]/graph_demo.cgi にアクセスすると、/home/www-data/log20.txtの内容が、Webブラウザで表とグラフになって見える。