投稿日 2009年8月13日 木曜日 カテゴリ javascript 投稿者 morimotoコメント(0) » 

morimotoです。

前回の「jQueryでシンプルにExpanderを作る」の続編です。

前回作成したものを使ってみて思ったこと、「うーん、いまいち!」

ということで改良してみました。

(function($){
  var options = {
    initCollapse: true,
    bindEvent: 'click',
    collapsedClass: 'collapsed'
  };

  $.fn.simpleExpander = function(target, opts){
    if (opts) { $.extend(options, opts); }
    $(this).addClass('simpleExpander');
    if (options.initCollapse)
        $(this).addClass(options.collapsedClass);
    return initializeExpander(this, target, options);
  };
  function initializeExpander(trigger, target, options) {
    toggleTarget(trigger, target, options.collapsedClass);
    $(trigger).bind(options.bindEvent, function(){
      $(this).toggleClass(options.collapsedClass);
      toggleTarget(trigger, target, options.collapsedClass);
    });
    return $(trigger);
  }
  function toggleTarget(trigger, target, collapsedClass) {
    if(target) 
      $(trigger).hasClass(collapsedClass) ? 
          $(target).hide() : $(target).show();
  }

})(jQuery);

使い方

expand/collapseする対象をjQueryオブジェクトで指定する

Demo

クリックすると…

朝食にバナナボートを食べました。冗談です。
Code
<p id="expander-test-1"  
style="border:1px solid #666;background-color: #FEE">test 1</p>
<div id="test-1">
  <span>朝食にバナナ<b>ボート</b>を食べました。<b>冗談です。</b></span>
</div>
<script type="text/javascript"><!--
$('#expander-test-1').simpleExpander($('#test-1').find('b'));
// --></script>

Optionを入れてみる

Demo

マウスを乗せると…

Expand対象Expand対象外もselector次第です。
Code
<p id="expander-test-2" 
style="border:1px solid #666;background-color: #FEE">マウスを乗せると...</p>
<div id="test-2">
  <span><b>Expand対象</b>と<b>Expand対象外</b>もselector次第です。</span>
</div>
<script type="text/javascript"><!--
$('#expander-test-2').simpleExpander($('#test-2').find('span b:first'), 
{initCollapse: false, bindEvent: 'mouseover'});
// --></script>

以上、morimotoでした。。。

投稿日 2009年8月3日 月曜日 カテゴリ javascript 投稿者 morimotoコメント(0) » 

morimotoです。

「もっと画面をすっきりとしたいな・・・」と思う時に良く使われるのが、閉じたり開いたりするExpand機能かと思います。 そのExpandをするために毎回javascriptを書くのは面倒くさい。

そこで簡単にExpandさせれるようにjQueryでPluginを書いてみました。 (完成しているとはいえませんが。。。)

(function($){
  $.fn.simpleExpander = function(options){
    var target = options.target || undefined;
    var trigger = options.trigger || 'click';
    var collapsedClass = options.collapsedClass || 'collapsed';
    if (typeof(options) == 'string') target = options;
    if (target) {
      $(this).addClass('expander');
      targetToggle(this, target, collapsedClass);
      $(this).bind(trigger, function(){
        $(this).toggleClass(collapsedClass);
        targetToggle(this, target, collapsedClass);
      });
    }
    return this;
  };

  function targetToggle(el, target, collapsedClass) {
    if ($(el).hasClass(collapsedClass)) { 
      $(target).hide(); 
    } else { 
      $(target).show(); 
    }
  }
})(jQuery);

使い方


<button id="trigger1">button 1</button>
<button id="trigger2">button 2</button>

<div class="target apple">window 1</div>
<div class="target banana">window 2</div>
<div class="target grape">window 3</div>

<script type="text/javascript">
$('#trigger1').simpleExpander('div.target');
$('#trigger2').simpleExpander('div.target.banana');
$('div.apple').simpleExpander({target: 'div.target.grape', trigger: 'mouseover'});
</script>

demo

target apple
target banana
target grape

ボタン1はdiv全てがtoggleします。 ボタン2は真ん中のdivのみtoggleします。 一番上のdivをマウスオーバーすると一番下のdivがtoggleします。

もっとシンプルに作れるのかもしれないですが、こんなのもあるんだなという程度で見ていただくとありがたいです。

以上、morimotoでした。。。

投稿日 2009年7月30日 木曜日 カテゴリ javascript 投稿者 matsushitaコメント(0) » 

こんにちは。松下です。

開発版のサンプルページで既に紹介されているものもありますが、flotで描画したグラフにイベント処理を追加する方法を紹介します。

flotには、あらかじめマウスのホバーやクリック時のカスタムイベントが定義されており、このカスタムイベントに対してコールバック関数を紐付ければ、独自のイベントを追加することができます。

クリックイベントを追加する

flotでは、”plotclick”というグラフのポイントをクリックした時のカスタムイベントが定義されているので、以下のようなコードを書けば、ポインンクリック時の処理が追加することができます。

