是否可以像下面的示例一样在 Flex中创建一个打包的气泡图?
来源:http ://blog.tiger.com.pl/wp-content/uploads/2013/06/bubble2.jpg
我用谷歌搜索并没有找到任何东西。如果没有本地方法可以做到这一点,有人可以建议我自己如何绘制它吗?
是否可以像下面的示例一样在 Flex中创建一个打包的气泡图?
来源:http ://blog.tiger.com.pl/wp-content/uploads/2013/06/bubble2.jpg
我用谷歌搜索并没有找到任何东西。如果没有本地方法可以做到这一点,有人可以建议我自己如何绘制它吗?
好吧,在搜索和搜索之后,我在这里找到了一个名为flare的库,您可以在Layout/Bubbles中看到我正在寻找的演示示例。但一切都是在 Actionscript 3 中完成的。然后我开始创建自己的类以在 Flex 中使用,我得到了它。这是我写的类的代码。
package classes
{
import flare.animate.FunctionSequence;
import flare.animate.Transition;
import flare.animate.TransitionEvent;
import flare.animate.Transitioner;
import flare.display.TextSprite;
import flare.query.methods.add;
import flare.query.methods.div;
import flare.query.methods.mul;
import flare.util.Shapes;
import flare.util.Strings;
import flare.vis.Visualization;
import flare.vis.controls.DragControl;
import flare.vis.controls.ExpandControl;
import flare.vis.controls.HoverControl;
import flare.vis.controls.IControl;
import flare.vis.controls.TooltipControl;
import flare.vis.data.Data;
import flare.vis.data.DataList;
import flare.vis.data.DataSprite;
import flare.vis.data.NodeSprite;
import flare.vis.events.SelectionEvent;
import flare.vis.events.TooltipEvent;
import flare.vis.operator.OperatorSwitch;
import flare.vis.operator.encoder.PropertyEncoder;
import flare.vis.operator.label.Labeler;
import flare.vis.operator.layout.CircleLayout;
import flare.vis.operator.layout.CirclePackingLayout;
import flare.vis.operator.layout.DendrogramLayout;
import flare.vis.operator.layout.ForceDirectedLayout;
import flare.vis.operator.layout.IcicleTreeLayout;
import flare.vis.operator.layout.IndentedTreeLayout;
import flare.vis.operator.layout.Layout;
import flare.vis.operator.layout.NodeLinkTreeLayout;
import flare.vis.operator.layout.RadialTreeLayout;
import flash.display.DisplayObjectContainer;
import flash.display.Sprite;
import flash.events.Event;
import flash.events.MouseEvent;
import flash.geom.Point;
import flash.geom.Rectangle;
import flash.text.TextFormat;
import flash.text.TextFormatAlign;
import mx.core.Container;
import mx.core.UIComponent;
import mx.core.mx_internal;
import mx.events.ResizeEvent;
public class PackedBubblesChart extends UIComponent {
public static const DEFAULT_FLEX_SERIES_COLORS:Array = [
0xe48701, 0xa5bc4e, 0x1b95d9, 0xcaca9e,
0x6693b0, 0xf05e27, 0x86d1e4, 0xe4f9a0,
0xffd512, 0x75b000, 0x0662b0, 0xede8c6,
0xcc3300, 0xd1dfe7, 0x52d4ca, 0xc5e05d,
0xe7c174, 0xfff797, 0xc5f68f, 0xbdf1e6,
0x9e987d, 0xeb988d, 0x91c9e5, 0x93dc4a,
0xffb900, 0x9ebbcd, 0x009797, 0x0db2c2
];
// Constructor
public function PackedBubblesChart() {
addEventListener(Event.ADDED_TO_STAGE, addedToStage);
addEventListener(Event.REMOVED_FROM_STAGE, removedFromStage);
}
protected function addedToStage(event: Event) : void {
(this.parent as Container).addEventListener(ResizeEvent.RESIZE, resizeBubbleChart);
tryRender();
}
protected function removedFromStage(event: Event) : void {
clearNodes();
(this.parent as Container).removeEventListener(ResizeEvent.RESIZE, resizeBubbleChart);
}
protected function clearNodes() : void {
if(vis) {
for each(var sprite : DataSprite in _nodesInformation.nodes) {
sprite.parent.removeChild(sprite);
}
vis = null;
}
}
protected function resizeBubbleChart(event:ResizeEvent) : void {
_bounds = new Rectangle(0, 0, parent.width, parent.height);
tryRender();
}
private var _init:Boolean = false;
private var _bounds:Rectangle;
public var labelField : String = "label";
public var valueField : String = "value";
public function get bounds():Rectangle { return _bounds; }
public function set bounds(b:Rectangle):void {
_bounds = b;
resize();
}
private var _dataProvider : Array = [];
private var _nodesInformation : Data = new Data();
private var _nodeDefaultFormat : Object =
{
name: "Bubbles",
op: new CirclePackingLayout(8, false, "depth"),
nodes:{
shape: Shapes.CIRCLE,
fillColor: 0x11aaaaaa,
lineColor: 0xdddddddd,
lineWidth: 4,
alpha: 1,
visible: true
},
edges: {alpha:0, visible:false},
ctrl: new DragControl(NodeSprite),
canStraighten: true
}
public function get dataProvider() : Array {
return _dataProvider;
}
public function set dataProvider(info : Array) : void {
/*
if(vis && _dataProvider && _dataProvider.length > 0) {
for each(var sprite : DataSprite in _nodesInformation.nodes) {
sprite.parent.removeChild(sprite);
}
vis = null;
}
*/
_dataProvider = info;
tryRender();
}
protected function tryRender() : void {
if(parent) _bounds = new Rectangle(0,0,parent.width, parent.height);
if(_dataProvider && _dataProvider.length > 0 && _bounds) {
clearNodes();
_nodesInformation = createNodes(_dataProvider.length);
_nodesInformation.nodes.setProperties(_nodeDefaultFormat.nodes);
var index : uint = 0;
for each(var item : Object in _dataProvider) {
var labelText : String = item[labelField];
var valueNumber : Number = item[valueField];
_nodesInformation.nodes[index].data.label = labelText;
_nodesInformation.nodes[index].buttonMode = true;
_nodesInformation.nodes[index].size = item[valueField];
_nodesInformation.nodes[index].props.value = valueNumber;
_nodesInformation.nodes[index].props.name =labelText;
_nodesInformation.nodes[index].props.name_value = labelText+"\n("+valueNumber+")";
_nodesInformation.nodes[index].fillColor = 0xff000000 + DEFAULT_FLEX_SERIES_COLORS[index % 28];
index++;
}
_nodesInformation.nodes.sortBy("props.value");
// create the visualization
vis = new Visualization(_nodesInformation);
vis.bounds = bounds;
vis.operators.add(_nodeDefaultFormat.op);
vis.setOperator("nodes", new PropertyEncoder(_nodeDefaultFormat.nodes, "nodes"));
vis.operators.add(new Labeler("props.name_value", Data.NODES,new TextFormat("Arial",12,0,true,null,null,null,null, TextFormatAlign.CENTER),null));
vis.controls.add(new TooltipControl(DataSprite, null,
function(evt:TooltipEvent):void {
var d:DataSprite = evt.node;
TextSprite(evt.tooltip).htmlText = Strings.format(_tipText, d.props.name, d.props.value);
}
));
init();
}
}
public static function createNodes(n:uint):Data {
var g:Data = new Data();
for (var i:uint=0; i < n; i++) {
var node:NodeSprite = g.addNode();
node.data.label = String(i);
}
return g;
}
public function set toolTipFormat(value : String) : void {
_tipText = value;
}
private var _tipText:String = "<b>Label</b>: {0}<br/><b>Value</b>: {1}";
private var vis:Visualization;
private var os:OperatorSwitch;
private var shape:String = null;
public function init():void {
vis.controls.add(new HoverControl(NodeSprite,
// by default, move highlighted items to front
HoverControl.MOVE_AND_RETURN,
// highlight node border on mouse over
function(e:SelectionEvent):void {
e.node.lineWidth = 10;
e.node.lineColor = 0x88ff0000;
},
// remove highlight on mouse out
function(e:SelectionEvent):void {
e.node.lineWidth = 4;
e.node.lineColor = _nodeDefaultFormat.nodes.lineColor;
}));
vis.controls.add(_nodeDefaultFormat.ctrl);
vis.update();
addChild(vis);
}
public function resize():void
{
if (vis) {
vis.bounds = bounds;
vis.update();
}
}
}
}
这是一个在 flex 中使用它的应用示例
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
minWidth="955" minHeight="600" creationComplete="init(event)" layout="vertical"
verticalAlign="middle">
<mx:Script>
<![CDATA[
import classes.PackedBubblesChart;
import mx.events.FlexEvent;
import mx.events.ResizeEvent;
protected var companies : Array = [];
protected var otherCompanies : Array = [];
protected var bubbleChart : PackedBubblesChart = new PackedBubblesChart();
protected function init(event:FlexEvent):void {
companies.push({company_name:"Sunray Management Group", count:92});
companies.push({company_name:"Chevron", count:145});
companies.push({company_name:"Nabors", count:35});
companies.push({company_name:"Milicom", count:23});
companies.push({company_name:"gNostos", count:200});
companies.push({company_name:"Cisco", count:43});
otherCompanies.push({company_name:"Chevron", count:145});
otherCompanies.push({company_name:"Nabors", count:35});
otherCompanies.push({company_name:"Milicom", count:23});
otherCompanies.push({company_name:"gNostos", count:200});
companies.push({company_name:"Sunray Management Group", count:92});
companies.push({company_name:"Chevron", count:145});
companies.push({company_name:"Nabors", count:35});
companies.push({company_name:"Milicom", count:23});
companies.push({company_name:"gNostos", count:200});
companies.push({company_name:"Cisco", count:43});
otherCompanies.push({company_name:"Chevron", count:145});
otherCompanies.push({company_name:"Nabors", count:35});
otherCompanies.push({company_name:"Milicom", count:23});
otherCompanies.push({company_name:"gNostos", count:200});
companies.push({company_name:"Sunray Management Group", count:92});
companies.push({company_name:"Chevron", count:145});
companies.push({company_name:"Nabors", count:35});
companies.push({company_name:"Milicom", count:23});
companies.push({company_name:"gNostos", count:200});
companies.push({company_name:"Cisco", count:43});
otherCompanies.push({company_name:"Chevron", count:145});
otherCompanies.push({company_name:"Nabors", count:35});
otherCompanies.push({company_name:"Milicom", count:23});
otherCompanies.push({company_name:"gNostos", count:200});
companies.push({company_name:"Sunray Management Group", count:92});
companies.push({company_name:"Chevron", count:145});
companies.push({company_name:"Nabors", count:35});
companies.push({company_name:"Milicom", count:23});
companies.push({company_name:"gNostos", count:200});
companies.push({company_name:"Cisco", count:43});
otherCompanies.push({company_name:"Chevron", count:145});
otherCompanies.push({company_name:"Nabors", count:35});
otherCompanies.push({company_name:"Milicom", count:23});
otherCompanies.push({company_name:"gNostos", count:200});
bubbleChart.labelField = "company_name";
bubbleChart.valueField = "count";
bubbleChart.toolTipFormat = "<b>Company</b>: {0}<br/><b>Count</b>: {1}";
bubbleChart.dataProvider = companies;
canvas.addChild(bubbleChart);
}
protected function button_clickHandler(event:MouseEvent):void {
if(bubbleChart.dataProvider == companies) bubbleChart.dataProvider = otherCompanies;
else bubbleChart.dataProvider = companies;
}
]]>
</mx:Script>
<mx:Canvas id="canvas" width="100%" height="100%">
</mx:Canvas>
<mx:Button label="New data provider" click="button_clickHandler(event)"/>
</mx:Application>
好吧,我回答我自己的问题,因为我认为它可能对其他人有用。对不起我的英语不好。
结果就是这样……啊,美人。感谢 Flare 人。