テスト

テストテストテストf:id:edvakf:20150310012107p:plainつれづれなるままにひぐらしすずりにむかいてこころにうつりゆくよしなしごとをそこはかとなくかきつくればあやしうこそものぐるおしけれ

 

テスト

Remove all ads

LionにGrowthForecastインストールするメモ

perlbrew

perlbrewは

curl -kL http://install.perlbrew.pl | bash

でインストール。.zshrc に source ~/perl5/perlbrew/etc/bashrc とか書いて設定ファイルを読むようにしたいけど、どうもエラーが出る。

Use of uninitialized value in split at /loader/0x7ff683851a10/local/lib.pm line 8.

ぐぐってみると、一時的な問題みたい。

よくわからないけど環境変数PERL5LIBが設定されてないとダメみたい。

こんな感じで書いた。

  export PERL5LIB=$HOME/perl5/lib/perl5
  source $HOME/perl5/perlbrew/etc/bashrc

で、よくわからないけど

perlbrew install perl-5.16.1
perlbrew init
perlbrew install-cpanm

とかやってperlをインストール。

RRDtool

cpanmでAlien::RRDtoolというのを入れないとGrowthForecastが入らない。このAlien::RRDtoolを入れるのが面倒だった。

homebrewで

brew install rrdtool

とかやってRRDtoolを入れる。あと

brew install libxml2

もやった。必要だったのかよくわからない。(確かGrowthForecastのインストールでエラーが出てたから一緒に入れたはず)

で、

cpanm -v Alien::RRDtool

とやると、どうやらcairo系のpkg-configがうまく動いてないみたい。色々調べてみると、Macに付いてくるpkg-configを使うようにすればよさそう。

というわけで、こんな感じでやると、

export PKG_CONFIG_PATH=/usr/X11/lib/pkgconfig:/usr/local/lib/pkgconfig

Alien::RRDtoolがテストまでいくようになった。テストが失敗してるのがglibの何かでよくわからなかったので、とりあえずテストなしで入れた。

cpanm --notest -v Alien::RRDtool

GrowthForecast

ようやくGrowthForecastが入るようになった。

cpanm -n https://github.com/downloads/kazeburo/GrowthForecast/GrowthForecast-0.31.tar.gz

perlbrewのモジュールにパスが通ってなかったみたいなので、.zshrcに以下も追加しておいた。

  export PATH=$HOME/perl5/bin:$PATH

これで

growthforecast.pl

だけで動くようになった。


↑やっぱりテストがこけたままではダメだったみたい。グラフ描画が失敗する。

その後

自分でコンパイルした。といっても先人の知恵があったので意外と楽だった。

気をつけるのは、PKG_CONFIG_PATH と PATH をローカルインストールするディレクトリに適切に指定することぐらい。

あとは

cpanm ./Alien-RRDtool-0.03

でローカルからインストールできる。

SQLクエリをINでまとめるパターン

PDOを使う場合。

↓こういう関数があったとする。

    public static function getHogeFromId($id)
    {
        ...

        $sql = "SELECT `hoge` FROM some_table WHERE `id` = ?";

        $pState = $con->prepare($sql);

        $pState->execute([$id]);

        $hogeList = array();
        while ($data = $pState->fetch(PDO::FETCH_ASSOC)) {
            $hogeList[] = $data['hoge'];
        }

        return $hogeList;
    }

これがループの中で呼ばれていて、毎回DBにアクセスするので、INクエリでまとめたい。さらに、idが整数なのでPDOのbindValueを使いたい。

そういうときはこうする。

    public static function getHogeHashFromIdList($idList)
    {
        ...

        $length = count($idList);
        $placeholder = implode(',', array_fill(0, $length, '?'));

        $sql = "SELECT `id`,`hoge` FROM some_table WHERE `id`IN({$placeholder})";

        $pState = $con->prepare($sql);

        for ($i = 0; $i < $length; $i++) {
            $pState->bindValue($i + 1, $idList[$i], PDO::PARAM_INT);
        }
        $pState->execute();

        $hogeHash = array();
        while ($data = $pState->fetch(PDO::FETCH_ASSOC)) {
            $hogeHash[$data['id']] = $data['hoge'];
        }

        return $hogeHash;
    }

implode(',', array_fill(0, $length, '?'));はクエスチョンマークを指定した個数並べる。

bindValueは1から始まるらしい。

fetchとfetchAllはどうなんだろうなー。↓のRichardsって人の回答だとfetchのほうがいいみたいだけど。


$idListが空だった場合にDBにアクセスせずにそのまま空の連想配列を返すといい。

        if (!is_array($idList) || empty($idList)) {
            return array();
        }

マウスオーバーで全体をビョーンと表示するUI部品

elasticというクラス名をつけるだけでいいようにした。data-min-height="150px" とかも指定できる。

foo

bar

baz

foobar

quux

hoge

fuga

piyo

puni