$("placeholder").bind("plotclick", function(event, pos, item) {
--略--
});

使用する上での前提条件は、plot描画時のgridオプションのclickableを有効にすること、seriesオプションのpointsを有効にすることです。

option = {
    series: {points:  {show: true}},
    grid: {clickable: true},
    --略--
};

以下に、グラフで描画したポイントで際に、ポイントをハイライトする処理を例示します。

$("#placeholder").bind("plotclick", function (event, pos, item) {
    if (item) {
        plot.highlight(item.series, item.datapoint);
    }
});

クリックすると以下のようにポイントがハイライトします。

before

after

windowリサイズにグラフをリロードする

単純に再プロットするなら以下のとおりで、windowリサイズ時に通常と同じように描画する処理をバインドするだけです。

$(window).resize(function() {
    var plot = $.plot($("#placeholder"), datalist, options);
});

なぜ、こんな処理を行うかというと、グラフを描画する領域のサイズを固定しない場合、グラフのラベルや判例がずれてしまうからです。以下の画面では、判例を左上に設定したにも関わらず、windowサイズを小さくしたことで判例が右側にずれています。

画面が崩れる

この問題をリサイズ時に描画処理を行うことで問題を解決できます。

しかしながら、この処理には少し不満に思いました。理由は、再描画を処理的にはcanvasオブジェクトを再作成してデータを描画してといった処理を一からやり直すことになるので、windowサイズが変更されるたびに行う処理として少しコストが高い処理だと思ったからです。

そこで、初期化処理を行うことなくリサイズ処理だけ行うことはできないか、調査してみました。 が、結論からいうとコードの作り上、どうしようもないことがわかりました。 グラフの描画処理は

var plot = $.plot($("#placeholder"), datalist, options);

のように行いますが、plot関数実行後に内部で生成したPlotクラスが返却されます。 これを使って、以下のように実行できないか試してみましたが、グラフのリサイズは行われない模様。

    var plot = $.plot($("#placeholder"), datalist, options);
    plot.setupGrid();
    plot.draw();

でさらに調べてみると、初期化処理において、canvasWidth、canvasHeightという内部変数を設定しており、グラフの描画処理はこれらの変数に依存していることが分かりました。これらの変数をwindowリサイズ時に再設定すれば良いのですが、これらの変数を外部から書き換える手段、及びタイミングが存在しません。

で苦肉の策ですが、Plotクラスの内部関数であるconstructCanvasでcanvasWidth、canvasHeightを設定する処理を行っているので、これを外部公開するようにflotのコードを修正した上で、以下のコードを実行。

    var plot = $.plot($("#placeholder"), datalist, options);
    plot.constructCanvas();
    plot.setupGrid();
    plot.draw();

これはうまく行きました。reloadとかメソッドがあればいいんですが、今のところこの方法と同様にflot自体に手を加える方法しかないようです。

自分がflotを使っていて思ったのが、今回みたいにイベントを追加したりする場合に、今のflotがユーザに公開されている情報(メソッドやフィールド)が必要不十分であること。highlightメソッド、unhighlightメソッドはあるのに、外部からはどこがハイライトされているのか、ハイライトしていないのか分からないとか。 開発版なのでしょうがないのかもしれませんが、グラフライブラリとしては良いものだと思っているので、今後の改善に期待したいと思ってます。

記事を読んでくださった方で、他になにか方法があれば教えてください。

投稿日 2009年7月15日 水曜日 カテゴリ javascript 投稿者 matsushitaComments Off 

Flotってご存知ですか

こんにちは。松下です。

みなさんはFlotというjqueryベースのjavascriptグラフ描画ライブラリををご存知でしょうか?

データ形式はjsonで行うことができ、flashベースのOpenFlashChartのように複雑なことはできないですが、きれいなグラフを簡単に描画することができます。

データのやり取りがjson形式で行うためサーバ側でデータをjsonに加工すれば、あとはライブラリがプロットするだけなので、扱いがかなり楽です。

flot sample

簡単なHow toをご紹介したいと思います。

まずは簡単に描画してみる

描画の仕方は、flotの描画ライブラリの呼び出し( $.plot()) 行うだけです。 以下に例を示します。ここでは、第一引数で描画を行う場所、第二引数でデータを設定してライブラリを呼び出しています。

var d1 = [
            [1, 96],
            [2, 89],
            [3, 85],
            [4, 90],
            [5, 87],
            [6, 86],
            [8, 83],
            [9, 86],
         ];
var d2 = [
            [1, 137],
            [2, 135],
            [3, 130],
            [4, 129],
            [5, 120],
            [6, 124],
            [8, 125],
            [9, 126],
         ];

var data_list = [];
data_list[data_list.length] = {label: "low", data:d1};
data_list[data_list.length] = {label: "high", data:d2};

$.plot($("#placeholder"), data_list);

flot sample1

棒グラフも描画することが可能です。

