HOME > 開発者向けBLOG > Ext JS >  Sencha Ext JS を使って美しく描画する方法 パート1

Technology Note 開発者向けBLOG

Ext JS

Sencha Ext JS を使って美しく描画する方法 パート1

こんにちは、ゼノフィseoです。

この記事は、US Sencha社ブログCreating Beautiful Drawings Using Sencha Ext JS – Part 1 (2015年12月8日 | Vitaly Kravchenko) を翻訳したものです。

多くの方はSencha Ext JSに付属しているSencha Charting パッケージを既によくご存じかと思います。このパッケージを使うことでデータを素早く3Dカラムチャート3Dパイチャートなどで可視化することができます。しかしながら時に、ウェブアプリケーションはチャートだけではなく、フローチャートやシートマップ、配線略図、インタラクティブなアニメーションを必要とします。

もちろんHTML5のCanvasやSVG を直接使用することもできますが、その場合にはしばしば、サポートされていないプラットホームで不備を生じさせます。クロスブラウザの問題、通常のディスプレイとretina ディスプレイとの差異、アニメーション等を考慮すると簡単ではありません。複数のレンダラーに対応し、かつ有用なアブストラクションを有するサードパーティ製のライブラリを利用することもできますが、結局それらのライブラリを組み合わせて使うことになっているでしょう。

Ext JS Charts には描画パッケージが付属しており、これにより、どのブラウザがどのような技術で描画するかを心配せずに任意のグラフィックやアニメーションを作成することができます。表示するブラウザに応じてパッケージが自動的に最適なレンダラ―を選択します(Canvas、SVG、VML)。その内部では、APIモデルの基となるHTML5のCanvas を利用しています。Canvas API を呼び出すと、必要に応じて自動的にSVGもしくはVMLに変換されます。

この記事では、Sencha Charts に付属している描画パッケージの機能とそれらがどのように実装されているかをご説明しますので、これでクロスブラウザの互換性の問題に悩まなくて済むようになります。

シンプルなスプライト

スプライトは描画可能なグラフィカルオブジェクトとして基本的なものです。複数のスプライトを組み合わせることで望む画像を描くことができます。描画パッケージには様々な種類のスプライトが存在します。各スプライトはどのような見た目になるかを定義する様々なアトリビュートを持っています。例えば以下はrectスプライトのものです:

{
    xtype: 'draw',
    width: 250,
    height: 250,
    sprites: [{
        type: 'rect',
        x: 50,
        y: 50,
        width: 100,
        height: 100,
        lineWidth: 4,
        strokeStyle: 'green',
        fillStyle: 'yellow'
    }]
}

Fiddleで表示する

ここでのtype: 'rect' はスプライトのエイリアスに対応するもので、残りのコンフィグプロパティはスプライトのアトリビュートです。ここで大事なことはスプライトアトリビュートはコンフィグではないということです。アトリビュートとコンフィグの違いについては追って解説します。ここでは単に、2つが別々に処理され、使用されるとします。

ドローコンテナ

前述のdraw xtypeはExt.draw.Container クラスに対応しています。これはドローサーフェスのコンテナで(Ext.draw.Surfaceのインスタンス)、ここにスプライトがレンダリングされます。

rectスプライトを追加するにあたってドローコンテナのアイテムコンフィグではなくスプライトコンフィグを使用した点に注目してください。これはドローコンテナのアイテムがそのサーフェスだからです。そしてスプライトコンフィグで定義されたスプライトは、デフォルトのメインサーフェスに載せられます。スプライトのサーフェスコンフィグを使えば、スプライトをデフォルト以外サーフェスに載せることもできます(これはアトリビュートではありません)。例えば:

{
    type: 'rect',
    surface: 'privateSurface',
    x: 50,
    y: 50,
    width: 100,
    height: 100,
    ...
}

上記はID privateSurface でサーフェスを作り、デフォルトのメインサーフェスではなく、この中にrect sprite が入ります。サーフェスコンフィグは実際のサーフェスインスタンスであっても構いません。つまりドローコンテナがインスタンスを生成してからスプライトを setSpritesメソッドを経由して載せることになります。

ここで注意すべきは、初期のスプライトコンフィグやsetSpritesへのコールで既に追加されているスプライトをsetSpritesは取り除きません。新しいスプライトを追加するだけとなります。これはスプライトコンフィグが宣言的に使用されるものであるからです。スプライトを操作する必要があれば、サーフェスメソッドを使用してください。

複数のサーフェスを使用

複数のサーフェスを持つことはパフォーマンス面(バッテリーの寿命の面でも)で大いに役立ちます。スプライトのアトリビュートの変更でサーフェス全体(およびその中のスプライト全て)が再度レンダリングされるため、これはサーフェスに合わせてグループ化されたスプライトに有効で、あるスプライトのグループの変更はそれが載っているサーフェスの再レンダリングのみを引き起こします。Drawパッケージの最上位であるSencha Chartパッケージはこの機能に多く依存しています。クロスズームのような機能をチャートに載せている場合、チャート上をドラッグして選択すると、ズームの矩形を表すサーフェスのみが再度描画され、シリーズや軸のサーフェスは再描画されません。

上記の例を以下のように書き直すことで、仕組みをより理解することができます:

var drawContainer = new Ext.draw.Container({
    renderTo: document.body,
    width: 250,
    height: 250
});
 
var mainSurface = drawContainer.getSurface(); // --- getSurface('main')
 
mainSurface.add({ // add sprite to the surface
    type: 'rect',
    x: 50,
    y: 50,
    width: 100,
    height: 100,
    lineWidth: 4,
    strokeStyle: 'green',
    fillStyle: 'yellow'
});
 
mainSurface.renderFrame(); // --- renders all the sprites in the surface

Fiddleで表示する

スプライトアトリビュートを変更

ここではスプライトのアトリビュートをどのように変更できるかを見ます。例えばrectスプライトの幅を広げることで、より長方形にすることができます。

まずスプライトへのレファレンスを取得する必要があり、これには、サーフェスのアイテムコンフィグ(配列)を取得する方法があります:

var items = mainSurface.getItems(),
    rectSprite = items[0];

サーフェスのゲットメソッドを使用することもできます:

var rectSprite = mainSurface.get(0);

もしくはスプライトにIDを割り振り、それを使用して取得することもできます:

mainSurface.add({
    type: 'rect',
    id: 'myRect',
    ...
});
 
var rectSprite = mainSurface.get('myRect');

これでスプライトの幅を変更することができます。手順は下記のとおりです:

rectSprite.setAttributes({
    width: 150
});
// --- Don't forget to repaint the surface after changing sprite's attributes
mainSurface.renderFrame();

rectSprite.setWidth(150);を使用できないことに気づかれたと思いますが、これは幅がコンフィグでないからです。

Fiddleで表示する

一度に複数のアトリビュートを設定することも可能です。これは一番効率の良い手段なので推奨します。フィルとストローク両方の色を変更しましょう:

rectSprite.setAttributes({
    fillStyle: 'rgba(255, 0, 0, .5)',
    strokeStyle: 'rgb(0, 0, 0)'
});

ここで色の値の指定には、命名された色ではなくCSSコンプライアントのfgbを使って色の値を指定します。

Fiddleで表示する

他のアトリビュートにも変更を加え、それがスプライトにどのように影響するか確認してください。どのアトリビュートに対応しているかの詳細は、Ext JS ドキュメント (英語)をご覧ください。

まとめ

ご理解いただいたとおり、スプライトの扱いはコンポーネントに対するもとの大して違いありません。コンポーネントと同じ仕組みがスプライトにも適用されています。HTMLを直接変更することに代わりコンポーネントを扱うようなアプローチを採ることで、SVGエレメントやCanvas APIの呼び出しを直接行う必要なく、時間を大幅に短縮することができます。スプライトを生成し、アトリビュートを定義さえすれば、ドローパッケージが後を引き受けてくれます。

次回は、スプライトをどのように動かしたり変換、作用させるかを、独自のスプライトの作成の仕方を含めて解説します。また、インスタンス化や合成などスプライトの特別な機能もご説明しますので、これでパフォーマンスを改善したり、コードが複雑にならないようにすることができます。

しばらくの間はテキストなどドローイングパッケージに含まれている色々なスプライトをお試しください。

PAGETOP