hogehoge

foo

bar

baz

foobar

quux

hoge

fuga

piyo

puni

hogehoge

掴んで移動させられるUI部品

こんな感じ。

drag me!
$(function(){

var ie = navigator.userAgent.match(/MSIE ([\d.]+)/);
if (ie) ie = parseFloat(ie[1]);

var movable = $('#id20120418a').find('.movable');

movable.bind('mousedown', function(e) {
  // 右クリックでコンテクストメニューが出るときはmousedownは出てもmouseupが出ないので、左クリックでしかドラグ開始しないようにする
  if (ie && ie < 9) {
    // IE8までは左クリックが1
    if (e.button !== 1) return;
  } else {
    // それ以外は左クリックが0
    if (e.button !== 0) return;
  }

  // ここはその要素の表示箇所によって top/left だったり margin-top/margin-left だったりする
  var top = parseFloat(movable.css('top')) || 0;
  var left = parseFloat(movable.css('left')) || 0;
  var x0 = e.pageX, y0 = e.pageY;

  movable.addClass('dragging');

  // ドラグ中に下の要素をガーっと選択しちゃうことがある
  $(document.body).css({
    '-webkit-user-select': 'none',
    '-moz-user-select': 'none',
    '-ms-user-select': 'none',
    'user-select': 'none'
  });

  function onmousemove(e) {
    movable.css('top', top + e.pageY - y0);
    movable.css('left', left + e.pageX - x0);
  }

  function onmouseup(e) {
    onmousemove(e);
    movable.removeClass('dragging');

    $(document.body).css({
      '-webkit-user-select': '',
      '-moz-user-select': '',
      '-ms-user-select': '',
      'user-select': ''
    });    

    $(document).unbind('mousemove', onmousemove).unbind('mouseup', onmouseup);
  }

  // 常にmousemoveを監視するのは重いので、mousedownのタイミングでmousemoveをつける
  // windowで監視しちゃうとIE8でマウスイベントが取れないのでdocumentで監視
  $(document).bind('mousemove', onmousemove).bind('mouseup', onmouseup);
});

});

JSFiddleもペタリ

Processing.jsでWebGL

JavaScript Advent Calendar 2011 WebGL駅伝13日目の記事です。

Three.jsを使うと超簡単にWebGLを扱えますが、簡単という面ではProcessing.jsも負けていないのではないでしょうか。

WebGLの有効なブラウザでスタートボタンを押してください。


int n = 0;
int N = 3000;

float xs = new float[N];
float ys = new float[N];
float[] zs = new float[N];

void setup(){
  size(500, 500, P3D);

  float dt = 0.01;
  float x = 1.0;
  float y = 1.0;
  float z = 1.0;
  float p = 10.0;
  float r = 28.0;
  float b = 8.0/3.0;

  for (int i = 0; i < N; i++) {
    xs[i] = x;
    ys[i] = y;
    zs[i] = z;
    x += dt * p * (y - x);
    y += dt * (x * (r - z) - y);
    z += dt * (x * y - b * z);
  }
}

void draw(){
  // fill the viewport with white
  background(255);

  camera(0,0,0.001, 0,0,0, 0,1,0);
  ortho(-60,60, 60,-60, -60,60);

  rotateX(PI/12);
  rotateY(0.005 * n);

  // x-axis (red)
  stroke(255, 0, 0);
  line(0,0,0, 100,0,0);

  // y-axis (green)
  stroke(0, 255, 0);
  line(0,0,0, 0,100,0);

  // z-axis (blue)
  stroke(0, 0, 255);
  line(0,0,0, 0,0,100);


  noFill();
  stroke(128,128,0);

  beginShape();
  int last = min(n,N);
  for(int i = 0; i < last; i++){
    vertex(xs[i],ys[i],zs[i]);
  }
  endShape();


  noStroke();
  fill(255, 0, 255);
  translate(xs[i], ys[i], zs[i]);
  sphere(1);

  n++;
}

ただ、マトリックスという概念が難しいかと思います。cameraなどの関数でもマトリックスが変わりますし。


同じようなことをThree.jsでやったのがこちらのデモです。↓

記述量はちょっと増えてますが、さほど変わりません。一つ決定的に違うのが、カメラの動かし方です。Processing.jsで

  rotateX(PI/12);
  rotateY(0.005 * n);

とやると、これはカメラではなく世界を回してるのに対し、Three.jsはカメラを動かすしかなさそうです。

  camera.rotation.x = Math.PI / 12;
  camera.rotation.y = 0.005 * n;

↑こういうふうにしてるんですが、これだとProcessing.jsのほうとちょっと意味が変わってきちゃうのです。(カメラではなくて一つ一つのオブジェクトを世界に対して動かす方法もあるみたいですが)

どちらが扱いやすいかといえば…どちらも面倒ですね。Processing.jsはステートフル、Three.jsはステートレス、という大きな違いです。