📄 visualization.as
字号:
else
throw new Error("Unknown operator: " + name);
}
} else {
_operators.operate(trans);
}
if (_axes != null) _axes.update(trans);
fireEvent(VisualizationEvent.UPDATE, trans, operators);
return trans;
}
/**
* A function generator that can be used to invoke a visualization
* update at a later time. This method returns a function that
* accepts a <code>Transitioner</code> as its sole argument and then
* executes a visualization update using the specified named
* operators.
* @param operators an optional array of named operators to run
* @return a function that takes a <code>Transitioner</code> argument
* and invokes an update.
*/
public function updateLater(...operators):Function
{
return function(t:Transitioner):Transitioner {
return update(t, operators);
}
}
/**
* Updates the data display bounds for a visualization based on a
* given aspect ratio and provided width and height values. If both
* width and height values are provided, they will be treated as the
* maximum bounds. If only one of the width or height is provided, then
* the width or height will match that value, and the other will be
* determined by the aspect ratio. Finally, if neither width nor height
* is provided, then the current width and height of the display bounds
* will be used as the maximum bounds. After calling this method, a
* call to <code>update</code> is necessary to reflect the change.
* @param ar the desired aspect ratio for the data display
* @param width the desired width. If a height value is also provided,
* this width value will be treated as the maximum possible width
* (the actual width may be lower).
* @param height the desired height. If a width value is also provided,
* this height value will be treated as the maximum possible height
* (the actual height may be lower).
*/
public function setAspectRatio(ar:Number, width:Number=-1,
height:Number=-1):void
{
// compute new bounds
if (width > 0 && height < 0) {
height = width / ar;
} else if (width < 0 && height > 0) {
width = ar * height;
} else {
if (width < 0 && height < 0) {
width = bounds.width;
height = bounds.height;
}
if (ar > 1) { // width > height
height = width / ar;
} else if (ar < 1) { // height > width
width = ar * height;
}
}
// update bounds
bounds.width = width;
bounds.height = height;
}
// -- Named Operators -------------------------------------------------
/**
* Sets a new named operator. This method can be used to add extra
* operators to a visualization, in addition to those in the main
* <code>operators</code> property. These operators can be invoked by
* passing the operator name as an additional parameter of the
* <code>update</code> method. If an operator of the same name
* already exists, it will be replaced. Note that the name "main"
* refers to the same operator list as the <code>operators</code>
* property and can not be replaced.
* @param name the name of the operator to add
* @param op the operator to add
* @return the added operator
*/
public function setOperator(name:String, op:IOperator):IOperator
{
if (name=="main") {
throw new ArgumentError("Illegal group name: " +
"\"main\" is a reserved name.");
}
_ops[name] = op;
op.visualization = this;
return op;
}
/**
* Removes a named operator. An error will be thrown if the caller
* attempts to remove the operator "main".
* @param name the name of the operator to remove
* @return the removed operator
*/
public function removeOperator(name:String):IOperator
{
if (name=="main") {
throw new ArgumentError("Illegal group name: " +
"\"main\" is a reserved name.");
}
var op:IOperator = _ops[name];
if (op) delete _ops[name];
return op;
}
/**
* Retrieves the operator with the given name. The name "main" will
* return the operator list stored in the <code>operators</code>
* property.
* @param name the name of the operator
* @return the operator
*/
public function operator(name:String):IOperator
{
return _ops[name];
}
// -- Event Handling --------------------------------------------------
/**
* Creates a sprite covering the bounds for this visualization and
* sets it to be this visualization's hit area. Typically, this
* method is triggered in response to a <code>RENDER</code> event.
* <p>To disable automatic hit area calculation, use
* <code>stage.removeEventListener(Event.RENDER, vis.setHitArea)</code>
* <em>after</em> the visualization has been added to the stage.</p>
* @param evt an event that triggered the hit area update
*/
public function setHitArea(evt:Event=null):void
{
// get the union of the specified and actual bounds
var rb:Rectangle = getBounds(this);
var x1:Number = rb.left, x2:Number = rb.right;
var y1:Number = rb.top, y2:Number = rb.bottom;
if (bounds) {
x1 = Math.min(x1, bounds.left);
y1 = Math.min(y1, bounds.top);
x2 = Math.max(x2, bounds.right);
y2 = Math.max(y1, bounds.bottom);
}
// create the hit area sprite
var hit:Sprite = getChildByName("_hitArea") as Sprite;
if (hit == null) {
hit = new Sprite();
hit.name = "_hitArea";
addChildAt(hit, 0);
}
hit.visible = false;
hit.mouseEnabled = false;
hit.graphics.clear();
hit.graphics.beginFill(0xffffff, 1);
hit.graphics.drawRect(x1, y1, x2-x1, y2-y1);
hitArea = hit;
}
/**
* Fires a visualization event of the given type.
* @param type the type of the event
* @param t a transitioner that listeners should use for any value
* updates performed in response to this event
*/
protected function fireEvent(type:String, t:Transitioner,
params:Array):void
{
// fire event, if anyone is listening
if (hasEventListener(type)) {
dispatchEvent(new VisualizationEvent(type, t, params));
}
}
/**
* Data listener invoked when new items are added to this
* Visualization's <code>data</code> instance.
* @param evt the data event
*/
protected function dataAdded(evt:DataEvent):void
{
if (evt.node) {
for each (var d:DisplayObject in evt.items)
_marks.addChild(d);
} else {
for each (d in evt.items)
_marks.addChildAt(d, 0);
}
}
/**
* Data listener invoked when new items are removed from this
* Visualization's <code>data</code> instance.
* @param evt the data event
*/
protected function dataRemoved(evt:DataEvent):void
{
for each (var d:DisplayObject in evt.items)
_marks.removeChild(d);
}
} // end of class Visualization
}
import flare.animate.ISchedulable;
import flare.vis.Visualization;
/**
* Simple ISchedulable instance that repeatedly calls a Visualization's
* <code>update</code> method.
*/
class Recurrence implements ISchedulable {
private var _vis:Visualization;
public function get id():String { return null; }
public function set id(s:String):void { /* do nothing */ }
public function cancelled():void { /* do nothing */ }
public function Recurrence(vis:Visualization) {
_vis = vis;
}
public function evaluate(t:Number):Boolean {
_vis.update(); return false;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -