ILOG Elixir

IBM ILOG Elixir:点滅する円形ゲージを作る

2009-05-28 08:00:00

 この記事では、IBM ILOG Elixirのゲージ・フレームワークを使って、ゲージの値が閾値よりも大きくなると点滅する丸いゲージを作る。この種のゲージは、多くのゲージが並ぶダッシュボードの中で、 重要な指標に注目させたい場合に便利だ(以下の画像ではマウスを使って目盛りを動かすことができる)。

 その方法の概要は、以下の通りだ。

  • 専用の円形ゲージを作成する
  • AnimatePropertyクラスとColorTransformクラスで、赤く点滅する背景を作成する

 最初に行うのは、専用円形ゲージの作成だ。背景と値の上限を作成するには、CircularGaugeAssetクラスで、黒いスタイルの円形アセットを扱う。このアセットは、ゲージ・フレームワークのソースコードの中にも見つかるが、この記事にリンクされているzipファイルの中にも入っている。このゲージには50から100まで赤いグラデーションで示された孤が入っているが、これがゲージの点滅する範囲を表している。円形ゲージの完全なソースコードを以下に示す。

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute"
  xmlns:ilog="http://www.ilog.com/2007/ilog/flex" backgroundColor="0xFFFFFF">
  <mx:Script>
    <![CDATA[
      import mx.graphics.Stroke;
      import ilog.gauges.RectangleTickRenderer;
      import mx.graphics.SolidColor;

      private function setTicksColor():void
      {
        var cf:ClassFactory = new ClassFactory(RectangleTickRenderer);
        cf.properties = { fill: new SolidColor(0xFFFFFF)};
        sr.majorTickRenderer = cf;
        sr.invalidateDisplayList();
        sr.minorTickRenderer = cf;
      }
    ]]>
  </mx:Script>
  <ilog:CircularGauge id="bcg" color="0xFFFFFF" width="100%" height="100%">

    <ilog:scales>
      <ilog:CircularLinearScale snapInterval="1"/>
    </ilog:scales>
    <ilog:elements>
      <ilog:CircularGaugeAsset id="cga"
        asset="@Embed(source='black_circle.swf')"/>
      <ilog:CircularScaleRenderer radius="45%" id="sr"
        initialize="setTicksColor()"/>

      <ilog:CircularTrackRenderer radius="28%" minimum="50" maximum="100"
        startThickness="5%" endThickness="20%">
        <ilog:gradientEntries>
          <mx:GradientEntry color="0x550000" ratio="0"/>
          <mx:GradientEntry color="0xAA0000" ratio="0.5"/>
          <mx:GradientEntry color="0xFF0000" ratio="1"/>
        </ilog:gradientEntries>

      </ilog:CircularTrackRenderer>
      <ilog:NeedleRenderer radius="30%" id="needle" editable="true"
        editMode="discrete" mouseMode="area" stroke="{new Stroke(0xDDDDDD, 2)}"/>
      <ilog:CircularGaugeAsset asset="@Embed(source='black_circle.swf')"
        radius="5%"/>
      <ilog:CircularLabelRenderer text="{needle.value}" labelFontSize="25%"
        originY="75%"/>
    </ilog:elements>
  </ilog:CircularGauge>

  <mx:Number id="value">{needle.value as Number}</mx:Number>
