package flare.vis.data.render
{
import flare.util.Geometry;
import flare.util.Shapes;
import flare.vis.data.DataSprite;
import flare.vis.data.EdgeSprite;
import flare.vis.data.NodeSprite;
import flash.display.Graphics;
import flash.geom.Point;
import flash.geom.Rectangle;
/**
* Renderer that draws edges as lines. The EdgeRenderer supports straight
* lines, poly lines, and curves as Bezier or cardinal splines. The type
* of edge drawn is determined from an EdgeSprite's <code>shape</code>
* property and control points found in the <code>points</code> property.
* The line rendering properties are set by the <code>setLineStyle</code>
* method, which can be overridden by subclasses. By default, the line
* rendering settings are determined using default property values set
* on this class (for example, the <code>scaleMode<code> and
* <code>caps</code> properties).
*/
public class EdgeRenderer implements IRenderer
{
private static const ROOT3:Number = Math.sqrt(3);
private static var _instance:EdgeRenderer = new EdgeRenderer();
/** Static EdgeRenderer instance. */
public static function get instance():EdgeRenderer { return _instance; }
/** Pixel hinting flag for line rendering. */
public var pixelHinting:Boolean = false;
/** Scale mode for line rendering (normal by default). */
public var scaleMode:String = "normal";
/** The joint style for line rendering. */
public var joints:String = null;
/** The caps style for line rendering. */
public var caps:String = null;
/** The miter limit for line rendering. */
public var miterLimit:int = 3;
private var _p:Point = new Point(), _q:Point = new Point();
private var _pts:Array = new Array(20);
/** @inheritDoc */
public function render(d:DataSprite):void
{
var e:EdgeSprite = d as EdgeSprite;
if (e == null) { return; } var s:NodeSprite = e.source;
var t:NodeSprite = e.target;
var g:Graphics = e.graphics;
var ctrls:Array = e.points as Array;
var x1:Number = e.x1, y1:Number = e.y1;
var x2:Number = e.x2, y2:Number = e.y2;
var xL:Number = ctrls==null ? x1 : ctrls[ctrls.length-2];
var yL:Number = ctrls==null ? y1 : ctrls[ctrls.length-1];
var dx:Number, dy:Number, dd:Number;
if (e.arrowType != ArrowType.NONE)
{
var ah:Number = e.arrowHeight, aw:Number = e.arrowWidth/2;
if (ah < 0 && aw < 0)
aw = 1.5 * e.lineWidth;
if (ah < 0) {
ah = ROOT3 * aw;
} else if (aw < 0) {
aw = ah / ROOT3;
}
if (t==null) {
_p.x = x2; _p.y = y2;
} else {
var r:Rectangle = t.getBounds(t.parent);
if (Geometry.intersectLineRect(xL,yL,x2,y2, r, _p,_q) <= 0)
{
_p.x = x2; _p.y = y2;
}
}
dx = _p.x - xL; dy = _p.y - yL;
dd = Math.sqrt(dx*dx + dy*dy);
dx /=