var d1 =  [
        [1950, 2535093],
            [1955, 2770753],
            [1960, 3031931],
            [1965, 3342771],
            [1970, 3698676],
            [1975, 4076080],
            [1980, 4451470],
            [1985, 4855264],
            [1990, 5294879],
            [1995, 5719045],
            [2000, 6124123],
            [2005, 6514751],
            [2010, 6906558],
            [2015, 7295135],
            [2020, 7667090],
            [2025, 8010509],
            [2030, 8317707],
            [2035, 8587050],
            [2040, 8823546],
            [2045, 9025982],
            [2050, 9191287]
        ];

var data_list = [];
data_list[data_list.length] = {label:'total', data:d1};

var options = {
    bars: {
    show: true,
    barWidth: 3,
    align: "center"
  }
};

$.plot($("#bar_placeholder"), data_list, options);

棒グラフ

判例の位置を変える

flotのコードをみると、判例で指定可能なオプションは以下のようになっています。 このうち、position、及びcontainerオプションを使うことで位置の変更をすることが可能です。 positionオプションは、

legend: {
    show: boolean,
    labelFormatter: null or (fn: string -> string),
    labelBoxBorderColor: color,
    noColumns: number,
    position: "ne" or "nw" or "se" or "sw",
    margin: number of pixels,
    backgroundColor: null or color,
    backgroundOpacity: number in 0.0 - 1.0,
    container: null or jQuery object
}

positionオプションは、凡例を領域内で任意の位置に表示ためのオプションで、以下の内容に設定することが可能です。

  • neが右上
  • nwが左上
  • seが右下
  • swが左下

コードでは以下のようにして指定します。このコードでは、左下に配置しています。

var data list = [];
.
.
[略]
.
.

var options = {
    legend:{position:'sw'}
};
$.plot($("#placeholder"), data_list, options);

判例の位置を変える

containerオプションは、判例を表示するコンテナでデフォルトnullで、グラフの描画領域内に表示されます。 containerオプションを使うことで判例の表示をグラフ描画領域外に配置することが可能です。

以下にコードサンプルを示します。

var data list = [];
.
.
[略]
.
.
var options = {
    legend:{container: $("#container")}
};
$.plot($("#placeholder"), data_list, options);

描画領域外に判例を表示する

最後にもう一つ。noColumnsオプションを指定することで、横並びにしたい判例の数を指定できます。 デフォルトでは、判例はすべて縦方向に展開されますが、このオプションを指定することで、同じ行に2個、3個と表示することが可能になります。

以下にコードサンプルを示します。ここでは、1行に2個判例を表示するように設定しています。

var data list = [];
.
.
[略]
.
.
var options = {
    legend:{noColumns: 2}
};
$.plot($("#placeholder"), data_list, options);

判例を横並びにする

いかがでしょうか。ブラウザでグラフを扱いたい方は是非おすすめします。

機会があれば、その他のいろいろな使い方をご紹介したいと思います。

投稿日 2008年3月21日 金曜日 カテゴリ javascript 投稿者 sugimotoComments Off 

sugimotoです。

javascriptのテストツールというと、seleniumが有名ですが、unit testのツールは使ったことがありませんでした。 先日、newjsというツール(javascrpt project generatorと言うことです。)のことを知り、使ってみました。

こちらでも紹介されていますが、newjsはjavascriptのプロジェクト管理を自動化するための管理コマンドを提供する、Rubyベースのパッケージです。

  • プロジェクトの生成
  • プロジェクト管理ディレクトリ自動作成
  • ドキュメントの雛形
  • テストフレームワーク
  • リリース管理
  • デプロイの自動化
  • 管理用ホームページの管理

など、オープンソースのjavascriptライブラリの管理を目的として利用できます。

使い方: (newjsのプロジェクトページを参照)

1. インストール

インストールはRubyGemでします。

> gem install newjs

簡単ですね。

2. プロジェクトの作成

これも簡単です。

> newjs -a "sugimto" -e "xxxx@opengroove.com" -t "GrooveLabo"  
        -u "http://xxx.opengroove.com/" -V "0.1.0"

オプションの意味は以下の通りです。

  • -a : プロジェクト管理者の名前
  • -e : プロジェクト管理者のメールアドレス
  • -t :プロジェクト名
  • -u : プロジェクトホームページのURL
  • -V : プロジェクトの最初のバージョン番号

これで自動的にプロジェクト管理用のディレクトリとファイルが作成されます。

javascriptのソースは src/[project-name].js に作成されたファイルを変更して管理します。

3. テスト

テストはjsunittestというフレームワークを使います。

> script/generate unit_test [test_name] [project_name]

とすると、test/unit/[test_name]_test.html にテスト用のHTMLが作成されます。 [test_name]_test.html:

new Test.Unit.Runner({
testXXXX: function() { with(this) {
// ここにテストコードを書く
}},
}, {testLog: "testlog"});

のようにしてunit testを書いて、[test_name]_test.html をブラウザで開くと、テストが実行され、テスト結果が表示されます。 unit test