</mx:Application>

 次に、ゲージの背景に点滅するエフェクトを追加する。点滅の速さと色の強さは、値が非常に高い場合には、見た目で強い印象を与えられるよう、ゲージの値によって決まるようにする。ここでは、このtweenオブジェクトを使って、特定のイージング関数で更新している。

  <mx:AnimateProperty id="ap" target="{this}" property="blinkRatio"
    duration="{duration}" fromValue="0" toValue="1" tweenUpdate="updateAP(event)"
    tweenEnd="endAP(event)" easingFunction="{Exponential.easeInOut}"/>

 tweenがアップデートされる度に、blinkRatioの値もアップデートされる。この値を使って、ColorTransformアセットの赤色のオフセット値を変更する。

      private function updateAP(e:TweenEvent = null):void
      {
        var ct:ColorTransform = cga.transform.colorTransform;
        ct.redOffset = blinkRatio * intensity;
        cga.transform.colorTransform = ct;
      }

 点滅の強さと長さは、ゲージの値に応じて決定される。

      private function onChange(e:Event):void
      {
        stopBlink();
        if (value > 50)
        {
          intensity = 55 + (value - 50) * 4;
          duration = 2200 -  (value - 50) * 40;
          playBlink();
        }
      }

 tweenのエフェクトが終了するごとに、それをもう一度実行する前にfromValueとtoValueの値を入れ替えてやる。ゲージの値が50よりも大きい間はループする。

      private function endAP(e:Event):void
      {
        if (stopped == true)
          return;
        ap.fromValue += ap.toValue;
        ap.toValue = ap.fromValue - ap.toValue;
        ap.fromValue = ap.fromValue - ap.toValue;
        ap.play();
      }

 完全なコードは、以下のようになる。

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute"
  xmlns:ilog="http://www.ilog.com/2007/ilog/flex" backgroundColor="0xFFFFFF">
  <mx:Script><![CDATA[
      import mx.graphics.Stroke;
      import mx.graphics.LinearGradient;
      import mx.effects.easing.Exponential;
      import mx.events.TweenEvent;
      import ilog.gauges.RectangleTickRenderer;
      import mx.graphics.SolidColor;

      [Bindable]
      public var blinkRatio:Number = 200;
      [Bindable]
      private var intensity:Number = 255;
      [Bindable]
      private var duration:Number = 2000;

      private var stopped:Boolean = false;

      private function playBlink():void
      {
        stopped = false;
        ap.play();
      }

      private function stopBlink():void
      {
        stopped = true;
        ap.stop();
        blinkRatio = 0;
        updateAP();
      }

      private function updateAP(e:TweenEvent = null):void
      {
        var ct:ColorTransform = cga.transform.colorTransform;
        ct.redOffset = blinkRatio * intensity;
        cga.transform.colorTransform = ct;
      }

      private function endAP(e:Event):void
      {
        if (stopped == true)
          return;
        ap.fromValue += ap.toValue;
        ap.toValue = ap.fromValue - ap.toValue;
        ap.fromValue = ap.fromValue - ap.toValue;
        ap.play();
      }

      private function onChange(e:Event):void
      {
        stopBlink();
        if (value > 50)
        {
          intensity = 55 + (value - 50) * 4;
          duration = 2200 -  (value - 50) * 40;
          playBlink();
        }
      }

      private function setTicksColor():void
      {
        var cf:ClassFactory = new ClassFactory(RectangleTickRenderer);
        cf.properties = { fill: new SolidColor(0xFFFFFF)};
        sr.majorTickRenderer = cf;
        sr.invalidateDisplayList();
        sr.minorTickRenderer = cf;
      }
    ]]>
  </mx:Script>
  <mx:AnimateProperty id="ap" target="{this}" property="blinkRatio"
    duration="{duration}" fromValue="0" toValue="1" tweenUpdate="updateAP(event)"
    tweenEnd="endAP(event)" easingFunction="{Exponential.easeInOut}"/>
  <ilog:CircularGauge id="bcg" color="0xFFFFFF" width="100%" height="100%">

    <ilog:scales>
      <ilog:CircularLinearScale snapInterval="1"/>
    </ilog:scales>
    <ilog:elements>
      <ilog:CircularGaugeAsset id="cga"
        asset="@Embed(source='black_circle.swf')"/>
      <ilog:CircularScaleRenderer radius="45%" id="sr"
        initialize="setTicksColor()"/>

      <ilog:CircularTrackRenderer radius="28%" minimum="50" maximum="100"
        startThickness="5%" endThickness="20%">
        <ilog:gradientEntries>
          <mx:GradientEntry color="0x550000" ratio="0"/>
          <mx:GradientEntry color="0xAA0000" ratio="0.5"/>
          <mx:GradientEntry color="0xFF0000" ratio="1"/>
        </ilog:gradientEntries>

      </ilog:CircularTrackRenderer>
      <ilog:NeedleRenderer radius="30%" id="needle" valueCommit="onChange(event)"
        editable="true" editMode="discrete" mouseMode="area"
        stroke="{new Stroke(0xDDDDDD, 2)}"/>
      <ilog:CircularGaugeAsset asset="@Embed(source='black_circle.swf')"
        radius="5%"/>
      <ilog:CircularLabelRenderer text="{needle.value}" labelFontSize="25%"
        originY="75%"/>
    </ilog:elements>
  </ilog:CircularGauge>

  <mx:Number id="value">{needle.value as Number}</mx:Number>
</mx:Application>

 このアプリケーションのFlex Builderプロジェクトは、ここから.zipファイルでダウンロードできる。実行するには、IBM ILOG Elixir自体もダウンロードする必要がある。

 IBM ILOG Elixirについての詳細は、http://www.ilog.co.jp/product/visu/ilogelixir/をご覧ください。

※このエントリは ブロガーにより投稿されたものです。朝日インタラクティブ および ZDNet Japan編集部の見解・意向を示すものではありません。
  • 新着記事
  • 特集
  • ブログ