diff --git a/site/Library/footer.lbi b/site/Library/footer.lbi new file mode 100644 index 0000000..dc67684 --- /dev/null +++ b/site/Library/footer.lbi @@ -0,0 +1,14 @@ + + + + + + diff --git a/site/Library/header.lbi b/site/Library/header.lbi new file mode 100644 index 0000000..7a1f1c5 --- /dev/null +++ b/site/Library/header.lbi @@ -0,0 +1,14 @@ + + \ No newline at end of file diff --git a/site/demo.html b/site/demo.html new file mode 100644 index 0000000..f4aa62e --- /dev/null +++ b/site/demo.html @@ -0,0 +1,66 @@ + + + + +Finger Chart + + + + +
+

目录

+ + + +
+ + + + + + + + + diff --git a/site/demo/1.1.html b/site/demo/1.1.html new file mode 100644 index 0000000..5a93ced --- /dev/null +++ b/site/demo/1.1.html @@ -0,0 +1,62 @@ + + + + + + + +Document + + + + +

线图

+
chart here
+ + + + 视频演示 +

技巧

+
+1.点击右键可以查看原始数据
+2.通过CSS可以设定线的宽度,参见皮肤和样式部分
+
+3.当line-width >= dot-width*2时,可以实现无点显示的效果
+
+4.通过给CSS设置line-mode:bezier,可以实现曲线效果
+示例CSS:gContainer {line-mode:bezier}
+
+5.动态添加数据节点
+var randomData = {日期:"6月"+count+"日",参考线:"300",频道一:Math.random()*300,频道二:Math.random()*300+300};
+finger.addData("mySWF",randomData,"replace");
+
+ + + + + + + + + diff --git a/site/demo/1.2.html b/site/demo/1.2.html new file mode 100644 index 0000000..6d02bee --- /dev/null +++ b/site/demo/1.2.html @@ -0,0 +1,37 @@ + + + + + + + +Document + + + + +

2.柱图

+
chart here
+ + + + + + + + + + + diff --git a/site/demo/1.3.html b/site/demo/1.3.html new file mode 100644 index 0000000..d7cc540 --- /dev/null +++ b/site/demo/1.3.html @@ -0,0 +1,37 @@ + + + + + + + +Document + + + + +

3.条图

+
chart here
+ + + + + + + + + + + diff --git a/site/demo/1.4.html b/site/demo/1.4.html new file mode 100644 index 0000000..133391c --- /dev/null +++ b/site/demo/1.4.html @@ -0,0 +1,37 @@ + + + + + + + +Document + + + + +

4.饼图

+
chart here
+ + + + + + + + + + + diff --git a/site/demo/1.5.html b/site/demo/1.5.html new file mode 100644 index 0000000..3f6ecaa --- /dev/null +++ b/site/demo/1.5.html @@ -0,0 +1,37 @@ + + + + + + + +Document + + + + +

5.区域图

+
chart here
+ + + + + + + + + + + diff --git a/site/demo/1.6.html b/site/demo/1.6.html new file mode 100644 index 0000000..5d44589 --- /dev/null +++ b/site/demo/1.6.html @@ -0,0 +1,37 @@ + + + + + + + +Document + + + + +

6.散点图

+
chart here
+ + + + + + + + + + + diff --git a/site/demo/1.7.html b/site/demo/1.7.html new file mode 100644 index 0000000..71fcaee --- /dev/null +++ b/site/demo/1.7.html @@ -0,0 +1,37 @@ + + + + + + + +Document + + + + +

7.气泡图

+
chart here
+ + + + + + + + + + + diff --git a/site/doc/1.html b/site/doc/1.html new file mode 100644 index 0000000..5e85056 --- /dev/null +++ b/site/doc/1.html @@ -0,0 +1,107 @@ + + + + + +Document + + + +

快速入门

+

这篇文章将带您快速了解Finger Chart的使用方法,如果您没有其它个性化的需求,那么遵循下面的步骤您就可以快速上手。

+

第一步:下载,解压

+

请从下载页面下载最新的压缩包(目前版本是0.8),并解压到您项目中的某一目录下面。下表是对解压后文件结构的大致说明:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
文件名或目录说明
readme.html关于图表的简短说明,并附有一个嵌入图表的示例
plot_chart.swf散点图的SWF文件
pie_chart.swf饼图的SWF文件
line_chart.swf线图的SWF文件
column_chart.swf柱图的SWF文件
bubble_chart.swf气泡图的SWF文件
bar_chart.swf条图的SWF文件
area_chart.swf区域图的SWF文件
plugin包含扩展SWF文件的目录
js包含swfobject.js和finger.js,后者是对finger嵌入方式的JavaScript封装
data包含虚拟的XML数据,供您参考数据结构
+

第二步:准备数据

+

支持两种数据格式:XML和JSON,请参考XML示例和JSON示例。将您的数据转换为图表所支持的格式待用。

+

第三步:HTML嵌入

+

首先在HTML的Head区域,引入两个需要的JavaScript文件(依据您实际的路径而定):

+
+<script type="text/javascript" src="js/swfobject.js"></script>
+<script type="text/javascript" src="js/finger.js"></script>
+
+

声明嵌入图表所需的容器,比如:

+
+<div id="chartContainer">chart here</div>
+
+

通过CSS约束图表容器的尺寸,比如:

+
+#chartContainer{width:600px;height:300px;border:1px solid #CCC;}
+
+

然后调用finger.ouput方法,嵌入图表,代码示例:

+
+//如果需要,请设置图表文件所在的路径
+finger.initPath("");
+//第一个参数是图表类型,包括:line,column,bar,pie,area,plot,bubble
+//第二个参数是容器ID
+//第三个参数是数据源
+//第四个参数(可选)是配置对象,比如{plugin:"xx.swf"}
+finger.output("line","chartContainer","data/xml/linechart_data1.xml");
+
+

没有第四步了:)

+ + + + + + + + + diff --git a/site/doc/2.1.html b/site/doc/2.1.html new file mode 100644 index 0000000..64abe91 --- /dev/null +++ b/site/doc/2.1.html @@ -0,0 +1,52 @@ + + + + + +Document + + + +

数据格式说明

+

图表支持两种数据格式:XML和JSON,这两种数据格式都将被图表解释为统一的DatasetVO来使用。解析是依赖实现IParser接口的类来完成,您也可以实现自定义的Parser类来解析其它的数据格式。

+

XML格式说明

+

在根标签<finger>下面,需要定义两个标签:<config>和<dataset>。

+

其中config是数据配置,定义取值字段,文本显示等等,注意这里的配置完全是数据相关的配置,与样式无关。关于样式请参考“皮肤与样式”部分。

+

config包含以下的属性:

+
    +
  1. yTitle:必须,定义y轴的显示文本
  2. +
  3. categoryField:必须,但不可与xField同时使用,定义x轴的显示字段(类型为文本),用于线图,柱图,条图,饼图,区域图
  4. +
  5. xField:必须,但不可与categoryField同时使用,定义x轴的显示字段(类型必须为数值),用于散点图和气泡图
  6. +
  7. yField:必须,定义y轴的显示字段,可以为多个,用逗号相隔
  8. +
  9. zField:可选,适用于用于Z轴的图表类型,比如气泡图
  10. +
  11. benchmark:可选,定义参考线的显示字段,参考线为一条灰色折线
  12. +
+

注:因为x轴允许两种模式:按照类别,等分图表宽度的显示方式,和按照数值确定x坐标的方式,所以提供categoryField和xField两种定义方式,这两种方式是排斥关系。

+

dataset标签下面,是一组<node>标签,每一个<node>标签包含若干个数据属性,当然具体数据属性是什么,根据您的需求而定。

+

来看线图的一段XML数据Demo:

+
<finger>
+<config yTitle="访问量" categoryField="日期" yField="频道一,频道二,参考线" benchmark="参考线"/>
+<dataset>
+<node 日期="6月1日" 参考线="300" 频道一="100" 频道二="430"/>
+<node 日期="6月2日" 参考线="300" 频道一="240" 频道二="530"/>
+</dataset>
+</finger>
+

JSON格式说明

+

跟XML类似,JSON格式也应该有类似的结构,即:具备config和dataset。config是一个object,而dataset则是一个数组。来看一段Demo:

+{"config":{"yTitle":"访问量","categoryField":"日期","yField":"频道一,频道二,参考线","benchmark":"参考线"},"dataset":[{"日期":"6月1日","参考线":"300","频道一":"100","频道二":"430"},{"日期":"6月2日","参考线":"300","频道一":"600","频道二":"230"}]} + + + + + + + + diff --git a/site/doc/2.2.html b/site/doc/2.2.html new file mode 100644 index 0000000..ffcf81d --- /dev/null +++ b/site/doc/2.2.html @@ -0,0 +1,85 @@ + + + + + +Document + + + +

图表嵌入方式

+

按照使用场合,可分为两种方式:HTML嵌入方式,和组件引用方式。HTML嵌入方式是指在网页HTML中嵌入SWF的方式来使用图表;组件引用方式,则是指在Flash开发中,使用Finger组件的方式来引入图表。

+

HTML嵌入方式

+

可以使用finger.js或swfobject.js来嵌入图表。

+

首先在HTML的Head区域,引入两个需要的JavaScript文件(依据您实际的路径而定):

+
+<script type="text/javascript" src="js/swfobject.js"></script>
+<script type="text/javascript" src="js/finger.js"></script>
+
+

声明嵌入图表所需的容器,比如:

+
+<div id="chartContainer">chart here</div>
+
+

通过CSS约束图表容器的尺寸,比如:

+
+#chartContainer{width:600px;height:300px;border:1px solid #CCC;}
+
+

然后调用finger.ouput方法,嵌入图表,代码示例:

+
+//如果需要,请设置图表文件所在的路径
+finger.initPath("");
+//第一个参数是图表类型,包括:line,column,bar,pie,area,plot,bubble
+//第二个参数是容器ID
+//第三个参数是数据源
+//第四个参数(可选)是配置对象,比如{plugin:"xx.swf"}
+finger.output("line","chartContainer","data/xml/linechart_data1.xml");
+
+

您也可以直接使用swfobject.js来完成嵌入工作,比如嵌入线图的一段JavaScript示例:

+ +var LineChartConfig = {data:"data/json/line_json1.txt",legend:"selectable",plugin:"plugin/context_menu.swf",callback:"callBack"}; +var params = {allowscriptaccess:"always",allowFullScreen:"true"}; +swfobject.embedSWF("line_chart.swf", "myContent", "100%", "100%", "9.0.0", "playerProductInstall.swf",LineChartConfig, params); + +

组件使用方式

+

Finger提供了一套封装组件(可视化组件库支持),您可以在您的Flash项目中基于ActionScript创建对象的方式来使用图表。组件位于包finger.components中。

+

您可以使用引入SWC的方式来引用类库,在下载包的lib目录下有两个SWC文件,请将它们加入您的项目或程序文件的SWC引用路径。

+

下面是一组示例代码:

+ +//linechart
+var chartConfig1:Object = {data:"data/xml/linechart_data1.xml"};
+var lineChart:LineChart = new LineChart(500,300);
+lineChart.chartConfig = chartConfig1;
+lineChart.x = 10;
+lineChart.y = 70;
+lineChart.loadAssets();
+addChild(lineChart);
+//columnchart
+var chartConfig2:Object = {data:"data/xml/columnchart_data1.xml"};
+var columnChart:ColumnChart = new ColumnChart(500,300);
+columnChart.chartConfig = chartConfig2;
+columnChart.x = 520;
+columnChart.y = 70;
+columnChart.loadAssets();
+addChild(columnChart);
+lineChart.addEventListener(ChartEvent.ITEM_CLICK,itemClickHandler);
+private function itemClickHandler(e:ChartEvent):void {
+Alert.show(e.data[e.yField]);
+}
+
+

注意:如果您希望以内联字符串的方式传递数据,而不提供单独的URL地址,则请将data属性替换为dataStr。

+ + + + + + + + diff --git a/site/doc/2.3.html b/site/doc/2.3.html new file mode 100644 index 0000000..aea93ca --- /dev/null +++ b/site/doc/2.3.html @@ -0,0 +1,68 @@ + + + + + +Document + + + +

皮肤与样式

+

Finger采用一种灵活的组合方式来定义外观,它就是skin和css的有机结合。

+

CSS

+

CSS定义(更新中):

+ +/*color-collection是图表图形所需的颜色数组*/
+global {color-collection:0xff0000 0xff0078 0xff00d2 0x9c00ff 0x0c00ff 0x00a2ff 0x09c700 0xe7b300 0xe75c00;}
+/*定义图表背景颜色和背景透明度*/
+chart {bg-colors:0xFFFFFF 0xc8c8c8;bg-alphas:100 100;line-colors:0x000000 0x000000;line-alphas:0 20}
+/*定义坐标系样式*/
+axis {grid-height:50;padding-left:40;padding-top:30;padding-right:20;padding-bottom:50;offset-v:20;color:0x000000;bottom-color:0xFFFFFF;line-colors:0x272727 0x000000;line-alphas:100 100}
+/*定义图形的样式,包括文本颜色,参考线颜色,线的宽度*/
+gContainer {color:0x000000;benchmark-color:0x000000;line-width:2;dot-width:2}
+/*定义鼠标提示的样式,包括文本颜色,和背景颜色*/
+tContainer {color:0x000000;tipbg-color:0xFFFFFF;tipbg-alpha:100;border-width:3;border-color:0x000000;border-alpha:20}
+/*定义插件的样式,包括颜色*/
+pContainer {color:0x000000;}
+/*定义图表说明的样式*/
+legend {color:0xFFFFFF;padding-top:0;padding-left:0;benchmark-color:0xCCCCCC;bg-color:0x666666;bg-alpha:100} +
+

因为这些样式基本都是在Skin中得到应用,因此通过修改Skin,您可以添加更多的样式属性支持。具体参见下面的Skin部分。

+

一段实例

+ +var cssStr = "chart {bg-colors:0x333333 0x000000;bg-alphas:100 100;line-colors:0xFFFFFF 0xFFFFFF;line-alphas:0 10}"; +cssStr += "axis {color:0xFFFFFF;bottom-color:0xFFFFFF;line-colors:0xFF0000 0x000000;line-alphas:100 100}"; +cssStr += "tContainer {color:0xFFFFFF;tipbg-color:0x333333;tipbg-alpha:100;border-width:1;border-color:0xFFFFFF;border-alpha:20}"; + + +

点击这里运行在线CSS预览

+

SKIN

+

Finger所使用的SKIN是一个包含了素材类的SWF文件,基于skin.fla,您可以复制这个文件,修改素材来创建新的SKIN。注意所有 素材都位于库中,您在时间轴上将看不到任何内容。打开库面板,能看到所有的图形素材:

+

lib

+

每一个Skin素材类,都实现updateDisplayList方法,并接受两个参数:parm和style,parm是跟素材相关的一些属性,比如要适应的宽度和高度,style则是在CSS样式表中定义的属性引用。看一段代码示例:

+
+function updateDisplayList(parm:Object,style:Object):void {
+	graphics.clear();
+	graphics.beginFill(style["bgColor"],style["bgAlpha"]/100);
+	graphics.drawRect(0,0,parm.width,parm.height);
+	graphics.endFill();
+}
+
+

使用skin.swf所产生的默认效果:

+ + + + + + + + + diff --git a/site/doc/2.4.html b/site/doc/2.4.html new file mode 100644 index 0000000..e4e747d --- /dev/null +++ b/site/doc/2.4.html @@ -0,0 +1,59 @@ + + + + + +Document + + + +

插件机制说明

+

您可以基于IChartPlugin接口,开发独立的图表插件,编译为单独的SWF文件,嵌入图表中发挥作用。

+

嵌入插件的方式为,设置plugin参数,比如:

+
var LineChartConfig = {...,plugin:"plugin/context_menu.swf",...};
+

再来看一下右键菜单插件的代码片段:

+
+public class context_menu extends MovieClip implements IChartPlugin {
+	
+	private var container:IPluginContainer;
+	private var myContextMenu:ContextMenu;
+	private var dataset:DatasetVO;
+	private var chartRef:IChart;
+	
+	public function context_menu() {
+		
+	}
+	
+	public function initPlugin(container:IPluginContainer):void {
+		this.container = container;
+		chartRef = container.chartRef;
+		dataset = container.dataset;
+		myContextMenu = new ContextMenu();
+		(chartRef as Sprite).contextMenu = myContextMenu;
+		myContextMenu.hideBuiltInItems();
+		...
+	}
+	
+	public function updateDisplayList(w:uint,h:uint):void {
+		
+	}
+	
+}
+
+
+ + + + + + + + diff --git a/site/doc/2.5.html b/site/doc/2.5.html new file mode 100644 index 0000000..dea9273 --- /dev/null +++ b/site/doc/2.5.html @@ -0,0 +1,33 @@ + + + + + +Document + + + +

JavaScript接口

+

给传递参数callback设置方法名称,可以执行该方法回调。示例:

+
+var LineChartConfig = {...,callback:"callBack"};
+function callBack(data) {
+	alert(data);
+}
+
+ + + + + + + + diff --git a/site/doc/3.3.html b/site/doc/3.3.html new file mode 100644 index 0000000..667ec57 --- /dev/null +++ b/site/doc/3.3.html @@ -0,0 +1,27 @@ + + + + + +Document + + + +

结构设计

+

uml

+ + + + + + + + diff --git a/site/doc/img/fla_libs.png b/site/doc/img/fla_libs.png new file mode 100644 index 0000000..1d8cafb Binary files /dev/null and b/site/doc/img/fla_libs.png differ diff --git a/site/doc/img/pro_comps.png b/site/doc/img/pro_comps.png new file mode 100644 index 0000000..7d6e0bc Binary files /dev/null and b/site/doc/img/pro_comps.png differ diff --git a/site/doc/img/style_demo.png b/site/doc/img/style_demo.png new file mode 100644 index 0000000..5cef9b0 Binary files /dev/null and b/site/doc/img/style_demo.png differ diff --git a/site/doc/img/uml.jpg b/site/doc/img/uml.jpg new file mode 100644 index 0000000..7cadc3b Binary files /dev/null and b/site/doc/img/uml.jpg differ diff --git a/site/download/finger-chart-0.8/data/json/line_json1.txt b/site/download/finger-chart-0.8/data/json/line_json1.txt new file mode 100644 index 0000000..593340d --- /dev/null +++ b/site/download/finger-chart-0.8/data/json/line_json1.txt @@ -0,0 +1 @@ +{"config":{"yTitle":"访问量","categoryField":"日期","yField":"频道一,频道二,参考线","benchmark":"参考线"},"dataset":[{"日期":"6月1日","参考线":"300","频道一":"100","频道二":"430"},{"日期":"6月2日","参考线":"300","频道一":"600","频道二":"230"}]} \ No newline at end of file diff --git a/site/download/finger-chart-0.8/data/xml/barchart_data1.xml b/site/download/finger-chart-0.8/data/xml/barchart_data1.xml new file mode 100644 index 0000000..9d43a38 --- /dev/null +++ b/site/download/finger-chart-0.8/data/xml/barchart_data1.xml @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + \ No newline at end of file diff --git a/site/download/finger-chart-0.8/data/xml/columnchart_data1.xml b/site/download/finger-chart-0.8/data/xml/columnchart_data1.xml new file mode 100644 index 0000000..3dec6b6 --- /dev/null +++ b/site/download/finger-chart-0.8/data/xml/columnchart_data1.xml @@ -0,0 +1,19 @@ + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/site/download/finger-chart-0.8/data/xml/linechart_data1.xml b/site/download/finger-chart-0.8/data/xml/linechart_data1.xml new file mode 100644 index 0000000..2d20fc2 --- /dev/null +++ b/site/download/finger-chart-0.8/data/xml/linechart_data1.xml @@ -0,0 +1,19 @@ + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/site/download/finger-chart-0.8/data/xml/piechart_data1.xml b/site/download/finger-chart-0.8/data/xml/piechart_data1.xml new file mode 100644 index 0000000..48dc938 --- /dev/null +++ b/site/download/finger-chart-0.8/data/xml/piechart_data1.xml @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + \ No newline at end of file diff --git a/site/download/finger-chart-0.8/data/xml/plotchart_data1.xml b/site/download/finger-chart-0.8/data/xml/plotchart_data1.xml new file mode 100644 index 0000000..2c4493c --- /dev/null +++ b/site/download/finger-chart-0.8/data/xml/plotchart_data1.xml @@ -0,0 +1,12 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/site/download/finger-chart-0.8/js/finger.js b/site/download/finger-chart-0.8/js/finger.js new file mode 100644 index 0000000..1fb2a9a --- /dev/null +++ b/site/download/finger-chart-0.8/js/finger.js @@ -0,0 +1,127 @@ +/** +* @todo:Finger Chart图形报表 +* @date:2008-7-3 16:38 +* @author:finger,lovejes(http://lovejes.javaeye.com/) +* @remark + yTitle:必须,定义y轴的显示文本 + categoryField:必须,但不可与xField同时使用,定义x轴的显示字段(类型为文本),用于线图,柱图,条图,饼图,区域图 + xField:必须,但不可与categoryField同时使用,定义x轴的显示字段(类型必须为数值),用于散点图和气泡图 + yField:必须,定义y轴的显示字段,可以为多个,用逗号相隔 + zField:可选,适用于用于Z轴的图表类型,比如气泡图 + benchmark:可选,定义参考线的显示字段,参考线为一条灰色折线 +*/ +finger = { + baseURL : "" + ,params : {allowscriptaccess:"always",allowFullScreen:"true"} + ,attributes : {id:"chartSWF",name:"chartSWF"} + ,initPath : function(path){ + this.baseURL = path; + } + /** + * @todo:输出图形报表 + * @date:2008-7-3 16:38 + * @author:finger,lovejes + * @param chartType: 图表类型,包括:line,column,bar,pie,area,plot,bubble + * @param container: 图表容器ID + * @param data: 支持xml,txt...或者直接封装json数据 + * @param extendConfig: (可选)是配置对象,比如{plugin:"xx.swf"} + */ + ,output: function(chartType,container,data,extendConfig) { + var configObj = {legend:"selectable"}; + if(data.indexOf("config") !=-1 && data.indexOf("dataset") !=-1) configObj["dataStr"]= encodeURI(data); + else configObj["data"]= data; + var swfURL = this.baseURL+"swf/"+chartType+"_chart.swf"; + for(var node in extendConfig) {configObj[node] = extendConfig[node];} + if(configObj.id) {this.attributes.id = configObj.id;this.attributes.name = configObj.id} + swfobject.embedSWF(swfURL,container, "100%", "100%", "9.0.0", "playerProductInstall.swf",configObj, this.params,this.attributes); + } + /** + * @todo:JS获取图形报表JsonData + * @date:2010-12-20 11:04 + * @author:lovejes + * @param config: 传入:{"yTitle":"访问数","categoryField":"日期","yField":"","benchmark":""}; + yTitle: 必须 + categoryField :必须 + yField :"" + benchmark :可以"" 或者是"参考线" 那么图形就会显示出来参考线 + * @param dataset: 传入: + {"日期":"6月1日","参考线":"100","杭州":"110","宁波":"120","温州":"130","台州":"110","丽水":"120","绍兴":"110"} + {"日期":"6月2日","参考线":"100","温州":"130","台州":"120","杭州":"150","宁波":"110","丽水":"110","绍兴":"130"} + {"日期":"6月3日","参考线":"100","杭州":"130","宁波":"130","温州":"130","台州":"130","绍兴":"130"} + {"日期":"6月4日","参考线":"100","绍兴":"130"} + ... + * @param _defData: 这个数据主要封装成yField用,支持排序 + 传入:{"杭州":"1","丽水":"5","绍兴":"6","宁波":"2","温州":"3","台州":"4"} + 1,2,3,4,5,6 是排序号,顺序可以乱,如果不要排序,默认可以为0 + 这样解析就是yField="杭州,宁波,温州,台州,丽水,绍兴" + * @param _defVal: 比如6月4号 杭州,宁波,温州等没有数据,传入一个默认值:0 + * @remark 线图,柱图,条图,饼图 已经通过测试,其它会尽快更新 + */ + ,getJsonData : function(config,dataset,_defData,_defVal){ + var _defArr = new Array(); + for(pop in _defData){ + _defArr.push(_defData[pop]+"_"+pop); + } + _defArr.sort(function(a,b){//从小到大排序 + a = parseInt(a.split("_")[0]); + b = parseInt(b.split("_")[0]); + return a-b; + }) + var yField = ""; + for(var n=0;n<_defArr.length;n++){ + //alert(_defArr[n]); + if(n==0) yField += _defArr[n].split("_")[1]; + else yField += ","+_defArr[n].split("_")[1]; + } + if(config["benchmark"] && config["benchmark"] != "") yField += ","+config["benchmark"];//是否需要参考线 + config["yField"]=yField; + for(var i=0;i + is released under the MIT License +*/ + +var swfobject = function() { + + var UNDEF = "undefined", + OBJECT = "object", + SHOCKWAVE_FLASH = "Shockwave Flash", + SHOCKWAVE_FLASH_AX = "ShockwaveFlash.ShockwaveFlash", + FLASH_MIME_TYPE = "application/x-shockwave-flash", + EXPRESS_INSTALL_ID = "SWFObjectExprInst", + ON_READY_STATE_CHANGE = "onreadystatechange", + + win = window, + doc = document, + nav = navigator, + + plugin = false, + domLoadFnArr = [main], + regObjArr = [], + objIdArr = [], + listenersArr = [], + storedAltContent, + storedAltContentId, + storedCallbackFn, + storedCallbackObj, + isDomLoaded = false, + isExpressInstallActive = false, + dynamicStylesheet, + dynamicStylesheetMedia, + autoHideShow = true, + + /* Centralized function for browser feature detection + - User agent string detection is only used when no good alternative is possible + - Is executed directly for optimal performance + */ + ua = function() { + var w3cdom = typeof doc.getElementById != UNDEF && typeof doc.getElementsByTagName != UNDEF && typeof doc.createElement != UNDEF, + u = nav.userAgent.toLowerCase(), + p = nav.platform.toLowerCase(), + windows = p ? /win/.test(p) : /win/.test(u), + mac = p ? /mac/.test(p) : /mac/.test(u), + webkit = /webkit/.test(u) ? parseFloat(u.replace(/^.*webkit\/(\d+(\.\d+)?).*$/, "$1")) : false, // returns either the webkit version or false if not webkit + ie = !+"\v1", // feature detection based on Andrea Giammarchi's solution: http://webreflection.blogspot.com/2009/01/32-bytes-to-know-if-your-browser-is-ie.html + playerVersion = [0,0,0], + d = null; + if (typeof nav.plugins != UNDEF && typeof nav.plugins[SHOCKWAVE_FLASH] == OBJECT) { + d = nav.plugins[SHOCKWAVE_FLASH].description; + if (d && !(typeof nav.mimeTypes != UNDEF && nav.mimeTypes[FLASH_MIME_TYPE] && !nav.mimeTypes[FLASH_MIME_TYPE].enabledPlugin)) { // navigator.mimeTypes["application/x-shockwave-flash"].enabledPlugin indicates whether plug-ins are enabled or disabled in Safari 3+ + plugin = true; + ie = false; // cascaded feature detection for Internet Explorer + d = d.replace(/^.*\s+(\S+\s+\S+$)/, "$1"); + playerVersion[0] = parseInt(d.replace(/^(.*)\..*$/, "$1"), 10); + playerVersion[1] = parseInt(d.replace(/^.*\.(.*)\s.*$/, "$1"), 10); + playerVersion[2] = /[a-zA-Z]/.test(d) ? parseInt(d.replace(/^.*[a-zA-Z]+(.*)$/, "$1"), 10) : 0; + } + } + else if (typeof win.ActiveXObject != UNDEF) { + try { + var a = new ActiveXObject(SHOCKWAVE_FLASH_AX); + if (a) { // a will return null when ActiveX is disabled + d = a.GetVariable("$version"); + if (d) { + ie = true; // cascaded feature detection for Internet Explorer + d = d.split(" ")[1].split(","); + playerVersion = [parseInt(d[0], 10), parseInt(d[1], 10), parseInt(d[2], 10)]; + } + } + } + catch(e) {} + } + return { w3:w3cdom, pv:playerVersion, wk:webkit, ie:ie, win:windows, mac:mac }; + }(), + + /* Cross-browser onDomLoad + - Will fire an event as soon as the DOM of a web page is loaded + - Internet Explorer workaround based on Diego Perini's solution: http://javascript.nwbox.com/IEContentLoaded/ + - Regular onload serves as fallback + */ + onDomLoad = function() { + if (!ua.w3) { return; } + if ((typeof doc.readyState != UNDEF && doc.readyState == "complete") || (typeof doc.readyState == UNDEF && (doc.getElementsByTagName("body")[0] || doc.body))) { // function is fired after onload, e.g. when script is inserted dynamically + callDomLoadFunctions(); + } + if (!isDomLoaded) { + if (typeof doc.addEventListener != UNDEF) { + doc.addEventListener("DOMContentLoaded", callDomLoadFunctions, false); + } + if (ua.ie && ua.win) { + doc.attachEvent(ON_READY_STATE_CHANGE, function() { + if (doc.readyState == "complete") { + doc.detachEvent(ON_READY_STATE_CHANGE, arguments.callee); + callDomLoadFunctions(); + } + }); + if (win == top) { // if not inside an iframe + (function(){ + if (isDomLoaded) { return; } + try { + doc.documentElement.doScroll("left"); + } + catch(e) { + setTimeout(arguments.callee, 0); + return; + } + callDomLoadFunctions(); + })(); + } + } + if (ua.wk) { + (function(){ + if (isDomLoaded) { return; } + if (!/loaded|complete/.test(doc.readyState)) { + setTimeout(arguments.callee, 0); + return; + } + callDomLoadFunctions(); + })(); + } + addLoadEvent(callDomLoadFunctions); + } + }(); + + function callDomLoadFunctions() { + if (isDomLoaded) { return; } + try { // test if we can really add/remove elements to/from the DOM; we don't want to fire it too early + var t = doc.getElementsByTagName("body")[0].appendChild(createElement("span")); + t.parentNode.removeChild(t); + } + catch (e) { return; } + isDomLoaded = true; + var dl = domLoadFnArr.length; + for (var i = 0; i < dl; i++) { + domLoadFnArr[i](); + } + } + + function addDomLoadEvent(fn) { + if (isDomLoaded) { + fn(); + } + else { + domLoadFnArr[domLoadFnArr.length] = fn; // Array.push() is only available in IE5.5+ + } + } + + /* Cross-browser onload + - Based on James Edwards' solution: http://brothercake.com/site/resources/scripts/onload/ + - Will fire an event as soon as a web page including all of its assets are loaded + */ + function addLoadEvent(fn) { + if (typeof win.addEventListener != UNDEF) { + win.addEventListener("load", fn, false); + } + else if (typeof doc.addEventListener != UNDEF) { + doc.addEventListener("load", fn, false); + } + else if (typeof win.attachEvent != UNDEF) { + addListener(win, "onload", fn); + } + else if (typeof win.onload == "function") { + var fnOld = win.onload; + win.onload = function() { + fnOld(); + fn(); + }; + } + else { + win.onload = fn; + } + } + + /* Main function + - Will preferably execute onDomLoad, otherwise onload (as a fallback) + */ + function main() { + if (plugin) { + testPlayerVersion(); + } + else { + matchVersions(); + } + } + + /* Detect the Flash Player version for non-Internet Explorer browsers + - Detecting the plug-in version via the object element is more precise than using the plugins collection item's description: + a. Both release and build numbers can be detected + b. Avoid wrong descriptions by corrupt installers provided by Adobe + c. Avoid wrong descriptions by multiple Flash Player entries in the plugin Array, caused by incorrect browser imports + - Disadvantage of this method is that it depends on the availability of the DOM, while the plugins collection is immediately available + */ + function testPlayerVersion() { + var b = doc.getElementsByTagName("body")[0]; + var o = createElement(OBJECT); + o.setAttribute("type", FLASH_MIME_TYPE); + var t = b.appendChild(o); + if (t) { + var counter = 0; + (function(){ + if (typeof t.GetVariable != UNDEF) { + var d = t.GetVariable("$version"); + if (d) { + d = d.split(" ")[1].split(","); + ua.pv = [parseInt(d[0], 10), parseInt(d[1], 10), parseInt(d[2], 10)]; + } + } + else if (counter < 10) { + counter++; + setTimeout(arguments.callee, 10); + return; + } + b.removeChild(o); + t = null; + matchVersions(); + })(); + } + else { + matchVersions(); + } + } + + /* Perform Flash Player and SWF version matching; static publishing only + */ + function matchVersions() { + var rl = regObjArr.length; + if (rl > 0) { + for (var i = 0; i < rl; i++) { // for each registered object element + var id = regObjArr[i].id; + var cb = regObjArr[i].callbackFn; + var cbObj = {success:false, id:id}; + if (ua.pv[0] > 0) { + var obj = getElementById(id); + if (obj) { + if (hasPlayerVersion(regObjArr[i].swfVersion) && !(ua.wk && ua.wk < 312)) { // Flash Player version >= published SWF version: Houston, we have a match! + setVisibility(id, true); + if (cb) { + cbObj.success = true; + cbObj.ref = getObjectById(id); + cb(cbObj); + } + } + else if (regObjArr[i].expressInstall && canExpressInstall()) { // show the Adobe Express Install dialog if set by the web page author and if supported + var att = {}; + att.data = regObjArr[i].expressInstall; + att.width = obj.getAttribute("width") || "0"; + att.height = obj.getAttribute("height") || "0"; + if (obj.getAttribute("class")) { att.styleclass = obj.getAttribute("class"); } + if (obj.getAttribute("align")) { att.align = obj.getAttribute("align"); } + // parse HTML object param element's name-value pairs + var par = {}; + var p = obj.getElementsByTagName("param"); + var pl = p.length; + for (var j = 0; j < pl; j++) { + if (p[j].getAttribute("name").toLowerCase() != "movie") { + par[p[j].getAttribute("name")] = p[j].getAttribute("value"); + } + } + showExpressInstall(att, par, id, cb); + } + else { // Flash Player and SWF version mismatch or an older Webkit engine that ignores the HTML object element's nested param elements: display alternative content instead of SWF + displayAltContent(obj); + if (cb) { cb(cbObj); } + } + } + } + else { // if no Flash Player is installed or the fp version cannot be detected we let the HTML object element do its job (either show a SWF or alternative content) + setVisibility(id, true); + if (cb) { + var o = getObjectById(id); // test whether there is an HTML object element or not + if (o && typeof o.SetVariable != UNDEF) { + cbObj.success = true; + cbObj.ref = o; + } + cb(cbObj); + } + } + } + } + } + + function getObjectById(objectIdStr) { + var r = null; + var o = getElementById(objectIdStr); + if (o && o.nodeName == "OBJECT") { + if (typeof o.SetVariable != UNDEF) { + r = o; + } + else { + var n = o.getElementsByTagName(OBJECT)[0]; + if (n) { + r = n; + } + } + } + return r; + } + + /* Requirements for Adobe Express Install + - only one instance can be active at a time + - fp 6.0.65 or higher + - Win/Mac OS only + - no Webkit engines older than version 312 + */ + function canExpressInstall() { + return !isExpressInstallActive && hasPlayerVersion("6.0.65") && (ua.win || ua.mac) && !(ua.wk && ua.wk < 312); + } + + /* Show the Adobe Express Install dialog + - Reference: http://www.adobe.com/cfusion/knowledgebase/index.cfm?id=6a253b75 + */ + function showExpressInstall(att, par, replaceElemIdStr, callbackFn) { + isExpressInstallActive = true; + storedCallbackFn = callbackFn || null; + storedCallbackObj = {success:false, id:replaceElemIdStr}; + var obj = getElementById(replaceElemIdStr); + if (obj) { + if (obj.nodeName == "OBJECT") { // static publishing + storedAltContent = abstractAltContent(obj); + storedAltContentId = null; + } + else { // dynamic publishing + storedAltContent = obj; + storedAltContentId = replaceElemIdStr; + } + att.id = EXPRESS_INSTALL_ID; + if (typeof att.width == UNDEF || (!/%$/.test(att.width) && parseInt(att.width, 10) < 310)) { att.width = "310"; } + if (typeof att.height == UNDEF || (!/%$/.test(att.height) && parseInt(att.height, 10) < 137)) { att.height = "137"; } + doc.title = doc.title.slice(0, 47) + " - Flash Player Installation"; + var pt = ua.ie && ua.win ? "ActiveX" : "PlugIn", + fv = "MMredirectURL=" + encodeURI(window.location).toString().replace(/&/g,"%26") + "&MMplayerType=" + pt + "&MMdoctitle=" + doc.title; + if (typeof par.flashvars != UNDEF) { + par.flashvars += "&" + fv; + } + else { + par.flashvars = fv; + } + // IE only: when a SWF is loading (AND: not available in cache) wait for the readyState of the object element to become 4 before removing it, + // because you cannot properly cancel a loading SWF file without breaking browser load references, also obj.onreadystatechange doesn't work + if (ua.ie && ua.win && obj.readyState != 4) { + var newObj = createElement("div"); + replaceElemIdStr += "SWFObjectNew"; + newObj.setAttribute("id", replaceElemIdStr); + obj.parentNode.insertBefore(newObj, obj); // insert placeholder div that will be replaced by the object element that loads expressinstall.swf + obj.style.display = "none"; + (function(){ + if (obj.readyState == 4) { + obj.parentNode.removeChild(obj); + } + else { + setTimeout(arguments.callee, 10); + } + })(); + } + createSWF(att, par, replaceElemIdStr); + } + } + + /* Functions to abstract and display alternative content + */ + function displayAltContent(obj) { + if (ua.ie && ua.win && obj.readyState != 4) { + // IE only: when a SWF is loading (AND: not available in cache) wait for the readyState of the object element to become 4 before removing it, + // because you cannot properly cancel a loading SWF file without breaking browser load references, also obj.onreadystatechange doesn't work + var el = createElement("div"); + obj.parentNode.insertBefore(el, obj); // insert placeholder div that will be replaced by the alternative content + el.parentNode.replaceChild(abstractAltContent(obj), el); + obj.style.display = "none"; + (function(){ + if (obj.readyState == 4) { + obj.parentNode.removeChild(obj); + } + else { + setTimeout(arguments.callee, 10); + } + })(); + } + else { + obj.parentNode.replaceChild(abstractAltContent(obj), obj); + } + } + + function abstractAltContent(obj) { + var ac = createElement("div"); + if (ua.win && ua.ie) { + ac.innerHTML = obj.innerHTML; + } + else { + var nestedObj = obj.getElementsByTagName(OBJECT)[0]; + if (nestedObj) { + var c = nestedObj.childNodes; + if (c) { + var cl = c.length; + for (var i = 0; i < cl; i++) { + if (!(c[i].nodeType == 1 && c[i].nodeName == "PARAM") && !(c[i].nodeType == 8)) { + ac.appendChild(c[i].cloneNode(true)); + } + } + } + } + } + return ac; + } + + /* Cross-browser dynamic SWF creation + */ + function createSWF(attObj, parObj, id) { + var r, el = getElementById(id); + if (ua.wk && ua.wk < 312) { return r; } + if (el) { + if (typeof attObj.id == UNDEF) { // if no 'id' is defined for the object element, it will inherit the 'id' from the alternative content + attObj.id = id; + } + if (ua.ie && ua.win) { // Internet Explorer + the HTML object element + W3C DOM methods do not combine: fall back to outerHTML + var att = ""; + for (var i in attObj) { + if (attObj[i] != Object.prototype[i]) { // filter out prototype additions from other potential libraries + if (i.toLowerCase() == "data") { + parObj.movie = attObj[i]; + } + else if (i.toLowerCase() == "styleclass") { // 'class' is an ECMA4 reserved keyword + att += ' class="' + attObj[i] + '"'; + } + else if (i.toLowerCase() != "classid") { + att += ' ' + i + '="' + attObj[i] + '"'; + } + } + } + var par = ""; + for (var j in parObj) { + if (parObj[j] != Object.prototype[j]) { // filter out prototype additions from other potential libraries + par += ''; + } + } + el.outerHTML = '' + par + ''; + objIdArr[objIdArr.length] = attObj.id; // stored to fix object 'leaks' on unload (dynamic publishing only) + r = getElementById(attObj.id); + } + else { // well-behaving browsers + var o = createElement(OBJECT); + o.setAttribute("type", FLASH_MIME_TYPE); + for (var m in attObj) { + if (attObj[m] != Object.prototype[m]) { // filter out prototype additions from other potential libraries + if (m.toLowerCase() == "styleclass") { // 'class' is an ECMA4 reserved keyword + o.setAttribute("class", attObj[m]); + } + else if (m.toLowerCase() != "classid") { // filter out IE specific attribute + o.setAttribute(m, attObj[m]); + } + } + } + for (var n in parObj) { + if (parObj[n] != Object.prototype[n] && n.toLowerCase() != "movie") { // filter out prototype additions from other potential libraries and IE specific param element + createObjParam(o, n, parObj[n]); + } + } + el.parentNode.replaceChild(o, el); + r = o; + } + } + return r; + } + + function createObjParam(el, pName, pValue) { + var p = createElement("param"); + p.setAttribute("name", pName); + p.setAttribute("value", pValue); + el.appendChild(p); + } + + /* Cross-browser SWF removal + - Especially needed to safely and completely remove a SWF in Internet Explorer + */ + function removeSWF(id) { + var obj = getElementById(id); + if (obj && obj.nodeName == "OBJECT") { + if (ua.ie && ua.win) { + obj.style.display = "none"; + (function(){ + if (obj.readyState == 4) { + removeObjectInIE(id); + } + else { + setTimeout(arguments.callee, 10); + } + })(); + } + else { + obj.parentNode.removeChild(obj); + } + } + } + + function removeObjectInIE(id) { + var obj = getElementById(id); + if (obj) { + for (var i in obj) { + if (typeof obj[i] == "function") { + obj[i] = null; + } + } + obj.parentNode.removeChild(obj); + } + } + + /* Functions to optimize JavaScript compression + */ + function getElementById(id) { + var el = null; + try { + el = doc.getElementById(id); + } + catch (e) {} + return el; + } + + function createElement(el) { + return doc.createElement(el); + } + + /* Updated attachEvent function for Internet Explorer + - Stores attachEvent information in an Array, so on unload the detachEvent functions can be called to avoid memory leaks + */ + function addListener(target, eventType, fn) { + target.attachEvent(eventType, fn); + listenersArr[listenersArr.length] = [target, eventType, fn]; + } + + /* Flash Player and SWF content version matching + */ + function hasPlayerVersion(rv) { + var pv = ua.pv, v = rv.split("."); + v[0] = parseInt(v[0], 10); + v[1] = parseInt(v[1], 10) || 0; // supports short notation, e.g. "9" instead of "9.0.0" + v[2] = parseInt(v[2], 10) || 0; + return (pv[0] > v[0] || (pv[0] == v[0] && pv[1] > v[1]) || (pv[0] == v[0] && pv[1] == v[1] && pv[2] >= v[2])) ? true : false; + } + + /* Cross-browser dynamic CSS creation + - Based on Bobby van der Sluis' solution: http://www.bobbyvandersluis.com/articles/dynamicCSS.php + */ + function createCSS(sel, decl, media, newStyle) { + if (ua.ie && ua.mac) { return; } + var h = doc.getElementsByTagName("head")[0]; + if (!h) { return; } // to also support badly authored HTML pages that lack a head element + var m = (media && typeof media == "string") ? media : "screen"; + if (newStyle) { + dynamicStylesheet = null; + dynamicStylesheetMedia = null; + } + if (!dynamicStylesheet || dynamicStylesheetMedia != m) { + // create dynamic stylesheet + get a global reference to it + var s = createElement("style"); + s.setAttribute("type", "text/css"); + s.setAttribute("media", m); + dynamicStylesheet = h.appendChild(s); + if (ua.ie && ua.win && typeof doc.styleSheets != UNDEF && doc.styleSheets.length > 0) { + dynamicStylesheet = doc.styleSheets[doc.styleSheets.length - 1]; + } + dynamicStylesheetMedia = m; + } + // add style rule + if (ua.ie && ua.win) { + if (dynamicStylesheet && typeof dynamicStylesheet.addRule == OBJECT) { + dynamicStylesheet.addRule(sel, decl); + } + } + else { + if (dynamicStylesheet && typeof doc.createTextNode != UNDEF) { + dynamicStylesheet.appendChild(doc.createTextNode(sel + " {" + decl + "}")); + } + } + } + + function setVisibility(id, isVisible) { + if (!autoHideShow) { return; } + var v = isVisible ? "visible" : "hidden"; + if (isDomLoaded && getElementById(id)) { + getElementById(id).style.visibility = v; + } + else { + createCSS("#" + id, "visibility:" + v); + } + } + + /* Filter to avoid XSS attacks + */ + function urlEncodeIfNecessary(s) { + var regex = /[\\\"<>\.;]/; + var hasBadChars = regex.exec(s) != null; + return hasBadChars && typeof encodeURIComponent != UNDEF ? encodeURIComponent(s) : s; + } + + /* Release memory to avoid memory leaks caused by closures, fix hanging audio/video threads and force open sockets/NetConnections to disconnect (Internet Explorer only) + */ + var cleanup = function() { + if (ua.ie && ua.win) { + window.attachEvent("onunload", function() { + // remove listeners to avoid memory leaks + var ll = listenersArr.length; + for (var i = 0; i < ll; i++) { + listenersArr[i][0].detachEvent(listenersArr[i][1], listenersArr[i][2]); + } + // cleanup dynamically embedded objects to fix audio/video threads and force open sockets and NetConnections to disconnect + var il = objIdArr.length; + for (var j = 0; j < il; j++) { + removeSWF(objIdArr[j]); + } + // cleanup library's main closures to avoid memory leaks + for (var k in ua) { + ua[k] = null; + } + ua = null; + for (var l in swfobject) { + swfobject[l] = null; + } + swfobject = null; + }); + } + }(); + + return { + /* Public API + - Reference: http://code.google.com/p/swfobject/wiki/documentation + */ + registerObject: function(objectIdStr, swfVersionStr, xiSwfUrlStr, callbackFn) { + if (ua.w3 && objectIdStr && swfVersionStr) { + var regObj = {}; + regObj.id = objectIdStr; + regObj.swfVersion = swfVersionStr; + regObj.expressInstall = xiSwfUrlStr; + regObj.callbackFn = callbackFn; + regObjArr[regObjArr.length] = regObj; + setVisibility(objectIdStr, false); + } + else if (callbackFn) { + callbackFn({success:false, id:objectIdStr}); + } + }, + + getObjectById: function(objectIdStr) { + if (ua.w3) { + return getObjectById(objectIdStr); + } + }, + + embedSWF: function(swfUrlStr, replaceElemIdStr, widthStr, heightStr, swfVersionStr, xiSwfUrlStr, flashvarsObj, parObj, attObj, callbackFn) { + var callbackObj = {success:false, id:replaceElemIdStr}; + if (ua.w3 && !(ua.wk && ua.wk < 312) && swfUrlStr && replaceElemIdStr && widthStr && heightStr && swfVersionStr) { + setVisibility(replaceElemIdStr, false); + addDomLoadEvent(function() { + widthStr += ""; // auto-convert to string + heightStr += ""; + var att = {}; + if (attObj && typeof attObj === OBJECT) { + for (var i in attObj) { // copy object to avoid the use of references, because web authors often reuse attObj for multiple SWFs + att[i] = attObj[i]; + } + } + att.data = swfUrlStr; + att.width = widthStr; + att.height = heightStr; + var par = {}; + if (parObj && typeof parObj === OBJECT) { + for (var j in parObj) { // copy object to avoid the use of references, because web authors often reuse parObj for multiple SWFs + par[j] = parObj[j]; + } + } + if (flashvarsObj && typeof flashvarsObj === OBJECT) { + for (var k in flashvarsObj) { // copy object to avoid the use of references, because web authors often reuse flashvarsObj for multiple SWFs + if (typeof par.flashvars != UNDEF) { + par.flashvars += "&" + k + "=" + flashvarsObj[k]; + } + else { + par.flashvars = k + "=" + flashvarsObj[k]; + } + } + } + if (hasPlayerVersion(swfVersionStr)) { // create SWF + var obj = createSWF(att, par, replaceElemIdStr); + if (att.id == replaceElemIdStr) { + setVisibility(replaceElemIdStr, true); + } + callbackObj.success = true; + callbackObj.ref = obj; + } + else if (xiSwfUrlStr && canExpressInstall()) { // show Adobe Express Install + att.data = xiSwfUrlStr; + showExpressInstall(att, par, replaceElemIdStr, callbackFn); + return; + } + else { // show alternative content + setVisibility(replaceElemIdStr, true); + } + if (callbackFn) { callbackFn(callbackObj); } + }); + } + else if (callbackFn) { callbackFn(callbackObj); } + }, + + switchOffAutoHideShow: function() { + autoHideShow = false; + }, + + ua: ua, + + getFlashPlayerVersion: function() { + return { major:ua.pv[0], minor:ua.pv[1], release:ua.pv[2] }; + }, + + hasFlashPlayerVersion: hasPlayerVersion, + + createSWF: function(attObj, parObj, replaceElemIdStr) { + if (ua.w3) { + return createSWF(attObj, parObj, replaceElemIdStr); + } + else { + return undefined; + } + }, + + showExpressInstall: function(att, par, replaceElemIdStr, callbackFn) { + if (ua.w3 && canExpressInstall()) { + showExpressInstall(att, par, replaceElemIdStr, callbackFn); + } + }, + + removeSWF: function(objElemIdStr) { + if (ua.w3) { + removeSWF(objElemIdStr); + } + }, + + createCSS: function(selStr, declStr, mediaStr, newStyleBoolean) { + if (ua.w3) { + createCSS(selStr, declStr, mediaStr, newStyleBoolean); + } + }, + + addDomLoadEvent: addDomLoadEvent, + + addLoadEvent: addLoadEvent, + + getQueryParamValue: function(param) { + var q = doc.location.search || doc.location.hash; + if (q) { + if (/\?/.test(q)) { q = q.split("?")[1]; } // strip question mark + if (param == null) { + return urlEncodeIfNecessary(q); + } + var pairs = q.split("&"); + for (var i = 0; i < pairs.length; i++) { + if (pairs[i].substring(0, pairs[i].indexOf("=")) == param) { + return urlEncodeIfNecessary(pairs[i].substring((pairs[i].indexOf("=") + 1))); + } + } + } + return ""; + }, + + // For internal usage only + expressInstallCallback: function() { + if (isExpressInstallActive) { + var obj = getElementById(EXPRESS_INSTALL_ID); + if (obj && storedAltContent) { + obj.parentNode.replaceChild(storedAltContent, obj); + if (storedAltContentId) { + setVisibility(storedAltContentId, true); + if (ua.ie && ua.win) { storedAltContent.style.display = "block"; } + } + if (storedCallbackFn) { storedCallbackFn(storedCallbackObj); } + } + isExpressInstallActive = false; + } + } + }; +}(); diff --git a/site/download/finger-chart-0.8/readme.html b/site/download/finger-chart-0.8/readme.html new file mode 100644 index 0000000..7959e85 --- /dev/null +++ b/site/download/finger-chart-0.8/readme.html @@ -0,0 +1,27 @@ + + + + + + + +Finger Chart read me + + + +

Finger Chart

+
chart here
+ +

Finger Chart是一个轻量级的基于Flash技术开发的图表解决方案(未来考虑扩展到HTML5平台),由RIAMeeting社区推出,并基于LGPL协议开源。图表包括常见图表类型,包含线图,柱图,条图,饼图,区域图,散点图,气泡图等; Finger的应用目标是:Web应用和移动应用,因此也可以看出图表命名的初衷,即保持轻量级和较小的资源占用,以在有限的硬件资源下获得平稳流畅的运行。

+

详细用法与教程参见:

+

http://www.riameeting.com/fingerchart/

+ + diff --git a/site/download/finger-chart-0.8/swf/area_chart.swf b/site/download/finger-chart-0.8/swf/area_chart.swf new file mode 100644 index 0000000..5a44e98 Binary files /dev/null and b/site/download/finger-chart-0.8/swf/area_chart.swf differ diff --git a/site/download/finger-chart-0.8/swf/bar_chart.swf b/site/download/finger-chart-0.8/swf/bar_chart.swf new file mode 100644 index 0000000..5350417 Binary files /dev/null and b/site/download/finger-chart-0.8/swf/bar_chart.swf differ diff --git a/site/download/finger-chart-0.8/swf/bubble_chart.swf b/site/download/finger-chart-0.8/swf/bubble_chart.swf new file mode 100644 index 0000000..4b68631 Binary files /dev/null and b/site/download/finger-chart-0.8/swf/bubble_chart.swf differ diff --git a/site/download/finger-chart-0.8/swf/column_chart.swf b/site/download/finger-chart-0.8/swf/column_chart.swf new file mode 100644 index 0000000..6119552 Binary files /dev/null and b/site/download/finger-chart-0.8/swf/column_chart.swf differ diff --git a/site/download/finger-chart-0.8/swf/line_chart.swf b/site/download/finger-chart-0.8/swf/line_chart.swf new file mode 100644 index 0000000..f5929ff Binary files /dev/null and b/site/download/finger-chart-0.8/swf/line_chart.swf differ diff --git a/site/download/finger-chart-0.8/swf/pie_chart.swf b/site/download/finger-chart-0.8/swf/pie_chart.swf new file mode 100644 index 0000000..81880a9 Binary files /dev/null and b/site/download/finger-chart-0.8/swf/pie_chart.swf differ diff --git a/site/download/finger-chart-0.8/swf/plot_chart.swf b/site/download/finger-chart-0.8/swf/plot_chart.swf new file mode 100644 index 0000000..8d927ea Binary files /dev/null and b/site/download/finger-chart-0.8/swf/plot_chart.swf differ diff --git a/site/download/finger-flashpro-component.mxp b/site/download/finger-flashpro-component.mxp new file mode 100644 index 0000000..6e5a37a Binary files /dev/null and b/site/download/finger-flashpro-component.mxp differ diff --git a/site/guide.html b/site/guide.html new file mode 100644 index 0000000..7ff5a1d --- /dev/null +++ b/site/guide.html @@ -0,0 +1,62 @@ + + + + +Finger Chart + + + + + + + + + + + + + + diff --git a/site/image/all.png b/site/image/all.png new file mode 100644 index 0000000..c7e4250 Binary files /dev/null and b/site/image/all.png differ diff --git a/site/image/check_frame.js b/site/image/check_frame.js new file mode 100644 index 0000000..33cf39c --- /dev/null +++ b/site/image/check_frame.js @@ -0,0 +1,18 @@ +// JavaScript Document by Finger +function checkFrameHeight() { + var iframeid = document.getElementById("docFrame"); //iframe id + iframeid.height = "0px";//先给一个够小的初值,然后再长高. + if (document.getElementById) { + if (iframeid && !window.opera) { + if (iframeid.contentDocument && iframeid.contentDocument.body.offsetHeight) { + iframeid.height = iframeid.contentDocument.body.offsetHeight+100; + } else if (iframeid.Document && iframeid.Document.body.scrollHeight) { + iframeid.height = iframeid.Document.body.scrollHeight+100; + } + } + }else{ + if(iframeid.contentWindow.document && iframeid.contentWindow.document.body.scrollHeight) { + iframeid.height = iframeid.contentWindow.document.body.scrollHeight;//Opera + } + } +} \ No newline at end of file diff --git a/site/image/children.jpg b/site/image/children.jpg new file mode 100644 index 0000000..cc9a8d0 Binary files /dev/null and b/site/image/children.jpg differ diff --git a/site/image/icon_left.gif b/site/image/icon_left.gif new file mode 100644 index 0000000..4aac0f0 Binary files /dev/null and b/site/image/icon_left.gif differ diff --git a/site/image/line1.png b/site/image/line1.png new file mode 100644 index 0000000..25d7295 Binary files /dev/null and b/site/image/line1.png differ diff --git a/site/image/line2.png b/site/image/line2.png new file mode 100644 index 0000000..4895e65 Binary files /dev/null and b/site/image/line2.png differ diff --git a/site/image/line3.png b/site/image/line3.png new file mode 100644 index 0000000..cf787db Binary files /dev/null and b/site/image/line3.png differ diff --git a/site/image/line4.png b/site/image/line4.png new file mode 100644 index 0000000..1da36e7 Binary files /dev/null and b/site/image/line4.png differ diff --git a/site/image/line5.png b/site/image/line5.png new file mode 100644 index 0000000..acc3f59 Binary files /dev/null and b/site/image/line5.png differ diff --git a/site/image/line6.png b/site/image/line6.png new file mode 100644 index 0000000..1d9e425 Binary files /dev/null and b/site/image/line6.png differ diff --git a/site/image/logo2.png b/site/image/logo2.png new file mode 100644 index 0000000..843e063 Binary files /dev/null and b/site/image/logo2.png differ diff --git a/site/image/page_bg.gif b/site/image/page_bg.gif new file mode 100644 index 0000000..03862c5 Binary files /dev/null and b/site/image/page_bg.gif differ diff --git a/site/image/pie1.png b/site/image/pie1.png new file mode 100644 index 0000000..7a654f5 Binary files /dev/null and b/site/image/pie1.png differ diff --git a/site/image/pixel-gray.gif b/site/image/pixel-gray.gif new file mode 100644 index 0000000..f1edaa0 Binary files /dev/null and b/site/image/pixel-gray.gif differ diff --git a/site/index.html b/site/index.html new file mode 100644 index 0000000..7d1e4d7 --- /dev/null +++ b/site/index.html @@ -0,0 +1,65 @@ + + + + +Finger Chart + + + + +
+

Finger Chart (以下简称Finger)是一个轻量级的基于Flash技术开发的图表解决方案(未来考虑扩展到HTML5平台),由RIAMeeting社区推出,并基于LGPL协议开源。图表包括常见图表类型,包含线图,柱图,条图,饼图,区域图,散点图,气泡图等; Finger的应用目标是:Web应用和移动应用,因此也可以看出图表命名的初衷,即保持轻量级和较小的资源占用,以在有限的硬件资源下获得平稳流畅的运行。

+

Finger包含3个开发主体:

+
    +
  1. 基于AS3开发的图表展现
  2. +
  3. 基于JavaScript实现的图表HTML嵌入
  4. +
  5. 针对服务器端代码开发的类库(基于使用者的贡献)
  6. +
+

Finger具备如下的主要特点和设计初衷:

+
    +
  1. 轻量级:图表基于纯ActionScript开发,并不断得到优化,使得图表可以保持较小的体积和较小的资源占用率。
  2. +
  3. 易用:对前端工程师而言,使用封装的JavaScript类库让您可以很方便的将图表嵌入HTML。而对于后端程序员,使用针对服务器端代码开发的类库让您可以更方便的与项目代码集成。
  4. +
  5. 灵活的外观定义方式:如果您对Finger默认的外观不满意,大可以进行自我定制。Finger的外观使用了两套彼此协作的机制:CSS和Skin,其中CSS使用网页通用的样式表属性进行描述,而Skin部分则允许您通过Flash Pro进行创建和修改。结合这两种方式,将给您的外观创建带来极大的灵活性。
  6. +
  7. 允许载入外部插件:您可以基于约定的接口创建一个插件,编译为单独的SWF文件,并在图表中载入,与图表协同工作。这种方式将让您在不需修改基本功能的条件下,完成一些额外的功能。
  8. +
  9. 可扩展的架构设计:Finger基于一个可扩展的架构来实现,各个图表组成部分都得到抽象并与具体实现相分离,图表则基于工厂模式来进行组装,在此基础上扩展其它类型的图表将会更加方便。
  10. +
  11. 可视化组件支持:未来版本将针对Flash Pro创建一个组件库,允许通过Flash Pro轻松应用图表组件并绑定数据源。
  12. +
+

点击这里查看简介PPT

+

我可以做什么?

+

Finger Chart是一个开源项目,它的发展离不开大家共同的参与。如果您喜欢Finger Chart,并希望为它扩展功能或弥补不足,欢迎加入Finger Chart开发小组(请进入论坛申请)。您可以贡献的部分包括:

+
    +
  1. 客户端Code:包括增加新的图表类型,新的皮肤等等
  2. +
  3. 服务器端Code:包括针对PHP,.NET,JAVA等后端技术的图表封装
  4. +
+

依赖

+

本项目部分源码引用了AS3CorelibTweenLite

+
+ + + + + + + + + diff --git a/site/log.html b/site/log.html new file mode 100644 index 0000000..7f80ee7 --- /dev/null +++ b/site/log.html @@ -0,0 +1,72 @@ + + + + +Finger Chart + + + + +
+

更新日志

+

Finger Chart持续更新中...

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
日期变更
2011-1-6修正了Demo在Oprea浏览器中无法显示的问题(感谢用户豪杰的代码)
2010-12-30修正了饼图上多出的一条线
2010-12-27修正了图例说明不能记忆状态的Bug,同时优化了SKIN机制
2010-12-26为图表增加的动态添加数据节点的API,修改了一些默认显示效果
2010-12-21感谢LoveJes的杰出工作,更新了finger.js
2010-12-15
  1. 修正了坐标系不支持负数的Bug
  2. 为图表增加了默认的样式和皮肤,所以您现在可以在不传递皮肤和CSS的情况下使用图表,当然如果您传递CSS和皮肤的话,就会以您的定义为准
  3. 增加了曲线显示模式
+
+ + + + + + + + + diff --git a/site/style/global.css b/site/style/global.css new file mode 100644 index 0000000..1c28c17 --- /dev/null +++ b/site/style/global.css @@ -0,0 +1,32 @@ +@charset "utf-8"; +/* CSS Document */ +body {font-size:12px; background:url(../image/pixel-gray.gif); font-size:14px;line-height:24px;} +body.doc {background:#FFF;} +h1 {font-family:Arial;font-size:32px;background:url(../image/logo2.png) no-repeat left top; text-indent:-9999px;height:80px;} +h2 {border-bottom:3px solid #CCC;} +a {color:#000;} +img {border:1px dotted #999; padding:3px; background:#FFF;} +h3 {border-bottom:1px dotted #CCC;background:url(../image/icon_left.gif) no-repeat;padding-left:30px;color:#F30;} +table {border:3px solid #CCC;} +table th {background:#CCC;color:#666} +table th,table td {border-right:1px solid #CCC;border-bottom:1px solid #CCC;text-align:left;padding:4px 10px;} +pre,code {display:block;border:1px dotted #CCC;background:#FFC;padding:5px; word-wrap:break-word;} +/*ID Define*/ +#wrapper {width:960px;margin:0 auto;background:url(../image/page_bg.gif) #FFF repeat-x left top;min-height:400px; border-bottom:3px solid #F60; padding:20px; overflow:auto;} +#header {width:1000px;margin:0 auto;height:76px;color:#FFF;} +#header h1 {margin:0; padding:0;padding:10px 0 0 20px} +#header em {font-size:12px; display:block; font-style:normal;} +#globalNav {position:absolute; top:38px;right:50%; margin:0;padding:0; margin-right:-500px;} +#globalNav li{list-style:none;display:inline; font-weight:bold;} +#globalNav li a{display:block; padding:6px 15px; background:#000; color:#FFF; float:left;margin-top:4px;margin-right:6px; text-decoration:none;} +#globalNav li.selected a{margin-top:0;padding-top:12px;padding-bottom:25px;background:#FFF;color:#F60;border-top:3px solid #F60;} +#globalNav li.outside a{border-top:3px solid #F60; background:#333; padding-bottom:3px;} +#siteInfo { position:absolute; top:15px; left:50%; width:480px; text-align:right;} +#siteInfo a {color:#CCC;} +#footer {height:40px;color:#CCC; text-align:center; line-height:40px;} +#footer a {color:#CCC;} +#docNav {width:180px;border-right:1px solid #CCC;float:left;} +#docFrame {float:left;} +/**/ +.swf {width:100%;height:300px;border:1px solid #CCC;} +.important {background:#F00;color:#FFF;} \ No newline at end of file diff --git a/tags/0.8/assets/fla/mxp/comps/AreaChartImp.as b/tags/0.8/assets/fla/mxp/comps/AreaChartImp.as new file mode 100644 index 0000000..4948553 --- /dev/null +++ b/tags/0.8/assets/fla/mxp/comps/AreaChartImp.as @@ -0,0 +1,15 @@ +package comps { + + import com.riameeting.finger.component.*; + import flash.display.DisplayObject; + + public class AreaChartImp extends LineChartImp { + + public function AreaChartImp() { + chart = new AreaChart(width,height); + super(); + } + + } + +} diff --git a/tags/0.8/assets/fla/mxp/comps/BarChartImp.as b/tags/0.8/assets/fla/mxp/comps/BarChartImp.as new file mode 100644 index 0000000..52b90fe --- /dev/null +++ b/tags/0.8/assets/fla/mxp/comps/BarChartImp.as @@ -0,0 +1,15 @@ +package comps { + + import com.riameeting.finger.component.*; + import flash.display.DisplayObject; + + public class BarChartImp extends LineChartImp { + + public function BarChartImp() { + chart = new BarChart(width,height); + super(); + } + + } + +} diff --git a/tags/0.8/assets/fla/mxp/comps/BubbleChartImp.as b/tags/0.8/assets/fla/mxp/comps/BubbleChartImp.as new file mode 100644 index 0000000..b08dc3c --- /dev/null +++ b/tags/0.8/assets/fla/mxp/comps/BubbleChartImp.as @@ -0,0 +1,15 @@ +package comps { + + import com.riameeting.finger.component.*; + import flash.display.DisplayObject; + + public class BubbleChartImp extends LineChartImp { + + public function BubbleChartImp() { + chart = new BubbleChart(width,height); + super(); + } + + } + +} diff --git a/tags/0.8/assets/fla/mxp/comps/ColumnChartImp.as b/tags/0.8/assets/fla/mxp/comps/ColumnChartImp.as new file mode 100644 index 0000000..a0a7baa --- /dev/null +++ b/tags/0.8/assets/fla/mxp/comps/ColumnChartImp.as @@ -0,0 +1,15 @@ +package comps { + + import com.riameeting.finger.component.*; + import flash.display.DisplayObject; + + public class ColumnChartImp extends LineChartImp { + + public function ColumnChartImp() { + chart = new ColumnChart(width,height); + super(); + } + + } + +} diff --git a/tags/0.8/assets/fla/mxp/comps/LineChartImp.as b/tags/0.8/assets/fla/mxp/comps/LineChartImp.as new file mode 100644 index 0000000..9737b7c --- /dev/null +++ b/tags/0.8/assets/fla/mxp/comps/LineChartImp.as @@ -0,0 +1,82 @@ +package comps { + import flash.display.Sprite; + import flash.display.MovieClip; + import com.riameeting.finger.display.chart.IChart; + import com.riameeting.finger.component.*; + + import fl.core.UIComponent; + import flash.utils.setTimeout; + import flash.display.DisplayObject; + import flash.text.TextField; + + public class LineChartImp extends UIComponent { + + private var _css:String; + private var _skin:String; + private var _data:String; + + protected var label:TextField = new TextField(); + + protected var chart:IChart; + protected var config:Object = {}; + + public function LineChartImp() { + label.text = "FingerChart"; + addChild(label); + if(chart == null) chart = new LineChart(width,height); + addChild(chart as DisplayObject); + drawNow(); + } + + [Inspectable(defaultValue="default.css")] + public function get css():String { + return _css; + } + public function set css(value:String):void { + _css = value; + } + + [Inspectable(defaultValue="default_skin.swf")] + public function get skin():String { + return _skin; + } + public function set skin(value:String):void { + _skin = value; + } + + [Inspectable(type="String")] + public function get data():String { + return _data; + } + public function set data(value:String):void { + if(value == null || value == "") return; + if(isLivePreview) return; + _data = value; + setTimeout(delayInvoke,500); + } + + private function delayInvoke():void { + config.css = css; + config.skin = skin; + config.data = data; + chart.chartConfig = config; + chart.loadAssets(); + } + + override protected function configUI():void { + super.configUI(); + } + + override protected function draw():void { + this.graphics.clear(); + this.graphics.beginFill(0x000000,0.2); + this.graphics.drawRect(0,0,width,height); + this.graphics.endFill(); + chart.width = width; + chart.height = height; + super.draw(); + } + + } + +} diff --git a/tags/0.8/assets/fla/mxp/comps/PieChartImp.as b/tags/0.8/assets/fla/mxp/comps/PieChartImp.as new file mode 100644 index 0000000..f8b1e81 --- /dev/null +++ b/tags/0.8/assets/fla/mxp/comps/PieChartImp.as @@ -0,0 +1,15 @@ +package comps { + + import com.riameeting.finger.component.*; + import flash.display.DisplayObject; + + public class PieChartImp extends LineChartImp { + + public function PieChartImp() { + chart = new PieChart(width,height); + super(); + } + + } + +} diff --git a/tags/0.8/assets/fla/mxp/comps/PlotChartImp.as b/tags/0.8/assets/fla/mxp/comps/PlotChartImp.as new file mode 100644 index 0000000..8f656de --- /dev/null +++ b/tags/0.8/assets/fla/mxp/comps/PlotChartImp.as @@ -0,0 +1,15 @@ +package comps { + + import com.riameeting.finger.component.*; + import flash.display.DisplayObject; + + public class PlotChartImp extends LineChartImp { + + public function PlotChartImp() { + chart = new PlotChart(width,height); + super(); + } + + } + +} diff --git a/tags/0.8/assets/fla/mxp/default.css b/tags/0.8/assets/fla/mxp/default.css new file mode 100644 index 0000000..9e1079b --- /dev/null +++ b/tags/0.8/assets/fla/mxp/default.css @@ -0,0 +1,7 @@ +global {color-collection:0xff0000 0xff0078 0xff00d2 0x9c00ff 0x0c00ff 0x00a2ff 0x09c700 0xe7b300 0xe75c00;} +chart {bg-color:0xF5F5F5;bg-alpha:100;} +axis {grid-height:50;offset-x:40;offset-y:30;offset-v:20;color:0x000000;line-color:0x666666;} +gContainer {color:0x000000;benchmark-color:0xCCCCCC;line-width:4;} +tContainer {color:0x000000;tipbg-color:0xFFFFFF;} +pContainer {color:0x000000;} +legend {color:0xFFFFFF;padding-top:0;padding-left:0;benchmark-color:0xCCCCCC;bg-color:0x666666;bg-alpha:100;} \ No newline at end of file diff --git a/tags/0.8/assets/fla/mxp/default_skin.swf b/tags/0.8/assets/fla/mxp/default_skin.swf new file mode 100644 index 0000000..f7ab1ee Binary files /dev/null and b/tags/0.8/assets/fla/mxp/default_skin.swf differ diff --git a/tags/0.8/assets/fla/mxp/finger-flash-component.fla b/tags/0.8/assets/fla/mxp/finger-flash-component.fla new file mode 100644 index 0000000..64bfc60 Binary files /dev/null and b/tags/0.8/assets/fla/mxp/finger-flash-component.fla differ diff --git a/tags/0.8/assets/fla/mxp/finger-flashpro-component.mxi b/tags/0.8/assets/fla/mxp/finger-flashpro-component.mxi new file mode 100644 index 0000000..6be841b --- /dev/null +++ b/tags/0.8/assets/fla/mxp/finger-flashpro-component.mxi @@ -0,0 +1,38 @@ + + + + + + + + + + + + + + + + + + + + + + Components > FingerChart. + ]]> + + + + + + + + + diff --git a/tags/0.8/assets/fla/mxp/finger-flashpro-component.mxp b/tags/0.8/assets/fla/mxp/finger-flashpro-component.mxp new file mode 100644 index 0000000..6e5a37a Binary files /dev/null and b/tags/0.8/assets/fla/mxp/finger-flashpro-component.mxp differ diff --git a/tags/0.8/assets/fla/mxp/finger-flashpro-component.swc b/tags/0.8/assets/fla/mxp/finger-flashpro-component.swc new file mode 100644 index 0000000..7b01e57 Binary files /dev/null and b/tags/0.8/assets/fla/mxp/finger-flashpro-component.swc differ diff --git a/tags/0.8/assets/fla/mxp/line_json1.txt b/tags/0.8/assets/fla/mxp/line_json1.txt new file mode 100644 index 0000000..593340d --- /dev/null +++ b/tags/0.8/assets/fla/mxp/line_json1.txt @@ -0,0 +1 @@ +{"config":{"yTitle":"访问量","categoryField":"日期","yField":"频道一,频道二,参考线","benchmark":"参考线"},"dataset":[{"日期":"6月1日","参考线":"300","频道一":"100","频道二":"430"},{"日期":"6月2日","参考线":"300","频道一":"600","频道二":"230"}]} \ No newline at end of file diff --git a/tags/0.8/assets/fla/mxp/test.fla b/tags/0.8/assets/fla/mxp/test.fla new file mode 100644 index 0000000..428709c Binary files /dev/null and b/tags/0.8/assets/fla/mxp/test.fla differ diff --git a/tags/0.8/assets/fla/mxp/test.swf b/tags/0.8/assets/fla/mxp/test.swf new file mode 100644 index 0000000..1a3ca70 Binary files /dev/null and b/tags/0.8/assets/fla/mxp/test.swf differ diff --git a/tags/0.8/assets/fla/plugin/context_menu.as b/tags/0.8/assets/fla/plugin/context_menu.as new file mode 100644 index 0000000..96a159f --- /dev/null +++ b/tags/0.8/assets/fla/plugin/context_menu.as @@ -0,0 +1,129 @@ +package { + + import com.adobe.images.PNGEncoder; + + import flash.display.BitmapData; + import flash.display.Sprite; + import flash.display.StageDisplayState; + import flash.events.ContextMenuEvent; + import flash.events.Event; + import flash.events.MouseEvent; + import flash.net.*; + import flash.printing.PrintJob; + import flash.ui.ContextMenu; + import flash.ui.ContextMenuItem; + import flash.utils.ByteArray; + + import com.riameeting.finger.config.ChartGlobal; + import com.riameeting.finger.parser.CSVParser; + import com.riameeting.finger.vo.DatasetVO; + + import flash.display.MovieClip; + import com.riameeting.finger.plugin.IChartPlugin; + import com.riameeting.finger.display.container.IPluginContainer; + import flash.display.DisplayObject; + import com.riameeting.finger.display.chart.IChart; + + + public class context_menu extends MovieClip implements IChartPlugin { + + private var container:IPluginContainer; + private var myContextMenu:ContextMenu; + private var dataset:DatasetVO; + private var chartRef:IChart; + + public function context_menu() { + + } + + public function initPlugin(container:IPluginContainer):void { + this.container = container; + chartRef = container.chartRef; + dataset = container.dataset; + myContextMenu = new ContextMenu(); + (chartRef as Sprite).contextMenu = myContextMenu; + myContextMenu.hideBuiltInItems(); + var versionMenu:ContextMenuItem = new ContextMenuItem("Finger Chart, version: "+ChartGlobal.version); + versionMenu.enabled = false; + myContextMenu.customItems.push(versionMenu); + var fullscreenMenu:ContextMenuItem = new ContextMenuItem("全屏",true); + fullscreenMenu.addEventListener(ContextMenuEvent.MENU_ITEM_SELECT, fullscreenHandler); + myContextMenu.customItems.push(fullscreenMenu); + var saveMenu:ContextMenuItem = new ContextMenuItem("保存为位图",false); + saveMenu.addEventListener(ContextMenuEvent.MENU_ITEM_SELECT, saveHandler); + myContextMenu.customItems.push(saveMenu); + var saveCSVMenu:ContextMenuItem = new ContextMenuItem("保存为CSV",false); + saveCSVMenu.addEventListener(ContextMenuEvent.MENU_ITEM_SELECT, saveCSVHandler); + myContextMenu.customItems.push(saveCSVMenu); + var printMenu:ContextMenuItem = new ContextMenuItem("打印",false); + printMenu.addEventListener(ContextMenuEvent.MENU_ITEM_SELECT, printHandler); + myContextMenu.customItems.push(printMenu); + var viewDataMenu:ContextMenuItem = new ContextMenuItem("查看源数据",false); + viewDataMenu.addEventListener(ContextMenuEvent.MENU_ITEM_SELECT, viewDataSource); + myContextMenu.customItems.push(viewDataMenu); + var helpMenu:ContextMenuItem = new ContextMenuItem("www.riameeting.com/fingerchart",true); + helpMenu.addEventListener(ContextMenuEvent.MENU_ITEM_SELECT, getHelpLink); + myContextMenu.customItems.push(helpMenu); + var dateMenu:ContextMenuItem = new ContextMenuItem("最后更新日期:"+ChartGlobal.buildDate,true); + dateMenu.enabled = false; + myContextMenu.customItems.push(dateMenu); + stage.doubleClickEnabled = true; + stage.addEventListener(MouseEvent.DOUBLE_CLICK,fullscreenHandler); + } + + private function fullscreenHandler(e:Event):void { + stage.displayState = StageDisplayState.FULL_SCREEN; + } + + private function saveHandler(e:ContextMenuEvent):void { + var bmd:BitmapData = new BitmapData(stage.width,stage.height); + bmd.draw(chartRef as DisplayObject); + var bmdBytes:ByteArray = PNGEncoder.encode(bmd); + var saveFile:FileReference = new FileReference(); + saveFile.save(bmdBytes,getDate()+".png"); + } + + private function saveCSVHandler(e:ContextMenuEvent):void { + var csvStr:String = CSVParser.encode(dataset); + var csvBytes:ByteArray = new ByteArray(); + csvBytes.writeUTFBytes(csvStr); + var saveFile:FileReference = new FileReference(); + saveFile.save(csvBytes,getDate()+".csv"); + } + + private function printHandler(e:ContextMenuEvent):void { + var myPrintJob:PrintJob=new PrintJob(); + if(myPrintJob.start()) { + try{ + myPrintJob.addPage(chartRef as Sprite); + }catch(error:Error){ + trace("Print Error"); + } + myPrintJob.send(); + } + } + + private function viewDataSource(e:ContextMenuEvent):void { + navigateToURL(new URLRequest(chartRef.chartConfig["data"])); + } + + private function getHelpLink(e:ContextMenuEvent):void { + navigateToURL(new URLRequest("http://www.riameeting.com/fingerchart"),"_blank"); + } + + private function getDate():String { + var dateStr:String = "finger_"; + var date:Date = new Date(); + dateStr += date.getFullYear()+"-"; + dateStr += date.getMonth()+1+"-"; + dateStr += date.getDate(); + return dateStr; + } + + public function updateDisplayList(w:uint,h:uint):void { + + } + + } + +} diff --git a/tags/0.8/assets/fla/plugin/context_menu.fla b/tags/0.8/assets/fla/plugin/context_menu.fla new file mode 100644 index 0000000..1eded41 Binary files /dev/null and b/tags/0.8/assets/fla/plugin/context_menu.fla differ diff --git a/tags/0.8/assets/fla/plugin/context_menu.swf b/tags/0.8/assets/fla/plugin/context_menu.swf new file mode 100644 index 0000000..fc615c3 Binary files /dev/null and b/tags/0.8/assets/fla/plugin/context_menu.swf differ diff --git a/tags/0.8/assets/fla/skin/skin.fla b/tags/0.8/assets/fla/skin/skin.fla new file mode 100644 index 0000000..9f2e58a Binary files /dev/null and b/tags/0.8/assets/fla/skin/skin.fla differ diff --git a/tags/0.8/assets/fla/skin/skin.swf b/tags/0.8/assets/fla/skin/skin.swf new file mode 100644 index 0000000..cd50801 Binary files /dev/null and b/tags/0.8/assets/fla/skin/skin.swf differ diff --git a/tags/0.8/assets/psd/children.psd b/tags/0.8/assets/psd/children.psd new file mode 100644 index 0000000..5a85ff8 Binary files /dev/null and b/tags/0.8/assets/psd/children.psd differ diff --git a/tags/0.8/assets/psd/design.psd b/tags/0.8/assets/psd/design.psd new file mode 100644 index 0000000..c797cf8 Binary files /dev/null and b/tags/0.8/assets/psd/design.psd differ diff --git a/tags/0.8/assets/psd/logo.png b/tags/0.8/assets/psd/logo.png new file mode 100644 index 0000000..0681144 Binary files /dev/null and b/tags/0.8/assets/psd/logo.png differ diff --git a/tags/0.8/assets/psd/logo.psd b/tags/0.8/assets/psd/logo.psd new file mode 100644 index 0000000..9f09a6d Binary files /dev/null and b/tags/0.8/assets/psd/logo.psd differ diff --git a/tags/0.8/assets/psd/logo2.png b/tags/0.8/assets/psd/logo2.png new file mode 100644 index 0000000..720db51 Binary files /dev/null and b/tags/0.8/assets/psd/logo2.png differ diff --git a/tags/0.8/common-lib/pom.xml b/tags/0.8/common-lib/pom.xml new file mode 100644 index 0000000..46e1c26 --- /dev/null +++ b/tags/0.8/common-lib/pom.xml @@ -0,0 +1,41 @@ + + + + + com.riameeting.fingerchart + finger-chart-superpom + 0.8 + + + 4.0.0 + + com.riameeting.fingerchart + common-lib + 0.8 + swc + + common-lib Flex + + + src/main/flex + + + org.sonatype.flexmojos + flexmojos-maven-plugin + ${flexmojos.version} + true + + + com.adobe.flex + compiler + ${flex.version} + pom + + + + + + + diff --git a/tags/0.8/common-lib/src/main/flex/com/cartogrammar/drawing/CubicBezier.as b/tags/0.8/common-lib/src/main/flex/com/cartogrammar/drawing/CubicBezier.as new file mode 100644 index 0000000..4affebc --- /dev/null +++ b/tags/0.8/common-lib/src/main/flex/com/cartogrammar/drawing/CubicBezier.as @@ -0,0 +1,243 @@ +/* Cubic Bézier curve tools +* @author: Andy Woodruff (http://cartogrammar.com/blog || awoodruff@gmail.com) +* @date: May 2008, updated January 2009 +* @description: Contains methods for drawing a single cubic Bézier curve and for drawing +* a continuous series of curves through specified points. +* Updates in January 2009: +* - moveTo argument in curveThroughPoints (used on line 200) +* - some math corrections in lines 152-163, which I hope fix problems caused by 0 angles and such +* - introduced an option (though not from outside this class) to use lineTo on straight segments rather than curving (affects lines 208-224) +* Previous version is at http://cartogrammar.com/source/CubicBezier_May08.as in case I screwed something up. Sorry about the lack of proper versioning! +*/ + +package com.cartogrammar.drawing{ + + import flash.display.Graphics; + import flash.geom.Point; + import fl.motion.BezierSegment; + + public class CubicBezier{ + + /** pubic static function drawCurve + * Draws a single cubic Bézier curve + * @param: + * g:Graphics -Graphics on which to draw the curve + * p1:Point -First point in the curve + * p2:Point -Second point (control point) in the curve + * p3:Point -Third point (control point) in the curve + * p4:Point -Fourth point in the curve + * @return: + */ + public static function drawCurve(g:Graphics, p1:Point, p2:Point, p3:Point, p4:Point):void{ + var bezier:BezierSegment = new BezierSegment(p1,p2,p3,p4); // BezierSegment using the four points + g.moveTo(p1.x,p1.y); + // Construct the curve out of 100 segments (adjust number for less/more detail) + for (var t:Number=.01;t<1.01;t+=.01){ + var val:Object = bezier.getValue(t); // x,y on the curve for a given t + g.lineTo(val.x,val.y); + } + } + + /** public static function curveThroughPoints + * Draws a smooth curve through a series of points. For a closed curve, make the first and last points the same. + * @param: + * g:Graphics -Graphics on which to draw the curve + * p:Array -Array of Point instances + * z:Number -A factor (between 0 and 1) to reduce the size of curves by limiting the distance of control points from anchor points. + * For example, z=.5 limits control points to half the distance of the closer adjacent anchor point. + * I put the option here, but I recommend sticking with .5 + * angleFactor:Number -Adjusts the size of curves depending on how acute the angle between points is. Curves are reduced as acuteness + * increases, and this factor controls by how much. + * 1 = curves are reduced in direct proportion to acuteness + * 0 = curves are not reduced at all based on acuteness + * in between = the reduction is basically a percentage of the full reduction + * moveTo:Bollean -Specifies whether to move to the first point in the curve rather than continuing drawing + * from wherever drawing left off. + * @return: + */ + public static function curveThroughPoints(g:Graphics, points:Array/*of Points*/, z:Number = .5, angleFactor:Number = .75, moveTo:Boolean = true):void{ + try { + var p:Array = points.slice(); // Local copy of points array + var duplicates:Array = new Array(); // Array to hold indices of duplicate points + // Check to make sure array contains only Points + for (var i:Number=0; i 0){ + if (p[i].x == p[i-1].x && p[i].y == p[i-1].y){ + duplicates.push(i); // add index of duplicate to duplicates array + } + } + } + // Loop through duplicates array and remove points from the points array + for (i=duplicates.length-1; i>=0; i--){ + p.splice(duplicates[i],1); + } + + // Make sure z is between 0 and 1 (too messy otherwise) + if (z <= 0){ + z = .5; + } else if (z > 1){ + z = 1; + } + // Make sure angleFactor is between 0 and 1 + if (angleFactor < 0){ + angleFactor = 0; + } else if (angleFactor > 1){ + angleFactor = 1; + } + + // + // First calculate all the curve control points + // + + // None of this junk will do any good if there are only two points + if (p.length > 2){ + // Ordinarily, curve calculations will start with the second point and go through the second-to-last point + var firstPt:Number = 1; + var lastPt:Number = p.length-1; + // Check if this is a closed line (the first and last points are the same) + if (p[0].x == p[p.length-1].x && p[0].y == p[p.length-1].y){ + // Include first and last points in curve calculations + firstPt = 0; + lastPt = p.length; + } + + var controlPts:Array = new Array(); // An array to store the two control points (of a cubic Bézier curve) for each point + // Loop through all the points (except the first and last if not a closed line) to get curve control points for each. + for (i=firstPt; i 1) cos = 1; + var C:Number = Math.acos(cos); // Angle formed by the two sides of the triangle (described by the three points above) adjacent to the current point + // Duplicate set of points. Start by giving previous and next points values RELATIVE to the current point. + var aPt:Point = new Point(p0.x-p1.x,p0.y-p1.y); + var bPt:Point = new Point(p1.x,p1.y); + var cPt:Point = new Point(p2.x-p1.x,p2.y-p1.y); + /* + We'll be adding adding the vectors from the previous and next points to the current point, + but we don't want differing magnitudes (i.e. line segment lengths) to affect the direction + of the new vector. Therefore we make sure the segments we use, based on the duplicate points + created above, are of equal length. The angle of the new vector will thus bisect angle C + (defined above) and the perpendicular to this is nice for the line tangent to the curve. + The curve control points will be along that tangent line. + */ + if (a > b){ + aPt.normalize(b); // Scale the segment to aPt (bPt to aPt) to the size of b (bPt to cPt) if b is shorter. + } else if (b > a){ + cPt.normalize(a); // Scale the segment to cPt (bPt to cPt) to the size of a (aPt to bPt) if a is shorter. + } + // Offset aPt and cPt by the current point to get them back to their absolute position. + aPt.offset(p1.x,p1.y); + cPt.offset(p1.x,p1.y); + // Get the sum of the two vectors, which is perpendicular to the line along which our curve control points will lie. + var ax:Number = bPt.x-aPt.x; // x component of the segment from previous to current point + var ay:Number = bPt.y-aPt.y; + var bx:Number = bPt.x-cPt.x; // x component of the segment from next to current point + var by:Number = bPt.y-cPt.y; + var rx:Number = ax + bx; // sum of x components + var ry:Number = ay + by; + // Correct for three points in a line by finding the angle between just two of them + if (rx == 0 && ry == 0){ + rx = -bx; // Really not sure why this seems to have to be negative + ry = by; + } + // Switch rx and ry when y or x difference is 0. This seems to prevent the angle from being perpendicular to what it should be. + if (ay == 0 && by == 0){ + rx = 0; + ry = 1; + } else if (ax == 0 && bx == 0){ + rx = 1; + ry = 0; + } + var r:Number = Math.sqrt(rx*rx+ry*ry); // length of the summed vector - not being used, but there it is anyway + var theta:Number = Math.atan2(ry,rx); // angle of the new vector + + var controlDist:Number = Math.min(a,b)*z; // Distance of curve control points from current point: a fraction the length of the shorter adjacent triangle side + var controlScaleFactor:Number = C/Math.PI; // Scale the distance based on the acuteness of the angle. Prevents big loops around long, sharp-angled triangles. + controlDist *= ((1-angleFactor) + angleFactor*controlScaleFactor); // Mess with this for some fine-tuning + var controlAngle:Number = theta+Math.PI/2; // The angle from the current point to control points: the new vector angle plus 90 degrees (tangent to the curve). + var controlPoint2:Point = Point.polar(controlDist,controlAngle); // Control point 2, curving to the next point. + var controlPoint1:Point = Point.polar(controlDist,controlAngle+Math.PI); // Control point 1, curving from the previous point (180 degrees away from control point 2). + // Offset control points to put them in the correct absolute position + controlPoint1.offset(p1.x,p1.y); + controlPoint2.offset(p1.x,p1.y); + /* + Haven't quite worked out how this happens, but some control points will be reversed. + In this case controlPoint2 will be farther from the next point than controlPoint1 is. + Check for that and switch them if it's true. + */ + if (Point.distance(controlPoint2,p2) > Point.distance(controlPoint1,p2)){ + controlPts[i] = new Array(controlPoint2,controlPoint1); // Add the two control points to the array in reverse order + } else { + controlPts[i] = new Array(controlPoint1,controlPoint2); // Otherwise add the two control points to the array in normal order + } + // Uncomment to draw lines showing where the control points are. + /* + g.moveTo(p1.x,p1.y); + g.lineTo(controlPoint2.x,controlPoint2.y); + g.moveTo(p1.x,p1.y); + g.lineTo(controlPoint1.x,controlPoint1.y); + */ + } + // + // Now draw the curve + // + // If moveTo condition is false, this curve can connect to a previous curve on the same graphics. + if (moveTo) g.moveTo(p[0].x, p[0].y); + else g.lineTo(p[0].x, p[0].y); + // If this isn't a closed line + if (firstPt == 1){ + // Draw a regular quadratic Bézier curve from the first to second points, using the first control point of the second point + g.curveTo(controlPts[1][0].x,controlPts[1][0].y,p[1].x,p[1].y); + } + var straightLines:Boolean = true; // Change to true if you want to use lineTo for straight lines of 3 or more points rather than curves. You'll get straight lines but possible sharp corners! + // Loop through points to draw cubic Bézier curves through the penultimate point, or through the last point if the line is closed. + for (i=firstPt;i 0 && Math.atan2(p[i].y-p[i-1].y,p[i].x-p[i-1].x) == Math.atan2(p[i+1].y-p[i].y,p[i+1].x-p[i].x) ) || ( i < p.length - 2 && Math.atan2(p[i+2].y-p[i+1].y,p[i+2].x-p[i+1].x) == Math.atan2(p[i+1].y-p[i].y,p[i+1].x-p[i].x) ) ); + if (straightLines && isStraight){ + g.lineTo(p[i+1].x,p[i+1].y); + } else { + // BezierSegment instance using the current point, its second control point, the next point's first control point, and the next point + var bezier:BezierSegment = new BezierSegment(p[i],controlPts[i][1],controlPts[i+1][0],p[i+1]); + // Construct the curve out of 100 segments (adjust number for less/more detail) + for (var t:Number=.01;t<1.01;t+=.01){ + var val:Object = bezier.getValue(t); // x,y on the curve for a given t + g.lineTo(val.x,val.y); + } + } + } + // If this isn't a closed line + if (lastPt == p.length-1){ + // Curve to the last point using the second control point of the penultimate point. + g.curveTo(controlPts[i][1].x,controlPts[i][1].y,p[i+1].x,p[i+1].y); + } + // just draw a line if only two points + } else if (p.length == 2){ + g.moveTo(p[0].x,p[0].y); + g.lineTo(p[1].x,p[1].y); + } + } + // Catch error + catch (e:Error) { + trace(e.getStackTrace()); + } + } + + } + +} \ No newline at end of file diff --git a/tags/0.8/common-lib/src/main/flex/com/riameeting/controler/EventBus.as b/tags/0.8/common-lib/src/main/flex/com/riameeting/controler/EventBus.as new file mode 100644 index 0000000..e31eb84 --- /dev/null +++ b/tags/0.8/common-lib/src/main/flex/com/riameeting/controler/EventBus.as @@ -0,0 +1,38 @@ +package com.riameeting.controler +{ + import flash.events.EventDispatcher; + import flash.events.IEventDispatcher; + + /** + * 事件总线 + * + */ + public class EventBus + { + /** + * 事件派发器 + */ + public static var dispatcher:IEventDispatcher = new EventDispatcher(); + /** + * 添加事件侦听 + * @param eventType 事件类型 + * @param eventHandler 事件处理方法 + * + */ + public static function addEventListener(eventType:String,eventHandler:Function):void + { + dispatcher.addEventListener(eventType,eventHandler); + } + /** + * 删除事件侦听 + * @param eventType 事件类型 + * @param eventHandler 事件处理方法 + * + */ + public static function removeEventListener(eventType:String,eventHandler:Function):void + { + dispatcher.removeEventListener(eventType,eventHandler); + } + + } +} \ No newline at end of file diff --git a/tags/0.8/common-lib/src/main/flex/com/riameeting/net/ResourceLoader.as b/tags/0.8/common-lib/src/main/flex/com/riameeting/net/ResourceLoader.as new file mode 100644 index 0000000..774aeed --- /dev/null +++ b/tags/0.8/common-lib/src/main/flex/com/riameeting/net/ResourceLoader.as @@ -0,0 +1,87 @@ +package com.riameeting.net +{ + import com.riameeting.ui.control.Alert; + + import flash.display.Loader; + import flash.events.Event; + import flash.events.EventDispatcher; + import flash.events.IEventDispatcher; + import flash.events.IOErrorEvent; + import flash.net.URLLoader; + import flash.net.URLLoaderDataFormat; + import flash.net.URLRequest; + import flash.utils.Dictionary; + + /** + * 资源加载类 + * @author Finger + * + */ + public class ResourceLoader + { + private var callBackFunc:Function; + private var assetsArr:Array; + /** + * 资源哈希表 + */ + public var fileDict:Dictionary = new Dictionary(); + /** + * 加载资源 + * @param assets 资源地址列表 + * @param callBack 回调 + * + */ + public function loadAssets(assets:Array,callBack:Function):void { + callBackFunc = callBack; + assetsArr = assets; + for each(var url:String in assets) { + var loader:URLLoader = new URLLoader(); + if(getFileExtension(url) == "swf") { + loader.dataFormat = URLLoaderDataFormat.BINARY; + } + loader.addEventListener(Event.COMPLETE,completeHandler); + loader.addEventListener(IOErrorEvent.IO_ERROR,ioErrorHandler); + loader.load(new URLRequest(url)); + fileDict[loader] = url; + } + } + /** + * 获取文件扩展名 + * @param fileName + * @return + * + */ + public function getFileExtension(fileName:String):String { + var dotSpitArr:Array = fileName.split("."); + return dotSpitArr[dotSpitArr.length-1]; + } + /** + * 加载成功 + * @param e + * + */ + private function completeHandler(e:Event):void { + var url:String = fileDict[e.currentTarget]; + fileDict[url] = e.currentTarget.data; + checkStatus(); + } + /** + * 加载失败 + * @param e + * + */ + private function ioErrorHandler(e:IOErrorEvent):void { + Alert.show(e.toString(),"IOError"); + } + /** + * 检查整体加载状况 + * + */ + private function checkStatus():void { + for each(var url:String in assetsArr) { + if(fileDict[url] == null) return; + } + callBackFunc.apply(); + } + } +} \ No newline at end of file diff --git a/tags/0.8/common-lib/src/main/flex/com/riameeting/ui/control/Alert.as b/tags/0.8/common-lib/src/main/flex/com/riameeting/ui/control/Alert.as new file mode 100644 index 0000000..f158163 --- /dev/null +++ b/tags/0.8/common-lib/src/main/flex/com/riameeting/ui/control/Alert.as @@ -0,0 +1,117 @@ +package com.riameeting.ui.control +{ + import flash.display.Sprite; + import flash.events.MouseEvent; + /** + * 弹出信息显示类 + * @author Finger + * + */ + public class Alert + { + /** + * 弹出窗口的父层容器 + */ + public static var container:Sprite; + /** + * 窗体 + */ + private static var window:Window; + /** + * 显示信息 + * @param value 要显示的字符串 + * @param title 要显示的标题 + * + */ + public static function show(value:String,title:String="alert"):void + { + if(container == null) { + throw new Error("Alert.container not allow null"); + } + if(window == null) { + window = new Window(); + window.closeButton.addEventListener(MouseEvent.CLICK,hide); + window.addEventListener(MouseEvent.MOUSE_DOWN,startMove); + window.addEventListener(MouseEvent.MOUSE_UP,stopMove); + } + container.addChild(window); + window.title = title; + window.text = value; + window.x = (container.stage.stageWidth-window.width)/2; + window.y = (container.stage.stageHeight-window.height)/2; + function startMove(e:MouseEvent):void { + window.startDrag(); + } + function stopMove(e:MouseEvent):void { + window.stopDrag(); + } + } + /** + * 隐藏信息 + * @param e + * + */ + public static function hide(e:MouseEvent=null):void + { + container.removeChild(window); + } + } +} +import com.riameeting.ui.control.Button; + +import flash.display.Sprite; +import flash.text.TextField; +import flash.text.TextFieldAutoSize; + +/** + * 窗体类 + * + */ +class Window extends Sprite { + private var titleField:TextField = new TextField(); + private var txtField:TextField = new TextField(); + public var closeButton:Button = new Button(); + public function Window() + { + buttonMode = true; + txtField.width = 200; + titleField.width = 200; + txtField.mouseEnabled = false; + titleField.mouseEnabled = false; + txtField.y = 20; + txtField.autoSize = TextFieldAutoSize.LEFT; + txtField.wordWrap = true; + addChild(txtField); + addChild(titleField); + addChild(closeButton); + closeButton.x = 100-closeButton.width/2; + closeButton.label = "Close"; + } + /** + * 设置标题显示 + * @param value + * + */ + public function set title(value:String):void { + titleField.htmlText = ""+value+""; + } + /** + * 设置文本内容显示 + * @param value + * + */ + public function set text(value:String):void { + txtField.htmlText = ""+value+""; + txtField.height = txtField.textHeight + 5; + closeButton.y = txtField.y + txtField.height; + graphics.clear(); + graphics.lineStyle(3,0xFF0000,1); + graphics.beginFill(0xFF0000,1); + graphics.drawRoundRect(0,0,200,24,4,4); + graphics.endFill(); + graphics.beginFill(0x000000,1); + graphics.drawRoundRect(0,20,200,txtField.height+closeButton.height+4,4,4); + graphics.endFill(); + } + +} \ No newline at end of file diff --git a/tags/0.8/common-lib/src/main/flex/com/riameeting/ui/control/Button.as b/tags/0.8/common-lib/src/main/flex/com/riameeting/ui/control/Button.as new file mode 100644 index 0000000..bfc4ab5 --- /dev/null +++ b/tags/0.8/common-lib/src/main/flex/com/riameeting/ui/control/Button.as @@ -0,0 +1,43 @@ +package com.riameeting.ui.control +{ + import flash.display.Sprite; + /** + * 一个轻量级的按钮组件 + * @author Finger + * + */ + public class Button extends Sprite + { + private var _label:String; + /** + * 文本显示 + */ + protected var labelDisplay:Label = new Label(); + /** + * 构造方法 + * + */ + public function Button() + { + labelDisplay.color = 0xFFFFFF; + addChild(labelDisplay); + } + /** + * 设置文本显示 + * @return + * + */ + public function get label():String { + return _label; + } + public function set label(value:String):void { + _label = value; + labelDisplay.text = value; + this.graphics.clear(); + this.graphics.beginFill(0x333333,0.8); + this.graphics.drawRoundRect(-2,-2,labelDisplay.width+4,labelDisplay.height+4,4,4); + this.graphics.endFill(); + } + + } +} \ No newline at end of file diff --git a/tags/0.8/common-lib/src/main/flex/com/riameeting/ui/control/CheckBox.as b/tags/0.8/common-lib/src/main/flex/com/riameeting/ui/control/CheckBox.as new file mode 100644 index 0000000..3e0fa6f --- /dev/null +++ b/tags/0.8/common-lib/src/main/flex/com/riameeting/ui/control/CheckBox.as @@ -0,0 +1,79 @@ +package com.riameeting.ui.control +{ + import flash.display.Sprite; + import flash.events.MouseEvent; + /** + * 复选框类 + * @author Finger + * + */ + public class CheckBox extends Sprite + { + private var _selected:Boolean; + private var icon:Sprite = new Sprite(); + private var _label:String; + /** + * 文本显示 + */ + protected var labelDisplay:Label = new Label(); + /** + * 标记复选框的选择状态 + * @return 布尔量 + * + */ + public function get selected():Boolean{return _selected;} + public function set selected(value:Boolean):void + { + _selected = value; + if(_selected) { + icon.graphics.beginFill(0xCCCCCC,1); + icon.graphics.drawRect(2,2,11,11); + icon.graphics.endFill(); + } else { + icon.graphics.clear(); + } + } + + /** + * 构造方法 + * + */ + public function CheckBox() + { + super(); + buttonMode = true; + mouseChildren = false; + graphics.lineStyle(1,0xCCCCCC,1); + graphics.beginFill(0xFFFFFF,1); + graphics.drawRect(2,2,14,14); + graphics.endFill(); + addChild(icon); + icon.x = 2; + icon.y = 2; + addEventListener(MouseEvent.CLICK,checkStatus); + labelDisplay.x = 20; + addChild(labelDisplay); + } + /** + * 检查状态 + * @param e + * + */ + protected function checkStatus(e:MouseEvent):void { + selected = !selected; + } + /** + * 设置文本显示 + * @return + * + */ + public function get label():String { + return _label; + } + public function set label(value:String):void { + _label = value; + labelDisplay.text = value; + } + + } +} \ No newline at end of file diff --git a/tags/0.8/common-lib/src/main/flex/com/riameeting/ui/control/GraphicLabel.as b/tags/0.8/common-lib/src/main/flex/com/riameeting/ui/control/GraphicLabel.as new file mode 100644 index 0000000..dee4466 --- /dev/null +++ b/tags/0.8/common-lib/src/main/flex/com/riameeting/ui/control/GraphicLabel.as @@ -0,0 +1,49 @@ +package com.riameeting.ui.control +{ + import flash.text.TextField; + + import com.riameeting.utils.ColorUtils; + /** + * 带左侧图形显示的标签 + * @author Finger + * + */ + public class GraphicLabel extends Label + { + /** + * 构造方法 + * @param htmlMode html模式 + * @param lineColor 图形颜色 + * @param mode 图形模式 + * @param number 如果模式是数字,则传入此值 + * + */ + public function GraphicLabel(htmlMode:Boolean=false,lineColor:uint=0x000000,mode:String="line",number:uint=0) + { + super(htmlMode); + innerTxt.x = 20; + graphics.beginFill(lineColor,1); + switch(mode) { + case "line": + graphics.drawRect(0,8,15,2); + break; + case "double": + graphics.drawRect(0,8,15,2); + graphics.endFill(); + graphics.beginFill(ColorUtils.fadeColor(lineColor,0xFFFFFF,0.4),1); + graphics.drawRect(0,10,15,2); + break; + case "rect": + graphics.drawRect(0,2,14,14); + break; + case "number": + var numerTxt:Label = new Label(false); + numerTxt.color = lineColor; + numerTxt.text = number+""; + addChild(numerTxt); + break; + } + graphics.endFill(); + } + } +} \ No newline at end of file diff --git a/tags/0.8/common-lib/src/main/flex/com/riameeting/ui/control/Label.as b/tags/0.8/common-lib/src/main/flex/com/riameeting/ui/control/Label.as new file mode 100644 index 0000000..609ba03 --- /dev/null +++ b/tags/0.8/common-lib/src/main/flex/com/riameeting/ui/control/Label.as @@ -0,0 +1,81 @@ +package com.riameeting.ui.control +{ + import flash.display.Sprite; + import flash.text.Font; + import flash.text.TextField; + import flash.text.TextFormat; + /** + * 文本标签,对TextTield的简单封装 + * @author Finger + * + */ + public class Label extends Sprite + { + /** + * 内部的TextField对象 + */ + protected var innerTxt:TextField; + private var _text:String; + private var _color:uint; + /** + * 是否采用HTML方式显示文本 + */ + public var htmlMode:Boolean; + /** + * 要显示的文本 + * @return 文本 + * + */ + public function get text():String{return _text;} + public function set text(value:String):void + { + _text = value; + if(htmlMode) { + innerTxt.htmlText = _text; + } else { + innerTxt.text = _text; + } + innerTxt.width = innerTxt.textWidth + 4; + innerTxt.height = innerTxt.textHeight + 4; + } + /** + * 文本颜色 + * @return 颜色值 + * + */ + public function get color():uint{return _color;} + public function set color(value:uint):void{_color = value;innerTxt.textColor = value;} + /** + * 构造方法 + * @param htmlMode 是否启用HTML显示模式 + * + */ + public function Label(htmlMode:Boolean=false) + { + this.htmlMode = htmlMode; + innerTxt = new TextField(); + innerTxt.width = innerTxt.height = 20; + innerTxt.selectable = false; + innerTxt.mouseEnabled = false; + var tf:TextFormat = new TextFormat(); + for each(var f:* in Font.enumerateFonts()) { + tf.font = f.fontName; + innerTxt.embedFonts = true; + innerTxt.defaultTextFormat = tf; + } + addChild(innerTxt); + } + /** + * 执行清理动作 + * + */ + public function clear():void { + color = 0x000000; + text = ""; + x = y = 0; + name = ""; + visible = true; + } + + } +} \ No newline at end of file diff --git a/tags/0.8/common-lib/src/main/flex/com/riameeting/utils/ColorUtils.as b/tags/0.8/common-lib/src/main/flex/com/riameeting/utils/ColorUtils.as new file mode 100644 index 0000000..8cbf45a --- /dev/null +++ b/tags/0.8/common-lib/src/main/flex/com/riameeting/utils/ColorUtils.as @@ -0,0 +1,34 @@ +package com.riameeting.utils +{ + + /** + * 颜色工具 + */ + public final class ColorUtils { + + /** + * 合并色值 + */ + public static function fadeColor(startColor:uint, endColor:uint, position:Number):uint { + var r:uint = startColor >> 16; + var g:uint = startColor >> 8 & 0xFF; + var b:uint = startColor & 0xFF; + r += ((endColor >> 16) - r) * position; + g += ((endColor >> 8 & 0xFF) - g) * position; + b += ((endColor & 0xFF) - b) * position; + return (r << 16 | g << 8 | b); + } + /** + * 将色值转换为WEB色值 + * @param color + * @return + * + */ + public static function toWebColor(color:uint):String { + var colorStr:String = color.toString(16); + return "#"+colorStr; + } + + } + +} \ No newline at end of file diff --git a/tags/0.8/common-lib/src/main/flex/com/riameeting/utils/DrawTool.as b/tags/0.8/common-lib/src/main/flex/com/riameeting/utils/DrawTool.as new file mode 100644 index 0000000..f6a4583 --- /dev/null +++ b/tags/0.8/common-lib/src/main/flex/com/riameeting/utils/DrawTool.as @@ -0,0 +1,109 @@ +package com.riameeting.utils +{ + import flash.display.GradientType; + import flash.display.Graphics; + import flash.geom.Matrix; + import flash.geom.Point; + + /** + * 绘图工具 + * @author Finger + * + */ + public class DrawTool + { + /** + * 绘制一条虚线 + * @param graphics 进行绘制的容器 + * @param startX 起始X坐标 + * @param startY 起始Y坐标 + * @param endX 结束X坐标 + * @param endY 结束Y坐标 + * @param dotLength 虚线线段长度 + * + */ + public static function dotLineTo(graphics:Graphics,startX:Number,startY:Number,endX:Number,endY:Number,dotLength:uint=4):void + { + graphics.moveTo(startX,startY); + var offsetX:Number = endX - startX; + var offsetY:Number = endY - startY; + var lineWidth:Number = Math.sqrt(offsetX*offsetX+offsetY*offsetY); + var count:uint = lineWidth/dotLength; + offsetX = offsetX/count; + offsetY = offsetY/count; + var targetX:Number,targetY:Number; + for(var i:uint=0;i<=count;i++) { + targetX = startX+i*offsetX; + targetY = startY+i*offsetY; + if(i%2==0) { + graphics.lineTo(targetX,targetY); + } else { + graphics.moveTo(targetX,targetY); + } + } + } + /** + * 绘制一个扇形或环形 + * @param graphics 进行绘制的容器 + * @param point 圆心点坐标 + * @param radius 半径 + * @param beginAngle 起始角度 + * @param angle 角度 + * @param lineColor 线条颜色 + * @param lineWidth 线条宽度 + * @param lineAlpha 线条透明度 + * @param color 图形颜色 + * @param innerRadius 环形半径 + * @return 中心点的坐标 + * + */ + public static function drawSector(graphics:Graphics,point:Point,radius:Number,beginAngle:Number,angle:Number,lineColor:uint,lineWidth:uint,lineAlpha:Number,color:uint,innerRadius:uint=50):Point { + graphics.clear(); + var centerPoint:Point; + var sx:Number = radius,sxInner:Number = innerRadius; + var sy:Number = 0,syInner:Number = 0; + if (beginAngle != 0) { + sx = Math.cos(beginAngle * Math.PI/180) * radius; + sy = Math.sin(beginAngle * Math.PI/180) * radius; + sxInner = Math.cos(beginAngle * Math.PI/180) * innerRadius; + syInner = Math.sin(beginAngle * Math.PI/180) * innerRadius; + } + graphics.lineStyle(lineWidth,lineColor,lineAlpha); + //graphics.beginFill(color); + var matix:Matrix =new Matrix(); + matix.createGradientBox(radius*2, radius*2, 0, -radius, -radius); + graphics.beginGradientFill(GradientType.RADIAL,[ColorUtils.fadeColor(color,0xFFFFFF,0.2),ColorUtils.fadeColor(color,0x000000,0.2)],[1,1],[0x00,0xFF],matix); + graphics.moveTo(point.x + sxInner, point.y + syInner); + graphics.lineTo(point.x + sx, point.y +sy); + var rad:Number = angle * Math.PI / 180 / angle; + var cos:Number = Math.cos(rad); + var sin:Number = Math.sin(rad); + var i:uint,nx:Number,ny:Number,nxInner:Number,nyInner:Number; + for (i=0; i 0 ? valueString.charAt(0):valueString.charAt(1)); + if(value > 0) { + leftPat++; + } else { + leftPat--; + } + var valueLength:Number = value > 0 ? valueString.length:valueString.length-1; + for(var i:uint=1;i 0 ? leftPat:-leftPat); + return returnNum; + } + /** + * 获取离原值最接近的最小值 + * @param value 原值 + * @return 最大值 + * + */ + public static function getMinNumber(value:Number):Number + { + var returnNum:Number; + var valueString:String = value.toString().split(".")[0]; + var leftPat:Number = Number(value > 0 ? valueString.charAt(0):valueString.charAt(1)); + if(value > 0) { + leftPat--; + } else { + leftPat++; + } + var valueLength:Number = value > 0 ? valueString.length:valueString.length-1; + for(var i:uint=1;i 0 ? leftPat:-leftPat); + return returnNum; + } + /** + * 获取两点之间的距离 + * @param point1 点1 + * @param point2 点2 + * @return 距离 + * + */ + public static function getPointDistance(point1:Point,point2:Point):Number + { + var offsetX:Number = Math.abs(point1.x - point2.x); + var offsetY:Number = Math.abs(point1.y - point2.y); + var distance:Number = Math.sqrt(offsetX*offsetX+offsetY*offsetY); + return distance; + } + /** + * 将Array自身的数据扩展N倍 + * @param source + * @param num + * @return + * + */ + public static function extendArrayByClone(source:Array,num:int):Array { + var extendArray:Array = []; + for(var i:uint=0;itime or degree of progress along the curve, as a decimal value between 0 and 1. + *

Note: The t parameter does not necessarily move along the curve at a uniform speed. For example, a t value of 0.5 does not always produce a value halfway along the curve.

+ * + * @return A point object containing the x and y coordinates of the Bezier curve at the specified time. + * @playerversion Flash 9.0.28.0 + * @playerversion AIR 1.0 + * @productversion Flash CS3 + * @langversion 3.0 + * @keyword Bezier curve, node, Copy Motion as ActionScript + */ + public function getValue(t:Number):Point + { + var ax:Number = this.a.x; + var x:Number = (t*t*(this.d.x-ax) + 3*(1-t)*(t*(this.c.x-ax) + (1-t)*(this.b.x-ax)))*t + ax; + var ay:Number = this.a.y; + var y:Number = (t*t*(this.d.y-ay) + 3*(1-t)*(t*(this.c.y-ay) + (1-t)*(this.b.y-ay)))*t + ay; + return new Point(x, y); + } + + + /** + * Calculates the value of a one-dimensional cubic Bezier equation at a specific time. + * By contrast, a Bezier curve is usually two-dimensional + * and uses two of these equations, one for the x coordinate and one for the y coordinate. + * + * @param t The time or degree of progress along the curve, as a decimal value between 0 and 1. + *

Note: The t parameter does not necessarily move along the curve at a uniform speed. For example, a t value of 0.5 does not always produce a value halfway along the curve.

+ * + * @param a The first value of the Bezier equation. + * + * @param b The second value of the Bezier equation. + * + * @param c The third value of the Bezier equation. + * + * @param d The fourth value of the Bezier equation. + * + * @return The value of the Bezier equation at the specified time. + * @playerversion Flash 9.0.28.0 + * @playerversion AIR 1.0 + * @productversion Flash CS3 + * @langversion 3.0 + * @keyword Bezier curve, node, Copy Motion as ActionScript + */ + public static function getSingleValue(t:Number, a:Number=0, b:Number=0, c:Number=0, d:Number=0):Number + { + return (t*t*(d-a) + 3*(1-t)*(t*(c-a) + (1-t)*(b-a)))*t + a; + } + + + /** + * Finds the y value of a cubic Bezier curve at a given x coordinate. + * Some Bezier curves overlap themselves horizontally, + * resulting in more than one y value for a given x value. + * In that case, this method will return whichever value is most logical. + * + * Used by CustomEase and BezierEase interpolation. + * + * @param x An x coordinate that lies between the first and last point, inclusive. + * + * @param coefficients An optional array of number values that represent the polynomial + * coefficients for the Bezier. This array can be used to optimize performance by precalculating + * values that are the same everywhere on the curve and do not need to be recalculated for each iteration. + * + * @return The y value of the cubic Bezier curve at the given x coordinate. + * @playerversion Flash 9.0.28.0 + * @playerversion AIR 1.0 + * @productversion Flash CS3 + * @langversion 3.0 + * @keyword Bezier curve, Copy Motion as ActionScript + */ + public function getYForX(x:Number, coefficients:Array=null):Number + { + // Clamp to range between end points. + // The padding with the small decimal value is necessary to avoid bugs + // that result from reaching the limits of decimal precision in calculations. + // We have tests that demonstrate this. + if (this.a.x < this.d.x) + { + if (x <= this.a.x+0.0000000000000001) return this.a.y; + if (x >= this.d.x-0.0000000000000001) return this.d.y; + } + else + { + if (x >= this.a.x+0.0000000000000001) return this.a.y; + if (x <= this.d.x-0.0000000000000001) return this.d.y; + } + + if (!coefficients) + { + coefficients = getCubicCoefficients(this.a.x, this.b.x, this.c.x, this.d.x); + } + + // x(t) = a*t^3 + b*t^2 + c*t + d + var roots:Array = getCubicRoots(coefficients[0], coefficients[1], coefficients[2], coefficients[3]-x); + var time:Number = NaN; + if (roots.length == 0) + time = 0; + else if (roots.length == 1) + time = roots[0]; + else + { + for each (var root:Number in roots) + { + if (0 <= root && root <= 1) + { + time = root; + break; + } + } + } + + if (isNaN(time)) + return NaN; + + var y:Number = getSingleValue(time, this.a.y, this.b.y, this.c.y, this.d.y); + return y; + } + + + + + /** + * Calculates the coefficients for a cubic polynomial equation, + * given the values of the corresponding cubic Bezier equation. + * + * @param a The first value of the Bezier equation. + * + * @param b The second value of the Bezier equation. + * + * @param c The third value of the Bezier equation. + * + * @param d The fourth value of the Bezier equation. + * + * @return An array containing four number values, + * which are the coefficients for a cubic polynomial. + * The coefficients are ordered from the highest degree to the lowest, + * so the first number in the array would be multiplied by t^3, the second by t^2, and so on. + * + * @playerversion Flash 9.0.28.0 + * @playerversion AIR 1.0 + * @productversion Flash CS3 + * @langversion 3.0 + * @keyword Bezier curve, node, Copy Motion as ActionScript + * @see #getCubicRoots() + */ + public static function getCubicCoefficients(a:Number, b:Number, c:Number, d:Number):Array + { + return [ -a + 3*b - 3*c + d, + 3*a - 6*b + 3*c, + -3*a + 3*b, + a]; + } + + + /** + * Finds the real solutions, if they exist, to a cubic polynomial equation of the form: at^3 + bt^2 + ct + d. + * This method is used to evaluate custom easing curves. + * + * @param a The first coefficient of the cubic equation, which is multiplied by the cubed variable (t^3). + * + * @param b The second coefficient of the cubic equation, which is multiplied by the squared variable (t^2). + * + * @param c The third coefficient of the cubic equation, which is multiplied by the linear variable (t). + * + * @param d The fourth coefficient of the cubic equation, which is the constant. + * + * @return An array of number values, indicating the real roots of the equation. + * There may be no roots, or as many as three. + * Imaginary or complex roots are ignored. + * @playerversion Flash 9.0.28.0 + * @playerversion AIR 1.0 + * @productversion Flash CS3 + * @langversion 3.0 + * @keyword Bezier curve, node, Copy Motion as ActionScript + */ + public static function getCubicRoots(a:Number=0, b:Number=0, c:Number=0, d:Number=0):Array + { + // make sure we really have a cubic + if (!a) return BezierSegment.getQuadraticRoots(b, c, d); + + // normalize the coefficients so the cubed term is 1 and we can ignore it hereafter + if (a != 1) + { + b/=a; + c/=a; + d/=a; + } + + var q:Number = (b*b - 3*c)/9; // won't change over course of curve + var qCubed:Number = q*q*q; // won't change over course of curve + var r:Number = (2*b*b*b - 9*b*c + 27*d)/54; // will change because d changes + // but parts with b and c won't change + // determine if there are 1 or 3 real roots using r and q + var diff:Number = qCubed - r*r; // will change + if (diff >= 0) + { + // avoid division by zero + if (!q) return [0]; + // three real roots + var theta:Number = Math.acos(r/Math.sqrt(qCubed)); // will change because r changes + var qSqrt:Number = Math.sqrt(q); // won't change + + var root1:Number = -2*qSqrt * Math.cos(theta/3) - b/3; + var root2:Number = -2*qSqrt * Math.cos((theta + 2*Math.PI)/3) - b/3; + var root3:Number = -2*qSqrt * Math.cos((theta + 4*Math.PI)/3) - b/3; + + return [root1, root2, root3]; + } + else + { + // one real root + var tmp:Number = Math.pow( Math.sqrt(-diff) + Math.abs(r), 1/3); + var rSign:int = (r > 0) ? 1 : r < 0 ? -1 : 0; + var root:Number = -rSign * (tmp + q/tmp) - b/3; + return [root]; + } + return []; + } + + + /** + * Finds the real solutions, if they exist, to a quadratic equation of the form: at^2 + bt + c. + * + * @param a The first coefficient of the quadratic equation, which is multiplied by the squared variable (t^2). + * + * @param b The second coefficient of the quadratic equation, which is multiplied by the linear variable (t). + * + * @param c The third coefficient of the quadratic equation, which is the constant. + * + * @return An array of number values, indicating the real roots of the equation. + * There may be no roots, or as many as two. + * Imaginary or complex roots are ignored. + * @playerversion Flash 9.0.28.0 + * @playerversion AIR 1.0 + * @productversion Flash CS3 + * @langversion 3.0 + * @keyword Bezier curve, node, Copy Motion as ActionScript + */ + public static function getQuadraticRoots(a:Number, b:Number, c:Number):Array + { + var roots:Array = []; + // make sure we have a quadratic + if (!a) + { + if (!b) return []; + roots[0] = -c/b; + return roots; + } + + var q:Number = b*b - 4*a*c; + var signQ:int = + (q > 0) ? 1 + : q < 0 ? -1 + : 0; + + if (signQ < 0) + { + return []; + } + else if (!signQ) + { + roots[0] = -b/(2*a); + } + else + { + roots[0] = roots[1] = -b/(2*a); + var tmp:Number = Math.sqrt(q)/(2*a); + roots[0] -= tmp; + roots[1] += tmp; + } + + return roots; + } + + + +} +} diff --git a/tags/0.8/docs/features.docx b/tags/0.8/docs/features.docx new file mode 100644 index 0000000..9102176 Binary files /dev/null and b/tags/0.8/docs/features.docx differ diff --git a/tags/0.8/docs/finger-chart-intro.pptx b/tags/0.8/docs/finger-chart-intro.pptx new file mode 100644 index 0000000..c843f12 Binary files /dev/null and b/tags/0.8/docs/finger-chart-intro.pptx differ diff --git a/tags/0.8/docs/log.docx b/tags/0.8/docs/log.docx new file mode 100644 index 0000000..70edfd9 Binary files /dev/null and b/tags/0.8/docs/log.docx differ diff --git a/tags/0.8/docs/uml.pptx b/tags/0.8/docs/uml.pptx new file mode 100644 index 0000000..9795918 Binary files /dev/null and b/tags/0.8/docs/uml.pptx differ diff --git a/tags/0.8/finger-chart-core-lib/libs/TweenLiteLib.swc b/tags/0.8/finger-chart-core-lib/libs/TweenLiteLib.swc new file mode 100644 index 0000000..b21c0ae Binary files /dev/null and b/tags/0.8/finger-chart-core-lib/libs/TweenLiteLib.swc differ diff --git a/tags/0.8/finger-chart-core-lib/libs/as3corelib.swc b/tags/0.8/finger-chart-core-lib/libs/as3corelib.swc new file mode 100644 index 0000000..12dd6b3 Binary files /dev/null and b/tags/0.8/finger-chart-core-lib/libs/as3corelib.swc differ diff --git a/tags/0.8/finger-chart-core-lib/pom.xml b/tags/0.8/finger-chart-core-lib/pom.xml new file mode 100644 index 0000000..3dfc770 --- /dev/null +++ b/tags/0.8/finger-chart-core-lib/pom.xml @@ -0,0 +1,68 @@ + + + + + com.riameeting.fingerchart + finger-chart-superpom + 0.8 + + + 4.0.0 + + com.riameeting.fingerchart + finger-chart-core-lib + 0.8 + swc + + Finger Chart Core Library + + + src/main/flex + + + org.sonatype.flexmojos + flexmojos-maven-plugin + ${flexmojos.version} + true + + + com.adobe.flex + compiler + ${flex.version} + pom + + + + + + + + + com.riameeting.fingerchart + common-lib + 0.8 + swc + compile + + + + com.adobe + as3corelib + ${as3corelib.version} + swc + compile + + + + com.greensock + TweenLiteLib + ${TweenLiteLib.version} + swc + compile + + + + + diff --git a/tags/0.8/finger-chart-core-lib/src/main/flex/com/riameeting/finger/component/AreaChart.as b/tags/0.8/finger-chart-core-lib/src/main/flex/com/riameeting/finger/component/AreaChart.as new file mode 100644 index 0000000..af45f73 --- /dev/null +++ b/tags/0.8/finger-chart-core-lib/src/main/flex/com/riameeting/finger/component/AreaChart.as @@ -0,0 +1,28 @@ +package com.riameeting.finger.component +{ + import com.riameeting.finger.display.axis.*; + import com.riameeting.finger.display.chart.AbstractChart; + import com.riameeting.finger.display.container.*; + import com.riameeting.finger.display.graphic.*; + import com.riameeting.finger.display.tooltip.Tooltip; + import com.riameeting.finger.effect.*; + + /** + * 组件:区域图 + * + * @example var areaChart:AreaChart = new AreaChart(); + * @see AbstractChart + * @author Finger + */ + public class AreaChart extends AbstractChart + { + public function AreaChart(width:uint, height:uint) + { + axis = new BasicAxis(this,false); + chartGraphicContainer = new ChartGraphicContainer(this,AreaGraphic,"AreaGraphic",LineGraphic,false,new MoveIn(),new MoveOut()); + tooltipContainer = new TooltipContainer(this,Tooltip); + pluginContainer = new PluginContainer(this); + super(axis, chartGraphicContainer, tooltipContainer, pluginContainer, width, height); + } + } +} \ No newline at end of file diff --git a/tags/0.8/finger-chart-core-lib/src/main/flex/com/riameeting/finger/component/BarChart.as b/tags/0.8/finger-chart-core-lib/src/main/flex/com/riameeting/finger/component/BarChart.as new file mode 100644 index 0000000..c033e15 --- /dev/null +++ b/tags/0.8/finger-chart-core-lib/src/main/flex/com/riameeting/finger/component/BarChart.as @@ -0,0 +1,25 @@ +package com.riameeting.finger.component +{ + import com.riameeting.finger.display.axis.*; + import com.riameeting.finger.display.chart.AbstractChart; + import com.riameeting.finger.display.container.*; + import com.riameeting.finger.display.graphic.*; + import com.riameeting.finger.display.tooltip.Tooltip; + import com.riameeting.finger.effect.*; + /** + * 组件:柱图(横向) + * @author Finger + * + */ + public class BarChart extends AbstractChart + { + public function BarChart(width:uint, height:uint) + { + axis = new ReversalAxis(this,true); + chartGraphicContainer = new ChartGraphicContainer(this,BarGraphic,"BarGraphic",LineGraphic,false,new MoveIn(),new MoveOut()); + tooltipContainer = new TooltipContainer(this,Tooltip,"byy"); + pluginContainer = new PluginContainer(this); + super(axis, chartGraphicContainer, tooltipContainer, pluginContainer, width, height); + } + } +} \ No newline at end of file diff --git a/tags/0.8/finger-chart-core-lib/src/main/flex/com/riameeting/finger/component/BubbleChart.as b/tags/0.8/finger-chart-core-lib/src/main/flex/com/riameeting/finger/component/BubbleChart.as new file mode 100644 index 0000000..a76aedf --- /dev/null +++ b/tags/0.8/finger-chart-core-lib/src/main/flex/com/riameeting/finger/component/BubbleChart.as @@ -0,0 +1,25 @@ +package com.riameeting.finger.component +{ + import com.riameeting.finger.display.axis.*; + import com.riameeting.finger.display.chart.AbstractChart; + import com.riameeting.finger.display.container.*; + import com.riameeting.finger.display.graphic.*; + import com.riameeting.finger.display.tooltip.Tooltip; + import com.riameeting.finger.effect.*; + /** + * 组件:气泡图 + * @author Finger + * + */ + public class BubbleChart extends AbstractChart + { + public function BubbleChart(width:uint, height:uint) + { + axis = new BasicAxis(this); + chartGraphicContainer = new ChartGraphicContainer(this,BubbleGraphic,"BubbleGraphic",LineGraphic,true,new MoveIn(),new MoveOut()); + tooltipContainer = new TooltipContainer(this,Tooltip); + pluginContainer = new PluginContainer(this); + super(axis, chartGraphicContainer, tooltipContainer, pluginContainer, width, height); + } + } +} \ No newline at end of file diff --git a/tags/0.8/finger-chart-core-lib/src/main/flex/com/riameeting/finger/component/ChartWrapper.as b/tags/0.8/finger-chart-core-lib/src/main/flex/com/riameeting/finger/component/ChartWrapper.as new file mode 100644 index 0000000..f780245 --- /dev/null +++ b/tags/0.8/finger-chart-core-lib/src/main/flex/com/riameeting/finger/component/ChartWrapper.as @@ -0,0 +1,138 @@ +package com.riameeting.finger.component +{ + import com.riameeting.finger.component.LineChart; + import com.riameeting.finger.config.ChartGlobal; + import com.riameeting.finger.display.chart.IChart; + import com.riameeting.finger.display.legend.ILegend; + import com.riameeting.finger.display.legend.SelectableLegend; + import com.riameeting.finger.display.legend.SimpleLegend; + import com.riameeting.finger.vo.DatasetVO; + + import flash.display.DisplayObject; + import flash.display.DisplayObjectContainer; + import flash.display.Sprite; + import flash.display.StageAlign; + import flash.display.StageScaleMode; + import flash.events.Event; + import flash.external.ExternalInterface; + + /** + * 图表包装类,用于将图表,图例说明,外部配置整合 + * @author Finger + * + */ + public class ChartWrapper extends Sprite + { + /** + * 图表组件 + */ + protected var chart:IChart; + /** + * 图例说明 + */ + protected var legend:ILegend; + /** + * 图表所需的配置,引用请使用ChartGlobal.chartConfig + */ + protected var chartConfig:Object; + private var preloader:Preloader = new Preloader(); + /** + * 构造方法 + * + */ + public function ChartWrapper() + { + super(); + if(stage != null) { + stage.scaleMode = StageScaleMode.NO_SCALE; + stage.align = StageAlign.TOP_LEFT; + stage.showDefaultContextMenu = false; + } + addEventListener(Event.ENTER_FRAME,checkStage); + chartConfig = loaderInfo.parameters; + } + /** + * 检查Stage是否为空,当不为空时执行初始化方法 + * @param e 事件 + * + */ + protected function checkStage(e:Event):void { + if(stage!=null && stage.stageWidth != 0) { + init(); + //removelistener + removeEventListener(Event.ENTER_FRAME,checkStage); + } + } + /** + * 初始化方法,将创建图表,并加载外部文件 + * @param e + * + */ + protected function init(e:Event=null):void { + stage.addEventListener(Event.RESIZE,resizeHandler); + chart.chartConfig = chartConfig; + chart.loadAssets(); + (chart as DisplayObjectContainer).addEventListener(Event.COMPLETE,hideProloader); + addChild(chart as DisplayObject); + //legend + if(chartConfig["legend"] != null) { + addChild(legend as DisplayObject); + legend.x = chart.width; + chart.bindLegend(legend); + } + addChild(preloader); + preloader.x = stage.stageWidth/2; + preloader.y = stage.stageHeight/2; + //receivedFromJavaScript + if(ExternalInterface.available) { + ExternalInterface.addCallback("addData",addDataFromJavaScript); + } + } + /** + * 从JavaScript加入数据 + * @param data + * @param policy + * + */ + protected function addDataFromJavaScript(data:Object,policy:String):void { + chart.addData(data,policy); + } + /** + * 隐藏进度条 + * @param e + * + */ + protected function hideProloader(e:Event):void { + removeChild(preloader); + } + /** + * Flash尺寸发生改变触发的回调方法,将重绘图表的显示元素。 + * @param e 事件 + * + */ + protected function resizeHandler(e:Event):void + { + chart.width = stage.stageWidth; + chart.height = stage.stageHeight; + legend.x = chart.width; + legend.updateDisplayList(legend.width,chart.height); + } + } +} +import com.riameeting.ui.control.Label; + +import flash.display.Sprite; + +class Preloader extends Sprite { + public function Preloader() { + var label:Label = new Label(); + label.color = 0xFFFFFF; + label.text = "加载中"; + label.x = -label.width/2; + label.y = -label.height/2; + addChild(label); + this.graphics.beginFill(0xCCCCCC,1); + this.graphics.drawCircle(0,0,label.width/2+4); + this.graphics.endFill(); + } +} \ No newline at end of file diff --git a/tags/0.8/finger-chart-core-lib/src/main/flex/com/riameeting/finger/component/ColumnChart.as b/tags/0.8/finger-chart-core-lib/src/main/flex/com/riameeting/finger/component/ColumnChart.as new file mode 100644 index 0000000..efb64de --- /dev/null +++ b/tags/0.8/finger-chart-core-lib/src/main/flex/com/riameeting/finger/component/ColumnChart.as @@ -0,0 +1,25 @@ +package com.riameeting.finger.component +{ + import com.riameeting.finger.display.axis.*; + import com.riameeting.finger.display.chart.AbstractChart; + import com.riameeting.finger.display.container.*; + import com.riameeting.finger.display.graphic.*; + import com.riameeting.finger.display.tooltip.Tooltip; + import com.riameeting.finger.effect.*; + /** + * 组件:柱图 + * @author Finger + * + */ + public class ColumnChart extends AbstractChart + { + public function ColumnChart(width:uint, height:uint) + { + axis = new BasicAxis(this,true); + chartGraphicContainer = new ChartGraphicContainer(this,ColumnGraphic,"ColumnGraphic",LineGraphic,false,new MoveIn(),new MoveOut()); + tooltipContainer = new TooltipContainer(this,Tooltip); + pluginContainer = new PluginContainer(this); + super(axis, chartGraphicContainer, tooltipContainer, pluginContainer, width, height); + } + } +} \ No newline at end of file diff --git a/tags/0.8/finger-chart-core-lib/src/main/flex/com/riameeting/finger/component/LineChart.as b/tags/0.8/finger-chart-core-lib/src/main/flex/com/riameeting/finger/component/LineChart.as new file mode 100644 index 0000000..c1e0646 --- /dev/null +++ b/tags/0.8/finger-chart-core-lib/src/main/flex/com/riameeting/finger/component/LineChart.as @@ -0,0 +1,25 @@ +package com.riameeting.finger.component +{ + import com.riameeting.finger.display.axis.*; + import com.riameeting.finger.display.chart.AbstractChart; + import com.riameeting.finger.display.container.*; + import com.riameeting.finger.display.graphic.*; + import com.riameeting.finger.display.tooltip.Tooltip; + import com.riameeting.finger.effect.*; + /** + * 组件:线图 + * @author Finger + * + */ + public class LineChart extends AbstractChart + { + public function LineChart(width:uint, height:uint) + { + axis = new BasicAxis(this); + chartGraphicContainer = new ChartGraphicContainer(this,LineGraphic,"LineGraphic",LineGraphic,false,new MoveIn(),new MoveOut()); + tooltipContainer = new TooltipContainer(this,Tooltip); + pluginContainer = new PluginContainer(this); + super(axis, chartGraphicContainer, tooltipContainer, pluginContainer, width, height); + } + } +} \ No newline at end of file diff --git a/tags/0.8/finger-chart-core-lib/src/main/flex/com/riameeting/finger/component/PieChart.as b/tags/0.8/finger-chart-core-lib/src/main/flex/com/riameeting/finger/component/PieChart.as new file mode 100644 index 0000000..cf1d3df --- /dev/null +++ b/tags/0.8/finger-chart-core-lib/src/main/flex/com/riameeting/finger/component/PieChart.as @@ -0,0 +1,25 @@ +package com.riameeting.finger.component +{ + import com.riameeting.finger.display.axis.*; + import com.riameeting.finger.display.chart.AbstractChart; + import com.riameeting.finger.display.container.*; + import com.riameeting.finger.display.graphic.*; + import com.riameeting.finger.display.tooltip.Tooltip; + import com.riameeting.finger.effect.*; + /** + * 组件:饼图(横向) + * @author Finger + * + */ + public class PieChart extends AbstractChart + { + public function PieChart(width:uint, height:uint) + { + axis = new PieAxis(this,true); + chartGraphicContainer = new ChartGraphicContainer(this,PieGraphic,"PieGraphic",LineGraphic,true,new FadeIn(),new FadeOut()); + tooltipContainer = new TooltipContainer(this,Tooltip,"byp"); + pluginContainer = new PluginContainer(this); + super(axis, chartGraphicContainer, tooltipContainer, pluginContainer, width, height); + } + } +} \ No newline at end of file diff --git a/tags/0.8/finger-chart-core-lib/src/main/flex/com/riameeting/finger/component/PlotChart.as b/tags/0.8/finger-chart-core-lib/src/main/flex/com/riameeting/finger/component/PlotChart.as new file mode 100644 index 0000000..cba3548 --- /dev/null +++ b/tags/0.8/finger-chart-core-lib/src/main/flex/com/riameeting/finger/component/PlotChart.as @@ -0,0 +1,25 @@ +package com.riameeting.finger.component +{ + import com.riameeting.finger.display.axis.*; + import com.riameeting.finger.display.chart.AbstractChart; + import com.riameeting.finger.display.container.*; + import com.riameeting.finger.display.graphic.*; + import com.riameeting.finger.display.tooltip.Tooltip; + import com.riameeting.finger.effect.*; + /** + * 组件:散点图 + * @author Finger + * + */ + public class PlotChart extends AbstractChart + { + public function PlotChart(width:uint, height:uint) + { + axis = new BasicAxis(this); + chartGraphicContainer = new ChartGraphicContainer(this,PlotGraphic,"PlotGraphic",LineGraphic,true,new MoveIn(),new MoveOut()); + tooltipContainer = new TooltipContainer(this,Tooltip); + pluginContainer = new PluginContainer(this); + super(axis, chartGraphicContainer, tooltipContainer, pluginContainer, width, height); + } + } +} \ No newline at end of file diff --git a/tags/0.8/finger-chart-core-lib/src/main/flex/com/riameeting/finger/config/ChartGlobal.as b/tags/0.8/finger-chart-core-lib/src/main/flex/com/riameeting/finger/config/ChartGlobal.as new file mode 100644 index 0000000..02d9613 --- /dev/null +++ b/tags/0.8/finger-chart-core-lib/src/main/flex/com/riameeting/finger/config/ChartGlobal.as @@ -0,0 +1,64 @@ +package com.riameeting.finger.config +{ + import com.riameeting.finger.display.chart.IChart; + import com.riameeting.finger.display.skin.*; + + import flash.display.MovieClip; + import flash.display.Sprite; + import flash.utils.Dictionary; + + /** + * 定义全局可访问的变量和配置,属性皆是静态属性,直接引用即可 + * @author Finger + * + */ + public class ChartGlobal + { + /** + * 定义当前图表的版本号 + */ + public static const version:String = "0.8"; + + /** + * 最后更新日期 + */ + public static const buildDate:String = "2010-12-26"; + /** + * 皮肤源 + */ + public static var skinSource:MovieClip; + /** + * 图表引用 + */ + private static var skinClassDict:Dictionary; + /** + * 获取皮肤素材 + * @param skinName + * @return + * + */ + public static function getSkin(skinName:String):MovieClip { + if(skinClassDict == null) { + skinClassDict = new Dictionary(); + skinClassDict["skin.ChartSkin"] = ChartSkin; + skinClassDict["skin.AxisSkin"] = AxisSkin; + skinClassDict["skin.TooltipSkin"] = TooltipSkin; + skinClassDict["skin.ColumnGraphic"] = ColumnGraphic; + skinClassDict["skin.BarGraphic"] = BarGraphic; + skinClassDict["skin.DotGraphic"] = DotGraphic; + } + var skin:MovieClip,skinClass:Class; + if(skinSource != null) { + skinClass = skinSource.loaderInfo.applicationDomain.getDefinition(skinName) as Class; + } else { + skinClass = skinClassDict[skinName] as Class; + } + skin = new skinClass() as MovieClip; + return skin; + } + /** + * 颜色数组,用于图表图形的绘制 + */ + public static var colorCollection:Array = [0xff0000,0xff0078,0xff00d2,0x9c00ff,0x0c00ff,0x00a2ff,0x09c700,0xe7b300,0xe75c00]; + } +} \ No newline at end of file diff --git a/tags/0.8/finger-chart-core-lib/src/main/flex/com/riameeting/finger/display/axis/BasicAxis.as b/tags/0.8/finger-chart-core-lib/src/main/flex/com/riameeting/finger/display/axis/BasicAxis.as new file mode 100644 index 0000000..8ea43df --- /dev/null +++ b/tags/0.8/finger-chart-core-lib/src/main/flex/com/riameeting/finger/display/axis/BasicAxis.as @@ -0,0 +1,282 @@ +package com.riameeting.finger.display.axis +{ + import com.riameeting.finger.display.chart.IChart; + import com.riameeting.finger.factory.ObjectFactory; + import com.riameeting.finger.vo.DatasetVO; + import com.riameeting.ui.control.Alert; + import com.riameeting.ui.control.Label; + import com.riameeting.utils.ColorUtils; + import com.riameeting.utils.DrawTool; + import com.riameeting.utils.NumberTool; + + import flash.display.GradientType; + import flash.display.MovieClip; + import flash.display.Sprite; + import flash.geom.Matrix; + import flash.geom.Point; + import flash.geom.Rectangle; + + /** + * 基础坐标系,支持X和Y方向的定位 + * @author Finger + * + */ + public class BasicAxis extends Sprite implements IAxis + { + private var _dataset:DatasetVO; + private var _chartRef:IChart; + /** + * 对Chart的 引用 + * @return + * + */ + public function get chartRef():IChart {return _chartRef;} + public function set chartRef(value:IChart):void {_chartRef=value;} + /** + * 坐标系宽度 + */ + public var axisWidth:uint; + /** + * 坐标系高度 + */ + public var axisHeight:uint; + /** + * 数据在2个轴上的最小值(X轴,Y轴) + */ + public var minValueX:Number = 0,minValueY:Number = 0; + /** + * 数据在2个轴上的最大值(X轴,Y轴) + */ + public var maxValueX:Number = 0,maxValueY:Number = 0; + /** + * 在X轴方向上划分的区块数量 + */ + public var countX:uint = 0; + /** + * 在Y轴方向上划分的区块数量 + */ + public var countY:uint = 0; + /** + * Y轴定义的数据显示字段,可以为1个或多个 + */ + public var yFields:Array; + /** + * X轴定义的数据显示字段,只能是一个 + */ + public var xField:String; + /** + * 绘制时,最后计算所得的单元格高度 + */ + public var realGridHeight:Number; + /** + * 绘制时,最后计算所得的单元格宽度 + */ + public var realGridWidth:Number; + /** + * 坐标系的图形绘制范围 + */ + public var graphicArea:Rectangle = new Rectangle(0,0,0,0); + + private var _style:Object = {gridHeight:50,paddingLeft:40,paddingTop:30,paddingRight:20,paddingBottom:50,offsetV:20,color:0x000000,lineColors:[0x000000,0x000000],lineAlphas:[0,100],lineWidth:2}; + private var _skin:MovieClip; + /** + * 设置为true,则偏移与单元格相同 + */ + public var ignoreOffsetV:Boolean; + + /** + * 坐标系的CSS样式定义 + * @return 对象 + * + */ + public function get style():Object{return _style;} + public function set style(value:Object):void{_style = value;} + /** + * 皮肤定义 + * @return + * + */ + public function get skin():MovieClip {return _skin;} + public function set skin(value:MovieClip):void {if(_skin != null) removeChild(_skin);_skin = value;_skin.hostComponent=this;addChildAt(_skin,0);} + /** + * 宽度 + * @return + * + */ + override public function get width():Number {return axisWidth;} + override public function set width(value:Number):void {axisWidth = value;} + /** + * 高度 + * @return + * + */ + override public function get height():Number {return axisHeight;} + override public function set height(value:Number):void {axisHeight = value;} + /** + * 坐标系中对数据源的引用 + * @return DatasetVO引用 + * + */ + public function get dataset():DatasetVO{return _dataset;} + public function set dataset(value:DatasetVO):void + { + _dataset = value; + xField = _dataset.config["xField"]; + yFields = _dataset.config["yField"].split(","); + } + /** + * 当数据传入之后,需要计算各个轴上的取值范围(最小为0,最大则需要循环计算) + * + */ + protected function calculateMaxValue():void { + var i:uint=0,j:uint=0,obj:Object; + if(_dataset.config["minValueX"] != null) { + minValueX = _dataset.config["minValueX"]; + } else { + minValueX = 0; + } + if(_dataset.config["maxValueX"] != null) { + maxValueX = _dataset.config["maxValueX"]; + } else { + maxValueX = 0; + } + if(_dataset.config["minValueY"] != null) { + minValueY = _dataset.config["minValueY"]; + } else { + minValueY = 0; + } + if(_dataset.config["maxValueY"] != null) { + maxValueY = _dataset.config["maxValueY"]; + } else { + maxValueY = 0; + } + //x + if(xField != null) { + if(yFields.length != 1) { + Alert.show("you must define 1 y fileds with xField mode","Error"); + throw new Error("you must define 1 y fileds with xField mode"); + } + countX = (graphicArea.width-int(style["offsetV"])*2)/int(style["gridHeight"]); + //maxXValue + for(j=0;j maxValueX) { + maxValueX = obj[xField]; + } + if(obj[xField] < minValueX) { + minValueX = obj[xField]; + } + } + maxValueX = NumberTool.getMaxNumber(maxValueX); + minValueX = NumberTool.getMinNumber(minValueX); + } else { + countX = dataset.collection.length; + } + //y + for(i=0;i maxValueY) { + maxValueY = obj[yFields[i]]; + } + if(obj[yFields[i]] < minValueY) { + minValueY = obj[yFields[i]]; + } + } + } + maxValueY = NumberTool.getMaxNumber(maxValueY); + minValueY = NumberTool.getMinNumber(minValueY); + countY = graphicArea.height/int(style["gridHeight"]); + //ignoreOffsetV + if(ignoreOffsetV) { + style["offsetH"] = graphicArea.width/(countX+1); + } + } + /** + * 构造方法 + * + */ + public function BasicAxis(chartRef:IChart,ignoreOffsetV:Boolean = false) + { + _chartRef = chartRef; + this.ignoreOffsetV = ignoreOffsetV; + this.cacheAsBitmap = true; + mouseChildren = false; + mouseEnabled = false; + } + /** + * 设置坐标系的宽度和高度 + * @param w 宽度 + * @param h 高度 + * + */ + protected function initSize(w:uint,h:uint):void { + axisWidth = w; + axisHeight = h; + graphicArea.x = int(style["paddingLeft"]); + graphicArea.y = int(style["paddingTop"]); + graphicArea.width = w - int(style["paddingLeft"]) - int(style["paddingRight"]); + graphicArea.height = h - int(style["paddingTop"]) - int(style["paddingBottom"]); + } + /** + * 更新显示列表的方法,当Flash场景尺寸发生改变,将调用此方法重绘坐标系 + * @param w 宽度 + * @param h 高度 + * + */ + public function updateDisplayList(w:uint,h:uint):void { + initSize(w,h); + calculateMaxValue(); + //clear + clear(); + skin.updateDisplayList(); + } + /** + * 获取一个数据对象在坐标系上的坐标点(映射),包含x和y + * @param vo 数据对象 + * @param yField Y轴字段 + * @return 坐标点 + * + */ + public function getPoint(vo:Object,yField:String):Point { + var targetX:Number; + var targetY:Number; + var objIndex:int = dataset.collection.indexOf(vo); + var currentOffset:Number = ignoreOffsetV ? style["offsetH"]:style["offsetV"]; + if(xField != null) { + var rw:uint = graphicArea.width - currentOffset*2; + targetX = graphicArea.x + currentOffset + (vo[xField] - minValueX)/(maxValueX-minValueX)*rw; + } else { + targetX = graphicArea.x + currentOffset + objIndex*realGridWidth; + } + targetY = graphicArea.y + graphicArea.height*(1-(vo[yField]-minValueY)/(maxValueY-minValueY)); + return new Point(targetX,targetY); + } + /** + * 基础坐标系不实现此方法 + * @param vo + * @param yField + * @return + * + */ + public function getAngle(vo:Object,yField:String):Object {return null} + /** + * 获取坐标系可见区域的范围 + * @return 矩形区域 + * + */ + public function getAxisRect():Rectangle { + return graphicArea; + } + /** + * 当需重绘坐标系的时候,调用此方法 + * + */ + public function clear():void { + this.graphics.clear(); + (_skin as Object).clear(); + } + + } +} \ No newline at end of file diff --git a/tags/0.8/finger-chart-core-lib/src/main/flex/com/riameeting/finger/display/axis/IAxis.as b/tags/0.8/finger-chart-core-lib/src/main/flex/com/riameeting/finger/display/axis/IAxis.as new file mode 100644 index 0000000..e7a91d9 --- /dev/null +++ b/tags/0.8/finger-chart-core-lib/src/main/flex/com/riameeting/finger/display/axis/IAxis.as @@ -0,0 +1,90 @@ +/** + * 此包下面是坐标系相关的接口和实现类 + */ +package com.riameeting.finger.display.axis +{ + import com.riameeting.finger.vo.DatasetVO; + + import flash.display.MovieClip; + import flash.geom.Point; + import flash.geom.Rectangle; + + /** + * 定义坐标系的接口 + * @author Finger + * + */ + public interface IAxis + { + /** + * 更新显示列表的方法,当Flash场景尺寸发生改变,将调用此方法重绘坐标系 + * @param width 图表宽度 + * @param height 图表高度 + * + */ + function updateDisplayList(width:uint,height:uint):void; + /** + * 坐标系中对数据源的引用 + * @return DatasetVO引用 + * + */ + function get dataset():DatasetVO; + function set dataset(value:DatasetVO):void; + /** + * 坐标系的CSS样式定义 + * @return 对象 + * + */ + function get style():Object; + function set style(value:Object):void; + /** + * 坐标系的SKIN定义 + * @return 对象 + * + */ + function get skin():MovieClip; + function set skin(value:MovieClip):void; + /** + * width + * @return + * + */ + function get width():Number; + function set width(value:Number):void; + /** + * height + * @return + * + */ + function get height():Number; + function set height(value:Number):void; + /** + * 当需要清理坐标系的时候,调用此方法 + * + */ + function clear():void; + /** + * 获取一个数据对象在坐标系上的坐标点(映射),包含x和y + * @param vo 数据对象 + * @param yField Y轴字段 + * @return 坐标点 + * + */ + function getPoint(vo:Object,yField:String):Point; + /** + * 获取一个数据对象在坐标系上的角度(映射),饼图专用 + * @param vo 数据对象 + * @param yField Y轴字段 + * @return 角度值 + * + */ + function getAngle(vo:Object,yField:String):Object; + /** + * 获取坐标系可见区域的范围 + * @return 矩形区域 + * + */ + function getAxisRect():Rectangle; + + } +} \ No newline at end of file diff --git a/tags/0.8/finger-chart-core-lib/src/main/flex/com/riameeting/finger/display/axis/PieAxis.as b/tags/0.8/finger-chart-core-lib/src/main/flex/com/riameeting/finger/display/axis/PieAxis.as new file mode 100644 index 0000000..0555223 --- /dev/null +++ b/tags/0.8/finger-chart-core-lib/src/main/flex/com/riameeting/finger/display/axis/PieAxis.as @@ -0,0 +1,86 @@ +package com.riameeting.finger.display.axis +{ + import com.riameeting.finger.display.chart.IChart; + + import flash.display.MovieClip; + import flash.geom.Point; + + /** + * 用于饼图的坐标系 + * @author Finger + * + */ + public class PieAxis extends BasicAxis + { + /** + * 起始角度 + */ + protected var beginAngle:Number = -90; + /** + * 当前数据项计算所得的角度 + */ + protected var currentAngle:Number = 0; + /** + * Pie无需Skin + * @param value + * + */ + override public function set skin(value:MovieClip):void {} + /** + * 构造方法 + * @param chartRef + * @param ignoreOffsetV + * + */ + public function PieAxis(chartRef:IChart, ignoreOffsetV:Boolean=false) + { + super(chartRef, ignoreOffsetV); + //titleB.visible = false; + } + /** + * 更新显示列表的方法,当Flash场景尺寸发生改变,将调用此方法重绘坐标系 + * @param w 宽度 + * @param h 高度 + * + */ + override public function updateDisplayList(w:uint, h:uint):void + { + axisWidth = w; + axisHeight = h; + style["paddingLeft"] = style["paddingTop"] = style["paddingRight"] = style["paddingBottom"] = 0; + graphicArea.x = int(style["paddingLeft"]); + graphicArea.y = int(style["paddingTop"]); + graphicArea.width = w - int(style["paddingLeft"]) - int(style["paddingRight"]); + graphicArea.height = h - int(style["paddingTop"]) - int(style["paddingBottom"]); + } + /** + * 获取一个数据对象在坐标系上的坐标点(映射),包含x和y + * @param vo 数据对象 + * @param yField Y轴字段 + * @return 坐标点 + * + */ + override public function getPoint(vo:Object, yField:String):Point + { + return new Point(axisWidth/2,axisHeight/2); + } + /** + * 获取一个数据对象在坐标系上的角度(映射),饼图专用 + * @param vo 数据对象 + * @param yField Y轴字段 + * @return 角度值 + * + */ + override public function getAngle(vo:Object,yField:String):Object { + var count:Number = 0; + for each(var item:Object in dataset.collection) { + count += Number(item[yField]); + } + var proportion:Number = Number(vo[yField])/count; + currentAngle = proportion*360; + var obj:Object = {beginAngle:beginAngle,angle:currentAngle}; + beginAngle += currentAngle; + return obj; + } + } +} \ No newline at end of file diff --git a/tags/0.8/finger-chart-core-lib/src/main/flex/com/riameeting/finger/display/axis/ReversalAxis.as b/tags/0.8/finger-chart-core-lib/src/main/flex/com/riameeting/finger/display/axis/ReversalAxis.as new file mode 100644 index 0000000..f699609 --- /dev/null +++ b/tags/0.8/finger-chart-core-lib/src/main/flex/com/riameeting/finger/display/axis/ReversalAxis.as @@ -0,0 +1,80 @@ +package com.riameeting.finger.display.axis +{ + import com.riameeting.finger.display.chart.IChart; + import com.riameeting.finger.factory.ObjectFactory; + import com.riameeting.finger.vo.DatasetVO; + import com.riameeting.ui.control.Alert; + import com.riameeting.ui.control.Label; + import com.riameeting.utils.NumberTool; + + import flash.geom.Point; + import flash.geom.Rectangle; + + /** + * 翻转坐标系 + * @author Finger + * + */ + public class ReversalAxis extends BasicAxis + { + /** + * 构造方法 + * @param chartRef + * @param ignoreOffsetV + * + */ + public function ReversalAxis(chartRef:IChart, ignoreOffsetV:Boolean=false) + { + super(chartRef, ignoreOffsetV); + } + /** + * 当数据传入之后,需要计算各个轴上的取值范围(最小为0,最大则需要循环计算) + * + */ + override protected function calculateMaxValue():void { + super.calculateMaxValue(); + var i:uint=0,j:uint=0,obj:Object; + //x + if(xField != null) { + countX = (graphicArea.height-int(style["offsetV"])*2)/int(style["gridHeight"]); + } else { + countX = dataset.collection.length; + } + countY = graphicArea.width/int(style["gridHeight"]); + } + /** + * 更新显示列表的方法,当Flash场景尺寸发生改变,将调用此方法重绘坐标系 + * @param w 宽度 + * @param h 高度 + * + */ + override public function updateDisplayList(w:uint,h:uint):void { + super.updateDisplayList(w,h); + skin.titleB.color = style["color"]; + skin.titleB.x = 0; + skin.titleB.y = 0; + skin.titleL.color = style["bottomColor"]; + skin.titleL.x = (w - skin.titleL.width)/2; + skin.titleL.y = h - skin.titleL.height; + } + /** + * 获取一个数据对象在坐标系上的坐标点(映射),包含x和y + * @param vo 数据对象 + * @param yField Y轴字段 + * @return 坐标点 + * + */ + override public function getPoint(vo:Object,yField:String):Point { + var targetX:Number; + var targetY:Number; + var objIndex:int = dataset.collection.indexOf(vo); + if(xField != null) { + throw new Error("ReveralAxis doesn't support xField"); + } else { + targetX = graphicArea.x + graphicArea.width*((vo[yField]-minValueY)/(maxValueY-minValueY)); + } + targetY = graphicArea.y + int(style["offsetV"]) + (dataset.collection.length-objIndex-1)*realGridWidth; + return new Point(targetX,targetY); + } + } +} \ No newline at end of file diff --git a/tags/0.8/finger-chart-core-lib/src/main/flex/com/riameeting/finger/display/chart/AbstractChart.as b/tags/0.8/finger-chart-core-lib/src/main/flex/com/riameeting/finger/display/chart/AbstractChart.as new file mode 100644 index 0000000..5eee1f9 --- /dev/null +++ b/tags/0.8/finger-chart-core-lib/src/main/flex/com/riameeting/finger/display/chart/AbstractChart.as @@ -0,0 +1,365 @@ +package com.riameeting.finger.display.chart +{ + import com.adobe.images.PNGEncoder; + import com.riameeting.finger.config.ChartGlobal; + import com.riameeting.finger.display.axis.IAxis; + import com.riameeting.finger.display.container.*; + import com.riameeting.finger.display.legend.ILegend; + import com.riameeting.finger.effect.IEffect; + import com.riameeting.finger.parser.CSSParser; + import com.riameeting.finger.parser.IParser; + import com.riameeting.finger.parser.JSONParser; + import com.riameeting.finger.parser.XMLParser; + import com.riameeting.finger.vo.DatasetVO; + import com.riameeting.net.ResourceLoader; + import com.riameeting.ui.control.Alert; + import com.riameeting.utils.NumberTool; + import com.riameeting.utils.ObjectUtils; + + import flash.display.BitmapData; + import flash.display.DisplayObject; + import flash.display.Loader; + import flash.display.MovieClip; + import flash.display.Sprite; + import flash.display.StageDisplayState; + import flash.events.ContextMenuEvent; + import flash.events.Event; + import flash.events.MouseEvent; + import flash.net.*; + import flash.ui.ContextMenu; + import flash.ui.ContextMenuItem; + import flash.utils.*; + + /** + * 抽象图表。此类并不确定图表的类型(线状图,柱状图或其它),依据它的依赖而定。 + * @author Finger + * + */ + public class AbstractChart extends Sprite implements IChart + { + //4 layer + private var _axis:IAxis; + private var _chartGraphicContainer:IChartGraphicContainer; + private var _tooltipContainer:ITooltipContainer; + private var _pluginContainer:IPluginContainer; + private var _chartConfig:Object; + //model + private var _dataset:DatasetVO; + private var _legend:ILegend; + //effect + private var _showEffect:IEffect; + private var _hideEffect:IEffect; + private var _graphicShowEffect:IEffect; + private var _graphicHideEffect:IEffect; + private var _tipShowEffect:IEffect; + private var _tipHideEffect:IEffect; + private var globalStyle:Object; + private var myContextMenu:ContextMenu; + /** + * 图表宽度 + */ + protected var chartWidth:uint; + /** + * 图表高度 + */ + protected var chartHeight:uint; + /** + * 资源加载器 + */ + protected var resourceLoader:ResourceLoader = new ResourceLoader(); + //style + private var _style:Object = {bgColors:[0xFFFFFF,0xFFFFFF],bgAlphas:[100,100],lineColors:[0x000000,0x000000],lineAlphas:[0,5]}; + private var _skin:MovieClip; + /** + * 图表的配置 + * @return + * + */ + public function get chartConfig():Object {return _chartConfig;} + public function set chartConfig(value:Object):void {_chartConfig = value;} + /** + * CSS样式定义 + * @return 对象 + * @default {bgColors:[0xFFFFFF,0xc8c8c8],bgAlphas:[100,100],lineColors:[0x000000,0x000000],lineAlphas:[0,20]} + */ + public function get style():Object{return _style;} + public function set style(value:Object):void{_style = value;} + /** + * SKIN定义 + * @return 对象 + * + */ + public function get skin():MovieClip{return _skin;} + public function set skin(value:MovieClip):void{if(_skin != null) removeChild(_skin);_skin = value;_skin.hostComponent=this;addChildAt(_skin,0);} + /** + * 对数据源的引用 + * @return DatasetVO引用 + * + */ + public function get dataset():DatasetVO{return _dataset;} + public function set dataset(value:DatasetVO):void + { + if(value == null) throw new Error("dataset not allow null"); + _dataset = value; + _axis.dataset = value; + _chartGraphicContainer.dataset = value; + _tooltipContainer.dataset = value; + _pluginContainer.dataset = value; + updateDisplayList(); + } + /** + * 图表的4个显示层级之一:坐标系 + * @return 坐标系 + * + */ + public function get axis():IAxis{return _axis;} + public function set axis(value:IAxis):void{_axis = value;} + /** + * 图表的4个显示层级之一:图形容器 + * @return 图形容器 + * + */ + public function get chartGraphicContainer():IChartGraphicContainer{return _chartGraphicContainer;} + public function set chartGraphicContainer(value:IChartGraphicContainer):void{_chartGraphicContainer = value;} + /** + * 图表的4个显示层级之一:鼠标提示容器 + * @return 鼠标提示容器 + * + */ + public function get tooltipContainer():ITooltipContainer{return _tooltipContainer;} + public function set tooltipContainer(value:ITooltipContainer):void{_tooltipContainer = value;} + /** + * 图表的4个显示层级之一:插件容器 + * @return 插件容器 + * + */ + public function get pluginContainer():IPluginContainer{return _pluginContainer;} + public function set pluginContainer(value:IPluginContainer):void{_pluginContainer = value;} + /** + * CSS解析器 + */ + protected var cssParser:CSSParser = new CSSParser(); + /** + * 构造方法 + * @param axis 坐标系 + * @param chartGraphicContainer 图形容器 + * @param tooltipContainer 鼠标提示容器 + * @param pluginContainer 插件容器 + * @param width 宽度 + * @param height 高度 + * + */ + public function AbstractChart(axis:IAxis, chartGraphicContainer:IChartGraphicContainer, tooltipContainer:ITooltipContainer, pluginContainer:IPluginContainer, width:uint, height:uint) + { + this._axis = axis; + this._chartGraphicContainer = chartGraphicContainer; + this._tooltipContainer = tooltipContainer; + this._pluginContainer = pluginContainer; + this.chartWidth = width; + this.chartHeight = height; + addChild(axis as DisplayObject); + addChild(chartGraphicContainer as DisplayObject); + addChild(tooltipContainer as DisplayObject); + addChild(pluginContainer as DisplayObject); + if(Alert.container == null) Alert.container = this; + } + /** + * 图表宽度 + * @return 宽度值 + * + */ + override public function get width():Number {return chartWidth;} + override public function set width(value:Number):void { + chartWidth = value; + updateDisplayList(); + } + /** + * 图表高度 + * @return 高度值 + * + */ + override public function get height():Number {return chartHeight;} + override public function set height(value:Number):void { + chartHeight = value; + updateDisplayList(); + } + /** + * 更新显示列表的方法,当Flash场景尺寸发生改变,将调用此方法重绘图表 + * + */ + public function updateDisplayList():void { + if(dataset == null) return; + _axis.updateDisplayList(width,height); + _chartGraphicContainer.updateDisplayList(width,height); + _tooltipContainer.updateDisplayList(width,height); + _pluginContainer.updateDisplayList(width,height); + skin.updateDisplayList({width:width,height:height}); + } + /** + * 加载图表依赖的数据和资源 + * + */ + public function loadAssets(chartConfigObj:Object = null):void { + if(chartConfigObj != null) chartConfig = chartConfigObj; + var assets:Array = []; + if(chartConfig.data != null) assets.push(chartConfig.data); + if(chartConfig.skin != null) assets.push(chartConfig.skin); + if(chartConfig.css != null) assets.push(chartConfig.css); + if(chartConfig.dataStr != null) { + chartConfig.data = "innerData"; + resourceLoader.fileDict[chartConfig.data] = chartConfig.dataStr; + } + if(chartConfig.cssStr != null) { + chartConfig.css = "innerCSS"; + resourceLoader.fileDict[chartConfig.css] = chartConfig.cssStr; + } + if(assets.length > 0) { + resourceLoader.loadAssets(assets,loadAssetsCompleteHandler); + } else { + loadAssetsCompleteHandler(); + } + } + /** + * 加载完毕执行的方法 + * + */ + protected function loadAssetsCompleteHandler():void { + //css + if(chartConfig.css != null) { + cssParser.clear(); + cssParser.parseCSS(resourceLoader.fileDict[chartConfig.css]); + if(cssParser.getStyle("chart") != null) { + style = ObjectUtils.mergePromps(cssParser.getStyle("chart"),style); + } + if(cssParser.getStyle("axis") != null) axis.style = ObjectUtils.mergePromps(cssParser.getStyle("axis"),axis.style);; + if(cssParser.getStyle("gContainer") != null) chartGraphicContainer.style = ObjectUtils.mergePromps(cssParser.getStyle("gContainer"),chartGraphicContainer.style); + if(cssParser.getStyle("tContainer") != null) tooltipContainer.style = ObjectUtils.mergePromps(cssParser.getStyle("tContainer"),tooltipContainer.style); + if(cssParser.getStyle("pContainer") != null) pluginContainer.style = ObjectUtils.mergePromps(cssParser.getStyle("pContainer"),pluginContainer.style); + if(_legend != null && cssParser.getStyle("legend") != null) _legend.style = ObjectUtils.mergePromps(cssParser.getStyle("legend"),_legend.style); + if(cssParser.getStyle("global") != null) { + globalStyle = cssParser.getStyle("global"); + ChartGlobal.colorCollection = globalStyle["colorCollection"]; + ChartGlobal.colorCollection = NumberTool.extendArrayByClone(ChartGlobal.colorCollection,10); + } + } + //skin + if(chartConfig.skin != null) { + var skinLoader:Loader = new Loader(); + skinLoader.loadBytes(resourceLoader.fileDict[chartConfig.skin]); + skinLoader.contentLoaderInfo.addEventListener(Event.COMPLETE,function(e:Event):void { + drawChart(e); + }); + } else { + drawChart(); + } + } + /** + * 准备工作完成,将数据赋值给图表,让图表开始绘制 + * + */ + protected function drawChart(e:Event = null):void { + if(stage == null) { + setTimeout(drawChart,100,e); + return; + } + dispatchEvent(new Event(Event.COMPLETE)); + if(e != null) ChartGlobal.skinSource = e.currentTarget.content; + skin = ChartGlobal.getSkin("skin.ChartSkin"); + axis.skin = ChartGlobal.getSkin("skin.AxisSkin"); + //data + var parser:IParser; + var dataStr:String = resourceLoader.fileDict[chartConfig.data]; + if(dataStr.charAt(0) != "{") { + parser = new XMLParser(); + } else { + parser = new JSONParser(); + } + dataset = parser.parse(dataStr); + if(_legend != null) _legend.dataset = dataset; + contextMenuHandler(); + (chartGraphicContainer as Object).useAnimation = false; + } + /** + * 绑定到图例说明 + * @param legend + * + */ + public function bindLegend(legend:ILegend):void { + _legend = legend; + } + /** + * 添加数据 + * @param data + * @param policy 策略,可选:add, replace + * + */ + public function addData(data:Object,policy:String="add"):void { + if(policy == "replace") { + dataset.collection.shift(); + } + dataset.collection.push(data); + updateDisplayList(); + } + /** + * 响应右键操作 + * + */ + protected function contextMenuHandler():void { + myContextMenu = new ContextMenu(); + if(myContextMenu.customItems == null) return; + contextMenu = myContextMenu; + myContextMenu.hideBuiltInItems(); + var versionMenu:ContextMenuItem = new ContextMenuItem("Finger Chart, version: "+ChartGlobal.version); + versionMenu.enabled = false; + myContextMenu.customItems.push(versionMenu); + var fullscreenMenu:ContextMenuItem = new ContextMenuItem("全屏",true); + fullscreenMenu.addEventListener(ContextMenuEvent.MENU_ITEM_SELECT, fullscreenHandler); + myContextMenu.customItems.push(fullscreenMenu); + var saveMenu:ContextMenuItem = new ContextMenuItem("保存为位图",false); + saveMenu.addEventListener(ContextMenuEvent.MENU_ITEM_SELECT, saveHandler); + myContextMenu.customItems.push(saveMenu); + var helpMenu:ContextMenuItem = new ContextMenuItem("www.riameeting.com/fingerchart",true); + helpMenu.addEventListener(ContextMenuEvent.MENU_ITEM_SELECT, getHelpLink); + myContextMenu.customItems.push(helpMenu); + var dateMenu:ContextMenuItem = new ContextMenuItem("最后更新日期:"+ChartGlobal.buildDate,true); + dateMenu.enabled = false; + myContextMenu.customItems.push(dateMenu); + stage.doubleClickEnabled = true; + stage.addEventListener(MouseEvent.DOUBLE_CLICK,fullscreenHandler); + } + /** + * 全屏 + * @param e + * + */ + private function fullscreenHandler(e:Event):void { + stage.displayState = StageDisplayState.FULL_SCREEN; + } + /** + * 保存图片 + * @param e + * + */ + private function saveHandler(e:ContextMenuEvent):void { + var bmd:BitmapData = new BitmapData(stage.width,stage.height); + bmd.draw(this); + var bmdBytes:ByteArray = PNGEncoder.encode(bmd); + var saveFile:FileReference = new FileReference(); + var dateStr:String = "finger_"; + var date:Date = new Date(); + dateStr += date.getFullYear()+"-"; + dateStr += date.getMonth()+1+"-"; + dateStr += date.getDate(); + saveFile.save(bmdBytes,dateStr+".png"); + } + /** + * 链接 + * @param e + * + */ + private function getHelpLink(e:ContextMenuEvent):void { + navigateToURL(new URLRequest("http://www.riameeting.com/fingerchart"),"_blank"); + } + + } +} \ No newline at end of file diff --git a/tags/0.8/finger-chart-core-lib/src/main/flex/com/riameeting/finger/display/chart/IChart.as b/tags/0.8/finger-chart-core-lib/src/main/flex/com/riameeting/finger/display/chart/IChart.as new file mode 100644 index 0000000..585c148 --- /dev/null +++ b/tags/0.8/finger-chart-core-lib/src/main/flex/com/riameeting/finger/display/chart/IChart.as @@ -0,0 +1,109 @@ +package com.riameeting.finger.display.chart +{ + import com.riameeting.finger.display.axis.IAxis; + import com.riameeting.finger.display.container.IChartGraphicContainer; + import com.riameeting.finger.display.container.IPluginContainer; + import com.riameeting.finger.display.container.ITooltipContainer; + import com.riameeting.finger.display.legend.ILegend; + import com.riameeting.finger.effect.IEffect; + import com.riameeting.finger.vo.DatasetVO; + + import flash.display.MovieClip; + + /** + * 图表接口 + * @author Finger + * + */ + public interface IChart + { + /** + * 图表的配置 + * @return + * + */ + function get chartConfig():Object; + function set chartConfig(value:Object):void; + /** + * 宽度 + * @return + * + */ + function get width():Number; + function set width(value:Number):void; + /** + * 高度 + * @return + * + */ + function get height():Number; + function set height(value:Number):void; + /** * 图表的4个显示层级之一:坐标系 * @return 坐标系 * */ function get axis():IAxis; + function set axis(value:IAxis):void; + /** + * 图表的4个显示层级之一:图形容器 + * @return 图形容器 + * + */ + function get chartGraphicContainer():IChartGraphicContainer; + function set chartGraphicContainer(value:IChartGraphicContainer):void; + /** + * 图表的4个显示层级之一:鼠标提示容器 + * @return 鼠标提示容器 + * + */ + function get tooltipContainer():ITooltipContainer; + function set tooltipContainer(value:ITooltipContainer):void; + /** + * 图表的4个显示层级之一:插件容器 + * @return 插件容器 + * + */ + function get pluginContainer():IPluginContainer; + function set pluginContainer(value:IPluginContainer):void; + /** + * 对数据源的引用 + * @return DatasetVO引用 + * + */ + function get dataset():DatasetVO; + function set dataset(value:DatasetVO):void; + /** + * CSS样式定义 + * @return 对象 + * + */ + function get style():Object; + function set style(value:Object):void; + /** + * Skin + * @return 对象 + * + */ + function get skin():MovieClip; + function set skin(value:MovieClip):void; + /** + * 更新显示列表的方法,当Flash场景尺寸发生改变,将调用此方法重绘图表 + * + */ + function updateDisplayList():void; + /** + * 加载资源 + * + */ + function loadAssets(chartConfigObj:Object = null):void; + /** + * 绑定到图例说明 + * @param legend + * + */ + function bindLegend(legend:ILegend):void; + /** + * 添加数据 + * @param data + * @param policy 策略,可选:add, replace + * + */ + function addData(data:Object,policy:String="add"):void; + } +} \ No newline at end of file diff --git a/tags/0.8/finger-chart-core-lib/src/main/flex/com/riameeting/finger/display/container/ChartGraphicContainer.as b/tags/0.8/finger-chart-core-lib/src/main/flex/com/riameeting/finger/display/container/ChartGraphicContainer.as new file mode 100644 index 0000000..8b67a51 --- /dev/null +++ b/tags/0.8/finger-chart-core-lib/src/main/flex/com/riameeting/finger/display/container/ChartGraphicContainer.as @@ -0,0 +1,360 @@ +package com.riameeting.finger.display.container +{ + import com.riameeting.finger.config.ChartGlobal; + import com.riameeting.finger.display.chart.IChart; + import com.riameeting.finger.display.graphic.IChartGraphic; + import com.riameeting.finger.effect.IEffect; + import com.riameeting.finger.events.ChartEvent; + import com.riameeting.finger.factory.ObjectFactory; + import com.riameeting.finger.vo.DatasetVO; + + import flash.display.DisplayObject; + import flash.display.Sprite; + import flash.events.Event; + import flash.events.MouseEvent; + import flash.external.ExternalInterface; + import flash.filters.DropShadowFilter; + import flash.geom.Rectangle; + + /** + * 图形容器类 + * @author Finger + * + */ + public class ChartGraphicContainer extends Sprite implements IChartGraphicContainer + { + private var _dataset:DatasetVO; + private var _graphicClass:Class; + private var _graphicKey:String; + private var _yFields:Array; + private var _benchmark:Array; + private var _graphicsCollection:Array; + private var _seriesCollection:Array; + private var _seriesMode:Object = {}; + private var _style:Object = {color:0x000000,benchmarkColor:0x999999,lineWidth:2,dotWidth:2,lineMode:"line"}; + private var _benchmarkClass:Class; + private var _graphicShowEffect:IEffect; + private var _graphicHideEffect:IEffect; + private var _chartRef:IChart; + private var _differentColors:Boolean; + /** + * 遮罩 + */ + protected var maskRect:Sprite = new Sprite(); + /** + * 是否开启动画模式 + */ + public var useAnimation:Boolean = true; + /** + * 对Chart的 引用 + * @return + * + */ + public function get chartRef():IChart {return _chartRef;} + public function set chartRef(value:IChart):void {_chartRef=value;} + /** + * 是否开启多色彩模式(每个图形使用单独的色彩) + * @return 布尔量 + * + */ + public function get differentColors():Boolean{return _differentColors;} + public function set differentColors(value:Boolean):void{_differentColors = value;} + /** + * 图形显示的特效 + * @return + * + */ + public function get graphicShowEffect():IEffect{return _graphicShowEffect;} + public function set graphicShowEffect(value:IEffect):void{_graphicShowEffect = value;} + /** + * 图形隐藏的特效 + * @return + * + */ + public function get graphicHideEffect():IEffect{return _graphicHideEffect;} + public function set graphicHideEffect(value:IEffect):void{_graphicHideEffect = value;} + /** + * 参考线类 + * @return 类 + * + */ + public function get benchmarkClass():Class{return _benchmarkClass;} + public function set benchmarkClass(value:Class):void{_benchmarkClass = value;} + /** + * CSS样式定义 + * @return 对象 + * + */ + public function get style():Object{return _style;} + public function set style(value:Object):void{_style = value;} + /** + * 图形类 + * @return 类 + * + */ + public function get graphicClass():Class{return _graphicClass;} + public function set graphicClass(value:Class):void{_graphicClass = value;} + /** + * 对数据源的引用 + * @return DatasetVO引用 + * + */ + public function get dataset():DatasetVO{return _dataset;} + public function set dataset(value:DatasetVO):void + { + _dataset = value; + yFields = value.config["yField"].split(","); + if(value.config["benchmark"] != null) benchmark = value.config["benchmark"].split(","); + } + /** + * Y轴定义的数据显示字段,可以为1个或多个 + * @return 数组 + * + */ + public function get yFields():Array{return _yFields;} + public function set yFields(value:Array):void{_yFields = value;} + /** + * Y轴定义的参考线显示字段,可以为1个或多个 + * @return 数组 + * + */ + public function get benchmark():Array {return _benchmark;} + public function set benchmark(value:Array):void {_benchmark = value;} + /** + * 构造方法 + * @param graphicClass 图形类 + * @param benchmarkClass 参考线类 + * @param differentColors 不同色彩模式 + * @param showEffect 显示特效 + * @param hideEffect 隐藏特效 + * + */ + public function ChartGraphicContainer(chartRef:IChart,graphicClass:Class,graphicKey:String,benchmarkClass:Class,differentColors:Boolean,showEffect:IEffect,hideEffect:IEffect) + { + super(); + _chartRef = chartRef; + _graphicClass = graphicClass; + _graphicKey = graphicKey; + _benchmarkClass = benchmarkClass; + _differentColors = differentColors; + graphicShowEffect = showEffect; + graphicHideEffect = hideEffect; + addEventListener(ChartEvent.ITEM_CLICK,itemClickHanlder); + } + /** + * 更新显示列表的方法,当Flash场景尺寸发生改变,将调用此方法进行重绘 + * @param width 宽度 + * @param height 高度 + * + */ + public function updateDisplayList(width:uint,height:uint):void { + clear(); + for(var i:uint=0;i -1) { + graphic = ObjectFactory.produce(_benchmarkClass,"BenchmarkClass",[chartRef]) as IChartGraphic; + } else { + graphic = ObjectFactory.produce(_graphicClass,_graphicKey,[chartRef]) as IChartGraphic; + } + graphic.data = dataset.collection[j]; + graphic.style = style; + if(graphic.skin == null) graphic.skin = ChartGlobal.getSkin(graphic.skinName); + if(graphic.data["name"] == null) graphic.data["name"] = graphic.data[dataset.config["categoryField"]]; + graphic.name = graphic.data["name"]; + graphic.yField = yFields[i]; + if(graphic.data[graphic.yField] == "-") { + graphic.enabled = false; + graphic.data.enabled = false; + } else { + graphic.enabled = true; + graphic.data.enabled = true; + } + if(dataset.config["benchmark"] != null && benchmark.indexOf(graphic.yField) > -1) { + graphic.color = style["benchmarkColor"]; + } else { + if(differentColors) { + graphic.color = ChartGlobal.colorCollection[j]; + } else { + graphic.color = ChartGlobal.colorCollection[i]; + } + } + if(graphic.enabled) { + series.addChild(graphic as DisplayObject); + graphic.locate(chartRef.axis.getPoint(graphic.data,graphic.yField)); + _graphicsCollection.push(graphic); + } + } + if(seriesMode[series.name] != false) { + showSeries(series.name); + } else { + hideSeries(series.name); + } + } + //mask + var axisRect:Rectangle = chartRef.axis.getAxisRect(); + maskRect.graphics.clear(); + maskRect.graphics.beginFill(0x000000,1); + maskRect.graphics.drawRect(axisRect.x,axisRect.y,axisRect.width,axisRect.height); + maskRect.graphics.endFill(); + mask = maskRect; + parent.addChild(maskRect); + } + /** + * 显示series(适用于多组数据,比如多条折线) + * @param seriesName 名称 + * + */ + public function showSeries(seriesName:String,animation:Boolean=false):void { + var series:DisplayObject = getChildByName(seriesName); + if(useAnimation) animation = true; + if(animation && graphicShowEffect!=null) { + graphicShowEffect.execute(series,0.5,effectComplete); + (chartRef as Sprite).mouseEnabled = false; + } else { + series.visible = true; + } + } + /** + * 隐藏series(适用于多组数据,比如多条折线) + * @param seriesName 名称 + * + */ + public function hideSeries(seriesName:String,animation:Boolean=false):void { + var series:DisplayObject = getChildByName(seriesName); + if(useAnimation) animation = true; + if(animation && graphicHideEffect!=null) { + graphicHideEffect.execute(series,0.5,effectComplete); + (chartRef as Sprite).mouseEnabled = false; + } else { + series.visible = false; + } + } + /** + * 显示图形 + * @param graphicName 名称 + * + */ + public function showGraphic(graphicName:String,animation:Boolean=false):void { + var g:DisplayObject = getObjByName(graphicName); + if(graphicShowEffect!=null) { + graphicShowEffect.execute(g,0.5,effectComplete); + (chartRef as Sprite).mouseEnabled = false; + } else { + g.visible = true; + } + } + /** + * 隐藏图形 + * @param graphicName 名称 + * + */ + public function hideGraphic(graphicName:String,animation:Boolean=false):void { + var g:DisplayObject = getObjByName(graphicName); + if(graphicHideEffect!=null) { + graphicHideEffect.execute(g,0.5,effectComplete); + (chartRef as Sprite).mouseEnabled = false; + } else { + g.visible = false; + } + } + /** + * 一个包含了所有图形的数组 + * @return 数组 + * + */ + public function get graphicsCollection():Array {return _graphicsCollection;} + /** + * 如果yFields是多个,则将数据分为N个series,series放置到这个数组 + * @return 数组 + * + */ + public function get seriesCollection():Array {return _seriesCollection;} + /** + * 同seriesCollection对应,但存储的是series的状态 + * @return + * + */ + public function get seriesMode():Object {return _seriesMode;} + /** + * 获取容器中的图形 + * @param data 数据对象 + * @param yField Y轴字段 + * @return IChartGraphic + * + */ + public function getGraphic(data:Object,yField:String):IChartGraphic { + var graphic:IChartGraphic; + f:for each(var item:IChartGraphic in _graphicsCollection) { + if(item.data == data && item.yField == yField) { + graphic = item; + break f; + } + } + return graphic; + } + /** + * 图形被点击触发的回调方法 + * @param e 图形点击事件 + * + */ + protected function itemClickHanlder(e:ChartEvent):void { + if(chartRef.chartConfig["callback"] != null && ExternalInterface.available) { + ExternalInterface.call(chartRef.chartConfig["callback"],e.data); + } + } + /** + * 通过名称获取对象的引用 + * @param objName 对象名称 + * @return 对象 + * + */ + protected function getObjByName(objName:String):DisplayObject { + var obj:DisplayObject; + f:for each(var item:DisplayObject in graphicsCollection) { + if(item.name == objName) { + obj = item; + break f; + } + } + return obj; + } + /** + * 特效执行完毕 + * @param e + * + */ + protected function effectComplete():void { + (chartRef as Sprite).mouseEnabled = true; + } + /** + * 执行清理动作 + * + */ + public function clear():void { + graphics.clear(); + _graphicsCollection = []; + _seriesCollection = []; + var series:Sprite; + while(numChildren > 0) { + series = getChildAt(0) as Sprite; + while(series.numChildren > 0) { + (series.getChildAt(0) as IChartGraphic).clear(); + if(benchmark != null &&benchmark.indexOf(series.name) > -1) { + ObjectFactory.reclaim(_benchmarkClass,series.removeChildAt(0),"BenchmarkClass"); + } else { + ObjectFactory.reclaim(_graphicClass,series.removeChildAt(0),_graphicKey); + } + } + series.name = ""; + series.graphics.clear(); + ObjectFactory.reclaim(Sprite,removeChild(series),"Sprite"); + } + } + + } +} \ No newline at end of file diff --git a/tags/0.8/finger-chart-core-lib/src/main/flex/com/riameeting/finger/display/container/IChartGraphicContainer.as b/tags/0.8/finger-chart-core-lib/src/main/flex/com/riameeting/finger/display/container/IChartGraphicContainer.as new file mode 100644 index 0000000..ec382e5 --- /dev/null +++ b/tags/0.8/finger-chart-core-lib/src/main/flex/com/riameeting/finger/display/container/IChartGraphicContainer.as @@ -0,0 +1,149 @@ +package com.riameeting.finger.display.container +{ + import com.riameeting.finger.display.chart.IChart; + import com.riameeting.finger.display.graphic.IChartGraphic; + import com.riameeting.finger.effect.IEffect; + import com.riameeting.finger.vo.DatasetVO; + + /** + * 图形容器接口 + * @author Finger + * + */ + public interface IChartGraphicContainer + { + /** + * 对Chart的 引用 + * @return + * + */ + function get chartRef():IChart; + function set chartRef(value:IChart):void; + /** + * 更新显示列表的方法,当Flash场景尺寸发生改变,将调用此方法进行重绘 + * @param width 宽度 + * @param height 高度 + * + */ + function updateDisplayList(width:uint,height:uint):void; + /** + * 对数据源的引用 + * @return DatasetVO引用 + * + */ + function get dataset():DatasetVO; + function set dataset(value:DatasetVO):void; + /** + * 图形类 + * @return 类 + * + */ + function get graphicClass():Class; + function set graphicClass(value:Class):void; + /** + * 参考线类 + * @return 类 + * + */ + function get benchmarkClass():Class; + function set benchmarkClass(value:Class):void; + /** + * Y轴定义的数据显示字段,可以为1个或多个 + * @return 数组 + * + */ + function get yFields():Array; + function set yFields(value:Array):void; + /** + * Y轴定义的参考线显示字段,可以为1个或多个 + * @return 数组 + * + */ + function get benchmark():Array; + function set benchmark(value:Array):void; + /** + * 是否开启多色彩模式(每个图形使用单独的色彩) + * @return 布尔量 + * + */ + function get differentColors():Boolean; + function set differentColors(value:Boolean):void; + /** + * CSS样式定义 + * @return 对象 + * + */ + function get style():Object; + function set style(value:Object):void; + /** + * 一个包含了所有图形的数组 + * @return 数组 + * + */ + function get graphicsCollection():Array; + /** + * 如果yFields是多个,则将数据分为N个series,series放置到这个数组 + * @return 数组 + * + */ + function get seriesCollection():Array; + /** + * 与seriesCollection对应,存储状态 + * @return Object + * + */ + function get seriesMode():Object; + /** + * 图形显示的特效 + * @return + * + */ + function get graphicShowEffect():IEffect; + function set graphicShowEffect(value:IEffect):void; + /** + * 图形隐藏的特效 + * @return + * + */ + function get graphicHideEffect():IEffect; + function set graphicHideEffect(value:IEffect):void; + /** + * 获取容器中的图形 + * @param data 数据对象 + * @param yField Y轴字段 + * @return IChartGraphic + * + */ + function getGraphic(data:Object,yField:String):IChartGraphic; + /** + * 显示series(适用于多组数据,比如多条折线) + * @param seriesName 名称 + * + */ + function showSeries(seriesName:String,animation:Boolean=false):void; + /** + * 隐藏series(适用于多组数据,比如多条折线) + * @param seriesName 名称 + * + */ + function hideSeries(seriesName:String,animation:Boolean=false):void; + /** + * 显示图形 + * @param graphicName 名称 + * + */ + function showGraphic(graphicName:String,animation:Boolean=false):void; + /** + * 隐藏图形 + * @param graphicName 名称 + * + */ + function hideGraphic(graphicName:String,animation:Boolean=false):void; + /** + * 执行清理动作 + * + */ + function clear():void; + + } +} \ No newline at end of file diff --git a/tags/0.8/finger-chart-core-lib/src/main/flex/com/riameeting/finger/display/container/IPluginContainer.as b/tags/0.8/finger-chart-core-lib/src/main/flex/com/riameeting/finger/display/container/IPluginContainer.as new file mode 100644 index 0000000..4478af0 --- /dev/null +++ b/tags/0.8/finger-chart-core-lib/src/main/flex/com/riameeting/finger/display/container/IPluginContainer.as @@ -0,0 +1,54 @@ +package com.riameeting.finger.display.container +{ + import com.riameeting.finger.display.chart.IChart; + import com.riameeting.finger.vo.DatasetVO; + + /** + * 插件容器接口 + * @author Finger + * + */ + public interface IPluginContainer + { + /** + * 对Chart的 引用 + * @return + * + */ + function get chartRef():IChart; + function set chartRef(value:IChart):void; + /** + * 更新显示列表的方法,当Flash场景尺寸发生改变,将调用此方法重绘图表 + * @param width 宽度 + * @param height 高度 + */ + function updateDisplayList(width:uint,height:uint):void; + /** + * 对数据源的引用 + * @return DatasetVO引用 + * + */ + function get dataset():DatasetVO; + function set dataset(value:DatasetVO):void; + /** + * CSS样式定义 + * @return 对象 + * + */ + function get style():Object; + function set style(value:Object):void; + /** + * 插件数组,即允许同时加载多个插件 + * @return + * + */ + function get pluginCollection():Array; + function set pluginCollection(value:Array):void; + /** + * 执行清理动作 + * + */ + function clear():void; + + } +} \ No newline at end of file diff --git a/tags/0.8/finger-chart-core-lib/src/main/flex/com/riameeting/finger/display/container/ITooltipContainer.as b/tags/0.8/finger-chart-core-lib/src/main/flex/com/riameeting/finger/display/container/ITooltipContainer.as new file mode 100644 index 0000000..22e4ace --- /dev/null +++ b/tags/0.8/finger-chart-core-lib/src/main/flex/com/riameeting/finger/display/container/ITooltipContainer.as @@ -0,0 +1,55 @@ +package com.riameeting.finger.display.container +{ + import com.riameeting.finger.display.chart.IChart; + import com.riameeting.finger.effect.IEffect; + import com.riameeting.finger.vo.DatasetVO; + + /** + * 鼠标提示容器接口 + * @author Finger + * + */ + public interface ITooltipContainer + { + /** + * 对Chart的 引用 + * @return + * + */ + function get chartRef():IChart; + function set chartRef(value:IChart):void; + /** + * 更新显示列表的方法,当Flash场景尺寸发生改变,将调用此方法重绘图表 + * @param width 宽度 + * @param height 高度 + */ + function updateDisplayList(width:uint,height:uint):void; + /** + * 对数据源的引用 + * @return DatasetVO引用 + * + */ + function get dataset():DatasetVO; + function set dataset(value:DatasetVO):void; + /** + * 鼠标提示类 + * @return 类 + * + */ + function get tooltipClass():Class; + function set tooltipClass(value:Class):void; + /** + * CSS样式定义 + * @return 对象 + * + */ + function get style():Object; + function set style(value:Object):void; + /** + * 执行清理动作 + * + */ + function clear():void; + + } +} \ No newline at end of file diff --git a/tags/0.8/finger-chart-core-lib/src/main/flex/com/riameeting/finger/display/container/PluginContainer.as b/tags/0.8/finger-chart-core-lib/src/main/flex/com/riameeting/finger/display/container/PluginContainer.as new file mode 100644 index 0000000..587b897 --- /dev/null +++ b/tags/0.8/finger-chart-core-lib/src/main/flex/com/riameeting/finger/display/container/PluginContainer.as @@ -0,0 +1,114 @@ +package com.riameeting.finger.display.container +{ + import com.adobe.images.PNGEncoder; + import com.riameeting.finger.config.ChartGlobal; + import com.riameeting.finger.display.chart.IChart; + import com.riameeting.finger.plugin.IChartPlugin; + import com.riameeting.finger.vo.DatasetVO; + import com.riameeting.ui.control.Alert; + + import flash.display.Loader; + import flash.display.Sprite; + import flash.events.Event; + import flash.events.IOErrorEvent; + import flash.net.URLRequest; + + /** + * 插件容器类 + * @author Finger + * + */ + public class PluginContainer extends Sprite implements IPluginContainer + { + private var _dataset:DatasetVO; + private var _style:Object; + private var _pluginCollection:Array = []; + private var _chartRef:IChart; + /** + * 对Chart的 引用 + * @return + * + */ + public function get chartRef():IChart {return _chartRef;} + public function set chartRef(value:IChart):void {_chartRef=value;} + /** + * 插件数组,即允许同时加载多个插件 + * @return + * + */ + public function get pluginCollection():Array{return _pluginCollection;} + public function set pluginCollection(value:Array):void{_pluginCollection = value;} + /** + * CSS样式定义 + * @return 对象 + * + */ + public function get style():Object{return _style;} + public function set style(value:Object):void{_style = value;} + /** + * 对数据源的引用 + * @return DatasetVO引用 + * + */ + public function get dataset():DatasetVO{return _dataset;} + public function set dataset(value:DatasetVO):void{ + _dataset = value; + var pluginStr:String = chartRef.chartConfig["plugin"]; + if(pluginStr != null) { + for each(var url:String in pluginStr.split(",")) { + var loader:Loader = new Loader(); + loader.load(new URLRequest(url)); + loader.contentLoaderInfo.addEventListener(Event.COMPLETE,completeHandler); + loader.contentLoaderInfo.addEventListener(IOErrorEvent.IO_ERROR,errorHandler); + addChild(loader); + } + } + } + /** + * 构造方法 + * @param pluginStr 插件地址 + * + */ + public function PluginContainer(chartRef:IChart){ + _chartRef = chartRef; + PNGEncoder; + } + /** + * 插件加载完毕执行的回调方法 + * @param e 事件 + * + */ + protected function completeHandler(e:Event):void { + var plugin:IChartPlugin = e.currentTarget.content as IChartPlugin; + plugin.initPlugin(this); + pluginCollection.push(plugin); + } + /** + * 插件加载错误触发的回调方法 + * @param e IO错误 + * + */ + protected function errorHandler(e:IOErrorEvent):void { + Alert.show(e.toString(),"Error"); + } + /** + * 更新显示列表的方法,当Flash场景尺寸发生改变,将调用此方法重绘图表 + * @param width 宽度 + * @param height 高度 + */ + public function updateDisplayList(w:uint,h:uint):void { + if(pluginCollection == null) return; + for each(var plugin:IChartPlugin in pluginCollection) { + plugin.updateDisplayList(w,h); + } + } + /** + * 执行清理动作 + * + */ + public function clear():void { + + } + + } +} \ No newline at end of file diff --git a/tags/0.8/finger-chart-core-lib/src/main/flex/com/riameeting/finger/display/container/TooltipContainer.as b/tags/0.8/finger-chart-core-lib/src/main/flex/com/riameeting/finger/display/container/TooltipContainer.as new file mode 100644 index 0000000..4ddc898 --- /dev/null +++ b/tags/0.8/finger-chart-core-lib/src/main/flex/com/riameeting/finger/display/container/TooltipContainer.as @@ -0,0 +1,232 @@ +package com.riameeting.finger.display.container +{ + import com.greensock.TweenLite; + import com.riameeting.controler.EventBus; + import com.riameeting.finger.config.ChartGlobal; + import com.riameeting.finger.display.chart.IChart; + import com.riameeting.finger.display.graphic.IChartGraphic; + import com.riameeting.finger.display.tooltip.ITooltip; + import com.riameeting.finger.vo.DatasetVO; + import com.riameeting.utils.NumberTool; + + import flash.display.DisplayObject; + import flash.display.DisplayObjectContainer; + import flash.display.Sprite; + import flash.events.Event; + import flash.events.MouseEvent; + import flash.geom.Point; + import flash.geom.Rectangle; + + /** + * 鼠标提示容器类 + * @author NeoGuo + * + */ + public class TooltipContainer extends Sprite implements ITooltipContainer + { + private var _dataset:DatasetVO; + private var _tooltipClass:Class; + + private var tooltip:ITooltip; + private var axisRect:Rectangle; + private var graphicsCollection:Array; + private var _style:Object = {color:0x000000,tipbgColor:0xFFFFFF,tipbgAlpha:100,borderWidth:3,borderColor:0x000000,borderAlpha:20}; + private var _chartRef:IChart; + /** + * 监测规则 + */ + protected var checkType:String; + /** + * 对Chart的 引用 + * @return + * + */ + public function get chartRef():IChart {return _chartRef;} + public function set chartRef(value:IChart):void {_chartRef=value;} + /** + * CSS样式定义 + * @return 对象 + * + */ + public function get style():Object{return _style;} + public function set style(value:Object):void{_style = value;} + /** + * 鼠标提示类 + * @return 类 + * + */ + public function get tooltipClass():Class{return _tooltipClass;} + public function set tooltipClass(value:Class):void{_tooltipClass = value;} + /** + * 对数据源的引用 + * @return DatasetVO引用 + * + */ + public function get dataset():DatasetVO{return _dataset;} + public function set dataset(value:DatasetVO):void + { + _dataset = value; + tooltip.style = style; + tooltip.skin = ChartGlobal.getSkin("skin.TooltipSkin"); + (chartRef as DisplayObjectContainer).addEventListener(MouseEvent.MOUSE_MOVE,containerMouseHandler); + if(stage!=null) stage.addEventListener(Event.MOUSE_LEAVE,function(e:Event):void {clear()}); + } + /** + * 构造方法 + * @param tooltipClass 鼠标提示类 + * @param unity 是否组合提示字符串 + * @param checkType 可选byx或byy + */ + public function TooltipContainer(chartRef:IChart,tooltipClass:Class,checkType:String = "byx") + { + _chartRef = chartRef; + _tooltipClass = tooltipClass; + this.checkType = checkType; + tooltip = new tooltipClass() as ITooltip; + addChild(tooltip as DisplayObject); + tooltip.hide(); + mouseChildren = false; + mouseEnabled = false; + } + /** + * 更新显示列表的方法,当Flash场景尺寸发生改变,将调用此方法重绘图表 + * @param width 宽度 + * @param height 高度 + */ + public function updateDisplayList(width:uint,height:uint):void { + axisRect = chartRef.axis.getAxisRect(); + graphicsCollection = chartRef.chartGraphicContainer.graphicsCollection; + } + /** + * 容器鼠标事件的回调方法 + * @param e 鼠标事件 + * + */ + protected function containerMouseHandler(e:MouseEvent):void { + if(mouseX < axisRect.x || mouseX > (axisRect.x+axisRect.width) || mouseY < axisRect.y || mouseY > (axisRect.y+axisRect.height)) { + tooltip.hide(); + clear(); + return; + } + clear(); + if(checkType == "byp") { + checkValueByPoint(); + return; + } + var i:uint=0,hindex:int = 0; + var seriel:Sprite = chartRef.chartGraphicContainer.seriesCollection[0]; + var nearlyGraphic:IChartGraphic = seriel.getChildAt(0) as IChartGraphic; + var nextGraphic:IChartGraphic,mousePoint:Point = new Point(),targetPoint:Point = new Point(),prevPoint:Point = new Point(); + prevPoint.x = nearlyGraphic.x + nearlyGraphic.center.x; + prevPoint.y = nearlyGraphic.y + nearlyGraphic.center.y; + mousePoint.x = mouseX; + mousePoint.y = mouseY; + for(i=0;i axisRect.x + axisRect.width) { + targetX = xValue - tooltip.width - 20; + } + if(targetY + tooltip.height > axisRect.y + axisRect.height) { + targetY = axisRect.y + axisRect.height - tooltip.height; + } + TweenLite.to(tooltip,0.2,{x:targetX,y:targetY}); + } + /** + * 执行清理动作 + * + */ + public function clear():void { + tooltip.hide(); + graphics.clear(); + var nextGraphic:IChartGraphic; + for each(nextGraphic in graphicsCollection) { + nextGraphic.state = MouseEvent.MOUSE_OUT; + } + } + + } +} \ No newline at end of file diff --git a/tags/0.8/finger-chart-core-lib/src/main/flex/com/riameeting/finger/display/graphic/AreaGraphic.as b/tags/0.8/finger-chart-core-lib/src/main/flex/com/riameeting/finger/display/graphic/AreaGraphic.as new file mode 100644 index 0000000..55d949f --- /dev/null +++ b/tags/0.8/finger-chart-core-lib/src/main/flex/com/riameeting/finger/display/graphic/AreaGraphic.as @@ -0,0 +1,77 @@ +package com.riameeting.finger.display.graphic +{ + import com.cartogrammar.drawing.CubicBezier; + import com.riameeting.finger.display.chart.IChart; + import com.riameeting.utils.ColorUtils; + + import flash.display.GradientType; + import flash.display.Sprite; + import flash.geom.Matrix; + import flash.geom.Point; + + /** + * 区域图图形 + * @author Finger + * + */ + public class AreaGraphic extends LineGraphic + { + /** + * 构造方法 + * @param chartRef + * + */ + public function AreaGraphic(chartRef:IChart) + { + super(chartRef); + } + /** + * 执行定位方法,确定图形的位置 + * @param value 坐标值 + * @param offset 偏移量 + * + */ + override public function locate(value:Point=null,offset:uint=10):void { + super.locate(value,offset); + var prevIndex:int = chartRef.dataset.collection.indexOf(data)-1; + var axisRectHeight:uint = chartRef.axis.getAxisRect().y + chartRef.axis.getAxisRect().height; + var prevObject:Object,prevPoint:Point; + var points:Array = []; + var i:uint = 0; + var matix:Matrix =new Matrix(); + if(prevIndex != -1) { + prevObject = chartRef.dataset.collection[prevIndex]; + prevPoint = chartRef.axis.getPoint(prevObject,yField); + if(style["lineMode"] == "line") { + if(prevObject.enabled) { + (parent as Sprite).graphics.lineStyle(); + matix.createGradientBox(x-prevPoint.x, axisRectHeight, Math.PI/2, 0, 0); + (parent as Sprite).graphics.beginGradientFill(GradientType.LINEAR,[ColorUtils.fadeColor(color,0xFFFFFF,0.2),color],[1,1],[0x00,0xFF],matix); + (parent as Sprite).graphics.moveTo(x+1,y-style.lineWidth); + (parent as Sprite).graphics.lineTo(prevPoint.x,prevPoint.y-style.lineWidth); + (parent as Sprite).graphics.lineTo(prevPoint.x,axisRectHeight); + (parent as Sprite).graphics.lineTo(x+1,axisRectHeight); + (parent as Sprite).graphics.lineTo(x+1,y-style.lineWidth); + (parent as Sprite).graphics.endFill(); + } + } else { + if(prevIndex == chartRef.dataset.collection.length-2) { + for(;i maxZValue) { + maxZValue = obj[zField]; + } + } + } + } + /** + * 构造方法 + * + */ + public function BubbleGraphic(chartRef:IChart) + { + super(chartRef); + } + /** + * 执行定位方法,确定图形的位置 + * @param value 坐标值 + * @param offset 偏移量 + * + */ + override public function locate(value:Point=null, offset:uint=10):void { + super.locate(value,offset); + var prevIndex:int = chartRef.dataset.collection.indexOf(data)-1; + var axis:IAxis = chartRef.axis; + if(prevIndex != -1) { + (parent as Sprite).graphics.clear(); + } + var r:uint = minRadius+(maxRadius-minRadius)*((data[zField]-minZValue))/(maxZValue-minZValue); + skin.width = skin.height = r+3; + //tip str + if(data["tipString"] == null) data["tipString"] = {}; + data["tipString"][yField] = ""+data.name+"
"; + var xField:String = chartRef.dataset.config["xField"]; + data["tipString"][yField] += xField+" : "+data[xField]+"
"; + var yTitle:String; + yTitle = chartRef.dataset.config["yTitle"]; + data["tipString"][yField] += yField+" : "+data[yField]+"
"; + data["tipString"][yField] += zField+" : "+data[zField]; + if(chartRef.dataset.config["qualifier"] != null) { + data["tipString"][yField] += chartRef.dataset.config["qualifier"]; + } + } + } +} \ No newline at end of file diff --git a/tags/0.8/finger-chart-core-lib/src/main/flex/com/riameeting/finger/display/graphic/ColumnGraphic.as b/tags/0.8/finger-chart-core-lib/src/main/flex/com/riameeting/finger/display/graphic/ColumnGraphic.as new file mode 100644 index 0000000..e92755b --- /dev/null +++ b/tags/0.8/finger-chart-core-lib/src/main/flex/com/riameeting/finger/display/graphic/ColumnGraphic.as @@ -0,0 +1,53 @@ +package com.riameeting.finger.display.graphic +{ + import com.riameeting.finger.config.ChartGlobal; + import com.riameeting.finger.display.axis.IAxis; + import com.riameeting.finger.display.chart.IChart; + + import flash.display.DisplayObject; + import flash.display.Sprite; + import flash.geom.Point; + import flash.geom.Rectangle; + + /** + * 柱状图图形类 + * @author Finger + * + */ + public class ColumnGraphic extends LineGraphic + { + protected var columnOffset:Number = 5; + override public function set color(value:uint):void{ + _color = value; + } + /** + * 构造方法 + * + */ + public function ColumnGraphic(chartRef:IChart) + { + super(chartRef); + skinName = "skin.ColumnGraphic"; + } + /** + * 执行定位方法,确定图形的位置 + * @param value 坐标值 + * @param offset 偏移量 + * + */ + override public function locate(value:Point=null, offset:uint=10):void { + super.locate(value,offset); + var prevIndex:int = chartRef.dataset.collection.indexOf(data)-1; + var axis:IAxis = chartRef.axis; + if(prevIndex != -1) { + (parent as Sprite).graphics.clear(); + } + var axisRect:Rectangle = axis.getAxisRect(); + var columnWidth:Number = axisRect.width/(axis.dataset.collection.length+2) - columnOffset; + var columnItemWidth:Number = columnWidth/(axis.dataset.config["yField"].split(",").length-(axis.dataset.config["benchmark"]!=null?axis.dataset.config["benchmark"].split(",").length:0)); + var yFieldIndex:int = axis.dataset.config["yField"].split(",").indexOf(yField); + x += -(columnWidth)/2+columnItemWidth*yFieldIndex+columnItemWidth/2; + skin.updateDisplayList({width:columnItemWidth,height:axisRect.y+axisRect.height-y,color:_color}); + } + } +} \ No newline at end of file diff --git a/tags/0.8/finger-chart-core-lib/src/main/flex/com/riameeting/finger/display/graphic/IChartGraphic.as b/tags/0.8/finger-chart-core-lib/src/main/flex/com/riameeting/finger/display/graphic/IChartGraphic.as new file mode 100644 index 0000000..ffb5c09 --- /dev/null +++ b/tags/0.8/finger-chart-core-lib/src/main/flex/com/riameeting/finger/display/graphic/IChartGraphic.as @@ -0,0 +1,141 @@ +package com.riameeting.finger.display.graphic +{ + import com.riameeting.finger.display.chart.IChart; + + import flash.display.MovieClip; + import flash.geom.Point; + + /** + * 图形接口 + * @author Finger + * + */ + public interface IChartGraphic + { + /** + * 对Chart的 引用 + * @return + * + */ + function get chartRef():IChart; + function set chartRef(value:IChart):void; + /** + * 数据点对应的定位坐标,一般与x和y一致 + * @return Object + * + */ + function get point():Point; + function set point(value:Point):void; + /** + * 数据对象 + * @return Object + * + */ + function get data():Object; + function set data(value:Object):void; + /** + * Y轴字段 + * @return 字符串 + * + */ + function get yField():String; + function set yField(value:String):void; + /** + * 颜色 + * @return 颜色值 + * + */ + function get color():uint; + function set color(value:uint):void; + /** + * 样式 + * @return + * + */ + function get style():Object; + function set style(value:Object):void; + /** + * 皮肤name + * @return + * + */ + function get skinName():String; + function set skinName(value:String):void; + /** + * 皮肤 + * @return + * + */ + function get skin():MovieClip; + function set skin(value:MovieClip):void; + /** + * 状态 + * @return 状态字符串 + * + */ + function get state():String; + function set state(value:String):void; + /** + * x坐标 + * @return Number + * + */ + function get x():Number; + function set x(value:Number):void; + /** + * y坐标 + * @return Number + * + */ + function get y():Number; + function set y(value:Number):void; + /** + * 宽度 + * @return Number + * + */ + function get width():Number; + function set width(value:Number):void; + /** + * 高度 + * @return Number + * + */ + function get height():Number; + function set height(value:Number):void; + /** + * 名称 + * @return 名称 + * + */ + function get name():String; + function set name(value:String):void; + /** + * 图形的中心点,鼠标提示将判断这个中心点来定位 + * @return 坐标值 + * + */ + function get center():Point; + function set center(value:Point):void; + /** + * 是否禁用 + * @return 布尔量 + * + */ + function get enabled():Boolean; + function set enabled(value:Boolean):void; + /** + * 执行定位方法,确定图形的位置 + * @param value 坐标值 + * @param offset 偏移量 + * + */ + function locate(value:Point=null,offset:uint=10):void; + /** + * 执行清理动作 + * + */ + function clear():void; + + } +} \ No newline at end of file diff --git a/tags/0.8/finger-chart-core-lib/src/main/flex/com/riameeting/finger/display/graphic/LineGraphic.as b/tags/0.8/finger-chart-core-lib/src/main/flex/com/riameeting/finger/display/graphic/LineGraphic.as new file mode 100644 index 0000000..ea060b2 --- /dev/null +++ b/tags/0.8/finger-chart-core-lib/src/main/flex/com/riameeting/finger/display/graphic/LineGraphic.as @@ -0,0 +1,221 @@ +package com.riameeting.finger.display.graphic +{ + import com.cartogrammar.drawing.CubicBezier; + import com.riameeting.finger.config.ChartGlobal; + import com.riameeting.finger.display.chart.IChart; + import com.riameeting.finger.display.container.IChartGraphicContainer; + import com.riameeting.finger.events.ChartEvent; + + import flash.display.DisplayObject; + import flash.display.MovieClip; + import flash.display.Sprite; + import flash.events.MouseEvent; + import flash.filters.DropShadowFilter; + import flash.filters.GlowFilter; + import flash.geom.Point; + import flash.utils.setTimeout; + + /** + * 线状图图形类 + * @author Finger + * + */ + public class LineGraphic extends Sprite implements IChartGraphic + { + private var _data:Object; + private var _yField:String; + protected var _color:uint; + private var _state:String; + private var _style:Object; + private var _skinName:String; + private var _skin:MovieClip; + /** + * 鼠标提示字符串 + */ + protected var tipStr:String; + private var _point:Point; + private var _center:Point; + private var _enabled:Boolean = true; + private var _chartRef:IChart; + /** + * 对Chart的 引用 + * @return + * + */ + public function get chartRef():IChart {return _chartRef;} + public function set chartRef(value:IChart):void {_chartRef=value;} + /** + * 是否禁用 + * @return 布尔量 + * + */ + public function get enabled():Boolean{return _enabled;} + public function set enabled(value:Boolean):void{_enabled = value;} + /** + * 数据点对应的定位坐标,一般与x和y一致 + * @return Object + * + */ + public function get point():Point {return _point;}; + public function set point(value:Point):void {_point = value;}; + /** + * 图形的中心点,鼠标提示将判断这个中心点来定位 + * @return 坐标值 + * + */ + public function get center():Point{return _center;} + public function set center(value:Point):void{_center = value;} + /** + * 颜色 + * @return 颜色值 + * + */ + public function get color():uint{return _color;} + public function set color(value:uint):void{_color = value;skin.updateDisplayList({color:value})} + /** + * 样式 + * @return + * + */ + public function get style():Object {return _style}; + public function set style(value:Object):void {_style = value;}; + /** + * 皮肤name + * @return + * + */ + public function get skinName():String {return _skinName}; + public function set skinName(value:String):void {_skinName = value}; + /** + * 皮肤 + * @return + * + */ + public function get skin():MovieClip {return _skin}; + public function set skin(value:MovieClip):void {if(_skin != null) removeChild(_skin);_skin = value;_skin.hostComponent=this;addChildAt(_skin,0)}; + /** + * 数据对象 + * @return Object + * + */ + public function get data():Object{return _data;} + public function set data(value:Object):void{_data = value;} + /** + * Y轴字段 + * @return 字符串 + * + */ + public function get yField():String{return _yField;} + public function set yField(value:String):void{_yField = value;} + /** + * 状态 + * @return 状态字符串 + * + */ + public function get state():String{return _state;} + public function set state(value:String):void + { + _state = value; + if(skin == null) return; + graphics.clear(); + if(value == MouseEvent.MOUSE_OVER) { + skin.gotoAndStop(2); + } else if(value == MouseEvent.MOUSE_OUT) { + skin.gotoAndStop(1); + } + } + /** + * 构造方法 + * + */ + public function LineGraphic(chartRef:IChart) + { + super(); + _chartRef = chartRef; + addEventListener(MouseEvent.MOUSE_OVER,mouseHandler); + addEventListener(MouseEvent.MOUSE_OUT,mouseHandler); + addEventListener(MouseEvent.CLICK,mouseHandler); + buttonMode = true; + cacheAsBitmap = true; + _center = new Point(0,0); + _skinName = "skin.DotGraphic"; + } + /** + * 执行定位方法,确定图形的位置 + * @param value 坐标值 + * @param offset 偏移量 + * + */ + public function locate(value:Point=null,offset:uint=10):void { + if(value != null) _point = value; + x = _point.x; + y = _point.y; + var prevIndex:int = chartRef.dataset.collection.indexOf(data)-1; + if(style["lineMode"] == "line") { + if(prevIndex != -1) { + var prevObject:Object = chartRef.dataset.collection[prevIndex]; + if(prevObject.enabled) { + var prevPoint:Point = chartRef.axis.getPoint(prevObject,yField); + (parent as Sprite).graphics.lineStyle(style["lineWidth"],color); + (parent as Sprite).graphics.moveTo(x-0.5,y); + (parent as Sprite).graphics.lineTo(prevPoint.x,prevPoint.y); + } + } + } else { + if(prevIndex == chartRef.dataset.collection.length-2) { + var points:Array = []; + var i:uint = 0; + for(;i"+_yField+"
"; + var categoryField:String = chartRef.dataset.config["categoryField"]; + data["tipString"][_yField] += categoryField+" : "+data[categoryField]+"
"; + var yTitle:String = chartRef.dataset.config["yTitle"]; + data["tipString"][_yField] += yTitle+" : "+data[_yField]; + if(chartRef.dataset.config["qualifier"] != null) { + data["tipString"][_yField] += chartRef.dataset.config["qualifier"]; + } + } + /** + * 执行清理动作 + * + */ + public function clear():void { + graphics.clear(); + } + /** + * 响应鼠标事件的回调方法 + * @param e 鼠标事件 + * + */ + protected function mouseHandler(e:MouseEvent):void { + var itemEvt:ChartEvent; + switch(e.type) { + case MouseEvent.MOUSE_OVER: + itemEvt = new ChartEvent(ChartEvent.ITEM_MOUSE_OVER); + break; + case MouseEvent.MOUSE_OUT: + itemEvt = new ChartEvent(ChartEvent.ITEM_MOUSE_OUT); + break; + case MouseEvent.CLICK: + itemEvt = new ChartEvent(ChartEvent.ITEM_CLICK); + break; + } + //event dispatch + itemEvt.point = new Point(x,y); + itemEvt.data = data; + itemEvt.yField = yField; + dispatchEvent(itemEvt); + } + + } +} \ No newline at end of file diff --git a/tags/0.8/finger-chart-core-lib/src/main/flex/com/riameeting/finger/display/graphic/PieGraphic.as b/tags/0.8/finger-chart-core-lib/src/main/flex/com/riameeting/finger/display/graphic/PieGraphic.as new file mode 100644 index 0000000..859e881 --- /dev/null +++ b/tags/0.8/finger-chart-core-lib/src/main/flex/com/riameeting/finger/display/graphic/PieGraphic.as @@ -0,0 +1,110 @@ +package com.riameeting.finger.display.graphic +{ + import com.riameeting.finger.display.axis.IAxis; + import com.riameeting.finger.display.chart.IChart; + import com.riameeting.ui.control.Label; + import com.riameeting.utils.DrawTool; + + import flash.display.MovieClip; + import flash.events.MouseEvent; + import flash.geom.Point; + import flash.geom.Rectangle; + + /** + * 饼图图形 + * @author Finger + * + */ + public class PieGraphic extends LineGraphic + { + /** + * 定位坐标点 + */ + protected var locatePoint:Point; + /** + * 文本显示标签 + */ + protected var label:Label = new Label(false); + /** + * Pie无需Skin + * @param value + * + */ + override public function set skin(value:MovieClip):void {} + /** + * 设置颜色 + * @param value + * + */ + override public function set color(value:uint):void{_color = value} + /** + * 状态 + * @return 状态字符串 + * + */ + override public function set state(value:String):void{ + super.state = value; + if(value == MouseEvent.MOUSE_OVER) { + x+=center.x/10; + y+=center.y/10; + } else if(value == MouseEvent.MOUSE_OUT) { + filters = null; + x = locatePoint.x; + y = locatePoint.y; + } + } + /** + * 构造方法 + * @param chartRef + * + */ + public function PieGraphic(chartRef:IChart) + { + super(chartRef); + addChild(label); + } + /** + * 执行定位方法,确定图形的位置 + * @param value 坐标值 + * @param offset 偏移量 + * + */ + override public function locate(value:Point=null,offset:uint=0):void + { + if(value != null) point = value; + x = point.x; + y = point.y; + locatePoint = value; + var axis:IAxis = chartRef.axis; + var axisRect:Rectangle = chartRef.axis.getAxisRect(); + //sector + var angleObj:Object = axis.getAngle(data,yField); + center = DrawTool.drawSector(graphics,new Point(0,0),axisRect.height/2-30+offset,angleObj.beginAngle,angleObj.angle,0xFFFFFF,1,0,color,0); + //tip str + if(data["tipString"] == null) data["tipString"] = {}; + data["tipString"][yField] = ""; + var categoryField:String = chartRef.dataset.config["categoryField"]; + data["tipString"][yField] += ""+data[categoryField]+"
"; + var yTitle:String = chartRef.dataset.config["yTitle"]; + data["tipString"][yField] += yTitle+" : "+((angleObj.angle/360)*100).toFixed(2) + "%"; + if(chartRef.chartConfig["graphicLabel"] != "hidden") { + if(chartRef.chartConfig["graphicLabel"] == "first" && chartRef.dataset.collection.indexOf(data) != 0) { + return; + } + graphics.lineStyle(1,0x000000,1); + graphics.moveTo(center.x*2,center.y*2); + graphics.lineTo(center.x*2.1,center.y*2.1); + label.x = center.x*2.1; + label.y = center.y*2.1 - label.height; + label.text = data[categoryField]; + label.visible = true; + if(center.x > 0) { + graphics.lineTo(center.x*2.1+label.width,center.y*2.1); + } else { + label.x -= label.width; + graphics.lineTo(center.x*2.1-label.width,center.y*2.1); + } + } + } + } +} \ No newline at end of file diff --git a/tags/0.8/finger-chart-core-lib/src/main/flex/com/riameeting/finger/display/graphic/PlotGraphic.as b/tags/0.8/finger-chart-core-lib/src/main/flex/com/riameeting/finger/display/graphic/PlotGraphic.as new file mode 100644 index 0000000..30ded11 --- /dev/null +++ b/tags/0.8/finger-chart-core-lib/src/main/flex/com/riameeting/finger/display/graphic/PlotGraphic.as @@ -0,0 +1,63 @@ +package com.riameeting.finger.display.graphic +{ + import com.riameeting.finger.config.ChartGlobal; + import com.riameeting.finger.display.axis.IAxis; + import com.riameeting.finger.display.chart.IChart; + + import flash.display.DisplayObject; + import flash.display.MovieClip; + import flash.display.Sprite; + import flash.geom.Point; + import flash.geom.Rectangle; + + /** + * 散点图图形类 + * @author Finger + * + */ + public class PlotGraphic extends LineGraphic + { + /** + * 皮肤 + * @return + * + */ + override public function set skin(value:MovieClip):void { + super.skin = value; + value.scaleX = value.scaleY = 1.5; + } + /** + * 构造方法 + * + */ + public function PlotGraphic(chartRef:IChart) + { + super(chartRef); + } + /** + * 执行定位方法,确定图形的位置 + * @param value 坐标值 + * @param offset 偏移量 + * + */ + override public function locate(value:Point=null, offset:uint=10):void { + super.locate(value,offset); + var prevIndex:int = chartRef.dataset.collection.indexOf(data)-1; + var axis:IAxis = chartRef.axis; + if(prevIndex != -1) { + (parent as Sprite).graphics.clear(); + } + //tip str + if(data["tipString"] == null) data["tipString"] = {}; + data["tipString"][yField] = ""+data.name+"
"; + var xField:String = chartRef.dataset.config["xField"]; + data["tipString"][yField] += xField+" : "+data[xField]+"
"; + var yTitle:String; + yTitle = chartRef.dataset.config["yTitle"]; + data["tipString"][yField] += yField+" : "+data[yField]; + if(chartRef.dataset.config["qualifier"] != null) { + data["tipString"][yField] += chartRef.dataset.config["qualifier"]; + } + } + } +} \ No newline at end of file diff --git a/tags/0.8/finger-chart-core-lib/src/main/flex/com/riameeting/finger/display/legend/ILegend.as b/tags/0.8/finger-chart-core-lib/src/main/flex/com/riameeting/finger/display/legend/ILegend.as new file mode 100644 index 0000000..256270f --- /dev/null +++ b/tags/0.8/finger-chart-core-lib/src/main/flex/com/riameeting/finger/display/legend/ILegend.as @@ -0,0 +1,84 @@ +package com.riameeting.finger.display.legend +{ + import com.riameeting.finger.display.chart.IChart; + import com.riameeting.finger.vo.DatasetVO; + + /** + * 图表说明接口 + * @author Finger + * + */ + public interface ILegend + { + /** + * 对Chart的 引用 + * @return + * + */ + function get chartRef():IChart; + function set chartRef(value:IChart):void; + /** + * 名称 + * @return 字符串 + * + */ + function get name():String; + function set name(value:String):void; + /** + * x坐标值 + * @return + * + */ + function get x():Number; + function set x(value:Number):void; + /** + * y坐标值 + * @return + * + */ + function get y():Number; + function set y(value:Number):void; + /** + * 对数据源的引用 + * @return DatasetVO引用 + * + */ + function get dataset():DatasetVO; + function set dataset(value:DatasetVO):void; + /** + * CSS样式定义 + * @return 对象 + * + */ + function get style():Object; + function set style(value:Object):void; + /** + * 图表说明的类型 + * @return + * + */ + function get legendMode():String; + function set legendMode(value:String):void; + /** + * 图表说明宽度 + * @return + * + */ + function get width():Number; + function set width(value:Number):void; + /** + * 图表说明高度 + * @return + * + */ + function get height():Number; + function set height(value:Number):void; + /** + * 更新显示列表的方法,当Flash场景尺寸发生改变,将调用此方法重绘图表 + * @param width 宽度 + * @param height 高度 + */ + function updateDisplayList(w:uint,h:uint):void; + + } +} \ No newline at end of file diff --git a/tags/0.8/finger-chart-core-lib/src/main/flex/com/riameeting/finger/display/legend/SelectableLegend.as b/tags/0.8/finger-chart-core-lib/src/main/flex/com/riameeting/finger/display/legend/SelectableLegend.as new file mode 100644 index 0000000..32ff566 --- /dev/null +++ b/tags/0.8/finger-chart-core-lib/src/main/flex/com/riameeting/finger/display/legend/SelectableLegend.as @@ -0,0 +1,85 @@ +package com.riameeting.finger.display.legend +{ + import flash.display.DisplayObject; + import flash.display.Sprite; + import flash.events.MouseEvent; + + import com.riameeting.finger.config.ChartGlobal; + import com.riameeting.finger.display.chart.IChart; + import com.riameeting.ui.control.CheckBox; + import com.riameeting.finger.display.graphic.IChartGraphic; + /** + * 可选择的图表说明类 + * @author Finger + * + */ + public class SelectableLegend extends SimpleLegend + { + /** + * 用于显示复选框的容器 + */ + protected var checkboxContainer:Sprite = new Sprite(); + /** + * 构造方法 + * @param legendMode 模式 + * @param legendWidth 宽度 + * @param legendHeight 高度 + * + */ + public function SelectableLegend(chartRef:IChart,legendMode:String,legendWidth:Number,legendHeight:Number) + { + super(chartRef,legendMode,legendWidth,legendHeight); + addChild(checkboxContainer); + } + /** + * 重写创建标签的方法 + * + */ + override public function createLabel():void + { + super.createLabel(); + labelContainer.x += 20; + var yFiledArr:Array = dataset.config["yField"].split(","); + var checkBox:CheckBox; + for(var i:uint=0;i -1) { + label = new GraphicLabel(false,style["benchmarkColor"],"line"); + } else { + label = new GraphicLabel(false,ChartGlobal.colorCollection[i],legendMode); + } + label.color = style["color"]; + label.y = i*label.height; + label.text = yFiledArr[i]; + labelContainer.addChild(label); + } + labelContainer.x = style["paddingLeft"]; + labelContainer.y = style["paddingTop"]; + } + /** + * 更新显示列表的方法,当Flash场景尺寸发生改变,将调用此方法重绘图表 + * @param width 宽度 + * @param height 高度 + */ + public function updateDisplayList(w:uint,h:uint):void { + graphics.clear(); + if(style != null && style["bgColor"] != null) { + graphics.lineStyle(1,0x000000,0.3); + graphics.beginFill(style["bgColor"],style["bgAlpha"]/100); + graphics.drawRect(0,0,w,h); + graphics.endFill(); + } + } + + } +} \ No newline at end of file diff --git a/tags/0.8/finger-chart-core-lib/src/main/flex/com/riameeting/finger/display/legend/SlideLegend.as b/tags/0.8/finger-chart-core-lib/src/main/flex/com/riameeting/finger/display/legend/SlideLegend.as new file mode 100644 index 0000000..dde1d89 --- /dev/null +++ b/tags/0.8/finger-chart-core-lib/src/main/flex/com/riameeting/finger/display/legend/SlideLegend.as @@ -0,0 +1,230 @@ +package com.riameeting.finger.display.legend +{ + import com.riameeting.finger.config.ChartGlobal; + import com.riameeting.finger.display.chart.IChart; + import com.riameeting.finger.vo.DatasetVO; + import com.riameeting.ui.control.CheckBox; + import com.riameeting.ui.control.GraphicLabel; + + import flash.display.Bitmap; + import flash.display.Sprite; + import flash.events.MouseEvent; + + /** + * 专用于移动设备的图例说明 + * @author Finger + * + */ + public class SlideLegend extends Sprite implements ILegend + { + private var _dataset:DatasetVO; + private var _style:Object = {color:0xFFFFFF,paddingTop:0,paddingLeft:0,benchmarkColor:0xCCCCCC,bgColor:0x666666,bgAlpha:100}; + /** + * 标签容器 + */ + protected var labelContainer:Sprite = new Sprite(); + private var _legendMode:String; + private var _legendWidth:Number; + private var _legendHeight:Number; + + [Embed(source="../../../../../../resources/legend_button.png")] + private var SlideButtonClass:Class; + private var slideImage:Bitmap; + private var _chartRef:IChart; + /** + * 控制图例显示的按钮 + */ + protected var slideButton:Sprite = new Sprite(); + /** + * 当前状态,open or close + */ + protected var currentState:String; + /** + * 对Chart的 引用 + * @return + * + */ + public function get chartRef():IChart {return _chartRef;} + public function set chartRef(value:IChart):void {_chartRef=value;} + /** + * 图表说明宽度 + * @return + * + */ + override public function get width():Number{return _legendWidth;} + override public function set width(value:Number):void{_legendWidth = value;} + /** + * 图表说明高度 + * @return + * + */ + override public function get height():Number{return _legendHeight;} + override public function set height(value:Number):void{_legendHeight = value;} + /** + * 图表说明的类型 + * @return + * + */ + public function get legendMode():String{return _legendMode;} + public function set legendMode(value:String):void{_legendMode = value;} + /** + * CSS样式定义 + * @return 对象 + * + */ + public function get style():Object{return _style;} + public function set style(value:Object):void{_style = value;} + /** + * 对数据源的引用 + * @return DatasetVO引用 + * + */ + public function get dataset():DatasetVO{return _dataset;} + public function set dataset(value:DatasetVO):void{ + _dataset = value; + createLabel(); + updateDisplayList(_legendWidth,_legendHeight); + } + /** + * 构造方法 + * + */ + public function SlideLegend(chartRef:IChart,legendModeStr:String,w:int,h:int) + { + _chartRef = chartRef; + _legendMode = legendModeStr; + _legendWidth = w; + _legendHeight = h; + slideImage = new SlideButtonClass(); + slideButton.buttonMode = true; + slideButton.addChild(slideImage); + addChild(slideButton); + slideButton.addEventListener(MouseEvent.MOUSE_DOWN,slideButtonHandler); + addChild(labelContainer); + } + /** + * 创建标签 + * + */ + public function createLabel():void + { + var yFiledArr:Array = dataset.config["yField"].split(","); + var benchmarkArr:Array; + if(dataset.config["benchmark"] != null) benchmarkArr = dataset.config["benchmark"].split(","); + var label:GraphicLabel,checkBox:CheckBox;; + for(var i:uint=0;i -1) { + label = new GraphicLabel(false,style["benchmarkColor"],"line"); + } else { + label = new GraphicLabel(false,ChartGlobal.colorCollection[i],legendMode); + } + label.color = style["color"]; + label.x = 30; + label.y = 5; + label.text = yFiledArr[i]; + legendItem.addChild(label); + //check box + checkBox = new CheckBox(); + checkBox.x = 10; + checkBox.y = 5; + checkBox.name = yFiledArr[i]; + checkBox.selected = true; + legendItem.addChild(checkBox); + } + } + /** + * 点击按钮后触发的方法 + * @param e + * + */ + protected function slideButtonHandler(e:MouseEvent):void { + currentState = (currentState == "close")?"open":"close"; + if(currentState == "open") { + x -= width; + chartRef.width -= width; + } else { + x += width; + chartRef.width += width; + } + } + /** + * 刷新图表 + * @param e + * + */ + protected function refrishChart(e:MouseEvent):void { + var currentCheckbox:CheckBox = (e.target.getChildAt(1)) as CheckBox; + currentCheckbox.selected = !currentCheckbox.selected; + var currentYField:String = currentCheckbox.name; + displayGraphics(currentCheckbox.selected,currentYField); + } + /** + * 控制去显示某个图形 + * @param show 显示还是隐藏 + * @param yField y轴字段 + * + */ + protected function displayGraphics(show:Boolean,yField:String):void { + var seriesArr:Array = chartRef.chartGraphicContainer.seriesCollection; + var seriesMode:Object = chartRef.chartGraphicContainer.seriesMode; + for each(var item:Sprite in seriesArr) { + if(item.name == yField) { + if(show) { + seriesMode[item.name] = null; + chartRef.chartGraphicContainer.showSeries(item.name,true); + } else { + seriesMode[item.name] = false; + chartRef.chartGraphicContainer.hideSeries(item.name,true); + } + } + } + } + /** + * 更新显示列表的方法,当Flash场景尺寸发生改变,将调用此方法重绘图表 + * @param width 宽度 + * @param height 高度 + */ + public function updateDisplayList(w:uint, h:uint):void + { + //button + currentState = "close"; + slideButton.x = -slideImage.width; + slideButton.graphics.clear(); + slideButton.graphics.beginFill(0x000000,0); + slideButton.graphics.drawRect(-10,0,slideButton.width+10,h); + slideButton.graphics.endFill(); + slideImage.y = (h-slideImage.height)/2; + //bg + graphics.clear(); + graphics.beginFill(_style["bgColor"],_style["bgAlpha"]); + graphics.drawRect(0,0,w,h); + graphics.endFill(); + } + } +} +import flash.display.GradientType; +import flash.display.Sprite; +import flash.geom.Matrix; + +class LegendItem extends Sprite { + + private var itemWidth:int; + + public function LegendItem(w:int) { + itemWidth = w; + this.graphics.beginFill(0x000000,0.2); + this.graphics.drawRect(0,0,w,30); + this.graphics.endFill(); + this.graphics.lineStyle(1,0x000000,0.3); + this.graphics.moveTo(0,30); + this.graphics.lineTo(w,30); + mouseChildren = false; + buttonMode = true; + } +} diff --git a/tags/0.8/finger-chart-core-lib/src/main/flex/com/riameeting/finger/display/skin/AxisSkin.as b/tags/0.8/finger-chart-core-lib/src/main/flex/com/riameeting/finger/display/skin/AxisSkin.as new file mode 100644 index 0000000..1308adf --- /dev/null +++ b/tags/0.8/finger-chart-core-lib/src/main/flex/com/riameeting/finger/display/skin/AxisSkin.as @@ -0,0 +1,195 @@ +package com.riameeting.finger.display.skin +{ + import com.riameeting.finger.display.axis.ReversalAxis; + import com.riameeting.finger.factory.ObjectFactory; + import com.riameeting.ui.control.Label; + import com.riameeting.utils.ColorUtils; + + import flash.display.GradientType; + import flash.display.MovieClip; + import flash.display.Sprite; + import flash.geom.Matrix; + import flash.geom.Rectangle; + + /** + * 默认的坐标系皮肤 + * @author RIAMeeting + * + */ + public class AxisSkin extends MovieClip implements ISkin + { + /** + * 计算底部标签的宽度总和,用于宽度超出的时候,进行优化处理 + */ + public var allBottomLabelWidth:uint; + /** + * 左上角显示的标签 + */ + public var titleL:Label = new Label(true); + /** + * 底部显示的标签 + */ + public var titleB:Label = new Label(true); + /** + * 标签的显示容器 + */ + protected var labelContainer:Sprite = new Sprite(); + private var _hostComponent:Object; + /** + * 组件引用 + * @return + * + */ + public function get hostComponent():Object {return _hostComponent}; + public function set hostComponent(value:Object):void {_hostComponent = value}; + /** + * 构造方法 + * + */ + public function AxisSkin() + { + super(); + addChild(titleL); + addChild(titleB); + addChild(labelContainer); + } + /** + * 更新显示列表 + * @param parm + * @param style + * + */ + public function updateDisplayList(parms:Object=null):void + { + var style:Object = _hostComponent.style; + var w:Number = _hostComponent.axisWidth,h:Number = _hostComponent.axisHeight; + var value:Object = _hostComponent.dataset; + titleL.text = ""+value.config["yTitle"]+""; + if(_hostComponent.xField != null) { + titleB.text = ""+_hostComponent.xField+""; + } else { + titleB.text = ""+value.config["categoryField"]+""; + } + //reset location + titleB.x = (w - titleB.width)/2; + titleB.y = h - titleB.height; + drawBottomContainer(w,h); + //create label + if(parent is ReversalAxis) { + createLabelsByReversalMode(); + } else { + createLabels(); + } + } + /** + * 绘制底部容器 + * @param parm + * @param style + * + */ + protected function drawBottomContainer(w:Number,h:Number):void { + graphics.clear(); + var style:Object = _hostComponent.style; + var color1:uint = style["lineColors"][0]; + var color2:uint = style["lineColors"][1]; + var colorAlpha1:Number = style["lineAlphas"][0]/100; + var colorAlpha2:Number = style["lineAlphas"][1]/100; + var matix:Matrix =new Matrix(); + matix.createGradientBox(w, h, Math.PI/2); + graphics.beginGradientFill(GradientType.LINEAR,[color1,color2],[colorAlpha1,colorAlpha2],[0x00,0xFF],matix); + graphics.drawRect(style["paddingLeft"],style["paddingTop"],style["lineWidth"],h-style["paddingTop"]-style["paddingBottom"]); + graphics.drawRect(style["paddingLeft"],h-style["paddingBottom"],w-style["paddingLeft"]-style["paddingRight"],style["lineWidth"]); + graphics.endFill(); + } + /** + * 创建需要显示的标签 + * + */ + protected function createLabels():void { + var style:Object = _hostComponent.style; + //left label + var i:uint=0,currentLabel:Label; + _hostComponent.realGridHeight = _hostComponent.graphicArea.height/_hostComponent.countY; + var currentOffset:Number = _hostComponent.ignoreOffsetV ? style["offsetH"]:style["offsetV"]; + _hostComponent.realGridWidth = (_hostComponent.graphicArea.width-currentOffset*2)/(_hostComponent.countX-1); + for(;i<_hostComponent.countY;i++) { + currentLabel = ObjectFactory.produce(Label,"Label"); + currentLabel.color = style["color"]; + currentLabel.y = int(style["paddingTop"]) + _hostComponent.realGridHeight*i - currentLabel.height/2; + currentLabel.text = String(_hostComponent.maxValueY - int(((_hostComponent.maxValueY-_hostComponent.minValueY)/_hostComponent.countY)*i)); + labelContainer.addChild(currentLabel); + } + //Bottom label + allBottomLabelWidth = 0; + for(i=0;i<_hostComponent.countX;i++) { + currentLabel = ObjectFactory.produce(Label,"Label"); + currentLabel.color = style["color"]; + currentLabel.name = "l"+i; + if(_hostComponent.xField != null) { + currentLabel.text = String(int(((_hostComponent.maxValueX-_hostComponent.minValueX)/(_hostComponent.countX-1))*i+_hostComponent.minValueX)); + } else { + currentLabel.text = _hostComponent.dataset.collection[i][_hostComponent.dataset.config["categoryField"]]; + } + currentLabel.x = int(style["paddingLeft"]) + _hostComponent.realGridWidth*i + currentOffset - currentLabel.width/2; + currentLabel.y = _hostComponent.graphicArea.y + _hostComponent.graphicArea.height + 10; + labelContainer.addChild(currentLabel); + allBottomLabelWidth += currentLabel.width; + } + if(allBottomLabelWidth > _hostComponent.graphicArea.width) { + var hideIndex:uint = allBottomLabelWidth/_hostComponent.graphicArea.width; + var count:uint = 0; + for(i=1;i<_hostComponent.countX;i++) { + if(count == hideIndex) { + count = 0; + } else { + labelContainer.getChildByName("l"+i).visible = false; + count++; + } + } + } + } + /** + * 创建需要显示的标签(用于BarChart) + * + */ + protected function createLabelsByReversalMode():void { + var style:Object = _hostComponent.style; + //bottom label + var i:uint=0,currentLabel:Label; + _hostComponent.realGridHeight = _hostComponent.graphicArea.width/_hostComponent.countY; + _hostComponent.realGridWidth = (_hostComponent.graphicArea.height-int(style["offsetV"])*2)/(_hostComponent.countX-1); + for(i=1;i<=_hostComponent.countY;i++) { + currentLabel = ObjectFactory.produce(Label,"Label"); + currentLabel.color = style["bottomColor"]; + currentLabel.x = int(style["paddingTop"]) + _hostComponent.realGridHeight*i; + currentLabel.y = _hostComponent.graphicArea.y + _hostComponent.graphicArea.height + 10; + currentLabel.text = String(_hostComponent.maxValueY - int(((_hostComponent.maxValueY-_hostComponent.minValueY)/_hostComponent.countY)*(_hostComponent.countY-i))); + labelContainer.addChild(currentLabel); + } + //left label + for(i=0;i<_hostComponent.countX;i++) { + currentLabel = ObjectFactory.produce(Label,"Label"); + currentLabel.color = style["color"]; + currentLabel.name = "l"+i; + if(_hostComponent.xField != null) { + currentLabel.text = String(int((_hostComponent.maxValueX/(_hostComponent.countX-1))*i)); + } else { + currentLabel.text = _hostComponent.dataset.collection[i][_hostComponent.dataset.config["categoryField"]]; + } + currentLabel.y = int(style["paddingTop"]) + _hostComponent.realGridWidth*(_hostComponent.countX-i-1) + int(style["offsetV"]) - currentLabel.height/2; + labelContainer.addChild(currentLabel); + } + } + /** + * 当需重绘坐标系的时候,调用此方法 + * + */ + public function clear():void { + this.graphics.clear(); + while(labelContainer.numChildren > 0) { + (labelContainer.getChildAt(0) as Label).clear(); + ObjectFactory.reclaim(Label,labelContainer.removeChildAt(0),"Label"); + } + } + } +} \ No newline at end of file diff --git a/tags/0.8/finger-chart-core-lib/src/main/flex/com/riameeting/finger/display/skin/BarGraphic.as b/tags/0.8/finger-chart-core-lib/src/main/flex/com/riameeting/finger/display/skin/BarGraphic.as new file mode 100644 index 0000000..1628ba6 --- /dev/null +++ b/tags/0.8/finger-chart-core-lib/src/main/flex/com/riameeting/finger/display/skin/BarGraphic.as @@ -0,0 +1,60 @@ +package com.riameeting.finger.display.skin +{ + import com.riameeting.utils.ColorUtils; + + import flash.display.GradientType; + import flash.display.MovieClip; + import flash.display.Sprite; + import flash.geom.Matrix; + + /** + * 默认的条图皮肤 + * @author RIAMeeting + * + */ + public class BarGraphic extends MovieClip implements ISkin + { + protected var dot:Sprite = new Sprite(); + private var _hostComponent:Object; + /** + * 组件引用 + * @return + * + */ + public function get hostComponent():Object {return _hostComponent}; + public function set hostComponent(value:Object):void {_hostComponent = value}; + public function BarGraphic() + { + super(); + dot.graphics.lineStyle(1,0x000000,1); + dot.graphics.beginFill(0xFFFFFF,1); + dot.graphics.drawCircle(0,0,6); + dot.graphics.endFill(); + dot.graphics.lineStyle(); + dot.graphics.beginFill(0x000000,1); + dot.graphics.drawCircle(0,0,2); + dot.graphics.endFill(); + dot.visible = false; + addChild(dot); + } + + public function updateDisplayList(parms:Object=null):void + { + graphics.clear(); + var matix:Matrix =new Matrix(); + matix.createGradientBox(-parms.height, -parms.width/2, 0, 0, 0); + graphics.beginGradientFill(GradientType.LINEAR,[ColorUtils.fadeColor(parms.color,0xFFFFFF,0.2),parms.color],[1,1],[0x00,0xFF],matix); + graphics.drawRect(-parms.height,-parms.width/2,parms.height,parms.width); + graphics.endFill(); + } + + override public function gotoAndStop(frame:Object, scene:String=null):void { + if(frame == 1) { + dot.visible = false; + } else { + dot.visible = true; + } + } + + } +} \ No newline at end of file diff --git a/tags/0.8/finger-chart-core-lib/src/main/flex/com/riameeting/finger/display/skin/ChartSkin.as b/tags/0.8/finger-chart-core-lib/src/main/flex/com/riameeting/finger/display/skin/ChartSkin.as new file mode 100644 index 0000000..85e4116 --- /dev/null +++ b/tags/0.8/finger-chart-core-lib/src/main/flex/com/riameeting/finger/display/skin/ChartSkin.as @@ -0,0 +1,54 @@ +package com.riameeting.finger.display.skin +{ + import flash.display.GradientType; + import flash.display.MovieClip; + import flash.geom.Matrix; + + /** + * 默认的图表皮肤 + * @author RIAMeeting + * + */ + public class ChartSkin extends MovieClip implements ISkin + { + private var _hostComponent:Object; + /** + * 组件引用 + * @return + * + */ + public function get hostComponent():Object {return _hostComponent}; + public function set hostComponent(value:Object):void {_hostComponent = value}; + public function ChartSkin() + { + super(); + this.cacheAsBitmap = true; + } + + public function updateDisplayList(parm:Object=null):void { + graphics.clear(); + var style:Object = _hostComponent.style; + var color1:uint = style["bgColors"][0]; + var color2:uint = style["bgColors"][1]; + var colorAlpha1:Number = style["bgAlphas"][0]/100; + var colorAlpha2:Number = style["bgAlphas"][1]/100; + var color3:uint = style["lineColors"][0]; + var color4:uint = style["lineColors"][1]; + var colorAlpha3:Number = style["lineAlphas"][0]/100; + var colorAlpha4:Number = style["lineAlphas"][1]/100; + var matix:Matrix =new Matrix(); + matix.createGradientBox(parm.width, parm.height, Math.PI/2, 0, 0); + graphics.beginGradientFill(GradientType.LINEAR,[color1,color2],[colorAlpha1,colorAlpha2],[0x00,0xFF],matix); + graphics.drawRect(0,0,parm.width,parm.height); + graphics.endFill(); + var lineWidth:int = 50; + var lineNum:int = parm.width/lineWidth; + for(var i:uint=0;i<(lineNum)/2;i++) { + graphics.beginGradientFill(GradientType.LINEAR,[color3,color4,color3],[colorAlpha3,colorAlpha4,colorAlpha3],[0x00,0xCC,0xFF],matix); + graphics.drawRect(i*lineWidth*2+lineWidth,0,lineWidth,parm.height); + graphics.endFill(); + } + } + + } +} \ No newline at end of file diff --git a/tags/0.8/finger-chart-core-lib/src/main/flex/com/riameeting/finger/display/skin/ColumnGraphic.as b/tags/0.8/finger-chart-core-lib/src/main/flex/com/riameeting/finger/display/skin/ColumnGraphic.as new file mode 100644 index 0000000..6f76bb7 --- /dev/null +++ b/tags/0.8/finger-chart-core-lib/src/main/flex/com/riameeting/finger/display/skin/ColumnGraphic.as @@ -0,0 +1,62 @@ +package com.riameeting.finger.display.skin +{ + import com.riameeting.utils.ColorUtils; + + import flash.display.GradientType; + import flash.display.MovieClip; + import flash.display.Sprite; + import flash.geom.Matrix; + + /** + * 默认的柱图图形皮肤 + * @author RIAMeeting + * + */ + public class ColumnGraphic extends MovieClip implements ISkin + { + protected var dot:Sprite = new Sprite(); + + private var _hostComponent:Object; + /** + * 组件引用 + * @return + * + */ + public function get hostComponent():Object {return _hostComponent}; + public function set hostComponent(value:Object):void {_hostComponent = value}; + + public function ColumnGraphic() + { + super(); + dot.graphics.lineStyle(1,0x000000,1); + dot.graphics.beginFill(0xFFFFFF,1); + dot.graphics.drawCircle(0,0,6); + dot.graphics.endFill(); + dot.graphics.lineStyle(); + dot.graphics.beginFill(0x000000,1); + dot.graphics.drawCircle(0,0,2); + dot.graphics.endFill(); + dot.visible = false; + addChild(dot); + } + + public function updateDisplayList(parms:Object=null):void + { + graphics.clear(); + var matix:Matrix =new Matrix(); + matix.createGradientBox(parms.width, parms.height, Math.PI/2, 0, 0); + graphics.beginGradientFill(GradientType.LINEAR,[ColorUtils.fadeColor(parms.color,0xFFFFFF,0.2),parms.color],[1,1],[0x00,0xFF],matix); + graphics.drawRect(-parms.width/2,0,parms.width,parms.height); + graphics.endFill(); + } + + override public function gotoAndStop(frame:Object, scene:String=null):void { + if(frame == 1) { + dot.visible = false; + } else { + dot.visible = true; + } + } + + } +} \ No newline at end of file diff --git a/tags/0.8/finger-chart-core-lib/src/main/flex/com/riameeting/finger/display/skin/DotGraphic.as b/tags/0.8/finger-chart-core-lib/src/main/flex/com/riameeting/finger/display/skin/DotGraphic.as new file mode 100644 index 0000000..7ab66ae --- /dev/null +++ b/tags/0.8/finger-chart-core-lib/src/main/flex/com/riameeting/finger/display/skin/DotGraphic.as @@ -0,0 +1,64 @@ +package com.riameeting.finger.display.skin +{ + import flash.display.MovieClip; + /** + * 默认的点图形皮肤 + * @author RIAMeeting + * + */ + public class DotGraphic extends MovieClip implements ISkin + { + private var parms:Object; + + private var _hostComponent:Object; + /** + * 组件引用 + * @return + * + */ + public function get hostComponent():Object {return _hostComponent}; + public function set hostComponent(value:Object):void {_hostComponent = value}; + + public function DotGraphic() + { + super(); + } + + public function updateDisplayList(parms:Object=null):void + { + this.parms = parms; + drawGraphic(1); + } + + override public function gotoAndStop(frame:Object, scene:String=null):void { + drawGraphic(int(frame)); + } + + protected function drawGraphic(frame:int):void { + graphics.clear(); + var dotcolor:uint = parms.color; + var style:Object = _hostComponent.style; + if(style.dotWidth*2 <= style.lineWidth) { + if(frame == 2) { + graphics.beginFill(0x000000,1); + graphics.drawCircle(0,0,style.dotWidth+5); + graphics.endFill(); + graphics.beginFill(0xFFFFFF,1); + graphics.drawCircle(0,0,style.dotWidth+4); + graphics.endFill(); + } + } else { + if(frame == 2) dotcolor = 0x000000; + graphics.lineStyle(1,0x000000,1); + graphics.beginFill(0xFFFFFF,1); + graphics.drawCircle(0,0,style.dotWidth+4); + graphics.endFill(); + } + graphics.lineStyle(); + graphics.beginFill(dotcolor,1); + graphics.drawCircle(0,0,style.dotWidth); + graphics.endFill(); + } + + } +} \ No newline at end of file diff --git a/tags/0.8/finger-chart-core-lib/src/main/flex/com/riameeting/finger/display/skin/ISkin.as b/tags/0.8/finger-chart-core-lib/src/main/flex/com/riameeting/finger/display/skin/ISkin.as new file mode 100644 index 0000000..cea7653 --- /dev/null +++ b/tags/0.8/finger-chart-core-lib/src/main/flex/com/riameeting/finger/display/skin/ISkin.as @@ -0,0 +1,18 @@ +package com.riameeting.finger.display.skin +{ + /** + * 皮肤元件接口 + * @author RIAMeeting + * + */ + public interface ISkin + { + function get hostComponent():Object; + function set hostComponent(value:Object):void; + /** + * 皮肤应实现这个方法 + * + */ + function updateDisplayList(parms:Object=null):void; + } +} \ No newline at end of file diff --git a/tags/0.8/finger-chart-core-lib/src/main/flex/com/riameeting/finger/display/skin/TooltipSkin.as b/tags/0.8/finger-chart-core-lib/src/main/flex/com/riameeting/finger/display/skin/TooltipSkin.as new file mode 100644 index 0000000..774c24c --- /dev/null +++ b/tags/0.8/finger-chart-core-lib/src/main/flex/com/riameeting/finger/display/skin/TooltipSkin.as @@ -0,0 +1,44 @@ +package com.riameeting.finger.display.skin +{ + import flash.display.MovieClip; + import flash.text.TextField; + /** + * 默认的鼠标提示皮肤 + * @author RIAMeeting + * + */ + public class TooltipSkin extends MovieClip implements ISkin + { + public var label:TextField = new TextField(); + private var _hostComponent:Object; + /** + * 组件引用 + * @return + * + */ + public function get hostComponent():Object {return _hostComponent}; + public function set hostComponent(value:Object):void {_hostComponent = value}; + + public function TooltipSkin() + { + super(); + label.x = label.y = 8; + addChild(label); + } + + public function updateDisplayList(parms:Object=null):void + { + var style:Object = _hostComponent.style; + var color:String = style["color"]; + label.htmlText = "" + parms.value + ""; + label.width = label.textWidth + 4; + label.height = label.textHeight + 4; + graphics.clear(); + graphics.lineStyle(style["borderWidth"],style["borderColor"],style["borderAlpha"]/100); + graphics.beginFill(style["tipbgColor"],1); + graphics.drawRoundRect(10.5,5,label.width+10,label.height+10,8,8); + graphics.endFill(); + } + + } +} \ No newline at end of file diff --git a/tags/0.8/finger-chart-core-lib/src/main/flex/com/riameeting/finger/display/tooltip/ITooltip.as b/tags/0.8/finger-chart-core-lib/src/main/flex/com/riameeting/finger/display/tooltip/ITooltip.as new file mode 100644 index 0000000..5a89c23 --- /dev/null +++ b/tags/0.8/finger-chart-core-lib/src/main/flex/com/riameeting/finger/display/tooltip/ITooltip.as @@ -0,0 +1,73 @@ +package com.riameeting.finger.display.tooltip +{ + import flash.display.MovieClip; + + /** + * 鼠标提示接口 + * @author Finger + * + */ + public interface ITooltip + { + /** + * 设置显示文本 + * @return + * + */ + function get text():String; + function set text(value:String):void; + /** + * 显示文本 + * @param text + * + */ + function show(text:String):void; + /** + * 隐藏 + * + */ + function hide():void; + /** + * x坐标值 + * @return + * + */ + function get x():Number; + function set x(value:Number):void; + /** + * y坐标值 + * @return + * + */ + function get y():Number; + function set y(value:Number):void; + /** + * 宽度 + * @return + * + */ + function get width():Number; + function set width(value:Number):void; + /** + * 高度 + * @return + * + */ + function get height():Number; + function set height(value:Number):void; + /** + * 样式 + * @return + * + */ + function get style():Object; + function set style(value:Object):void; + /** + * 皮肤 + * @return + * + */ + function get skin():MovieClip; + function set skin(value:MovieClip):void; + } +} \ No newline at end of file diff --git a/tags/0.8/finger-chart-core-lib/src/main/flex/com/riameeting/finger/display/tooltip/Tooltip.as b/tags/0.8/finger-chart-core-lib/src/main/flex/com/riameeting/finger/display/tooltip/Tooltip.as new file mode 100644 index 0000000..35ae35a --- /dev/null +++ b/tags/0.8/finger-chart-core-lib/src/main/flex/com/riameeting/finger/display/tooltip/Tooltip.as @@ -0,0 +1,87 @@ +package com.riameeting.finger.display.tooltip +{ + import com.riameeting.finger.config.ChartGlobal; + import com.riameeting.finger.display.container.ITooltipContainer; + + import flash.display.MovieClip; + import flash.display.Sprite; + import flash.filters.DropShadowFilter; + import flash.text.Font; + import flash.text.TextField; + import flash.text.TextFieldAutoSize; + import flash.text.TextFormat; + + /** + * 鼠标提示类 + * @author Finger + * + */ + public class Tooltip extends Sprite implements ITooltip + { + private var _text:String; + private var label:TextField; + private var _style:Object; + private var _skin:MovieClip; + /** + * 样式 + * @return + * + */ + public function get style():Object {return _style}; + public function set style(value:Object):void {_style = value;}; + /** + * 皮肤 + * @return + * + */ + public function get skin():MovieClip {return _skin} + public function set skin(value:MovieClip):void { + if(_skin != null) removeChild(_skin); + _skin = value; + _skin.hostComponent=this; + _skin.mouseChildren = false; + _skin.mouseEnabled = false; + addChildAt(_skin,0); + label = _skin.label; + label.multiline = true; + label.autoSize = TextFieldAutoSize.LEFT; + label.wordWrap = false; + label.x = 15; + } + /** + * 设置显示文本 + * @return + * + */ + public function get text():String {return _text;} + public function set text(value:String):void { + _text = value; + skin.updateDisplayList({value:value}); + } + /** + * 显示文本 + * @param text + * + */ + public function show(value:String):void { + text = value; + visible = true; + } + /** + * 隐藏 + * + */ + public function hide():void { + visible = false; + } + /** + * 构造方法 + * + */ + public function Tooltip() + { + mouseEnabled = false; + mouseChildren = false; + } + } +} \ No newline at end of file diff --git a/tags/0.8/finger-chart-core-lib/src/main/flex/com/riameeting/finger/effect/FadeIn.as b/tags/0.8/finger-chart-core-lib/src/main/flex/com/riameeting/finger/effect/FadeIn.as new file mode 100644 index 0000000..f48afd1 --- /dev/null +++ b/tags/0.8/finger-chart-core-lib/src/main/flex/com/riameeting/finger/effect/FadeIn.as @@ -0,0 +1,39 @@ +package com.riameeting.finger.effect +{ + import com.greensock.TweenLite; + + import flash.events.Event; + import flash.events.EventDispatcher; + /** + * 透明度渐变进入 + * @author Finger + * + */ + public class FadeIn implements IEffect + { + /** + * 构造方法 + * + */ + public function FadeIn() + { + super(); + } + /** + * 执行 + * @param obj 对象 + * @param time 时长 + * + */ + public function execute(obj:Object,time:Number,callback:Function = null):void + { + obj.alpha = 0; + obj.visible = true; + TweenLite.to(obj,time,{alpha:1,onComplete:callBack}); + function callBack():void { + if(callback != null) callback(); + } + } + + } +} \ No newline at end of file diff --git a/tags/0.8/finger-chart-core-lib/src/main/flex/com/riameeting/finger/effect/FadeOut.as b/tags/0.8/finger-chart-core-lib/src/main/flex/com/riameeting/finger/effect/FadeOut.as new file mode 100644 index 0000000..91883ea --- /dev/null +++ b/tags/0.8/finger-chart-core-lib/src/main/flex/com/riameeting/finger/effect/FadeOut.as @@ -0,0 +1,35 @@ +package com.riameeting.finger.effect +{ + import com.greensock.TweenLite; + + import flash.events.Event; + import flash.events.EventDispatcher; + /** + * 透明度渐变淡出 + * @author Finger + * + */ + public class FadeOut implements IEffect + { + /** + * 构造方法 + * + */ + public function FadeOut() + { + } + /** + * 执行 + * @param obj 对象 + * @param time 时长 + * + */ + public function execute(obj:Object,time:Number,callback:Function=null):void + { + TweenLite.to(obj,time,{alpha:0,onComplete:callBack}); + function callBack():void { + if(callback != null) callback(); + } + } + } +} \ No newline at end of file diff --git a/tags/0.8/finger-chart-core-lib/src/main/flex/com/riameeting/finger/effect/IEffect.as b/tags/0.8/finger-chart-core-lib/src/main/flex/com/riameeting/finger/effect/IEffect.as new file mode 100644 index 0000000..9d4babc --- /dev/null +++ b/tags/0.8/finger-chart-core-lib/src/main/flex/com/riameeting/finger/effect/IEffect.as @@ -0,0 +1,18 @@ +package com.riameeting.finger.effect +{ + /** + * 特效接口 + * @author Finger + * + */ + public interface IEffect + { + /** + * 执行 + * @param obj 对象 + * @param time 时长 + * + */ + function execute(obj:Object,time:Number,callback:Function=null):void; + } +} \ No newline at end of file diff --git a/tags/0.8/finger-chart-core-lib/src/main/flex/com/riameeting/finger/effect/MoveIn.as b/tags/0.8/finger-chart-core-lib/src/main/flex/com/riameeting/finger/effect/MoveIn.as new file mode 100644 index 0000000..a69c4e7 --- /dev/null +++ b/tags/0.8/finger-chart-core-lib/src/main/flex/com/riameeting/finger/effect/MoveIn.as @@ -0,0 +1,61 @@ +package com.riameeting.finger.effect +{ + import com.greensock.TweenLite; + import com.greensock.easing.*; + import com.riameeting.finger.display.graphic.IChartGraphic; + + import flash.display.DisplayObject; + import flash.display.Sprite; + import flash.events.Event; + import flash.events.EventDispatcher; + import flash.events.TimerEvent; + import flash.geom.Point; + import flash.utils.Dictionary; + import flash.utils.Timer; + import flash.utils.setTimeout; + + /** + * 移动进入特效 + * @author Finger + * + */ + public class MoveIn implements IEffect + { + /** + * 对象哈希 + */ + public static var objDic:Dictionary = new Dictionary(); + /** + * 执行 + * @param obj 对象 + * @param time 时长 + * + */ + public function execute(obj:Object, time:Number, callback:Function = null):void + { + var seriel:Sprite = obj as Sprite; + seriel.visible = true; + var child:IChartGraphic; + var childNum:uint = seriel.numChildren; + var splitTime:Number = time/childNum; + var currentIndex:uint = 0; + seriel.graphics.clear(); + setTimeout(callBack,time*1000); + for(var i:uint=0;i= childNum) return; + child = seriel.getChildAt(currentIndex) as IChartGraphic; + child.locate(); + currentIndex++; + } + function callBack(...args):void { + if(callback != null) callback(); + } + } + } +} \ No newline at end of file diff --git a/tags/0.8/finger-chart-core-lib/src/main/flex/com/riameeting/finger/effect/MoveOut.as b/tags/0.8/finger-chart-core-lib/src/main/flex/com/riameeting/finger/effect/MoveOut.as new file mode 100644 index 0000000..24a5672 --- /dev/null +++ b/tags/0.8/finger-chart-core-lib/src/main/flex/com/riameeting/finger/effect/MoveOut.as @@ -0,0 +1,54 @@ +package com.riameeting.finger.effect +{ + import com.greensock.TweenLite; + import com.greensock.easing.*; + import com.riameeting.finger.display.graphic.IChartGraphic; + + import flash.display.DisplayObject; + import flash.display.Sprite; + import flash.events.Event; + import flash.events.EventDispatcher; + import flash.events.TimerEvent; + import flash.geom.Point; + import flash.utils.Dictionary; + import flash.utils.Timer; + import flash.utils.setTimeout; + /** + * 移动淡出特效 + * @author Finger + * + */ + public class MoveOut implements IEffect + { + /** + * 构造方法 + * + */ + public function MoveOut() + { + } + /** + * 执行 + * @param obj 对象 + * @param time 时长 + * + */ + public function execute(obj:Object, time:Number, callback:Function = null):void + { + var seriel:Sprite = obj as Sprite; + var child:IChartGraphic; + var childNum:uint = seriel.numChildren; + var splitTime:Number = time/childNum; + var currentIndex:uint = 0; + seriel.graphics.clear(); + setTimeout(callBack,time*1000); + for(var i:uint=0;i0) { + object = cacheDic[key].shift(); + } else { + if(parms == null) { + object = new clazz(); + } else { + //FIXME:这是一个临时策略,需要修改为完全支持参数传递的方式 + switch(parms.length) { + case 1: + object = new clazz(parms[0]); + break; + case 2: + object = new clazz(parms[0],parms[1]); + break; + case 3: + object = new clazz(parms[0],parms[1],parms[2]); + break; + case 4: + object = new clazz(parms[0],parms[1],parms[2],parms[3]); + break; + case 5: + object = new clazz(parms[0],parms[1],parms[2],parms[3],parms[4]); + break; + } + } + } + return object; + } + /** + * 回收对象 + * @param clazz 类 + * @param object 对象 + * + */ + public static function reclaim(clazz:Class,object:*,key:String):void { + if(cacheDic[key] == null) return; + cacheDic[key].push(object); + } + + } +} \ No newline at end of file diff --git a/tags/0.8/finger-chart-core-lib/src/main/flex/com/riameeting/finger/parser/CSSParser.as b/tags/0.8/finger-chart-core-lib/src/main/flex/com/riameeting/finger/parser/CSSParser.as new file mode 100644 index 0000000..a2bae51 --- /dev/null +++ b/tags/0.8/finger-chart-core-lib/src/main/flex/com/riameeting/finger/parser/CSSParser.as @@ -0,0 +1,100 @@ +package com.riameeting.finger.parser +{ + + import com.riameeting.utils.StringUtils; + + /** + * CSS解析器 + * + */ + public class CSSParser { + + private var _css:Object; + + /** + * 构造方法 + */ + public function CSSParser() { + _css = {}; + } + + /** + * 解析CSS到对象 + * @param cssStr + */ + public function parseCSS(cssStr:String):void { + var cssArr:Array = cssStr.match(/([\w \.:\#]+\{.+?\})/gs); //split all slectors{properties:values} + parseSelectors(cssArr); + } + + /** + * 解析CSS选择器和属性 + * @param cssArr Array + */ + private function parseSelectors(cssArr:Array):void { + var selector:String; + var properties:String; + var n:int = cssArr.length; + for (var i:int = 0; i < n; i++) { + selector = StringUtils.trim(cssArr[i].match(/.+(?=\{)/g)[0]); //everything before { + properties = cssArr[i].match(/(?<=\{).+(?=\})/g)[0]; //everything inside {} + setStyle(selector, parseProperties(properties)); + } + } + + /** + * 转换属性的字符串到对象 + * @param propStr + */ + private function parseProperties(propStr:String):Object { + var result:Object = {}; + var properties:Array = propStr.match(/\b\w[\w-:\#\/ ,]+/g); //split properties + var curProp:Array; + var n:int = properties.length; + for (var j:int = 0; j < n; j++) { + curProp = properties[j].split(":"); + result[StringUtils.toCamelCase(curProp[0])] = StringUtils.trim(curProp[1]); + if(curProp[1].split(" ").length > 1) { + result[StringUtils.toCamelCase(curProp[0])] = []; + for each(var value:String in curProp[1].split(" ")) { + result[StringUtils.toCamelCase(curProp[0])].push(value); + } + } + } + return result; + } + + /** + * 获取所有选择器的引用的数组 + */ + public function get selectors():Array { + var selectors:Array = []; + for (var prop:* in _css) { + selectors.push(prop); + } + return selectors; + } + + /** + * 通过选择器获取一个样式对象的引用 + */ + public function getStyle(selector:String):Object { return _css[selector]; } + + /** + * 设置样式 + * @param selector + * @param styleObj + */ + public function setStyle(selector:String, styleObj:Object):void { + if (_css[selector] === undefined) _css[selector] = { }; + _css[selector] = styleObj; + } + + /** + * 删除所有的选择器和属性 + */ + public function clear():void { _css = {}; } + + } + +} diff --git a/tags/0.8/finger-chart-core-lib/src/main/flex/com/riameeting/finger/parser/CSVParser.as b/tags/0.8/finger-chart-core-lib/src/main/flex/com/riameeting/finger/parser/CSVParser.as new file mode 100644 index 0000000..dbf48eb --- /dev/null +++ b/tags/0.8/finger-chart-core-lib/src/main/flex/com/riameeting/finger/parser/CSVParser.as @@ -0,0 +1,35 @@ +package com.riameeting.finger.parser +{ + import com.riameeting.finger.vo.DatasetVO; + /** + * CSV解析器 + * @author Finger + * + */ + public class CSVParser + { + /** + * 将数据对象转换为CSV格式 + * @param dataset 数据对象 + * @return 字符串 + * + */ + public static function encode(dataset:DatasetVO):String + { + var str:String = dataset.config["categoryField"]; + var yFiled:String; + for each(yFiled in dataset.config["yField"].split(",")) { + str += ","+yFiled; + } + str += "\n"; + for each(var obj:Object in dataset.collection) { + str += obj[dataset.config["categoryField"]]; + for each(yFiled in dataset.config["yField"].split(",")) { + str += ","+obj[yFiled]; + } + str += "\n"; + } + return str; + } + } +} \ No newline at end of file diff --git a/tags/0.8/finger-chart-core-lib/src/main/flex/com/riameeting/finger/parser/IParser.as b/tags/0.8/finger-chart-core-lib/src/main/flex/com/riameeting/finger/parser/IParser.as new file mode 100644 index 0000000..b95069d --- /dev/null +++ b/tags/0.8/finger-chart-core-lib/src/main/flex/com/riameeting/finger/parser/IParser.as @@ -0,0 +1,19 @@ +package com.riameeting.finger.parser +{ + import com.riameeting.finger.vo.DatasetVO; + /** + * 解析器接口 + * @author Finger + * + */ + public interface IParser + { + /** + * 解析 + * @param source 源格式 + * @return 返回转换后的对象 + * + */ + function parse(source:*):DatasetVO; + } +} \ No newline at end of file diff --git a/tags/0.8/finger-chart-core-lib/src/main/flex/com/riameeting/finger/parser/JSONParser.as b/tags/0.8/finger-chart-core-lib/src/main/flex/com/riameeting/finger/parser/JSONParser.as new file mode 100644 index 0000000..29736f5 --- /dev/null +++ b/tags/0.8/finger-chart-core-lib/src/main/flex/com/riameeting/finger/parser/JSONParser.as @@ -0,0 +1,37 @@ +package com.riameeting.finger.parser +{ + import com.adobe.serialization.json.JSONDecoder; + + import com.riameeting.finger.vo.DatasetVO; + /** + * JSON解析器 + * @author Finger + * + */ + public class JSONParser implements IParser + { + private var jsonObj:Object; + /** + * 构造方法 + * + */ + public function JSONParser() + { + } + /** + * 解析 + * @param source 源格式 + * @return 返回转换后的对象 + * + */ + public function parse(source:*):DatasetVO + { + var headerObj:Object = {}; + var arr:Array = []; + jsonObj = new JSONDecoder(source).getValue(); + headerObj = jsonObj.config; + arr = jsonObj.dataset; + return new DatasetVO(headerObj,arr); + } + } +} \ No newline at end of file diff --git a/tags/0.8/finger-chart-core-lib/src/main/flex/com/riameeting/finger/parser/XMLParser.as b/tags/0.8/finger-chart-core-lib/src/main/flex/com/riameeting/finger/parser/XMLParser.as new file mode 100644 index 0000000..1f781e5 --- /dev/null +++ b/tags/0.8/finger-chart-core-lib/src/main/flex/com/riameeting/finger/parser/XMLParser.as @@ -0,0 +1,50 @@ +package com.riameeting.finger.parser +{ + import com.riameeting.finger.vo.DatasetVO; + /** + * XML解析器 + * @author Finger + * + */ + public class XMLParser implements IParser + { + private var xmlSource:XML; + /** + * 构造方法 + * + */ + public function XMLParser() + { + } + /** + * 解析 + * @param source 源格式 + * @return 返回转换后的对象 + * + */ + public function parse(source:*):DatasetVO + { + var headerObj:Object = {}; + var arr:Array = []; + xmlSource = new XML(source); + var header:XML = xmlSource.config[0]; + var dt:String,dd:String,node:XML,nodeAtt:XML; + for each(node in header.attributes()) { + dt = node.localName().toString(); + dd = node.toString(); + headerObj[dt] = dd; + } + var nodes:XMLList = xmlSource.dataset.node; + for each(node in nodes) { + var valueObj:Object = {}; + for each(nodeAtt in node.attributes()) { + dt = nodeAtt.localName().toString(); + dd = nodeAtt.toString(); + valueObj[dt] = dd; + } + arr.push(valueObj); + } + return new DatasetVO(headerObj,arr); + } + } +} \ No newline at end of file diff --git a/tags/0.8/finger-chart-core-lib/src/main/flex/com/riameeting/finger/plugin/IChartPlugin.as b/tags/0.8/finger-chart-core-lib/src/main/flex/com/riameeting/finger/plugin/IChartPlugin.as new file mode 100644 index 0000000..075fa4a --- /dev/null +++ b/tags/0.8/finger-chart-core-lib/src/main/flex/com/riameeting/finger/plugin/IChartPlugin.as @@ -0,0 +1,25 @@ +package com.riameeting.finger.plugin +{ + import com.riameeting.finger.display.container.IPluginContainer; + /** + * 图表插件的接口 + * @author Finger + * + */ + public interface IChartPlugin + { + /** + * 初始化插件 + * @param container 插件容器 + * + */ + function initPlugin(container:IPluginContainer):void; + /** + * 更新显示列表 + * @param width 宽度 + * @param height 高度 + * + */ + function updateDisplayList(width:uint,height:uint):void; + } +} \ No newline at end of file diff --git a/tags/0.8/finger-chart-core-lib/src/main/flex/com/riameeting/finger/vo/DatasetVO.as b/tags/0.8/finger-chart-core-lib/src/main/flex/com/riameeting/finger/vo/DatasetVO.as new file mode 100644 index 0000000..3b54ce1 --- /dev/null +++ b/tags/0.8/finger-chart-core-lib/src/main/flex/com/riameeting/finger/vo/DatasetVO.as @@ -0,0 +1,42 @@ +package com.riameeting.finger.vo +{ + /** + * 数据对象的封装 + * @author Finger + * + */ + public class DatasetVO + { + /** + * 配置对象 + */ + public var config:Object; + /** + * 数据集合 + */ + public var collection:Array; + /** + * 构造方法 + * @param config 配置对象 + * @param collection 数据集合 + * + */ + public function DatasetVO(config:Object, collection:Array) + { + this.config = config; + this.collection = collection; + super(); + } + /** + * 转换为字符串 + * @return + * + */ + public function toString():String + { + return "DatasetVO{config:" + config + ", collection:[" + collection + "]}"; + } + + + } +} \ No newline at end of file diff --git a/tags/0.8/finger-chart-core-lib/src/main/resources/legend_button.png b/tags/0.8/finger-chart-core-lib/src/main/resources/legend_button.png new file mode 100644 index 0000000..de84867 Binary files /dev/null and b/tags/0.8/finger-chart-core-lib/src/main/resources/legend_button.png differ diff --git a/tags/0.8/finger-chart-main/area_chart/pom.xml b/tags/0.8/finger-chart-main/area_chart/pom.xml new file mode 100644 index 0000000..999b44e --- /dev/null +++ b/tags/0.8/finger-chart-main/area_chart/pom.xml @@ -0,0 +1,45 @@ + + + + + com.riameeting.fingerchart + finger-chart-main + 0.8 + + + 4.0.0 + + com.riameeting.fingerchart + area_chart + 0.8 + swf + Area Chart + + + ../src/main/flex + + + org.sonatype.flexmojos + flexmojos-maven-plugin + ${flexmojos.version} + true + + area_chart.as + + target/area_chart-0.8.swf + + + + + com.adobe.flex + compiler + ${flex.version} + pom + + + + + + diff --git a/tags/0.8/finger-chart-main/bar_chart/pom.xml b/tags/0.8/finger-chart-main/bar_chart/pom.xml new file mode 100644 index 0000000..7e7cbdb --- /dev/null +++ b/tags/0.8/finger-chart-main/bar_chart/pom.xml @@ -0,0 +1,42 @@ + + + + + com.riameeting.fingerchart + finger-chart-main + 0.8 + + + 4.0.0 + + com.riameeting.fingerchart + bar-chart + 0.8 + swf + Bar Chart + + + ../src/main/flex + + + org.sonatype.flexmojos + flexmojos-maven-plugin + ${flexmojos.version} + true + + bar_chart.as + + + + com.adobe.flex + compiler + ${flex.version} + pom + + + + + + diff --git a/tags/0.8/finger-chart-main/bubble_chart/pom.xml b/tags/0.8/finger-chart-main/bubble_chart/pom.xml new file mode 100644 index 0000000..bcb871a --- /dev/null +++ b/tags/0.8/finger-chart-main/bubble_chart/pom.xml @@ -0,0 +1,42 @@ + + + + + com.riameeting.fingerchart + finger-chart-main + 0.8 + + + 4.0.0 + + com.riameeting.fingerchart + bubble-chart + 0.8 + swf + Bubble Chart + + + ../src/main/flex + + + org.sonatype.flexmojos + flexmojos-maven-plugin + ${flexmojos.version} + true + + bubble_chart.as + + + + com.adobe.flex + compiler + ${flex.version} + pom + + + + + + diff --git a/tags/0.8/finger-chart-main/column_chart/pom.xml b/tags/0.8/finger-chart-main/column_chart/pom.xml new file mode 100644 index 0000000..fdbe640 --- /dev/null +++ b/tags/0.8/finger-chart-main/column_chart/pom.xml @@ -0,0 +1,42 @@ + + + + + com.riameeting.fingerchart + finger-chart-main + 0.8 + + + 4.0.0 + + com.riameeting.fingerchart + column-chart + 0.8 + swf + Column Chart + + + ../src/main/flex + + + org.sonatype.flexmojos + flexmojos-maven-plugin + ${flexmojos.version} + true + + column_chart.as + + + + com.adobe.flex + compiler + ${flex.version} + pom + + + + + + diff --git a/tags/0.8/finger-chart-main/line_chart/pom.xml b/tags/0.8/finger-chart-main/line_chart/pom.xml new file mode 100644 index 0000000..59fac6c --- /dev/null +++ b/tags/0.8/finger-chart-main/line_chart/pom.xml @@ -0,0 +1,42 @@ + + + + + com.riameeting.fingerchart + finger-chart-main + 0.8 + + + 4.0.0 + + com.riameeting.fingerchart + line-chart + 0.8 + swf + Line Chart + + + ../src/main/flex + + + org.sonatype.flexmojos + flexmojos-maven-plugin + ${flexmojos.version} + true + + line_chart.as + + + + com.adobe.flex + compiler + ${flex.version} + pom + + + + + + diff --git a/tags/0.8/finger-chart-main/pie_chart/pom.xml b/tags/0.8/finger-chart-main/pie_chart/pom.xml new file mode 100644 index 0000000..93caa59 --- /dev/null +++ b/tags/0.8/finger-chart-main/pie_chart/pom.xml @@ -0,0 +1,42 @@ + + + + + com.riameeting.fingerchart + finger-chart-main + 0.8 + + + 4.0.0 + + com.riameeting.fingerchart + pie-chart + 0.8 + swf + Pie Chart + + + ../src/main/flex + + + org.sonatype.flexmojos + flexmojos-maven-plugin + ${flexmojos.version} + true + + pie_chart.as + + + + com.adobe.flex + compiler + ${flex.version} + pom + + + + + + diff --git a/tags/0.8/finger-chart-main/plot_chart/pom.xml b/tags/0.8/finger-chart-main/plot_chart/pom.xml new file mode 100644 index 0000000..4406f8e --- /dev/null +++ b/tags/0.8/finger-chart-main/plot_chart/pom.xml @@ -0,0 +1,42 @@ + + + + + com.riameeting.fingerchart + finger-chart-main + 0.8 + + + 4.0.0 + + com.riameeting.fingerchart + plot-chart + 0.8 + swf + Plot Chart + + + ../src/main/flex + + + org.sonatype.flexmojos + flexmojos-maven-plugin + ${flexmojos.version} + true + + plot_chart.as + + + + com.adobe.flex + compiler + ${flex.version} + pom + + + + + + diff --git a/tags/0.8/finger-chart-main/pom.xml b/tags/0.8/finger-chart-main/pom.xml new file mode 100644 index 0000000..eb4648c --- /dev/null +++ b/tags/0.8/finger-chart-main/pom.xml @@ -0,0 +1,39 @@ + + + + + com.riameeting.fingerchart + finger-chart-superpom + 0.8 + + + 4.0.0 + + com.riameeting.fingerchart + finger-chart-main + 0.8 + pom + Finger Chart Main + + + area_chart + bar_chart + bubble_chart + column_chart + line_chart + pie_chart + plot_chart + + + + + + com.riameeting.fingerchart + finger-chart-core-lib + 0.8 + swc + + + diff --git a/tags/0.8/finger-chart-main/src/main/flex/area_chart.as b/tags/0.8/finger-chart-main/src/main/flex/area_chart.as new file mode 100644 index 0000000..9578533 --- /dev/null +++ b/tags/0.8/finger-chart-main/src/main/flex/area_chart.as @@ -0,0 +1,40 @@ +package +{ + import com.riameeting.finger.component.*; + import com.riameeting.finger.display.legend.*; + + import flash.events.Event; + + + [SWF(backgroundColor="#FFFFFF",pageTitle="AreaChart")] + /** + * 区域图 + * + *

Website:http://www.riameeting.com/fingerchart

+ *

在线交流QQ群:72916285

+ * @author RIAMeeting + * + */ + public class area_chart extends ChartWrapper + { + /** + * 构造方法 + * + */ + public function area_chart() { + super(); + } + /** + * 初始化方法,将创建图表,并加载外部文件 + * @param e + * + */ + override protected function init(e:Event=null):void { + chart = new AreaChart(stage.stageWidth,stage.stageHeight); + if(chartConfig["legend"] != null) { + legend = new SlideLegend(chart,"rect",200,stage.stageHeight); + } + super.init(e); + } + } +} \ No newline at end of file diff --git a/tags/0.8/finger-chart-main/src/main/flex/bar_chart.as b/tags/0.8/finger-chart-main/src/main/flex/bar_chart.as new file mode 100644 index 0000000..39020f9 --- /dev/null +++ b/tags/0.8/finger-chart-main/src/main/flex/bar_chart.as @@ -0,0 +1,37 @@ +package +{ + import com.riameeting.finger.component.*; + import com.riameeting.finger.display.legend.*; + + import flash.events.Event; + + /** + * 柱状图(横向) + * @author RIAMeeting + *

Website:http://www.riameeting.com/fingerchart

+ *

在线交流QQ群:72916285

+ */ + [SWF(backgroundColor="#FFFFFF",pageTitle="BarChart")] + public class bar_chart extends ChartWrapper + { + /** + * 构造方法 + * + */ + public function bar_chart() { + super(); + } + /** + * 初始化方法,将创建图表,并加载外部文件 + * @param e + * + */ + override protected function init(e:Event=null):void { + chart = new BarChart(stage.stageWidth,stage.stageHeight); + if(chartConfig["legend"] != null) { + legend = new SlideLegend(chart,"rect",200,stage.stageHeight); + } + super.init(e); + } + } +} \ No newline at end of file diff --git a/tags/0.8/finger-chart-main/src/main/flex/bubble_chart.as b/tags/0.8/finger-chart-main/src/main/flex/bubble_chart.as new file mode 100644 index 0000000..12d1411 --- /dev/null +++ b/tags/0.8/finger-chart-main/src/main/flex/bubble_chart.as @@ -0,0 +1,37 @@ +package +{ + import com.riameeting.finger.component.*; + import com.riameeting.finger.display.legend.*; + + import flash.events.Event; + + /** + * 气泡图 + * @author RIAMeeting + *

Website:http://www.riameeting.com/fingerchart

+ *

在线交流QQ群:72916285

+ */ + [SWF(backgroundColor="#FFFFFF",pageTitle="BubbleChart")] + public class bubble_chart extends ChartWrapper + { + /** + * 构造方法 + * + */ + public function bubble_chart() { + super(); + } + /** + * 初始化方法,将创建图表,并加载外部文件 + * @param e + * + */ + override protected function init(e:Event=null):void { + chart = new BubbleChart(stage.stageWidth,stage.stageHeight); + if(chartConfig["legend"] != null) { + legend = new SlideLegend(chart,"rect",200,stage.stageHeight); + } + super.init(e); + } + } +} \ No newline at end of file diff --git a/tags/0.8/finger-chart-main/src/main/flex/column_chart.as b/tags/0.8/finger-chart-main/src/main/flex/column_chart.as new file mode 100644 index 0000000..1ea5dd2 --- /dev/null +++ b/tags/0.8/finger-chart-main/src/main/flex/column_chart.as @@ -0,0 +1,37 @@ +package +{ + import com.riameeting.finger.component.*; + import com.riameeting.finger.display.legend.*; + + import flash.events.Event; + + /** + * 柱状图 + * @author RIAMeeting + *

Website:http://www.riameeting.com/fingerchart

+ *

在线交流QQ群:72916285

+ */ + [SWF(backgroundColor="#FFFFFF",pageTitle="ColumnChart")] + public class column_chart extends ChartWrapper + { + /** + * 构造方法 + * + */ + public function column_chart() { + super(); + } + /** + * 初始化方法,将创建图表,并加载外部文件 + * @param e + * + */ + override protected function init(e:Event=null):void { + chart = new ColumnChart(stage.stageWidth,stage.stageHeight); + if(chartConfig["legend"] != null) { + legend = new SlideLegend(chart,"rect",200,stage.stageHeight); + } + super.init(e); + } + } +} \ No newline at end of file diff --git a/tags/0.8/finger-chart-main/src/main/flex/data/json/line_json1.txt b/tags/0.8/finger-chart-main/src/main/flex/data/json/line_json1.txt new file mode 100644 index 0000000..593340d --- /dev/null +++ b/tags/0.8/finger-chart-main/src/main/flex/data/json/line_json1.txt @@ -0,0 +1 @@ +{"config":{"yTitle":"访问量","categoryField":"日期","yField":"频道一,频道二,参考线","benchmark":"参考线"},"dataset":[{"日期":"6月1日","参考线":"300","频道一":"100","频道二":"430"},{"日期":"6月2日","参考线":"300","频道一":"600","频道二":"230"}]} \ No newline at end of file diff --git a/tags/0.8/finger-chart-main/src/main/flex/data/xml/barchart_data1.xml b/tags/0.8/finger-chart-main/src/main/flex/data/xml/barchart_data1.xml new file mode 100644 index 0000000..9d43a38 --- /dev/null +++ b/tags/0.8/finger-chart-main/src/main/flex/data/xml/barchart_data1.xml @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + \ No newline at end of file diff --git a/tags/0.8/finger-chart-main/src/main/flex/data/xml/columnchart_data1.xml b/tags/0.8/finger-chart-main/src/main/flex/data/xml/columnchart_data1.xml new file mode 100644 index 0000000..3dec6b6 --- /dev/null +++ b/tags/0.8/finger-chart-main/src/main/flex/data/xml/columnchart_data1.xml @@ -0,0 +1,19 @@ + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/tags/0.8/finger-chart-main/src/main/flex/data/xml/linechart_data1.xml b/tags/0.8/finger-chart-main/src/main/flex/data/xml/linechart_data1.xml new file mode 100644 index 0000000..2d20fc2 --- /dev/null +++ b/tags/0.8/finger-chart-main/src/main/flex/data/xml/linechart_data1.xml @@ -0,0 +1,19 @@ + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/tags/0.8/finger-chart-main/src/main/flex/data/xml/piechart_data1.xml b/tags/0.8/finger-chart-main/src/main/flex/data/xml/piechart_data1.xml new file mode 100644 index 0000000..48dc938 --- /dev/null +++ b/tags/0.8/finger-chart-main/src/main/flex/data/xml/piechart_data1.xml @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + \ No newline at end of file diff --git a/tags/0.8/finger-chart-main/src/main/flex/data/xml/plotchart_data1.xml b/tags/0.8/finger-chart-main/src/main/flex/data/xml/plotchart_data1.xml new file mode 100644 index 0000000..2c4493c --- /dev/null +++ b/tags/0.8/finger-chart-main/src/main/flex/data/xml/plotchart_data1.xml @@ -0,0 +1,12 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/tags/0.8/finger-chart-main/src/main/flex/line_chart.as b/tags/0.8/finger-chart-main/src/main/flex/line_chart.as new file mode 100644 index 0000000..b9ccd9e --- /dev/null +++ b/tags/0.8/finger-chart-main/src/main/flex/line_chart.as @@ -0,0 +1,37 @@ +package +{ + import com.riameeting.finger.component.*; + import com.riameeting.finger.display.legend.*; + + import flash.events.Event; + + /** + * 线状图 + * @author RIAMeeting + *

Website:http://www.riameeting.com/fingerchart

+ *

在线交流QQ群:72916285

+ */ + [SWF(backgroundColor="#FFFFFF",pageTitle="LineChart")] + public class line_chart extends ChartWrapper + { + /** + * 构造方法 + * + */ + public function line_chart() { + super(); + } + /** + * 初始化方法,将创建图表,并加载外部文件 + * @param e + * + */ + override protected function init(e:Event=null):void { + chart = new LineChart(stage.stageWidth,stage.stageHeight); + if(chartConfig["legend"] != null) { + legend = new SlideLegend(chart,"rect",200,stage.stageHeight); + } + super.init(e); + } + } +} \ No newline at end of file diff --git a/tags/0.8/finger-chart-main/src/main/flex/package-description/package-description.xml b/tags/0.8/finger-chart-main/src/main/flex/package-description/package-description.xml new file mode 100644 index 0000000..03cb738 --- /dev/null +++ b/tags/0.8/finger-chart-main/src/main/flex/package-description/package-description.xml @@ -0,0 +1,28 @@ + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/tags/0.8/finger-chart-main/src/main/flex/pie_chart.as b/tags/0.8/finger-chart-main/src/main/flex/pie_chart.as new file mode 100644 index 0000000..492ca5a --- /dev/null +++ b/tags/0.8/finger-chart-main/src/main/flex/pie_chart.as @@ -0,0 +1,37 @@ +package +{ + import com.riameeting.finger.component.*; + import com.riameeting.finger.display.legend.*; + + import flash.events.Event; + + /** + * 饼图 + * @author RIAMeeting + *

Website:http://www.riameeting.com/fingerchart

+ *

在线交流QQ群:72916285

+ */ + [SWF(backgroundColor="#FFFFFF",pageTitle="PieChart")] + public class pie_chart extends ChartWrapper + { + /** + * 构造方法 + * + */ + public function pie_chart() { + super(); + } + /** + * 初始化方法,将创建图表,并加载外部文件 + * @param e + * + */ + override protected function init(e:Event=null):void { + chart = new PieChart(stage.stageWidth,stage.stageHeight); + if(chartConfig["legend"] != null) { + legend = new SlideLegend(chart,"rect",200,stage.stageHeight); + } + super.init(e); + } + } +} \ No newline at end of file diff --git a/tags/0.8/finger-chart-main/src/main/flex/plot_chart.as b/tags/0.8/finger-chart-main/src/main/flex/plot_chart.as new file mode 100644 index 0000000..46f8c92 --- /dev/null +++ b/tags/0.8/finger-chart-main/src/main/flex/plot_chart.as @@ -0,0 +1,37 @@ +package +{ + import com.riameeting.finger.component.*; + import com.riameeting.finger.display.legend.*; + + import flash.events.Event; + + /** + * 散点图 + * @author RIAMeeting + *

Website:http://www.riameeting.com/fingerchart

+ *

在线交流QQ群:72916285

+ */ + [SWF(backgroundColor="#FFFFFF",pageTitle="PlotChart")] + public class plot_chart extends ChartWrapper + { + /** + * 构造方法 + * + */ + public function plot_chart() { + super(); + } + /** + * 初始化方法,将创建图表,并加载外部文件 + * @param e + * + */ + override protected function init(e:Event=null):void { + chart = new PlotChart(stage.stageWidth,stage.stageHeight); + if(chartConfig["legend"] != null) { + legend = new SlideLegend(chart,"rect",200,stage.stageHeight); + } + super.init(e); + } + } +} \ No newline at end of file diff --git a/tags/0.8/finger-chart-main/src/test/flex/UITest.as b/tags/0.8/finger-chart-main/src/test/flex/UITest.as new file mode 100644 index 0000000..77f9bb9 --- /dev/null +++ b/tags/0.8/finger-chart-main/src/test/flex/UITest.as @@ -0,0 +1,130 @@ +package +{ + import com.riameeting.finger.component.*; + import com.riameeting.finger.config.ChartGlobal; + import com.riameeting.finger.display.graphic.*; + import com.riameeting.finger.events.ChartEvent; + import com.riameeting.ui.control.Alert; + import com.riameeting.ui.control.CheckBox; + import com.riameeting.ui.control.Label; + + import flash.display.Sprite; + import flash.display.StageAlign; + import flash.display.StageScaleMode; + import flash.events.Event; + + /** + * 测试类:测试UI组件 + * @author Finger + * + */ + public class UITest extends Sprite + { + /** + * 构造方法 + * + */ + public function UITest() + { + Alert.container = this; + stage.scaleMode = StageScaleMode.NO_SCALE; + stage.align = StageAlign.TOP_LEFT; + addEventListener(Event.ENTER_FRAME,checkStage); + } + /** + * 检查Stage是否获取了正确的宽度 + * @param e + * + */ + protected function checkStage(e:Event):void { + if(stage.stageWidth != 0) { + init(); + removeEventListener(Event.ENTER_FRAME,checkStage); + } + } + /** + * 初始化方法 + * + */ + protected function init():void { + //Label test + var t:Label = new Label(true); + addChild(t); + t.text = "Finger Chart UI示例"; + //Label test + var label:Label = new Label(); + addChild(label); + label.x = 200; + label.text = "100000"; + //check box + var checkBox:CheckBox = new CheckBox(); + checkBox.selected = true; + checkBox.y = 30; + checkBox.label = "我是复选框"; + addChild(checkBox); + //linechart + var chartConfig1:Object = {data:"data/xml/linechart_data1.xml",skin:"skin/default_skin.swf",css:"css/default.css",plugin:"plugin/context_menu.swf"}; + var lineChart:LineChart = new LineChart(500,300); + lineChart.chartConfig = chartConfig1; + lineChart.x = 10; + lineChart.y = 70; + lineChart.loadAssets(); + addChild(lineChart); + lineChart.addEventListener(ChartEvent.ITEM_CLICK,itemClickHandler); + //columnchart + var chartConfig2:Object = {data:"data/xml/columnchart_data1.xml",skin:"skin/default_skin.swf",css:"css/default.css",plugin:"plugin/context_menu.swf"}; + var columnChart:ColumnChart = new ColumnChart(500,300); + columnChart.chartConfig = chartConfig2; + columnChart.x = 520; + columnChart.y = 70; + columnChart.loadAssets(); + addChild(columnChart); + //barchart + var chartConfig3:Object = {data:"data/xml/barchart_data1.xml",skin:"skin/default_skin.swf",css:"css/default.css",plugin:"plugin/context_menu.swf"}; + var barChart:BarChart = new BarChart(500,300); + barChart.chartConfig = chartConfig3; + barChart.x = 10; + barChart.y = 380; + barChart.loadAssets(); + addChild(barChart); + //piechart + var chartConfig4:Object = {data:"data/xml/piechart_data1.xml",skin:"skin/default_skin.swf",css:"css/default.css",plugin:"plugin/context_menu.swf"}; + var pieChart:PieChart = new PieChart(500,300); + pieChart.chartConfig = chartConfig4; + pieChart.x = 520; + pieChart.y = 380; + pieChart.loadAssets(); + addChild(pieChart); + //areachart + var chartConfig5:Object = {data:"data/xml/linechart_data1.xml",skin:"skin/default_skin.swf",css:"css/default.css",plugin:"plugin/context_menu.swf"}; + var areaChart:AreaChart = new AreaChart(500,300); + areaChart.chartConfig = chartConfig5; + areaChart.x = 1020; + areaChart.y = 70; + areaChart.loadAssets(); + addChild(areaChart); + //plotchart + var chartConfig6:Object = {data:"data/xml/plotchart_data1.xml",skin:"skin/default_skin.swf",css:"css/default.css",plugin:"plugin/context_menu.swf"}; + var plotChart:PlotChart = new PlotChart(500,300); + plotChart.chartConfig = chartConfig6; + plotChart.x = 1020; + plotChart.y = 380; + plotChart.loadAssets(); + addChild(plotChart); + //bubblechart + var chartConfig7:Object = {data:"data/xml/plotchart_data1.xml",skin:"skin/default_skin.swf",css:"css/default.css",plugin:"plugin/context_menu.swf"}; + var bubbleChart:BubbleChart = new BubbleChart(500,300); + bubbleChart.chartConfig = chartConfig7; + bubbleChart.x = 10; + bubbleChart.y = 700; + bubbleChart.loadAssets(); + addChild(bubbleChart); + //Alert test + Alert.show("警告信息","hello"); + } + + private function itemClickHandler(e:ChartEvent):void { + Alert.show(e.data[e.yField]); + } + } +} \ No newline at end of file diff --git a/trunk/assets/fla/mxp/comps/AreaChartImp.as b/trunk/assets/fla/mxp/comps/AreaChartImp.as new file mode 100644 index 0000000..4948553 --- /dev/null +++ b/trunk/assets/fla/mxp/comps/AreaChartImp.as @@ -0,0 +1,15 @@ +package comps { + + import com.riameeting.finger.component.*; + import flash.display.DisplayObject; + + public class AreaChartImp extends LineChartImp { + + public function AreaChartImp() { + chart = new AreaChart(width,height); + super(); + } + + } + +} diff --git a/trunk/assets/fla/mxp/comps/BarChartImp.as b/trunk/assets/fla/mxp/comps/BarChartImp.as new file mode 100644 index 0000000..52b90fe --- /dev/null +++ b/trunk/assets/fla/mxp/comps/BarChartImp.as @@ -0,0 +1,15 @@ +package comps { + + import com.riameeting.finger.component.*; + import flash.display.DisplayObject; + + public class BarChartImp extends LineChartImp { + + public function BarChartImp() { + chart = new BarChart(width,height); + super(); + } + + } + +} diff --git a/trunk/assets/fla/mxp/comps/BubbleChartImp.as b/trunk/assets/fla/mxp/comps/BubbleChartImp.as new file mode 100644 index 0000000..b08dc3c --- /dev/null +++ b/trunk/assets/fla/mxp/comps/BubbleChartImp.as @@ -0,0 +1,15 @@ +package comps { + + import com.riameeting.finger.component.*; + import flash.display.DisplayObject; + + public class BubbleChartImp extends LineChartImp { + + public function BubbleChartImp() { + chart = new BubbleChart(width,height); + super(); + } + + } + +} diff --git a/trunk/assets/fla/mxp/comps/ColumnChartImp.as b/trunk/assets/fla/mxp/comps/ColumnChartImp.as new file mode 100644 index 0000000..a0a7baa --- /dev/null +++ b/trunk/assets/fla/mxp/comps/ColumnChartImp.as @@ -0,0 +1,15 @@ +package comps { + + import com.riameeting.finger.component.*; + import flash.display.DisplayObject; + + public class ColumnChartImp extends LineChartImp { + + public function ColumnChartImp() { + chart = new ColumnChart(width,height); + super(); + } + + } + +} diff --git a/trunk/assets/fla/mxp/comps/LineChartImp.as b/trunk/assets/fla/mxp/comps/LineChartImp.as new file mode 100644 index 0000000..9737b7c --- /dev/null +++ b/trunk/assets/fla/mxp/comps/LineChartImp.as @@ -0,0 +1,82 @@ +package comps { + import flash.display.Sprite; + import flash.display.MovieClip; + import com.riameeting.finger.display.chart.IChart; + import com.riameeting.finger.component.*; + + import fl.core.UIComponent; + import flash.utils.setTimeout; + import flash.display.DisplayObject; + import flash.text.TextField; + + public class LineChartImp extends UIComponent { + + private var _css:String; + private var _skin:String; + private var _data:String; + + protected var label:TextField = new TextField(); + + protected var chart:IChart; + protected var config:Object = {}; + + public function LineChartImp() { + label.text = "FingerChart"; + addChild(label); + if(chart == null) chart = new LineChart(width,height); + addChild(chart as DisplayObject); + drawNow(); + } + + [Inspectable(defaultValue="default.css")] + public function get css():String { + return _css; + } + public function set css(value:String):void { + _css = value; + } + + [Inspectable(defaultValue="default_skin.swf")] + public function get skin():String { + return _skin; + } + public function set skin(value:String):void { + _skin = value; + } + + [Inspectable(type="String")] + public function get data():String { + return _data; + } + public function set data(value:String):void { + if(value == null || value == "") return; + if(isLivePreview) return; + _data = value; + setTimeout(delayInvoke,500); + } + + private function delayInvoke():void { + config.css = css; + config.skin = skin; + config.data = data; + chart.chartConfig = config; + chart.loadAssets(); + } + + override protected function configUI():void { + super.configUI(); + } + + override protected function draw():void { + this.graphics.clear(); + this.graphics.beginFill(0x000000,0.2); + this.graphics.drawRect(0,0,width,height); + this.graphics.endFill(); + chart.width = width; + chart.height = height; + super.draw(); + } + + } + +} diff --git a/trunk/assets/fla/mxp/comps/PieChartImp.as b/trunk/assets/fla/mxp/comps/PieChartImp.as new file mode 100644 index 0000000..f8b1e81 --- /dev/null +++ b/trunk/assets/fla/mxp/comps/PieChartImp.as @@ -0,0 +1,15 @@ +package comps { + + import com.riameeting.finger.component.*; + import flash.display.DisplayObject; + + public class PieChartImp extends LineChartImp { + + public function PieChartImp() { + chart = new PieChart(width,height); + super(); + } + + } + +} diff --git a/trunk/assets/fla/mxp/comps/PlotChartImp.as b/trunk/assets/fla/mxp/comps/PlotChartImp.as new file mode 100644 index 0000000..8f656de --- /dev/null +++ b/trunk/assets/fla/mxp/comps/PlotChartImp.as @@ -0,0 +1,15 @@ +package comps { + + import com.riameeting.finger.component.*; + import flash.display.DisplayObject; + + public class PlotChartImp extends LineChartImp { + + public function PlotChartImp() { + chart = new PlotChart(width,height); + super(); + } + + } + +} diff --git a/trunk/assets/fla/mxp/default.css b/trunk/assets/fla/mxp/default.css new file mode 100644 index 0000000..9e1079b --- /dev/null +++ b/trunk/assets/fla/mxp/default.css @@ -0,0 +1,7 @@ +global {color-collection:0xff0000 0xff0078 0xff00d2 0x9c00ff 0x0c00ff 0x00a2ff 0x09c700 0xe7b300 0xe75c00;} +chart {bg-color:0xF5F5F5;bg-alpha:100;} +axis {grid-height:50;offset-x:40;offset-y:30;offset-v:20;color:0x000000;line-color:0x666666;} +gContainer {color:0x000000;benchmark-color:0xCCCCCC;line-width:4;} +tContainer {color:0x000000;tipbg-color:0xFFFFFF;} +pContainer {color:0x000000;} +legend {color:0xFFFFFF;padding-top:0;padding-left:0;benchmark-color:0xCCCCCC;bg-color:0x666666;bg-alpha:100;} \ No newline at end of file diff --git a/trunk/assets/fla/mxp/default_skin.swf b/trunk/assets/fla/mxp/default_skin.swf new file mode 100644 index 0000000..f7ab1ee Binary files /dev/null and b/trunk/assets/fla/mxp/default_skin.swf differ diff --git a/trunk/assets/fla/mxp/finger-flash-component.fla b/trunk/assets/fla/mxp/finger-flash-component.fla new file mode 100644 index 0000000..64bfc60 Binary files /dev/null and b/trunk/assets/fla/mxp/finger-flash-component.fla differ diff --git a/trunk/assets/fla/mxp/finger-flashpro-component.mxi b/trunk/assets/fla/mxp/finger-flashpro-component.mxi new file mode 100644 index 0000000..6be841b --- /dev/null +++ b/trunk/assets/fla/mxp/finger-flashpro-component.mxi @@ -0,0 +1,38 @@ + + + + + + + + + + + + + + + + + + + + + + Components > FingerChart. + ]]> + + + + + + + + + diff --git a/trunk/assets/fla/mxp/finger-flashpro-component.mxp b/trunk/assets/fla/mxp/finger-flashpro-component.mxp new file mode 100644 index 0000000..6e5a37a Binary files /dev/null and b/trunk/assets/fla/mxp/finger-flashpro-component.mxp differ diff --git a/trunk/assets/fla/mxp/finger-flashpro-component.swc b/trunk/assets/fla/mxp/finger-flashpro-component.swc new file mode 100644 index 0000000..7b01e57 Binary files /dev/null and b/trunk/assets/fla/mxp/finger-flashpro-component.swc differ diff --git a/trunk/assets/fla/mxp/line_json1.txt b/trunk/assets/fla/mxp/line_json1.txt new file mode 100644 index 0000000..593340d --- /dev/null +++ b/trunk/assets/fla/mxp/line_json1.txt @@ -0,0 +1 @@ +{"config":{"yTitle":"访问量","categoryField":"日期","yField":"频道一,频道二,参考线","benchmark":"参考线"},"dataset":[{"日期":"6月1日","参考线":"300","频道一":"100","频道二":"430"},{"日期":"6月2日","参考线":"300","频道一":"600","频道二":"230"}]} \ No newline at end of file diff --git a/trunk/assets/fla/mxp/test.fla b/trunk/assets/fla/mxp/test.fla new file mode 100644 index 0000000..428709c Binary files /dev/null and b/trunk/assets/fla/mxp/test.fla differ diff --git a/trunk/assets/fla/mxp/test.swf b/trunk/assets/fla/mxp/test.swf new file mode 100644 index 0000000..1a3ca70 Binary files /dev/null and b/trunk/assets/fla/mxp/test.swf differ diff --git a/trunk/assets/fla/plugin/context_menu.as b/trunk/assets/fla/plugin/context_menu.as new file mode 100644 index 0000000..96a159f --- /dev/null +++ b/trunk/assets/fla/plugin/context_menu.as @@ -0,0 +1,129 @@ +package { + + import com.adobe.images.PNGEncoder; + + import flash.display.BitmapData; + import flash.display.Sprite; + import flash.display.StageDisplayState; + import flash.events.ContextMenuEvent; + import flash.events.Event; + import flash.events.MouseEvent; + import flash.net.*; + import flash.printing.PrintJob; + import flash.ui.ContextMenu; + import flash.ui.ContextMenuItem; + import flash.utils.ByteArray; + + import com.riameeting.finger.config.ChartGlobal; + import com.riameeting.finger.parser.CSVParser; + import com.riameeting.finger.vo.DatasetVO; + + import flash.display.MovieClip; + import com.riameeting.finger.plugin.IChartPlugin; + import com.riameeting.finger.display.container.IPluginContainer; + import flash.display.DisplayObject; + import com.riameeting.finger.display.chart.IChart; + + + public class context_menu extends MovieClip implements IChartPlugin { + + private var container:IPluginContainer; + private var myContextMenu:ContextMenu; + private var dataset:DatasetVO; + private var chartRef:IChart; + + public function context_menu() { + + } + + public function initPlugin(container:IPluginContainer):void { + this.container = container; + chartRef = container.chartRef; + dataset = container.dataset; + myContextMenu = new ContextMenu(); + (chartRef as Sprite).contextMenu = myContextMenu; + myContextMenu.hideBuiltInItems(); + var versionMenu:ContextMenuItem = new ContextMenuItem("Finger Chart, version: "+ChartGlobal.version); + versionMenu.enabled = false; + myContextMenu.customItems.push(versionMenu); + var fullscreenMenu:ContextMenuItem = new ContextMenuItem("全屏",true); + fullscreenMenu.addEventListener(ContextMenuEvent.MENU_ITEM_SELECT, fullscreenHandler); + myContextMenu.customItems.push(fullscreenMenu); + var saveMenu:ContextMenuItem = new ContextMenuItem("保存为位图",false); + saveMenu.addEventListener(ContextMenuEvent.MENU_ITEM_SELECT, saveHandler); + myContextMenu.customItems.push(saveMenu); + var saveCSVMenu:ContextMenuItem = new ContextMenuItem("保存为CSV",false); + saveCSVMenu.addEventListener(ContextMenuEvent.MENU_ITEM_SELECT, saveCSVHandler); + myContextMenu.customItems.push(saveCSVMenu); + var printMenu:ContextMenuItem = new ContextMenuItem("打印",false); + printMenu.addEventListener(ContextMenuEvent.MENU_ITEM_SELECT, printHandler); + myContextMenu.customItems.push(printMenu); + var viewDataMenu:ContextMenuItem = new ContextMenuItem("查看源数据",false); + viewDataMenu.addEventListener(ContextMenuEvent.MENU_ITEM_SELECT, viewDataSource); + myContextMenu.customItems.push(viewDataMenu); + var helpMenu:ContextMenuItem = new ContextMenuItem("www.riameeting.com/fingerchart",true); + helpMenu.addEventListener(ContextMenuEvent.MENU_ITEM_SELECT, getHelpLink); + myContextMenu.customItems.push(helpMenu); + var dateMenu:ContextMenuItem = new ContextMenuItem("最后更新日期:"+ChartGlobal.buildDate,true); + dateMenu.enabled = false; + myContextMenu.customItems.push(dateMenu); + stage.doubleClickEnabled = true; + stage.addEventListener(MouseEvent.DOUBLE_CLICK,fullscreenHandler); + } + + private function fullscreenHandler(e:Event):void { + stage.displayState = StageDisplayState.FULL_SCREEN; + } + + private function saveHandler(e:ContextMenuEvent):void { + var bmd:BitmapData = new BitmapData(stage.width,stage.height); + bmd.draw(chartRef as DisplayObject); + var bmdBytes:ByteArray = PNGEncoder.encode(bmd); + var saveFile:FileReference = new FileReference(); + saveFile.save(bmdBytes,getDate()+".png"); + } + + private function saveCSVHandler(e:ContextMenuEvent):void { + var csvStr:String = CSVParser.encode(dataset); + var csvBytes:ByteArray = new ByteArray(); + csvBytes.writeUTFBytes(csvStr); + var saveFile:FileReference = new FileReference(); + saveFile.save(csvBytes,getDate()+".csv"); + } + + private function printHandler(e:ContextMenuEvent):void { + var myPrintJob:PrintJob=new PrintJob(); + if(myPrintJob.start()) { + try{ + myPrintJob.addPage(chartRef as Sprite); + }catch(error:Error){ + trace("Print Error"); + } + myPrintJob.send(); + } + } + + private function viewDataSource(e:ContextMenuEvent):void { + navigateToURL(new URLRequest(chartRef.chartConfig["data"])); + } + + private function getHelpLink(e:ContextMenuEvent):void { + navigateToURL(new URLRequest("http://www.riameeting.com/fingerchart"),"_blank"); + } + + private function getDate():String { + var dateStr:String = "finger_"; + var date:Date = new Date(); + dateStr += date.getFullYear()+"-"; + dateStr += date.getMonth()+1+"-"; + dateStr += date.getDate(); + return dateStr; + } + + public function updateDisplayList(w:uint,h:uint):void { + + } + + } + +} diff --git a/trunk/assets/fla/plugin/context_menu.fla b/trunk/assets/fla/plugin/context_menu.fla new file mode 100644 index 0000000..1eded41 Binary files /dev/null and b/trunk/assets/fla/plugin/context_menu.fla differ diff --git a/trunk/assets/fla/plugin/context_menu.swf b/trunk/assets/fla/plugin/context_menu.swf new file mode 100644 index 0000000..fc615c3 Binary files /dev/null and b/trunk/assets/fla/plugin/context_menu.swf differ diff --git a/trunk/assets/fla/skin/skin.fla b/trunk/assets/fla/skin/skin.fla new file mode 100644 index 0000000..9f2e58a Binary files /dev/null and b/trunk/assets/fla/skin/skin.fla differ diff --git a/trunk/assets/fla/skin/skin.swf b/trunk/assets/fla/skin/skin.swf new file mode 100644 index 0000000..cd50801 Binary files /dev/null and b/trunk/assets/fla/skin/skin.swf differ diff --git a/trunk/assets/psd/children.psd b/trunk/assets/psd/children.psd new file mode 100644 index 0000000..5a85ff8 Binary files /dev/null and b/trunk/assets/psd/children.psd differ diff --git a/trunk/assets/psd/design.psd b/trunk/assets/psd/design.psd new file mode 100644 index 0000000..c797cf8 Binary files /dev/null and b/trunk/assets/psd/design.psd differ diff --git a/trunk/assets/psd/logo.png b/trunk/assets/psd/logo.png new file mode 100644 index 0000000..0681144 Binary files /dev/null and b/trunk/assets/psd/logo.png differ diff --git a/trunk/assets/psd/logo.psd b/trunk/assets/psd/logo.psd new file mode 100644 index 0000000..9f09a6d Binary files /dev/null and b/trunk/assets/psd/logo.psd differ diff --git a/trunk/assets/psd/logo2.png b/trunk/assets/psd/logo2.png new file mode 100644 index 0000000..720db51 Binary files /dev/null and b/trunk/assets/psd/logo2.png differ diff --git a/trunk/common-lib/pom.xml b/trunk/common-lib/pom.xml new file mode 100644 index 0000000..46e1c26 --- /dev/null +++ b/trunk/common-lib/pom.xml @@ -0,0 +1,41 @@ + + + + + com.riameeting.fingerchart + finger-chart-superpom + 0.8 + + + 4.0.0 + + com.riameeting.fingerchart + common-lib + 0.8 + swc + + common-lib Flex + + + src/main/flex + + + org.sonatype.flexmojos + flexmojos-maven-plugin + ${flexmojos.version} + true + + + com.adobe.flex + compiler + ${flex.version} + pom + + + + + + + diff --git a/trunk/common-lib/src/main/flex/com/cartogrammar/drawing/CubicBezier.as b/trunk/common-lib/src/main/flex/com/cartogrammar/drawing/CubicBezier.as new file mode 100644 index 0000000..4affebc --- /dev/null +++ b/trunk/common-lib/src/main/flex/com/cartogrammar/drawing/CubicBezier.as @@ -0,0 +1,243 @@ +/* Cubic Bézier curve tools +* @author: Andy Woodruff (http://cartogrammar.com/blog || awoodruff@gmail.com) +* @date: May 2008, updated January 2009 +* @description: Contains methods for drawing a single cubic Bézier curve and for drawing +* a continuous series of curves through specified points. +* Updates in January 2009: +* - moveTo argument in curveThroughPoints (used on line 200) +* - some math corrections in lines 152-163, which I hope fix problems caused by 0 angles and such +* - introduced an option (though not from outside this class) to use lineTo on straight segments rather than curving (affects lines 208-224) +* Previous version is at http://cartogrammar.com/source/CubicBezier_May08.as in case I screwed something up. Sorry about the lack of proper versioning! +*/ + +package com.cartogrammar.drawing{ + + import flash.display.Graphics; + import flash.geom.Point; + import fl.motion.BezierSegment; + + public class CubicBezier{ + + /** pubic static function drawCurve + * Draws a single cubic Bézier curve + * @param: + * g:Graphics -Graphics on which to draw the curve + * p1:Point -First point in the curve + * p2:Point -Second point (control point) in the curve + * p3:Point -Third point (control point) in the curve + * p4:Point -Fourth point in the curve + * @return: + */ + public static function drawCurve(g:Graphics, p1:Point, p2:Point, p3:Point, p4:Point):void{ + var bezier:BezierSegment = new BezierSegment(p1,p2,p3,p4); // BezierSegment using the four points + g.moveTo(p1.x,p1.y); + // Construct the curve out of 100 segments (adjust number for less/more detail) + for (var t:Number=.01;t<1.01;t+=.01){ + var val:Object = bezier.getValue(t); // x,y on the curve for a given t + g.lineTo(val.x,val.y); + } + } + + /** public static function curveThroughPoints + * Draws a smooth curve through a series of points. For a closed curve, make the first and last points the same. + * @param: + * g:Graphics -Graphics on which to draw the curve + * p:Array -Array of Point instances + * z:Number -A factor (between 0 and 1) to reduce the size of curves by limiting the distance of control points from anchor points. + * For example, z=.5 limits control points to half the distance of the closer adjacent anchor point. + * I put the option here, but I recommend sticking with .5 + * angleFactor:Number -Adjusts the size of curves depending on how acute the angle between points is. Curves are reduced as acuteness + * increases, and this factor controls by how much. + * 1 = curves are reduced in direct proportion to acuteness + * 0 = curves are not reduced at all based on acuteness + * in between = the reduction is basically a percentage of the full reduction + * moveTo:Bollean -Specifies whether to move to the first point in the curve rather than continuing drawing + * from wherever drawing left off. + * @return: + */ + public static function curveThroughPoints(g:Graphics, points:Array/*of Points*/, z:Number = .5, angleFactor:Number = .75, moveTo:Boolean = true):void{ + try { + var p:Array = points.slice(); // Local copy of points array + var duplicates:Array = new Array(); // Array to hold indices of duplicate points + // Check to make sure array contains only Points + for (var i:Number=0; i 0){ + if (p[i].x == p[i-1].x && p[i].y == p[i-1].y){ + duplicates.push(i); // add index of duplicate to duplicates array + } + } + } + // Loop through duplicates array and remove points from the points array + for (i=duplicates.length-1; i>=0; i--){ + p.splice(duplicates[i],1); + } + + // Make sure z is between 0 and 1 (too messy otherwise) + if (z <= 0){ + z = .5; + } else if (z > 1){ + z = 1; + } + // Make sure angleFactor is between 0 and 1 + if (angleFactor < 0){ + angleFactor = 0; + } else if (angleFactor > 1){ + angleFactor = 1; + } + + // + // First calculate all the curve control points + // + + // None of this junk will do any good if there are only two points + if (p.length > 2){ + // Ordinarily, curve calculations will start with the second point and go through the second-to-last point + var firstPt:Number = 1; + var lastPt:Number = p.length-1; + // Check if this is a closed line (the first and last points are the same) + if (p[0].x == p[p.length-1].x && p[0].y == p[p.length-1].y){ + // Include first and last points in curve calculations + firstPt = 0; + lastPt = p.length; + } + + var controlPts:Array = new Array(); // An array to store the two control points (of a cubic Bézier curve) for each point + // Loop through all the points (except the first and last if not a closed line) to get curve control points for each. + for (i=firstPt; i 1) cos = 1; + var C:Number = Math.acos(cos); // Angle formed by the two sides of the triangle (described by the three points above) adjacent to the current point + // Duplicate set of points. Start by giving previous and next points values RELATIVE to the current point. + var aPt:Point = new Point(p0.x-p1.x,p0.y-p1.y); + var bPt:Point = new Point(p1.x,p1.y); + var cPt:Point = new Point(p2.x-p1.x,p2.y-p1.y); + /* + We'll be adding adding the vectors from the previous and next points to the current point, + but we don't want differing magnitudes (i.e. line segment lengths) to affect the direction + of the new vector. Therefore we make sure the segments we use, based on the duplicate points + created above, are of equal length. The angle of the new vector will thus bisect angle C + (defined above) and the perpendicular to this is nice for the line tangent to the curve. + The curve control points will be along that tangent line. + */ + if (a > b){ + aPt.normalize(b); // Scale the segment to aPt (bPt to aPt) to the size of b (bPt to cPt) if b is shorter. + } else if (b > a){ + cPt.normalize(a); // Scale the segment to cPt (bPt to cPt) to the size of a (aPt to bPt) if a is shorter. + } + // Offset aPt and cPt by the current point to get them back to their absolute position. + aPt.offset(p1.x,p1.y); + cPt.offset(p1.x,p1.y); + // Get the sum of the two vectors, which is perpendicular to the line along which our curve control points will lie. + var ax:Number = bPt.x-aPt.x; // x component of the segment from previous to current point + var ay:Number = bPt.y-aPt.y; + var bx:Number = bPt.x-cPt.x; // x component of the segment from next to current point + var by:Number = bPt.y-cPt.y; + var rx:Number = ax + bx; // sum of x components + var ry:Number = ay + by; + // Correct for three points in a line by finding the angle between just two of them + if (rx == 0 && ry == 0){ + rx = -bx; // Really not sure why this seems to have to be negative + ry = by; + } + // Switch rx and ry when y or x difference is 0. This seems to prevent the angle from being perpendicular to what it should be. + if (ay == 0 && by == 0){ + rx = 0; + ry = 1; + } else if (ax == 0 && bx == 0){ + rx = 1; + ry = 0; + } + var r:Number = Math.sqrt(rx*rx+ry*ry); // length of the summed vector - not being used, but there it is anyway + var theta:Number = Math.atan2(ry,rx); // angle of the new vector + + var controlDist:Number = Math.min(a,b)*z; // Distance of curve control points from current point: a fraction the length of the shorter adjacent triangle side + var controlScaleFactor:Number = C/Math.PI; // Scale the distance based on the acuteness of the angle. Prevents big loops around long, sharp-angled triangles. + controlDist *= ((1-angleFactor) + angleFactor*controlScaleFactor); // Mess with this for some fine-tuning + var controlAngle:Number = theta+Math.PI/2; // The angle from the current point to control points: the new vector angle plus 90 degrees (tangent to the curve). + var controlPoint2:Point = Point.polar(controlDist,controlAngle); // Control point 2, curving to the next point. + var controlPoint1:Point = Point.polar(controlDist,controlAngle+Math.PI); // Control point 1, curving from the previous point (180 degrees away from control point 2). + // Offset control points to put them in the correct absolute position + controlPoint1.offset(p1.x,p1.y); + controlPoint2.offset(p1.x,p1.y); + /* + Haven't quite worked out how this happens, but some control points will be reversed. + In this case controlPoint2 will be farther from the next point than controlPoint1 is. + Check for that and switch them if it's true. + */ + if (Point.distance(controlPoint2,p2) > Point.distance(controlPoint1,p2)){ + controlPts[i] = new Array(controlPoint2,controlPoint1); // Add the two control points to the array in reverse order + } else { + controlPts[i] = new Array(controlPoint1,controlPoint2); // Otherwise add the two control points to the array in normal order + } + // Uncomment to draw lines showing where the control points are. + /* + g.moveTo(p1.x,p1.y); + g.lineTo(controlPoint2.x,controlPoint2.y); + g.moveTo(p1.x,p1.y); + g.lineTo(controlPoint1.x,controlPoint1.y); + */ + } + // + // Now draw the curve + // + // If moveTo condition is false, this curve can connect to a previous curve on the same graphics. + if (moveTo) g.moveTo(p[0].x, p[0].y); + else g.lineTo(p[0].x, p[0].y); + // If this isn't a closed line + if (firstPt == 1){ + // Draw a regular quadratic Bézier curve from the first to second points, using the first control point of the second point + g.curveTo(controlPts[1][0].x,controlPts[1][0].y,p[1].x,p[1].y); + } + var straightLines:Boolean = true; // Change to true if you want to use lineTo for straight lines of 3 or more points rather than curves. You'll get straight lines but possible sharp corners! + // Loop through points to draw cubic Bézier curves through the penultimate point, or through the last point if the line is closed. + for (i=firstPt;i 0 && Math.atan2(p[i].y-p[i-1].y,p[i].x-p[i-1].x) == Math.atan2(p[i+1].y-p[i].y,p[i+1].x-p[i].x) ) || ( i < p.length - 2 && Math.atan2(p[i+2].y-p[i+1].y,p[i+2].x-p[i+1].x) == Math.atan2(p[i+1].y-p[i].y,p[i+1].x-p[i].x) ) ); + if (straightLines && isStraight){ + g.lineTo(p[i+1].x,p[i+1].y); + } else { + // BezierSegment instance using the current point, its second control point, the next point's first control point, and the next point + var bezier:BezierSegment = new BezierSegment(p[i],controlPts[i][1],controlPts[i+1][0],p[i+1]); + // Construct the curve out of 100 segments (adjust number for less/more detail) + for (var t:Number=.01;t<1.01;t+=.01){ + var val:Object = bezier.getValue(t); // x,y on the curve for a given t + g.lineTo(val.x,val.y); + } + } + } + // If this isn't a closed line + if (lastPt == p.length-1){ + // Curve to the last point using the second control point of the penultimate point. + g.curveTo(controlPts[i][1].x,controlPts[i][1].y,p[i+1].x,p[i+1].y); + } + // just draw a line if only two points + } else if (p.length == 2){ + g.moveTo(p[0].x,p[0].y); + g.lineTo(p[1].x,p[1].y); + } + } + // Catch error + catch (e:Error) { + trace(e.getStackTrace()); + } + } + + } + +} \ No newline at end of file diff --git a/trunk/common-lib/src/main/flex/com/riameeting/controler/EventBus.as b/trunk/common-lib/src/main/flex/com/riameeting/controler/EventBus.as new file mode 100644 index 0000000..e31eb84 --- /dev/null +++ b/trunk/common-lib/src/main/flex/com/riameeting/controler/EventBus.as @@ -0,0 +1,38 @@ +package com.riameeting.controler +{ + import flash.events.EventDispatcher; + import flash.events.IEventDispatcher; + + /** + * 事件总线 + * + */ + public class EventBus + { + /** + * 事件派发器 + */ + public static var dispatcher:IEventDispatcher = new EventDispatcher(); + /** + * 添加事件侦听 + * @param eventType 事件类型 + * @param eventHandler 事件处理方法 + * + */ + public static function addEventListener(eventType:String,eventHandler:Function):void + { + dispatcher.addEventListener(eventType,eventHandler); + } + /** + * 删除事件侦听 + * @param eventType 事件类型 + * @param eventHandler 事件处理方法 + * + */ + public static function removeEventListener(eventType:String,eventHandler:Function):void + { + dispatcher.removeEventListener(eventType,eventHandler); + } + + } +} \ No newline at end of file diff --git a/trunk/common-lib/src/main/flex/com/riameeting/net/ResourceLoader.as b/trunk/common-lib/src/main/flex/com/riameeting/net/ResourceLoader.as new file mode 100644 index 0000000..774aeed --- /dev/null +++ b/trunk/common-lib/src/main/flex/com/riameeting/net/ResourceLoader.as @@ -0,0 +1,87 @@ +package com.riameeting.net +{ + import com.riameeting.ui.control.Alert; + + import flash.display.Loader; + import flash.events.Event; + import flash.events.EventDispatcher; + import flash.events.IEventDispatcher; + import flash.events.IOErrorEvent; + import flash.net.URLLoader; + import flash.net.URLLoaderDataFormat; + import flash.net.URLRequest; + import flash.utils.Dictionary; + + /** + * 资源加载类 + * @author Finger + * + */ + public class ResourceLoader + { + private var callBackFunc:Function; + private var assetsArr:Array; + /** + * 资源哈希表 + */ + public var fileDict:Dictionary = new Dictionary(); + /** + * 加载资源 + * @param assets 资源地址列表 + * @param callBack 回调 + * + */ + public function loadAssets(assets:Array,callBack:Function):void { + callBackFunc = callBack; + assetsArr = assets; + for each(var url:String in assets) { + var loader:URLLoader = new URLLoader(); + if(getFileExtension(url) == "swf") { + loader.dataFormat = URLLoaderDataFormat.BINARY; + } + loader.addEventListener(Event.COMPLETE,completeHandler); + loader.addEventListener(IOErrorEvent.IO_ERROR,ioErrorHandler); + loader.load(new URLRequest(url)); + fileDict[loader] = url; + } + } + /** + * 获取文件扩展名 + * @param fileName + * @return + * + */ + public function getFileExtension(fileName:String):String { + var dotSpitArr:Array = fileName.split("."); + return dotSpitArr[dotSpitArr.length-1]; + } + /** + * 加载成功 + * @param e + * + */ + private function completeHandler(e:Event):void { + var url:String = fileDict[e.currentTarget]; + fileDict[url] = e.currentTarget.data; + checkStatus(); + } + /** + * 加载失败 + * @param e + * + */ + private function ioErrorHandler(e:IOErrorEvent):void { + Alert.show(e.toString(),"IOError"); + } + /** + * 检查整体加载状况 + * + */ + private function checkStatus():void { + for each(var url:String in assetsArr) { + if(fileDict[url] == null) return; + } + callBackFunc.apply(); + } + } +} \ No newline at end of file diff --git a/trunk/common-lib/src/main/flex/com/riameeting/ui/control/Alert.as b/trunk/common-lib/src/main/flex/com/riameeting/ui/control/Alert.as new file mode 100644 index 0000000..f158163 --- /dev/null +++ b/trunk/common-lib/src/main/flex/com/riameeting/ui/control/Alert.as @@ -0,0 +1,117 @@ +package com.riameeting.ui.control +{ + import flash.display.Sprite; + import flash.events.MouseEvent; + /** + * 弹出信息显示类 + * @author Finger + * + */ + public class Alert + { + /** + * 弹出窗口的父层容器 + */ + public static var container:Sprite; + /** + * 窗体 + */ + private static var window:Window; + /** + * 显示信息 + * @param value 要显示的字符串 + * @param title 要显示的标题 + * + */ + public static function show(value:String,title:String="alert"):void + { + if(container == null) { + throw new Error("Alert.container not allow null"); + } + if(window == null) { + window = new Window(); + window.closeButton.addEventListener(MouseEvent.CLICK,hide); + window.addEventListener(MouseEvent.MOUSE_DOWN,startMove); + window.addEventListener(MouseEvent.MOUSE_UP,stopMove); + } + container.addChild(window); + window.title = title; + window.text = value; + window.x = (container.stage.stageWidth-window.width)/2; + window.y = (container.stage.stageHeight-window.height)/2; + function startMove(e:MouseEvent):void { + window.startDrag(); + } + function stopMove(e:MouseEvent):void { + window.stopDrag(); + } + } + /** + * 隐藏信息 + * @param e + * + */ + public static function hide(e:MouseEvent=null):void + { + container.removeChild(window); + } + } +} +import com.riameeting.ui.control.Button; + +import flash.display.Sprite; +import flash.text.TextField; +import flash.text.TextFieldAutoSize; + +/** + * 窗体类 + * + */ +class Window extends Sprite { + private var titleField:TextField = new TextField(); + private var txtField:TextField = new TextField(); + public var closeButton:Button = new Button(); + public function Window() + { + buttonMode = true; + txtField.width = 200; + titleField.width = 200; + txtField.mouseEnabled = false; + titleField.mouseEnabled = false; + txtField.y = 20; + txtField.autoSize = TextFieldAutoSize.LEFT; + txtField.wordWrap = true; + addChild(txtField); + addChild(titleField); + addChild(closeButton); + closeButton.x = 100-closeButton.width/2; + closeButton.label = "Close"; + } + /** + * 设置标题显示 + * @param value + * + */ + public function set title(value:String):void { + titleField.htmlText = ""+value+""; + } + /** + * 设置文本内容显示 + * @param value + * + */ + public function set text(value:String):void { + txtField.htmlText = ""+value+""; + txtField.height = txtField.textHeight + 5; + closeButton.y = txtField.y + txtField.height; + graphics.clear(); + graphics.lineStyle(3,0xFF0000,1); + graphics.beginFill(0xFF0000,1); + graphics.drawRoundRect(0,0,200,24,4,4); + graphics.endFill(); + graphics.beginFill(0x000000,1); + graphics.drawRoundRect(0,20,200,txtField.height+closeButton.height+4,4,4); + graphics.endFill(); + } + +} \ No newline at end of file diff --git a/trunk/common-lib/src/main/flex/com/riameeting/ui/control/Button.as b/trunk/common-lib/src/main/flex/com/riameeting/ui/control/Button.as new file mode 100644 index 0000000..bfc4ab5 --- /dev/null +++ b/trunk/common-lib/src/main/flex/com/riameeting/ui/control/Button.as @@ -0,0 +1,43 @@ +package com.riameeting.ui.control +{ + import flash.display.Sprite; + /** + * 一个轻量级的按钮组件 + * @author Finger + * + */ + public class Button extends Sprite + { + private var _label:String; + /** + * 文本显示 + */ + protected var labelDisplay:Label = new Label(); + /** + * 构造方法 + * + */ + public function Button() + { + labelDisplay.color = 0xFFFFFF; + addChild(labelDisplay); + } + /** + * 设置文本显示 + * @return + * + */ + public function get label():String { + return _label; + } + public function set label(value:String):void { + _label = value; + labelDisplay.text = value; + this.graphics.clear(); + this.graphics.beginFill(0x333333,0.8); + this.graphics.drawRoundRect(-2,-2,labelDisplay.width+4,labelDisplay.height+4,4,4); + this.graphics.endFill(); + } + + } +} \ No newline at end of file diff --git a/trunk/common-lib/src/main/flex/com/riameeting/ui/control/CheckBox.as b/trunk/common-lib/src/main/flex/com/riameeting/ui/control/CheckBox.as new file mode 100644 index 0000000..a1d5c36 --- /dev/null +++ b/trunk/common-lib/src/main/flex/com/riameeting/ui/control/CheckBox.as @@ -0,0 +1,79 @@ +package com.riameeting.ui.control +{ + import flash.display.Sprite; + import flash.events.MouseEvent; + /** + * 复选框类 + * @author Finger + * + */ + public class CheckBox extends Sprite + { + private var _selected:Boolean; + private var icon:Sprite = new Sprite(); + private var _label:String; + /** + * 文本显示 + */ + protected var labelDisplay:Label = new Label(); + /** + * 标记复选框的选择状态 + * @return 布尔量 + * + */ + public function get selected():Boolean{return _selected;} + public function set selected(value:Boolean):void + { + _selected = value; + if(_selected) { + icon.graphics.beginFill(0x000000,1); + icon.graphics.drawRect(2,2,11,11); + icon.graphics.endFill(); + } else { + icon.graphics.clear(); + } + } + + /** + * 构造方法 + * + */ + public function CheckBox() + { + super(); + buttonMode = true; + mouseChildren = false; + graphics.lineStyle(1,0xCCCCCC,1); + graphics.beginFill(0xFFFFFF,1); + graphics.drawRect(2,2,14,14); + graphics.endFill(); + addChild(icon); + icon.x = 2; + icon.y = 2; + addEventListener(MouseEvent.CLICK,checkStatus); + labelDisplay.x = 20; + addChild(labelDisplay); + } + /** + * 检查状态 + * @param e + * + */ + protected function checkStatus(e:MouseEvent):void { + selected = !selected; + } + /** + * 设置文本显示 + * @return + * + */ + public function get label():String { + return _label; + } + public function set label(value:String):void { + _label = value; + labelDisplay.text = value; + } + + } +} \ No newline at end of file diff --git a/trunk/common-lib/src/main/flex/com/riameeting/ui/control/GraphicLabel.as b/trunk/common-lib/src/main/flex/com/riameeting/ui/control/GraphicLabel.as new file mode 100644 index 0000000..bdf77f7 --- /dev/null +++ b/trunk/common-lib/src/main/flex/com/riameeting/ui/control/GraphicLabel.as @@ -0,0 +1,49 @@ +package com.riameeting.ui.control +{ + import flash.text.TextField; + + import com.riameeting.utils.ColorUtils; + /** + * 带左侧图形显示的标签 + * @author Finger + * + */ + public class GraphicLabel extends Label + { + /** + * 构造方法 + * @param htmlMode html模式 + * @param lineColor 图形颜色 + * @param mode 图形模式 + * @param number 如果模式是数字,则传入此值 + * + */ + public function GraphicLabel(htmlMode:Boolean=false,lineColor:uint=0x000000,mode:String="line",number:uint=0) + { + super(htmlMode); + innerTxt.x = 20; + graphics.beginFill(lineColor,1); + switch(mode) { + case "line": + graphics.drawRect(0,8,15,4); + break; + case "double": + graphics.drawRect(0,8,15,2); + graphics.endFill(); + graphics.beginFill(ColorUtils.fadeColor(lineColor,0xFFFFFF,0.4),1); + graphics.drawRect(0,10,15,2); + break; + case "rect": + graphics.drawRect(0,2,14,14); + break; + case "number": + var numerTxt:Label = new Label(false); + numerTxt.color = lineColor; + numerTxt.text = number+""; + addChild(numerTxt); + break; + } + graphics.endFill(); + } + } +} \ No newline at end of file diff --git a/trunk/common-lib/src/main/flex/com/riameeting/ui/control/Label.as b/trunk/common-lib/src/main/flex/com/riameeting/ui/control/Label.as new file mode 100644 index 0000000..7157c0b --- /dev/null +++ b/trunk/common-lib/src/main/flex/com/riameeting/ui/control/Label.as @@ -0,0 +1,85 @@ +package com.riameeting.ui.control +{ + import com.riameeting.utils.DPIReset; + + import flash.display.Sprite; + import flash.text.Font; + import flash.text.TextField; + import flash.text.TextFormat; + + /** + * 文本标签,对TextTield的简单封装 + * @author Finger + * + */ + public class Label extends Sprite + { + /** + * 内部的TextField对象 + */ + protected var innerTxt:TextField; + private var _text:String; + private var _color:uint; + /** + * 是否采用HTML方式显示文本 + */ + public var htmlMode:Boolean; + /** + * 要显示的文本 + * @return 文本 + * + */ + public function get text():String{return _text;} + public function set text(value:String):void + { + _text = value; + if(htmlMode) { + innerTxt.htmlText = _text; + } else { + innerTxt.text = _text; + } + innerTxt.width = innerTxt.textWidth + 4; + innerTxt.height = innerTxt.textHeight + 4; + } + /** + * 文本颜色 + * @return 颜色值 + * + */ + public function get color():uint{return _color;} + public function set color(value:uint):void{_color = value;innerTxt.textColor = value;} + /** + * 构造方法 + * @param htmlMode 是否启用HTML显示模式 + * + */ + public function Label(htmlMode:Boolean=false) + { + this.htmlMode = htmlMode; + innerTxt = new TextField(); + innerTxt.width = innerTxt.height = 20; + innerTxt.selectable = false; + innerTxt.mouseEnabled = false; + var tf:TextFormat = new TextFormat(); + tf.size = DPIReset.getNumber(20); + for each(var f:* in Font.enumerateFonts()) { + tf.font = f.fontName; + innerTxt.embedFonts = true; + } + innerTxt.defaultTextFormat = tf; + addChild(innerTxt); + } + /** + * 执行清理动作 + * + */ + public function clear():void { + color = 0x000000; + text = ""; + x = y = 0; + name = ""; + visible = true; + } + + } +} \ No newline at end of file diff --git a/trunk/common-lib/src/main/flex/com/riameeting/utils/ArrayUtils.as b/trunk/common-lib/src/main/flex/com/riameeting/utils/ArrayUtils.as new file mode 100644 index 0000000..c0cd3e9 --- /dev/null +++ b/trunk/common-lib/src/main/flex/com/riameeting/utils/ArrayUtils.as @@ -0,0 +1,32 @@ +package com.riameeting.utils +{ + public class ArrayUtils + { + /** + * 将Array自身的数据扩展N倍 + * @param source + * @param num + * @return + * + */ + public static function extendArrayByClone(source:Array,num:int):Array { + var extendArray:Array = []; + for(var i:uint=0;i> 16; + var g:uint = startColor >> 8 & 0xFF; + var b:uint = startColor & 0xFF; + r += ((endColor >> 16) - r) * position; + g += ((endColor >> 8 & 0xFF) - g) * position; + b += ((endColor & 0xFF) - b) * position; + return (r << 16 | g << 8 | b); + } + /** + * 将色值转换为WEB色值 + * @param color + * @return + * + */ + public static function toWebColor(color:uint):String { + var colorStr:String = color.toString(16); + return "#"+colorStr; + } + + } + +} \ No newline at end of file diff --git a/trunk/common-lib/src/main/flex/com/riameeting/utils/DPIReset.as b/trunk/common-lib/src/main/flex/com/riameeting/utils/DPIReset.as new file mode 100644 index 0000000..b057164 --- /dev/null +++ b/trunk/common-lib/src/main/flex/com/riameeting/utils/DPIReset.as @@ -0,0 +1,35 @@ +package com.riameeting.utils +{ + import flash.system.Capabilities; + /** + * got number via DPI refect + * @author RIADEV + * + */ + public class DPIReset + { + public static var applicationDPI:Number = 240; + + public static function getNumber(value:Number):Number + { + var dpi:Number = getRuntimeDPI(); + return value*(dpi/applicationDPI); + } + + public static function getRuntimeDPI():Number + { + // Arbitrary mapping for Mac OS. + if (Capabilities.os == "Mac OS 10.6.5") + return 320; + + if (Capabilities.screenDPI < 200) + return 160; + + if (Capabilities.screenDPI <= 280) + return 240; + + return 320; + } + + } +} \ No newline at end of file diff --git a/trunk/common-lib/src/main/flex/com/riameeting/utils/DrawTool.as b/trunk/common-lib/src/main/flex/com/riameeting/utils/DrawTool.as new file mode 100644 index 0000000..f6a4583 --- /dev/null +++ b/trunk/common-lib/src/main/flex/com/riameeting/utils/DrawTool.as @@ -0,0 +1,109 @@ +package com.riameeting.utils +{ + import flash.display.GradientType; + import flash.display.Graphics; + import flash.geom.Matrix; + import flash.geom.Point; + + /** + * 绘图工具 + * @author Finger + * + */ + public class DrawTool + { + /** + * 绘制一条虚线 + * @param graphics 进行绘制的容器 + * @param startX 起始X坐标 + * @param startY 起始Y坐标 + * @param endX 结束X坐标 + * @param endY 结束Y坐标 + * @param dotLength 虚线线段长度 + * + */ + public static function dotLineTo(graphics:Graphics,startX:Number,startY:Number,endX:Number,endY:Number,dotLength:uint=4):void + { + graphics.moveTo(startX,startY); + var offsetX:Number = endX - startX; + var offsetY:Number = endY - startY; + var lineWidth:Number = Math.sqrt(offsetX*offsetX+offsetY*offsetY); + var count:uint = lineWidth/dotLength; + offsetX = offsetX/count; + offsetY = offsetY/count; + var targetX:Number,targetY:Number; + for(var i:uint=0;i<=count;i++) { + targetX = startX+i*offsetX; + targetY = startY+i*offsetY; + if(i%2==0) { + graphics.lineTo(targetX,targetY); + } else { + graphics.moveTo(targetX,targetY); + } + } + } + /** + * 绘制一个扇形或环形 + * @param graphics 进行绘制的容器 + * @param point 圆心点坐标 + * @param radius 半径 + * @param beginAngle 起始角度 + * @param angle 角度 + * @param lineColor 线条颜色 + * @param lineWidth 线条宽度 + * @param lineAlpha 线条透明度 + * @param color 图形颜色 + * @param innerRadius 环形半径 + * @return 中心点的坐标 + * + */ + public static function drawSector(graphics:Graphics,point:Point,radius:Number,beginAngle:Number,angle:Number,lineColor:uint,lineWidth:uint,lineAlpha:Number,color:uint,innerRadius:uint=50):Point { + graphics.clear(); + var centerPoint:Point; + var sx:Number = radius,sxInner:Number = innerRadius; + var sy:Number = 0,syInner:Number = 0; + if (beginAngle != 0) { + sx = Math.cos(beginAngle * Math.PI/180) * radius; + sy = Math.sin(beginAngle * Math.PI/180) * radius; + sxInner = Math.cos(beginAngle * Math.PI/180) * innerRadius; + syInner = Math.sin(beginAngle * Math.PI/180) * innerRadius; + } + graphics.lineStyle(lineWidth,lineColor,lineAlpha); + //graphics.beginFill(color); + var matix:Matrix =new Matrix(); + matix.createGradientBox(radius*2, radius*2, 0, -radius, -radius); + graphics.beginGradientFill(GradientType.RADIAL,[ColorUtils.fadeColor(color,0xFFFFFF,0.2),ColorUtils.fadeColor(color,0x000000,0.2)],[1,1],[0x00,0xFF],matix); + graphics.moveTo(point.x + sxInner, point.y + syInner); + graphics.lineTo(point.x + sx, point.y +sy); + var rad:Number = angle * Math.PI / 180 / angle; + var cos:Number = Math.cos(rad); + var sin:Number = Math.sin(rad); + var i:uint,nx:Number,ny:Number,nxInner:Number,nyInner:Number; + for (i=0; i 0 ? valueString.charAt(0):valueString.charAt(1)); + if(value > 0) { + leftPat++; + } else { + leftPat--; + } + var valueLength:Number = value > 0 ? valueString.length:valueString.length-1; + for(var i:uint=1;i 0 ? leftPat:-leftPat); + return returnNum; + } + /** + * 获取离原值最接近的最小值 + * @param value 原值 + * @return 最大值 + * + */ + public static function getMinNumber(value:Number):Number + { + var returnNum:Number; + var valueString:String = value.toString().split(".")[0]; + var leftPat:Number = Number(value > 0 ? valueString.charAt(0):valueString.charAt(1)); + if(value > 0) { + leftPat--; + } else { + leftPat++; + } + var valueLength:Number = value > 0 ? valueString.length:valueString.length-1; + for(var i:uint=1;i 0 ? leftPat:-leftPat); + return returnNum; + } + /** + * 获取两点之间的距离 + * @param point1 点1 + * @param point2 点2 + * @return 距离 + * + */ + public static function getPointDistance(point1:Point,point2:Point):Number + { + var offsetX:Number = Math.abs(point1.x - point2.x); + var offsetY:Number = Math.abs(point1.y - point2.y); + var distance:Number = Math.sqrt(offsetX*offsetX+offsetY*offsetY); + return distance; + } + + } +} \ No newline at end of file diff --git a/trunk/common-lib/src/main/flex/com/riameeting/utils/ObjectUtils.as b/trunk/common-lib/src/main/flex/com/riameeting/utils/ObjectUtils.as new file mode 100644 index 0000000..d62a623 --- /dev/null +++ b/trunk/common-lib/src/main/flex/com/riameeting/utils/ObjectUtils.as @@ -0,0 +1,29 @@ +package com.riameeting.utils +{ + /** + * 对象工具类 + * @author Finger + * + */ + public class ObjectUtils + { + /** + * 合并两个对象的属性到一个新对象 + * @param obj1 + * @param obj2 + * @return + * + */ + public static function mergePromps(obj1:Object,obj2:Object):Object { + var newObj:Object = new Object(); + var name:String; + for(name in obj2) { + newObj[name] = obj2[name]; + } + for(name in obj1) { + newObj[name] = obj1[name]; + } + return newObj; + } + } +} \ No newline at end of file diff --git a/trunk/common-lib/src/main/flex/com/riameeting/utils/StringUtils.as b/trunk/common-lib/src/main/flex/com/riameeting/utils/StringUtils.as new file mode 100644 index 0000000..2617f33 --- /dev/null +++ b/trunk/common-lib/src/main/flex/com/riameeting/utils/StringUtils.as @@ -0,0 +1,45 @@ +package com.riameeting.utils +{ + /** + * 字符串工具类 + */ + public class StringUtils { + /** + * 删除字符串两端的空格 + * @param str + * @return + * + */ + public static function trim(str:String):String { + var strRep:String = str.replace(/^\s*/, ""); + strRep = strRep.replace(/\s*$/, ""); + return strRep; + } + /** + * 将字符串转换成为标准变量命名格式,比如:bgColor + * @param str + * @return + * + */ + public static function toCamelCase(str:String):String { + str = str.replace("-", " "); + str = toProperCase(str).replace(" ", ""); + function capsFn():String { + return arguments[0].toLowerCase(); + } + return str.replace(/\b\w/g, capsFn); + } + /** + * 将字符串单词的首字母转换为大写格式 + * @param str + * @return + * + */ + public static function toProperCase(str:String):String { + function capsFn():String { + return arguments[0].toUpperCase(); + } + return str.toLowerCase().replace(/^[a-z\xE0-\xFF]|\s[a-z\xE0-\xFF]/g, capsFn); //replaces first letter of each word + } + } +} \ No newline at end of file diff --git a/trunk/common-lib/src/main/flex/fl/motion/BezierSegment.as b/trunk/common-lib/src/main/flex/fl/motion/BezierSegment.as new file mode 100644 index 0000000..d55eada --- /dev/null +++ b/trunk/common-lib/src/main/flex/fl/motion/BezierSegment.as @@ -0,0 +1,374 @@ +// Copyright � 2007. Adobe Systems Incorporated. All Rights Reserved. +package fl.motion +{ +import flash.geom.Point; + +/** + * A Bezier segment consists of four Point objects that define a single cubic Bezier curve. + * The BezierSegment class also contains methods to find coordinate values along the curve. + * @playerversion Flash 9.0.28.0 + * @playerversion AIR 1.0 + * @productversion Flash CS3 + * @langversion 3.0 + * @keyword BezierSegment, Copy Motion as ActionScript + * @see ../../motionXSD.html Motion XML Elements + */ +public class BezierSegment +{ + /** + * The first point of the Bezier curve. + * It is a node, which means it falls directly on the curve. + * @playerversion Flash 9.0.28.0 + * @playerversion AIR 1.0 + * @productversion Flash CS3 + * @langversion 3.0 + * @keyword Bezier curve, node, Copy Motion as ActionScript + */ + public var a:Point; + + + /** + * The second point of the Bezier curve. + * It is a control point, which means the curve moves toward it, + * but usually does not pass through it. + * @playerversion Flash 9.0.28.0 + * @playerversion AIR 1.0 + * @productversion Flash CS3 + * @langversion 3.0 + * @keyword Bezier curve, node, Copy Motion as ActionScript + */ + public var b:Point; + + + /** + * The third point of the Bezier curve. + * It is a control point, which means the curve moves toward it, + * but usually does not pass through it. + * @playerversion Flash 9.0.28.0 + * @playerversion AIR 1.0 + * @productversion Flash CS3 + * @langversion 3.0 + * @keyword Bezier curve, node, Copy Motion as ActionScript + */ + public var c:Point; + + + /** + * The fourth point of the Bezier curve. + * It is a node, which means it falls directly on the curve. + * @playerversion Flash 9.0.28.0 + * @playerversion AIR 1.0 + * @productversion Flash CS3 + * @langversion 3.0 + * @keyword Bezier curve, node, Copy Motion as ActionScript + */ + public var d:Point; + + + /** + * Constructor for BezierSegment instances. + * + * @param a The first point of the curve, a node. + * + * @param b The second point of the curve, a control point. + * + * @param c The third point of the curve, a control point. + * + * @param d The fourth point of the curve, a node. + * @playerversion Flash 9.0.28.0 + * @playerversion AIR 1.0 + * @productversion Flash CS3 + * @langversion 3.0 + * @keyword Bezier curve, node, Copy Motion as ActionScript + * @see #propertyDetail property details + */ + function BezierSegment(a:Point, b:Point, c:Point, d:Point) + { + this.a = a; + this.b = b; + this.c = c; + this.d = d; + } + + + /** + * Calculates the location of a two-dimensional cubic Bezier curve at a specific time. + * + * @param t The time or degree of progress along the curve, as a decimal value between 0 and 1. + *

Note: The t parameter does not necessarily move along the curve at a uniform speed. For example, a t value of 0.5 does not always produce a value halfway along the curve.

+ * + * @return A point object containing the x and y coordinates of the Bezier curve at the specified time. + * @playerversion Flash 9.0.28.0 + * @playerversion AIR 1.0 + * @productversion Flash CS3 + * @langversion 3.0 + * @keyword Bezier curve, node, Copy Motion as ActionScript + */ + public function getValue(t:Number):Point + { + var ax:Number = this.a.x; + var x:Number = (t*t*(this.d.x-ax) + 3*(1-t)*(t*(this.c.x-ax) + (1-t)*(this.b.x-ax)))*t + ax; + var ay:Number = this.a.y; + var y:Number = (t*t*(this.d.y-ay) + 3*(1-t)*(t*(this.c.y-ay) + (1-t)*(this.b.y-ay)))*t + ay; + return new Point(x, y); + } + + + /** + * Calculates the value of a one-dimensional cubic Bezier equation at a specific time. + * By contrast, a Bezier curve is usually two-dimensional + * and uses two of these equations, one for the x coordinate and one for the y coordinate. + * + * @param t The time or degree of progress along the curve, as a decimal value between 0 and 1. + *

Note: The t parameter does not necessarily move along the curve at a uniform speed. For example, a t value of 0.5 does not always produce a value halfway along the curve.

+ * + * @param a The first value of the Bezier equation. + * + * @param b The second value of the Bezier equation. + * + * @param c The third value of the Bezier equation. + * + * @param d The fourth value of the Bezier equation. + * + * @return The value of the Bezier equation at the specified time. + * @playerversion Flash 9.0.28.0 + * @playerversion AIR 1.0 + * @productversion Flash CS3 + * @langversion 3.0 + * @keyword Bezier curve, node, Copy Motion as ActionScript + */ + public static function getSingleValue(t:Number, a:Number=0, b:Number=0, c:Number=0, d:Number=0):Number + { + return (t*t*(d-a) + 3*(1-t)*(t*(c-a) + (1-t)*(b-a)))*t + a; + } + + + /** + * Finds the y value of a cubic Bezier curve at a given x coordinate. + * Some Bezier curves overlap themselves horizontally, + * resulting in more than one y value for a given x value. + * In that case, this method will return whichever value is most logical. + * + * Used by CustomEase and BezierEase interpolation. + * + * @param x An x coordinate that lies between the first and last point, inclusive. + * + * @param coefficients An optional array of number values that represent the polynomial + * coefficients for the Bezier. This array can be used to optimize performance by precalculating + * values that are the same everywhere on the curve and do not need to be recalculated for each iteration. + * + * @return The y value of the cubic Bezier curve at the given x coordinate. + * @playerversion Flash 9.0.28.0 + * @playerversion AIR 1.0 + * @productversion Flash CS3 + * @langversion 3.0 + * @keyword Bezier curve, Copy Motion as ActionScript + */ + public function getYForX(x:Number, coefficients:Array=null):Number + { + // Clamp to range between end points. + // The padding with the small decimal value is necessary to avoid bugs + // that result from reaching the limits of decimal precision in calculations. + // We have tests that demonstrate this. + if (this.a.x < this.d.x) + { + if (x <= this.a.x+0.0000000000000001) return this.a.y; + if (x >= this.d.x-0.0000000000000001) return this.d.y; + } + else + { + if (x >= this.a.x+0.0000000000000001) return this.a.y; + if (x <= this.d.x-0.0000000000000001) return this.d.y; + } + + if (!coefficients) + { + coefficients = getCubicCoefficients(this.a.x, this.b.x, this.c.x, this.d.x); + } + + // x(t) = a*t^3 + b*t^2 + c*t + d + var roots:Array = getCubicRoots(coefficients[0], coefficients[1], coefficients[2], coefficients[3]-x); + var time:Number = NaN; + if (roots.length == 0) + time = 0; + else if (roots.length == 1) + time = roots[0]; + else + { + for each (var root:Number in roots) + { + if (0 <= root && root <= 1) + { + time = root; + break; + } + } + } + + if (isNaN(time)) + return NaN; + + var y:Number = getSingleValue(time, this.a.y, this.b.y, this.c.y, this.d.y); + return y; + } + + + + + /** + * Calculates the coefficients for a cubic polynomial equation, + * given the values of the corresponding cubic Bezier equation. + * + * @param a The first value of the Bezier equation. + * + * @param b The second value of the Bezier equation. + * + * @param c The third value of the Bezier equation. + * + * @param d The fourth value of the Bezier equation. + * + * @return An array containing four number values, + * which are the coefficients for a cubic polynomial. + * The coefficients are ordered from the highest degree to the lowest, + * so the first number in the array would be multiplied by t^3, the second by t^2, and so on. + * + * @playerversion Flash 9.0.28.0 + * @playerversion AIR 1.0 + * @productversion Flash CS3 + * @langversion 3.0 + * @keyword Bezier curve, node, Copy Motion as ActionScript + * @see #getCubicRoots() + */ + public static function getCubicCoefficients(a:Number, b:Number, c:Number, d:Number):Array + { + return [ -a + 3*b - 3*c + d, + 3*a - 6*b + 3*c, + -3*a + 3*b, + a]; + } + + + /** + * Finds the real solutions, if they exist, to a cubic polynomial equation of the form: at^3 + bt^2 + ct + d. + * This method is used to evaluate custom easing curves. + * + * @param a The first coefficient of the cubic equation, which is multiplied by the cubed variable (t^3). + * + * @param b The second coefficient of the cubic equation, which is multiplied by the squared variable (t^2). + * + * @param c The third coefficient of the cubic equation, which is multiplied by the linear variable (t). + * + * @param d The fourth coefficient of the cubic equation, which is the constant. + * + * @return An array of number values, indicating the real roots of the equation. + * There may be no roots, or as many as three. + * Imaginary or complex roots are ignored. + * @playerversion Flash 9.0.28.0 + * @playerversion AIR 1.0 + * @productversion Flash CS3 + * @langversion 3.0 + * @keyword Bezier curve, node, Copy Motion as ActionScript + */ + public static function getCubicRoots(a:Number=0, b:Number=0, c:Number=0, d:Number=0):Array + { + // make sure we really have a cubic + if (!a) return BezierSegment.getQuadraticRoots(b, c, d); + + // normalize the coefficients so the cubed term is 1 and we can ignore it hereafter + if (a != 1) + { + b/=a; + c/=a; + d/=a; + } + + var q:Number = (b*b - 3*c)/9; // won't change over course of curve + var qCubed:Number = q*q*q; // won't change over course of curve + var r:Number = (2*b*b*b - 9*b*c + 27*d)/54; // will change because d changes + // but parts with b and c won't change + // determine if there are 1 or 3 real roots using r and q + var diff:Number = qCubed - r*r; // will change + if (diff >= 0) + { + // avoid division by zero + if (!q) return [0]; + // three real roots + var theta:Number = Math.acos(r/Math.sqrt(qCubed)); // will change because r changes + var qSqrt:Number = Math.sqrt(q); // won't change + + var root1:Number = -2*qSqrt * Math.cos(theta/3) - b/3; + var root2:Number = -2*qSqrt * Math.cos((theta + 2*Math.PI)/3) - b/3; + var root3:Number = -2*qSqrt * Math.cos((theta + 4*Math.PI)/3) - b/3; + + return [root1, root2, root3]; + } + else + { + // one real root + var tmp:Number = Math.pow( Math.sqrt(-diff) + Math.abs(r), 1/3); + var rSign:int = (r > 0) ? 1 : r < 0 ? -1 : 0; + var root:Number = -rSign * (tmp + q/tmp) - b/3; + return [root]; + } + return []; + } + + + /** + * Finds the real solutions, if they exist, to a quadratic equation of the form: at^2 + bt + c. + * + * @param a The first coefficient of the quadratic equation, which is multiplied by the squared variable (t^2). + * + * @param b The second coefficient of the quadratic equation, which is multiplied by the linear variable (t). + * + * @param c The third coefficient of the quadratic equation, which is the constant. + * + * @return An array of number values, indicating the real roots of the equation. + * There may be no roots, or as many as two. + * Imaginary or complex roots are ignored. + * @playerversion Flash 9.0.28.0 + * @playerversion AIR 1.0 + * @productversion Flash CS3 + * @langversion 3.0 + * @keyword Bezier curve, node, Copy Motion as ActionScript + */ + public static function getQuadraticRoots(a:Number, b:Number, c:Number):Array + { + var roots:Array = []; + // make sure we have a quadratic + if (!a) + { + if (!b) return []; + roots[0] = -c/b; + return roots; + } + + var q:Number = b*b - 4*a*c; + var signQ:int = + (q > 0) ? 1 + : q < 0 ? -1 + : 0; + + if (signQ < 0) + { + return []; + } + else if (!signQ) + { + roots[0] = -b/(2*a); + } + else + { + roots[0] = roots[1] = -b/(2*a); + var tmp:Number = Math.sqrt(q)/(2*a); + roots[0] -= tmp; + roots[1] += tmp; + } + + return roots; + } + + + +} +} diff --git a/trunk/docs/FingerChart.pdf b/trunk/docs/FingerChart.pdf new file mode 100644 index 0000000..80c234c Binary files /dev/null and b/trunk/docs/FingerChart.pdf differ diff --git a/trunk/docs/FingerChart.pptx b/trunk/docs/FingerChart.pptx new file mode 100644 index 0000000..9872464 Binary files /dev/null and b/trunk/docs/FingerChart.pptx differ diff --git a/trunk/docs/features.docx b/trunk/docs/features.docx new file mode 100644 index 0000000..9102176 Binary files /dev/null and b/trunk/docs/features.docx differ diff --git a/trunk/docs/finger-chart-intro.pptx b/trunk/docs/finger-chart-intro.pptx new file mode 100644 index 0000000..c843f12 Binary files /dev/null and b/trunk/docs/finger-chart-intro.pptx differ diff --git a/trunk/docs/photos/IMGP2762.JPG b/trunk/docs/photos/IMGP2762.JPG new file mode 100644 index 0000000..e7f7ad0 Binary files /dev/null and b/trunk/docs/photos/IMGP2762.JPG differ diff --git a/trunk/docs/photos/IMGP2763.JPG b/trunk/docs/photos/IMGP2763.JPG new file mode 100644 index 0000000..dd233fe Binary files /dev/null and b/trunk/docs/photos/IMGP2763.JPG differ diff --git a/trunk/docs/photos/IMGP2764.JPG b/trunk/docs/photos/IMGP2764.JPG new file mode 100644 index 0000000..25df73d Binary files /dev/null and b/trunk/docs/photos/IMGP2764.JPG differ diff --git a/trunk/docs/photos/IMGP2765.JPG b/trunk/docs/photos/IMGP2765.JPG new file mode 100644 index 0000000..f4e8d6c Binary files /dev/null and b/trunk/docs/photos/IMGP2765.JPG differ diff --git a/trunk/docs/photos/IMGP2766.JPG b/trunk/docs/photos/IMGP2766.JPG new file mode 100644 index 0000000..d7c9de6 Binary files /dev/null and b/trunk/docs/photos/IMGP2766.JPG differ diff --git a/trunk/docs/photos/IMGP2767.JPG b/trunk/docs/photos/IMGP2767.JPG new file mode 100644 index 0000000..12ae036 Binary files /dev/null and b/trunk/docs/photos/IMGP2767.JPG differ diff --git a/trunk/docs/uml.pptx b/trunk/docs/uml.pptx new file mode 100644 index 0000000..9795918 Binary files /dev/null and b/trunk/docs/uml.pptx differ diff --git a/trunk/finger-chart-core-lib/libs/TweenLiteLib.swc b/trunk/finger-chart-core-lib/libs/TweenLiteLib.swc new file mode 100644 index 0000000..b21c0ae Binary files /dev/null and b/trunk/finger-chart-core-lib/libs/TweenLiteLib.swc differ diff --git a/trunk/finger-chart-core-lib/libs/as3corelib.swc b/trunk/finger-chart-core-lib/libs/as3corelib.swc new file mode 100644 index 0000000..12dd6b3 Binary files /dev/null and b/trunk/finger-chart-core-lib/libs/as3corelib.swc differ diff --git a/trunk/finger-chart-core-lib/pom.xml b/trunk/finger-chart-core-lib/pom.xml new file mode 100644 index 0000000..3dfc770 --- /dev/null +++ b/trunk/finger-chart-core-lib/pom.xml @@ -0,0 +1,68 @@ + + + + + com.riameeting.fingerchart + finger-chart-superpom + 0.8 + + + 4.0.0 + + com.riameeting.fingerchart + finger-chart-core-lib + 0.8 + swc + + Finger Chart Core Library + + + src/main/flex + + + org.sonatype.flexmojos + flexmojos-maven-plugin + ${flexmojos.version} + true + + + com.adobe.flex + compiler + ${flex.version} + pom + + + + + + + + + com.riameeting.fingerchart + common-lib + 0.8 + swc + compile + + + + com.adobe + as3corelib + ${as3corelib.version} + swc + compile + + + + com.greensock + TweenLiteLib + ${TweenLiteLib.version} + swc + compile + + + + + diff --git a/trunk/finger-chart-core-lib/src/main/flex/com/riameeting/finger/component/AreaChart.as b/trunk/finger-chart-core-lib/src/main/flex/com/riameeting/finger/component/AreaChart.as new file mode 100644 index 0000000..af45f73 --- /dev/null +++ b/trunk/finger-chart-core-lib/src/main/flex/com/riameeting/finger/component/AreaChart.as @@ -0,0 +1,28 @@ +package com.riameeting.finger.component +{ + import com.riameeting.finger.display.axis.*; + import com.riameeting.finger.display.chart.AbstractChart; + import com.riameeting.finger.display.container.*; + import com.riameeting.finger.display.graphic.*; + import com.riameeting.finger.display.tooltip.Tooltip; + import com.riameeting.finger.effect.*; + + /** + * 组件:区域图 + * + * @example var areaChart:AreaChart = new AreaChart(); + * @see AbstractChart + * @author Finger + */ + public class AreaChart extends AbstractChart + { + public function AreaChart(width:uint, height:uint) + { + axis = new BasicAxis(this,false); + chartGraphicContainer = new ChartGraphicContainer(this,AreaGraphic,"AreaGraphic",LineGraphic,false,new MoveIn(),new MoveOut()); + tooltipContainer = new TooltipContainer(this,Tooltip); + pluginContainer = new PluginContainer(this); + super(axis, chartGraphicContainer, tooltipContainer, pluginContainer, width, height); + } + } +} \ No newline at end of file diff --git a/trunk/finger-chart-core-lib/src/main/flex/com/riameeting/finger/component/BubbleChart.as b/trunk/finger-chart-core-lib/src/main/flex/com/riameeting/finger/component/BubbleChart.as new file mode 100644 index 0000000..a76aedf --- /dev/null +++ b/trunk/finger-chart-core-lib/src/main/flex/com/riameeting/finger/component/BubbleChart.as @@ -0,0 +1,25 @@ +package com.riameeting.finger.component +{ + import com.riameeting.finger.display.axis.*; + import com.riameeting.finger.display.chart.AbstractChart; + import com.riameeting.finger.display.container.*; + import com.riameeting.finger.display.graphic.*; + import com.riameeting.finger.display.tooltip.Tooltip; + import com.riameeting.finger.effect.*; + /** + * 组件:气泡图 + * @author Finger + * + */ + public class BubbleChart extends AbstractChart + { + public function BubbleChart(width:uint, height:uint) + { + axis = new BasicAxis(this); + chartGraphicContainer = new ChartGraphicContainer(this,BubbleGraphic,"BubbleGraphic",LineGraphic,true,new MoveIn(),new MoveOut()); + tooltipContainer = new TooltipContainer(this,Tooltip); + pluginContainer = new PluginContainer(this); + super(axis, chartGraphicContainer, tooltipContainer, pluginContainer, width, height); + } + } +} \ No newline at end of file diff --git a/trunk/finger-chart-core-lib/src/main/flex/com/riameeting/finger/component/ChartWrapper.as b/trunk/finger-chart-core-lib/src/main/flex/com/riameeting/finger/component/ChartWrapper.as new file mode 100644 index 0000000..038e991 --- /dev/null +++ b/trunk/finger-chart-core-lib/src/main/flex/com/riameeting/finger/component/ChartWrapper.as @@ -0,0 +1,138 @@ +package com.riameeting.finger.component +{ + import com.riameeting.finger.component.LineChart; + import com.riameeting.finger.config.ChartGlobal; + import com.riameeting.finger.display.chart.IChart; + import com.riameeting.finger.display.legend.ILegend; + import com.riameeting.finger.display.legend.SelectableLegend; + import com.riameeting.finger.display.legend.SimpleLegend; + import com.riameeting.finger.vo.DatasetVO; + + import flash.display.DisplayObject; + import flash.display.DisplayObjectContainer; + import flash.display.Sprite; + import flash.display.StageAlign; + import flash.display.StageScaleMode; + import flash.events.Event; + import flash.external.ExternalInterface; + + /** + * 图表包装类,用于将图表,图例说明,外部配置整合 + * @author Finger + * + */ + public class ChartWrapper extends Sprite + { + /** + * 图表组件 + */ + protected var chart:IChart; + /** + * 图例说明 + */ + protected var legend:ILegend; + /** + * 图表所需的配置,引用请使用ChartGlobal.chartConfig + */ + protected var chartConfig:Object; + private var preloader:Preloader = new Preloader(); + /** + * 构造方法 + * + */ + public function ChartWrapper() + { + super(); + if(stage != null) { + stage.scaleMode = StageScaleMode.NO_SCALE; + stage.align = StageAlign.TOP_LEFT; + stage.showDefaultContextMenu = false; + } + addEventListener(Event.ENTER_FRAME,checkStage); + chartConfig = loaderInfo.parameters; + } + /** + * 检查Stage是否为空,当不为空时执行初始化方法 + * @param e 事件 + * + */ + protected function checkStage(e:Event):void { + if(stage!=null && stage.stageWidth != 0) { + init(); + //removelistener + removeEventListener(Event.ENTER_FRAME,checkStage); + } + } + /** + * 初始化方法,将创建图表,并加载外部文件 + * @param e + * + */ + protected function init(e:Event=null):void { + stage.addEventListener(Event.RESIZE,resizeHandler); + chart.chartConfig = chartConfig; + chart.loadAssets(); + (chart as DisplayObjectContainer).addEventListener(Event.COMPLETE,hideProloader); + addChild(chart as DisplayObject); + //legend + if(chartConfig["legend"] != null) { + addChild(legend as DisplayObject); + legend.x = chart.width; + chart.bindLegend(legend); + } + addChild(preloader); + preloader.x = stage.stageWidth/2; + preloader.y = stage.stageHeight/2; + //receivedFromJavaScript + if(ExternalInterface.available) { + ExternalInterface.addCallback("addData",addDataFromJavaScript); + } + } + /** + * 从JavaScript加入数据 + * @param data + * @param policy + * + */ + protected function addDataFromJavaScript(data:Object,policy:String):void { + chart.addData(data,policy); + } + /** + * 隐藏进度条 + * @param e + * + */ + protected function hideProloader(e:Event):void { + removeChild(preloader); + } + /** + * Flash尺寸发生改变触发的回调方法,将重绘图表的显示元素。 + * @param e 事件 + * + */ + protected function resizeHandler(e:Event):void + { + chart.width = stage.stageWidth; + chart.height = stage.stageHeight; + legend.x = chart.width; + legend.updateDisplayList(legend.width,chart.height); + } + } +} +import com.riameeting.ui.control.Label; + +import flash.display.Sprite; + +class Preloader extends Sprite { + public function Preloader() { + var label:Label = new Label(); + label.color = 0xFFFFFF; + label.text = "Loadding..."; + label.x = -label.width/2; + label.y = -label.height/2; + addChild(label); + this.graphics.beginFill(0xCCCCCC,1); + this.graphics.drawCircle(0,0,label.width/2+4); + this.graphics.endFill(); + } +} \ No newline at end of file diff --git a/trunk/finger-chart-core-lib/src/main/flex/com/riameeting/finger/component/ColumnChart.as b/trunk/finger-chart-core-lib/src/main/flex/com/riameeting/finger/component/ColumnChart.as new file mode 100644 index 0000000..efb64de --- /dev/null +++ b/trunk/finger-chart-core-lib/src/main/flex/com/riameeting/finger/component/ColumnChart.as @@ -0,0 +1,25 @@ +package com.riameeting.finger.component +{ + import com.riameeting.finger.display.axis.*; + import com.riameeting.finger.display.chart.AbstractChart; + import com.riameeting.finger.display.container.*; + import com.riameeting.finger.display.graphic.*; + import com.riameeting.finger.display.tooltip.Tooltip; + import com.riameeting.finger.effect.*; + /** + * 组件:柱图 + * @author Finger + * + */ + public class ColumnChart extends AbstractChart + { + public function ColumnChart(width:uint, height:uint) + { + axis = new BasicAxis(this,true); + chartGraphicContainer = new ChartGraphicContainer(this,ColumnGraphic,"ColumnGraphic",LineGraphic,false,new MoveIn(),new MoveOut()); + tooltipContainer = new TooltipContainer(this,Tooltip); + pluginContainer = new PluginContainer(this); + super(axis, chartGraphicContainer, tooltipContainer, pluginContainer, width, height); + } + } +} \ No newline at end of file diff --git a/trunk/finger-chart-core-lib/src/main/flex/com/riameeting/finger/component/LineChart.as b/trunk/finger-chart-core-lib/src/main/flex/com/riameeting/finger/component/LineChart.as new file mode 100644 index 0000000..54ab6d1 --- /dev/null +++ b/trunk/finger-chart-core-lib/src/main/flex/com/riameeting/finger/component/LineChart.as @@ -0,0 +1,63 @@ +package com.riameeting.finger.component +{ + import com.riameeting.finger.display.axis.*; + import com.riameeting.finger.display.chart.AbstractChart; + import com.riameeting.finger.display.container.*; + import com.riameeting.finger.display.graphic.*; + import com.riameeting.finger.display.tooltip.Tooltip; + import com.riameeting.finger.effect.*; + import com.riameeting.ui.control.Label; + + import flash.events.Event; + import flash.events.TransformGestureEvent; + import flash.ui.Multitouch; + + /** + * 组件:线图 + * @author Finger + * + */ + public class LineChart extends AbstractChart + { + /** + * 是否启用数据缩放,需要移动设备手势支持 + */ + public var enabledZoom:Boolean = false; + /** + * 缩放的速度 + */ + public var zoomSpeed:int = 1; + + public function LineChart(width:uint, height:uint) + { + axis = new BasicAxis(this); + chartGraphicContainer = new ChartGraphicContainer(this,LineGraphic,"LineGraphic",LineGraphic,false,new MoveIn(),new MoveOut()); + tooltipContainer = new TooltipContainer(this,Tooltip); + pluginContainer = new PluginContainer(this); + super(axis, chartGraphicContainer, tooltipContainer, pluginContainer, width, height); + } + + override protected function drawChart(e:Event=null):void + { + super.drawChart(e); + if(enabledZoom && Multitouch.supportsGestureEvents) + { + if(dataRange == null) + dataRange = [0,dataset.collectionPrototype.length-1]; + addEventListener(TransformGestureEvent.GESTURE_ZOOM,zoomHandler); + } + } + + protected function zoomHandler(event:TransformGestureEvent):void + { + var endIndex:int = dataRange[1]; + if(event.scaleX < 1) + endIndex+=zoomSpeed; + else + endIndex-=zoomSpeed; + if(endIndex > 0 && endIndex < dataset.collectionPrototype.length) + dataRange = [0,endIndex]; + } + + } +} \ No newline at end of file diff --git a/trunk/finger-chart-core-lib/src/main/flex/com/riameeting/finger/component/PieChart.as b/trunk/finger-chart-core-lib/src/main/flex/com/riameeting/finger/component/PieChart.as new file mode 100644 index 0000000..cf1d3df --- /dev/null +++ b/trunk/finger-chart-core-lib/src/main/flex/com/riameeting/finger/component/PieChart.as @@ -0,0 +1,25 @@ +package com.riameeting.finger.component +{ + import com.riameeting.finger.display.axis.*; + import com.riameeting.finger.display.chart.AbstractChart; + import com.riameeting.finger.display.container.*; + import com.riameeting.finger.display.graphic.*; + import com.riameeting.finger.display.tooltip.Tooltip; + import com.riameeting.finger.effect.*; + /** + * 组件:饼图(横向) + * @author Finger + * + */ + public class PieChart extends AbstractChart + { + public function PieChart(width:uint, height:uint) + { + axis = new PieAxis(this,true); + chartGraphicContainer = new ChartGraphicContainer(this,PieGraphic,"PieGraphic",LineGraphic,true,new FadeIn(),new FadeOut()); + tooltipContainer = new TooltipContainer(this,Tooltip,"byp"); + pluginContainer = new PluginContainer(this); + super(axis, chartGraphicContainer, tooltipContainer, pluginContainer, width, height); + } + } +} \ No newline at end of file diff --git a/trunk/finger-chart-core-lib/src/main/flex/com/riameeting/finger/component/PlotChart.as b/trunk/finger-chart-core-lib/src/main/flex/com/riameeting/finger/component/PlotChart.as new file mode 100644 index 0000000..cba3548 --- /dev/null +++ b/trunk/finger-chart-core-lib/src/main/flex/com/riameeting/finger/component/PlotChart.as @@ -0,0 +1,25 @@ +package com.riameeting.finger.component +{ + import com.riameeting.finger.display.axis.*; + import com.riameeting.finger.display.chart.AbstractChart; + import com.riameeting.finger.display.container.*; + import com.riameeting.finger.display.graphic.*; + import com.riameeting.finger.display.tooltip.Tooltip; + import com.riameeting.finger.effect.*; + /** + * 组件:散点图 + * @author Finger + * + */ + public class PlotChart extends AbstractChart + { + public function PlotChart(width:uint, height:uint) + { + axis = new BasicAxis(this); + chartGraphicContainer = new ChartGraphicContainer(this,PlotGraphic,"PlotGraphic",LineGraphic,true,new MoveIn(),new MoveOut()); + tooltipContainer = new TooltipContainer(this,Tooltip); + pluginContainer = new PluginContainer(this); + super(axis, chartGraphicContainer, tooltipContainer, pluginContainer, width, height); + } + } +} \ No newline at end of file diff --git a/trunk/finger-chart-core-lib/src/main/flex/com/riameeting/finger/config/ChartGlobal.as b/trunk/finger-chart-core-lib/src/main/flex/com/riameeting/finger/config/ChartGlobal.as new file mode 100644 index 0000000..4b1ac89 --- /dev/null +++ b/trunk/finger-chart-core-lib/src/main/flex/com/riameeting/finger/config/ChartGlobal.as @@ -0,0 +1,64 @@ +package com.riameeting.finger.config +{ + import com.riameeting.finger.display.chart.IChart; + import com.riameeting.finger.display.skin.*; + + import flash.display.MovieClip; + import flash.display.Sprite; + import flash.utils.Dictionary; + + /** + * 定义全局可访问的变量和配置,属性皆是静态属性,直接引用即可 + * @author Finger + * + */ + public class ChartGlobal + { + /** + * 定义当前图表的版本号 + */ + public static const version:String = "0.9"; + + /** + * 最后更新日期 + */ + public static const buildDate:String = "2011-8-21"; + /** + * 皮肤源 + */ + public static var skinSource:MovieClip; + /** + * 图表引用 + */ + private static var skinClassDict:Dictionary; + /** + * 获取皮肤素材 + * @param skinName + * @return + * + */ + public static function getSkin(skinName:String):MovieClip { + if(skinClassDict == null) { + skinClassDict = new Dictionary(); + skinClassDict["skin.ChartSkin"] = ChartSkin; + skinClassDict["skin.AxisSkin"] = AxisSkin; + skinClassDict["skin.TooltipSkin"] = TooltipSkin; + skinClassDict["skin.ColumnGraphic"] = ColumnGraphic; + skinClassDict["skin.BarGraphic"] = BarGraphic; + skinClassDict["skin.DotGraphic"] = DotGraphic; + } + var skin:MovieClip,skinClass:Class; + if(skinSource != null) { + skinClass = skinSource.loaderInfo.applicationDomain.getDefinition(skinName) as Class; + } else { + skinClass = skinClassDict[skinName] as Class; + } + skin = new skinClass() as MovieClip; + return skin; + } + /** + * 颜色数组,用于图表图形的绘制 + */ + public static var colorCollection:Array = [0xFF0000,0x00FF00,0x0000FF,0x9c00ff,0x0c00ff,0x00a2ff,0x09c700,0xe7b300,0xe75c00]; + } +} \ No newline at end of file diff --git a/trunk/finger-chart-core-lib/src/main/flex/com/riameeting/finger/display/axis/BasicAxis.as b/trunk/finger-chart-core-lib/src/main/flex/com/riameeting/finger/display/axis/BasicAxis.as new file mode 100644 index 0000000..7d9913f --- /dev/null +++ b/trunk/finger-chart-core-lib/src/main/flex/com/riameeting/finger/display/axis/BasicAxis.as @@ -0,0 +1,380 @@ +package com.riameeting.finger.display.axis +{ + import com.riameeting.finger.display.chart.IChart; + import com.riameeting.finger.factory.ObjectFactory; + import com.riameeting.finger.vo.DatasetVO; + import com.riameeting.ui.control.Alert; + import com.riameeting.ui.control.Label; + import com.riameeting.utils.ColorUtils; + import com.riameeting.utils.DPIReset; + import com.riameeting.utils.DrawTool; + import com.riameeting.utils.NumberTool; + + import flash.display.GradientType; + import flash.display.MovieClip; + import flash.display.Sprite; + import flash.geom.Matrix; + import flash.geom.Point; + import flash.geom.Rectangle; + + /** + * 基础坐标系,支持X和Y方向的定位 + * @author Finger + * + */ + public class BasicAxis extends Sprite implements IAxis + { + private var _dataset:DatasetVO; + private var _chartRef:IChart; + + /** + * 对Chart的 引用 + * @return + * + */ + public function get chartRef():IChart + { + return _chartRef; + } + + public function set chartRef(value:IChart):void + { + _chartRef=value; + } + /** + * 坐标系宽度 + */ + public var axisWidth:uint; + /** + * 坐标系高度 + */ + public var axisHeight:uint; + /** + * 数据在2个轴上的最小值(X轴,Y轴) + */ + public var minValueX:Number=0, minValueY:Number=0; + /** + * 数据在2个轴上的最大值(X轴,Y轴) + */ + public var maxValueX:Number=0, maxValueY:Number=0; + /** + * 在X轴方向上划分的区块数量 + */ + public var countX:uint=0; + /** + * 在Y轴方向上划分的区块数量 + */ + public var countY:uint=0; + /** + * Y轴定义的数据显示字段,可以为1个或多个 + */ + public var yFields:Array; + /** + * X轴定义的数据显示字段,只能是一个 + */ + public var xField:String; + /** + * 绘制时,最后计算所得的单元格高度 + */ + public var realGridHeight:Number; + /** + * 绘制时,最后计算所得的单元格宽度 + */ + public var realGridWidth:Number; + /** + * 坐标系的图形绘制范围 + */ + public var graphicArea:Rectangle=new Rectangle(0, 0, 0, 0); + + private var _style:Object={gridHeight: 50, paddingLeft: 60, paddingTop: 40, paddingRight: 20, paddingBottom: 70, offsetV: 20, color: 0x000000, lineColors: [0x000000, 0xCCCCCC], lineAlphas: [100, 100], lineStrokes: [2,1]}; + private var _skin:MovieClip; + /** + * 设置为true,则偏移与单元格相同 + */ + public var ignoreOffsetV:Boolean; + + /** + * 坐标系的CSS样式定义 + * @return 对象 + * + */ + public function get style():Object + { + return _style; + } + + public function set style(value:Object):void + { + _style=value; + } + + /** + * 皮肤定义 + * @return + * + */ + public function get skin():MovieClip + { + return _skin; + } + + public function set skin(value:MovieClip):void + { + if (_skin != null) + removeChild(_skin); + _skin=value; + _skin.hostComponent=this; + addChildAt(_skin, 0); + } + + /** + * 宽度 + * @return + * + */ + override public function get width():Number + { + return axisWidth; + } + + override public function set width(value:Number):void + { + axisWidth=value; + } + + /** + * 高度 + * @return + * + */ + override public function get height():Number + { + return axisHeight; + } + + override public function set height(value:Number):void + { + axisHeight=value; + } + + /** + * 坐标系中对数据源的引用 + * @return DatasetVO引用 + * + */ + public function get dataset():DatasetVO + { + return _dataset; + } + + public function set dataset(value:DatasetVO):void + { + _dataset=value; + xField=_dataset.config["xField"]; + yFields=_dataset.config["yField"].split(","); + } + + /** + * 当数据传入之后,需要计算各个轴上的取值范围(最小为0,最大则需要循环计算) + * + */ + protected function calculateMaxValue():void + { + var i:uint=0, j:uint=0, obj:Object; + if (_dataset.config["minValueX"] != null) + { + minValueX=_dataset.config["minValueX"]; + } + else + { + minValueX=0; + } + if (_dataset.config["maxValueX"] != null) + { + maxValueX=_dataset.config["maxValueX"]; + } + else + { + maxValueX=0; + } + if (_dataset.config["minValueY"] != null) + { + minValueY=_dataset.config["minValueY"]; + } + else + { + minValueY=0; + } + if (_dataset.config["maxValueY"] != null) + { + maxValueY=_dataset.config["maxValueY"]; + } + else + { + maxValueY=0; + } + //x + if (xField != null) + { + if (yFields.length != 1) + { + Alert.show("you must define 1 y fileds with xField mode", "Error"); + throw new Error("you must define 1 y fileds with xField mode"); + } + countX=(graphicArea.width - int(style["offsetV"]) * 2) / int(style["gridHeight"]); + //maxXValue + for (j=0; j < dataset.collection.length; j++) + { + obj=dataset.collection[j]; + if (obj[xField] > maxValueX) + { + maxValueX=obj[xField]; + } + if (obj[xField] < minValueX) + { + minValueX=obj[xField]; + } + } + maxValueX=NumberTool.getMaxNumber(maxValueX); + minValueX=NumberTool.getMinNumber(minValueX); + } + else + { + countX=dataset.collection.length; + } + //y + for (i=0; i < yFields.length; i++) + { + for (j=0; j < dataset.collection.length; j++) + { + obj=dataset.collection[j]; + obj.doubleArbor=false; + if (obj[yFields[i]] > maxValueY) + { + maxValueY=obj[yFields[i]]; + } + if (obj[yFields[i]] < minValueY) + { + minValueY=obj[yFields[i]]; + } + } + } + maxValueY=NumberTool.getMaxNumber(maxValueY); + minValueY=NumberTool.getMinNumber(minValueY); + countY=graphicArea.height / int(style["gridHeight"]); + //ignoreOffsetV + if (ignoreOffsetV) + { + style["offsetH"]=graphicArea.width / (countX + 1); + } + } + + /** + * 构造方法 + * + */ + public function BasicAxis(chartRef:IChart, ignoreOffsetV:Boolean=false) + { + _chartRef=chartRef; + this.ignoreOffsetV=ignoreOffsetV; + this.cacheAsBitmap=true; + mouseChildren=false; + mouseEnabled=false; + //reset default style via DPI + _style["paddingLeft"] = DPIReset.getNumber(_style["paddingLeft"]); + _style["paddingRight"] = DPIReset.getNumber(_style["paddingRight"]); + _style["paddingTop"] = DPIReset.getNumber(_style["paddingTop"]); + _style["paddingBottom"] = DPIReset.getNumber(_style["paddingBottom"]); + } + + /** + * 设置坐标系的宽度和高度 + * @param w 宽度 + * @param h 高度 + * + */ + protected function initSize(w:uint, h:uint):void + { + axisWidth=w; + axisHeight=h; + graphicArea.x=int(style["paddingLeft"]); + graphicArea.y=int(style["paddingTop"]); + graphicArea.width=w - int(style["paddingLeft"]) - int(style["paddingRight"]); + graphicArea.height=h - int(style["paddingTop"]) - int(style["paddingBottom"]); + } + + /** + * 更新显示列表的方法,当Flash场景尺寸发生改变,将调用此方法重绘坐标系 + * @param w 宽度 + * @param h 高度 + * + */ + public function updateDisplayList(w:uint, h:uint):void + { + initSize(w, h); + calculateMaxValue(); + //clear + clear(); + skin.updateDisplayList(); + } + + /** + * 获取一个数据对象在坐标系上的坐标点(映射),包含x和y + * @param vo 数据对象 + * @param yField Y轴字段 + * @return 坐标点 + * + */ + public function getPoint(vo:Object, yField:String):Point + { + var targetX:Number; + var targetY:Number; + var objIndex:int=dataset.collection.indexOf(vo); + var currentOffset:Number=ignoreOffsetV ? style["offsetH"] : style["offsetV"]; + if (xField != null) + { + var rw:uint=graphicArea.width - currentOffset * 2; + targetX=graphicArea.x + currentOffset + (vo[xField] - minValueX) / (maxValueX - minValueX) * rw; + } + else + { + targetX=graphicArea.x + currentOffset + objIndex * realGridWidth; + } + targetY=graphicArea.y + graphicArea.height * (1 - (vo[yField] - minValueY) / (maxValueY - minValueY)); + return new Point(targetX, targetY); + } + + /** + * 基础坐标系不实现此方法 + * @param vo + * @param yField + * @return + * + */ + public function getAngle(vo:Object, yField:String):Object + { + return null + } + + /** + * 获取坐标系可见区域的范围 + * @return 矩形区域 + * + */ + public function getAxisRect():Rectangle + { + return graphicArea; + } + + /** + * 当需重绘坐标系的时候,调用此方法 + * + */ + public function clear():void + { + this.graphics.clear(); + (_skin as Object).clear(); + } + + } +} diff --git a/trunk/finger-chart-core-lib/src/main/flex/com/riameeting/finger/display/axis/IAxis.as b/trunk/finger-chart-core-lib/src/main/flex/com/riameeting/finger/display/axis/IAxis.as new file mode 100644 index 0000000..e7a91d9 --- /dev/null +++ b/trunk/finger-chart-core-lib/src/main/flex/com/riameeting/finger/display/axis/IAxis.as @@ -0,0 +1,90 @@ +/** + * 此包下面是坐标系相关的接口和实现类 + */ +package com.riameeting.finger.display.axis +{ + import com.riameeting.finger.vo.DatasetVO; + + import flash.display.MovieClip; + import flash.geom.Point; + import flash.geom.Rectangle; + + /** + * 定义坐标系的接口 + * @author Finger + * + */ + public interface IAxis + { + /** + * 更新显示列表的方法,当Flash场景尺寸发生改变,将调用此方法重绘坐标系 + * @param width 图表宽度 + * @param height 图表高度 + * + */ + function updateDisplayList(width:uint,height:uint):void; + /** + * 坐标系中对数据源的引用 + * @return DatasetVO引用 + * + */ + function get dataset():DatasetVO; + function set dataset(value:DatasetVO):void; + /** + * 坐标系的CSS样式定义 + * @return 对象 + * + */ + function get style():Object; + function set style(value:Object):void; + /** + * 坐标系的SKIN定义 + * @return 对象 + * + */ + function get skin():MovieClip; + function set skin(value:MovieClip):void; + /** + * width + * @return + * + */ + function get width():Number; + function set width(value:Number):void; + /** + * height + * @return + * + */ + function get height():Number; + function set height(value:Number):void; + /** + * 当需要清理坐标系的时候,调用此方法 + * + */ + function clear():void; + /** + * 获取一个数据对象在坐标系上的坐标点(映射),包含x和y + * @param vo 数据对象 + * @param yField Y轴字段 + * @return 坐标点 + * + */ + function getPoint(vo:Object,yField:String):Point; + /** + * 获取一个数据对象在坐标系上的角度(映射),饼图专用 + * @param vo 数据对象 + * @param yField Y轴字段 + * @return 角度值 + * + */ + function getAngle(vo:Object,yField:String):Object; + /** + * 获取坐标系可见区域的范围 + * @return 矩形区域 + * + */ + function getAxisRect():Rectangle; + + } +} \ No newline at end of file diff --git a/trunk/finger-chart-core-lib/src/main/flex/com/riameeting/finger/display/axis/PieAxis.as b/trunk/finger-chart-core-lib/src/main/flex/com/riameeting/finger/display/axis/PieAxis.as new file mode 100644 index 0000000..0555223 --- /dev/null +++ b/trunk/finger-chart-core-lib/src/main/flex/com/riameeting/finger/display/axis/PieAxis.as @@ -0,0 +1,86 @@ +package com.riameeting.finger.display.axis +{ + import com.riameeting.finger.display.chart.IChart; + + import flash.display.MovieClip; + import flash.geom.Point; + + /** + * 用于饼图的坐标系 + * @author Finger + * + */ + public class PieAxis extends BasicAxis + { + /** + * 起始角度 + */ + protected var beginAngle:Number = -90; + /** + * 当前数据项计算所得的角度 + */ + protected var currentAngle:Number = 0; + /** + * Pie无需Skin + * @param value + * + */ + override public function set skin(value:MovieClip):void {} + /** + * 构造方法 + * @param chartRef + * @param ignoreOffsetV + * + */ + public function PieAxis(chartRef:IChart, ignoreOffsetV:Boolean=false) + { + super(chartRef, ignoreOffsetV); + //titleB.visible = false; + } + /** + * 更新显示列表的方法,当Flash场景尺寸发生改变,将调用此方法重绘坐标系 + * @param w 宽度 + * @param h 高度 + * + */ + override public function updateDisplayList(w:uint, h:uint):void + { + axisWidth = w; + axisHeight = h; + style["paddingLeft"] = style["paddingTop"] = style["paddingRight"] = style["paddingBottom"] = 0; + graphicArea.x = int(style["paddingLeft"]); + graphicArea.y = int(style["paddingTop"]); + graphicArea.width = w - int(style["paddingLeft"]) - int(style["paddingRight"]); + graphicArea.height = h - int(style["paddingTop"]) - int(style["paddingBottom"]); + } + /** + * 获取一个数据对象在坐标系上的坐标点(映射),包含x和y + * @param vo 数据对象 + * @param yField Y轴字段 + * @return 坐标点 + * + */ + override public function getPoint(vo:Object, yField:String):Point + { + return new Point(axisWidth/2,axisHeight/2); + } + /** + * 获取一个数据对象在坐标系上的角度(映射),饼图专用 + * @param vo 数据对象 + * @param yField Y轴字段 + * @return 角度值 + * + */ + override public function getAngle(vo:Object,yField:String):Object { + var count:Number = 0; + for each(var item:Object in dataset.collection) { + count += Number(item[yField]); + } + var proportion:Number = Number(vo[yField])/count; + currentAngle = proportion*360; + var obj:Object = {beginAngle:beginAngle,angle:currentAngle}; + beginAngle += currentAngle; + return obj; + } + } +} \ No newline at end of file diff --git a/trunk/finger-chart-core-lib/src/main/flex/com/riameeting/finger/display/axis/ReversalAxis.as b/trunk/finger-chart-core-lib/src/main/flex/com/riameeting/finger/display/axis/ReversalAxis.as new file mode 100644 index 0000000..f699609 --- /dev/null +++ b/trunk/finger-chart-core-lib/src/main/flex/com/riameeting/finger/display/axis/ReversalAxis.as @@ -0,0 +1,80 @@ +package com.riameeting.finger.display.axis +{ + import com.riameeting.finger.display.chart.IChart; + import com.riameeting.finger.factory.ObjectFactory; + import com.riameeting.finger.vo.DatasetVO; + import com.riameeting.ui.control.Alert; + import com.riameeting.ui.control.Label; + import com.riameeting.utils.NumberTool; + + import flash.geom.Point; + import flash.geom.Rectangle; + + /** + * 翻转坐标系 + * @author Finger + * + */ + public class ReversalAxis extends BasicAxis + { + /** + * 构造方法 + * @param chartRef + * @param ignoreOffsetV + * + */ + public function ReversalAxis(chartRef:IChart, ignoreOffsetV:Boolean=false) + { + super(chartRef, ignoreOffsetV); + } + /** + * 当数据传入之后,需要计算各个轴上的取值范围(最小为0,最大则需要循环计算) + * + */ + override protected function calculateMaxValue():void { + super.calculateMaxValue(); + var i:uint=0,j:uint=0,obj:Object; + //x + if(xField != null) { + countX = (graphicArea.height-int(style["offsetV"])*2)/int(style["gridHeight"]); + } else { + countX = dataset.collection.length; + } + countY = graphicArea.width/int(style["gridHeight"]); + } + /** + * 更新显示列表的方法,当Flash场景尺寸发生改变,将调用此方法重绘坐标系 + * @param w 宽度 + * @param h 高度 + * + */ + override public function updateDisplayList(w:uint,h:uint):void { + super.updateDisplayList(w,h); + skin.titleB.color = style["color"]; + skin.titleB.x = 0; + skin.titleB.y = 0; + skin.titleL.color = style["bottomColor"]; + skin.titleL.x = (w - skin.titleL.width)/2; + skin.titleL.y = h - skin.titleL.height; + } + /** + * 获取一个数据对象在坐标系上的坐标点(映射),包含x和y + * @param vo 数据对象 + * @param yField Y轴字段 + * @return 坐标点 + * + */ + override public function getPoint(vo:Object,yField:String):Point { + var targetX:Number; + var targetY:Number; + var objIndex:int = dataset.collection.indexOf(vo); + if(xField != null) { + throw new Error("ReveralAxis doesn't support xField"); + } else { + targetX = graphicArea.x + graphicArea.width*((vo[yField]-minValueY)/(maxValueY-minValueY)); + } + targetY = graphicArea.y + int(style["offsetV"]) + (dataset.collection.length-objIndex-1)*realGridWidth; + return new Point(targetX,targetY); + } + } +} \ No newline at end of file diff --git a/trunk/finger-chart-core-lib/src/main/flex/com/riameeting/finger/display/chart/AbstractChart.as b/trunk/finger-chart-core-lib/src/main/flex/com/riameeting/finger/display/chart/AbstractChart.as new file mode 100644 index 0000000..cfac707 --- /dev/null +++ b/trunk/finger-chart-core-lib/src/main/flex/com/riameeting/finger/display/chart/AbstractChart.as @@ -0,0 +1,534 @@ +package com.riameeting.finger.display.chart +{ + import com.adobe.images.PNGEncoder; + import com.riameeting.finger.config.ChartGlobal; + import com.riameeting.finger.display.axis.IAxis; + import com.riameeting.finger.display.container.*; + import com.riameeting.finger.display.legend.ILegend; + import com.riameeting.finger.effect.IEffect; + import com.riameeting.finger.parser.CSSParser; + import com.riameeting.finger.parser.IParser; + import com.riameeting.finger.parser.JSONParser; + import com.riameeting.finger.parser.XMLParser; + import com.riameeting.finger.vo.DatasetVO; + import com.riameeting.net.ResourceLoader; + import com.riameeting.ui.control.Alert; + import com.riameeting.utils.ArrayUtils; + import com.riameeting.utils.NumberTool; + import com.riameeting.utils.ObjectUtils; + + import flash.display.BitmapData; + import flash.display.DisplayObject; + import flash.display.Loader; + import flash.display.MovieClip; + import flash.display.Sprite; + import flash.display.StageDisplayState; + import flash.events.ContextMenuEvent; + import flash.events.Event; + import flash.events.MouseEvent; + import flash.net.*; + import flash.ui.ContextMenu; + import flash.ui.ContextMenuItem; + import flash.ui.Multitouch; + import flash.ui.MultitouchInputMode; + import flash.utils.*; + + /** + * 抽象图表。此类并不确定图表的类型(线状图,柱状图或其它),依据它的依赖而定。 + * @author Finger + * + */ + public class AbstractChart extends Sprite implements IChart + { + //4 layer + private var _axis:IAxis; + private var _chartGraphicContainer:IChartGraphicContainer; + private var _tooltipContainer:ITooltipContainer; + private var _pluginContainer:IPluginContainer; + private var _chartConfig:Object; + //model + private var _dataset:DatasetVO; + private var _legend:ILegend; + //effect + private var _showEffect:IEffect; + private var _hideEffect:IEffect; + private var _graphicShowEffect:IEffect; + private var _graphicHideEffect:IEffect; + private var _tipShowEffect:IEffect; + private var _tipHideEffect:IEffect; + private var globalStyle:Object; + private var myContextMenu:ContextMenu; + /** + * 图表宽度 + */ + protected var chartWidth:uint; + /** + * 图表高度 + */ + protected var chartHeight:uint; + /** + * 资源加载器 + */ + protected var resourceLoader:ResourceLoader=new ResourceLoader(); + //style + private var _style:Object={bgColors: [0xFFFFFF, 0xEFEFEF], bgAlphas: [100, 100]}; + private var _skin:MovieClip; + private var _dataRange:Array; + + /** + * 图表的配置 + * @return + * + */ + public function get chartConfig():Object + { + return _chartConfig; + } + + public function set chartConfig(value:Object):void + { + _chartConfig=value; + } + + /** + * CSS样式定义 + * @return 对象 + * @default {bgColors:[0xFFFFFF,0xc8c8c8],bgAlphas:[100,100],lineColors:[0x000000,0x000000],lineAlphas:[0,20]} + */ + public function get style():Object + { + return _style; + } + + public function set style(value:Object):void + { + _style=value; + } + + /** + * SKIN定义 + * @return 对象 + * + */ + public function get skin():MovieClip + { + return _skin; + } + + public function set skin(value:MovieClip):void + { + if (_skin != null) + removeChild(_skin); + _skin=value; + _skin.hostComponent=this; + addChildAt(_skin, 0); + } + + /** + * 对数据源的引用 + * @return DatasetVO引用 + * + */ + public function get dataset():DatasetVO + { + return _dataset; + } + + public function set dataset(value:DatasetVO):void + { + if (value == null) + throw new Error("dataset not allow null"); + if(_dataRange != null) + { + value.filterByRange(_dataRange); + } + _dataset=value; + _axis.dataset=value; + _chartGraphicContainer.dataset=value; + _tooltipContainer.dataset=value; + _pluginContainer.dataset=value; + updateDisplayList(); + } + + /** + * 图表的4个显示层级之一:坐标系 + * @return 坐标系 + * + */ + public function get axis():IAxis + { + return _axis; + } + + public function set axis(value:IAxis):void + { + _axis=value; + } + + /** + * 图表的4个显示层级之一:图形容器 + * @return 图形容器 + * + */ + public function get chartGraphicContainer():IChartGraphicContainer + { + return _chartGraphicContainer; + } + + public function set chartGraphicContainer(value:IChartGraphicContainer):void + { + _chartGraphicContainer=value; + } + + /** + * 图表的4个显示层级之一:鼠标提示容器 + * @return 鼠标提示容器 + * + */ + public function get tooltipContainer():ITooltipContainer + { + return _tooltipContainer; + } + + public function set tooltipContainer(value:ITooltipContainer):void + { + _tooltipContainer=value; + } + + /** + * 图表的4个显示层级之一:插件容器 + * @return 插件容器 + * + */ + public function get pluginContainer():IPluginContainer + { + return _pluginContainer; + } + + public function set pluginContainer(value:IPluginContainer):void + { + _pluginContainer=value; + } + + public function get dataRange():Array + { + return _dataRange; + } + + public function set dataRange(value:Array):void + { + if(value!=null && value.length!=2) + throw new Error("dataRange must had 2 value"); + _dataRange=value; + if(_dataset != null) + { + _dataset.filterByRange(_dataRange); + updateDisplayList(); + } + } + /** + * CSS解析器 + */ + protected var cssParser:CSSParser=new CSSParser(); + + /** + * 构造方法 + * @param axis 坐标系 + * @param chartGraphicContainer 图形容器 + * @param tooltipContainer 鼠标提示容器 + * @param pluginContainer 插件容器 + * @param width 宽度 + * @param height 高度 + * + */ + public function AbstractChart(axis:IAxis, chartGraphicContainer:IChartGraphicContainer, tooltipContainer:ITooltipContainer, pluginContainer:IPluginContainer, width:uint, height:uint) + { + this._axis=axis; + this._chartGraphicContainer=chartGraphicContainer; + this._tooltipContainer=tooltipContainer; + this._pluginContainer=pluginContainer; + this.chartWidth=width; + this.chartHeight=height; + addChild(axis as DisplayObject); + addChild(chartGraphicContainer as DisplayObject); + addChild(tooltipContainer as DisplayObject); + addChild(pluginContainer as DisplayObject); + if (Alert.container == null) + Alert.container=this; + //Multitouch mode + Multitouch.inputMode=MultitouchInputMode.GESTURE; + } + + /** + * 图表宽度 + * @return 宽度值 + * + */ + override public function get width():Number + { + return chartWidth; + } + + override public function set width(value:Number):void + { + chartWidth=value; + updateDisplayList(); + } + + /** + * 图表高度 + * @return 高度值 + * + */ + override public function get height():Number + { + return chartHeight; + } + + override public function set height(value:Number):void + { + chartHeight=value; + updateDisplayList(); + } + + /** + * 更新显示列表的方法,当Flash场景尺寸发生改变,将调用此方法重绘图表 + * + */ + public function updateDisplayList():void + { + if (dataset == null) + return; + _axis.updateDisplayList(width, height); + _chartGraphicContainer.updateDisplayList(width, height); + _tooltipContainer.updateDisplayList(width, height); + _pluginContainer.updateDisplayList(width, height); + skin.updateDisplayList({width: width, height: height}); + } + + /** + * 加载图表依赖的数据和资源 + * + */ + public function loadAssets(chartConfigObj:Object=null):void + { + if (chartConfigObj != null) + chartConfig=chartConfigObj; + var assets:Array=[]; + if (chartConfig.data != null) + assets.push(chartConfig.data); + if (chartConfig.skin != null) + assets.push(chartConfig.skin); + if (chartConfig.css != null) + assets.push(chartConfig.css); + if (chartConfig.dataStr != null) + { + chartConfig.data="innerData"; + resourceLoader.fileDict[chartConfig.data]=chartConfig.dataStr; + } + if (chartConfig.cssStr != null) + { + chartConfig.css="innerCSS"; + resourceLoader.fileDict[chartConfig.css]=chartConfig.cssStr; + } + if (assets.length > 0) + { + resourceLoader.loadAssets(assets, loadAssetsCompleteHandler); + } + else + { + loadAssetsCompleteHandler(); + } + } + + /** + * 加载完毕执行的方法 + * + */ + protected function loadAssetsCompleteHandler():void + { + //css + if (chartConfig.css != null) + { + cssParser.clear(); + cssParser.parseCSS(resourceLoader.fileDict[chartConfig.css]); + if (cssParser.getStyle("chart") != null) + { + style=ObjectUtils.mergePromps(cssParser.getStyle("chart"), style); + } + if (cssParser.getStyle("axis") != null) + axis.style=ObjectUtils.mergePromps(cssParser.getStyle("axis"), axis.style); + ; + if (cssParser.getStyle("gContainer") != null) + chartGraphicContainer.style=ObjectUtils.mergePromps(cssParser.getStyle("gContainer"), chartGraphicContainer.style); + if (cssParser.getStyle("tContainer") != null) + tooltipContainer.style=ObjectUtils.mergePromps(cssParser.getStyle("tContainer"), tooltipContainer.style); + if (cssParser.getStyle("pContainer") != null) + pluginContainer.style=ObjectUtils.mergePromps(cssParser.getStyle("pContainer"), pluginContainer.style); + if (_legend != null && cssParser.getStyle("legend") != null) + _legend.style=ObjectUtils.mergePromps(cssParser.getStyle("legend"), _legend.style); + if (cssParser.getStyle("global") != null) + { + globalStyle=cssParser.getStyle("global"); + ChartGlobal.colorCollection=globalStyle["colorCollection"]; + ChartGlobal.colorCollection=ArrayUtils.extendArrayByClone(ChartGlobal.colorCollection, 10); + } + } + //skin + if (chartConfig.skin != null) + { + var skinLoader:Loader=new Loader(); + skinLoader.loadBytes(resourceLoader.fileDict[chartConfig.skin]); + skinLoader.contentLoaderInfo.addEventListener(Event.COMPLETE, function(e:Event):void + { + drawChart(e); + }); + } + else + { + drawChart(); + } + } + + /** + * 准备工作完成,将数据赋值给图表,让图表开始绘制 + * + */ + protected function drawChart(e:Event=null):void + { + if (stage == null) + { + setTimeout(drawChart, 100, e); + return; + } + dispatchEvent(new Event(Event.COMPLETE)); + if (e != null) + ChartGlobal.skinSource=e.currentTarget.content; + skin=ChartGlobal.getSkin("skin.ChartSkin"); + axis.skin=ChartGlobal.getSkin("skin.AxisSkin"); + //data + var parser:IParser; + var dataStr:String=resourceLoader.fileDict[chartConfig.data]; + if (dataStr.charAt(0) != "{") + { + parser=new XMLParser(); + } + else + { + parser=new JSONParser(); + } + dataset=parser.parse(dataStr); + if (_legend != null) + _legend.dataset=dataset; + contextMenuHandler(); + (chartGraphicContainer as Object).useAnimation=false; + } + + /** + * 绑定到图例说明 + * @param legend + * + */ + public function bindLegend(legend:ILegend):void + { + _legend=legend; + } + + /** + * 添加数据 + * @param data + * @param policy 策略,可选:add, replace + * + */ + public function addData(data:Object, policy:String="add"):void + { + if (policy == "replace") + { + dataset.collection.shift(); + } + dataset.collection.push(data); + updateDisplayList(); + } + + /** + * 删除数据 + * @param index 索引 + * + */ + public function deleteDataAt(index:int):void + { + dataset.collection.splice(index,1); + updateDisplayList(); + } + + /** + * 响应右键操作 + * + */ + protected function contextMenuHandler():void + { + myContextMenu=new ContextMenu(); + if (myContextMenu.customItems == null) + return; + contextMenu=myContextMenu; + myContextMenu.hideBuiltInItems(); + var versionMenu:ContextMenuItem=new ContextMenuItem("Finger Chart, version: " + ChartGlobal.version); + versionMenu.enabled=false; + myContextMenu.customItems.push(versionMenu); + var fullscreenMenu:ContextMenuItem=new ContextMenuItem("Full Screen", true); + fullscreenMenu.addEventListener(ContextMenuEvent.MENU_ITEM_SELECT, fullscreenHandler); + myContextMenu.customItems.push(fullscreenMenu); + var saveMenu:ContextMenuItem=new ContextMenuItem("Save as Bitmap", false); + saveMenu.addEventListener(ContextMenuEvent.MENU_ITEM_SELECT, saveHandler); + myContextMenu.customItems.push(saveMenu); + var helpMenu:ContextMenuItem=new ContextMenuItem("www.riadev.com/o/fingerchart", true); + helpMenu.addEventListener(ContextMenuEvent.MENU_ITEM_SELECT, getHelpLink); + myContextMenu.customItems.push(helpMenu); + var dateMenu:ContextMenuItem=new ContextMenuItem("Last Update:" + ChartGlobal.buildDate, true); + dateMenu.enabled=false; + myContextMenu.customItems.push(dateMenu); + stage.doubleClickEnabled=true; + stage.addEventListener(MouseEvent.DOUBLE_CLICK, fullscreenHandler); + } + + /** + * 全屏 + * @param e + * + */ + private function fullscreenHandler(e:Event):void + { + stage.displayState=StageDisplayState.FULL_SCREEN; + } + + /** + * 保存图片 + * @param e + * + */ + private function saveHandler(e:ContextMenuEvent):void + { + var bmd:BitmapData=new BitmapData(stage.width, stage.height); + bmd.draw(this); + var bmdBytes:ByteArray=PNGEncoder.encode(bmd); + var saveFile:FileReference=new FileReference(); + var dateStr:String="finger_"; + var date:Date=new Date(); + dateStr+=date.getFullYear() + "-"; + dateStr+=date.getMonth() + 1 + "-"; + dateStr+=date.getDate(); + saveFile.save(bmdBytes, dateStr + ".png"); + } + + /** + * 链接 + * @param e + * + */ + private function getHelpLink(e:ContextMenuEvent):void + { + navigateToURL(new URLRequest("http://www.riadev.com/o/fingerchart"), "_blank"); + } + + } +} diff --git a/trunk/finger-chart-core-lib/src/main/flex/com/riameeting/finger/display/chart/IChart.as b/trunk/finger-chart-core-lib/src/main/flex/com/riameeting/finger/display/chart/IChart.as new file mode 100644 index 0000000..1701cb1 --- /dev/null +++ b/trunk/finger-chart-core-lib/src/main/flex/com/riameeting/finger/display/chart/IChart.as @@ -0,0 +1,121 @@ +package com.riameeting.finger.display.chart +{ + import com.riameeting.finger.display.axis.IAxis; + import com.riameeting.finger.display.container.IChartGraphicContainer; + import com.riameeting.finger.display.container.IPluginContainer; + import com.riameeting.finger.display.container.ITooltipContainer; + import com.riameeting.finger.display.legend.ILegend; + import com.riameeting.finger.effect.IEffect; + import com.riameeting.finger.vo.DatasetVO; + + import flash.display.DisplayObject; + import flash.display.MovieClip; + + /** + * 图表接口 + * @author Finger + * + */ + public interface IChart + { + /** + * 图表的配置 + * @return + * + */ + function get chartConfig():Object; + function set chartConfig(value:Object):void; + /** + * 宽度 + * @return + * + */ + function get width():Number; + function set width(value:Number):void; + /** + * 高度 + * @return + * + */ + function get height():Number; + function set height(value:Number):void; + /** * 图表的4个显示层级之一:坐标系 * @return 坐标系 * */ function get axis():IAxis; + function set axis(value:IAxis):void; + /** + * 图表的4个显示层级之一:图形容器 + * @return 图形容器 + * + */ + function get chartGraphicContainer():IChartGraphicContainer; + function set chartGraphicContainer(value:IChartGraphicContainer):void; + /** + * 图表的4个显示层级之一:鼠标提示容器 + * @return 鼠标提示容器 + * + */ + function get tooltipContainer():ITooltipContainer; + function set tooltipContainer(value:ITooltipContainer):void; + /** + * 图表的4个显示层级之一:插件容器 + * @return 插件容器 + * + */ + function get pluginContainer():IPluginContainer; + function set pluginContainer(value:IPluginContainer):void; + /** + * 对数据源的引用 + * @return DatasetVO引用 + * + */ + function get dataset():DatasetVO; + function set dataset(value:DatasetVO):void; + /** + * CSS样式定义 + * @return 对象 + * + */ + function get style():Object; + function set style(value:Object):void; + /** + * Skin + * @return 对象 + * + */ + function get skin():MovieClip; + function set skin(value:MovieClip):void; + /** + * 数据区间,只有区间定义的范围内数据才能显示 + * @return 数组 + * + */ + function get dataRange():Array; + function set dataRange(value:Array):void; + /** + * 更新显示列表的方法,当Flash场景尺寸发生改变,将调用此方法重绘图表 + * + */ + function updateDisplayList():void; + /** + * 加载资源 + * + */ + function loadAssets(chartConfigObj:Object = null):void; + /** + * 绑定到图例说明 + * @param legend + * + */ + function bindLegend(legend:ILegend):void; + /** + * 添加数据 + * @param data + * @param policy 策略,可选:add, replace + * + */ + function addData(data:Object,policy:String="add"):void; + + function addChild(child:DisplayObject):DisplayObject; + function removeChild(child:DisplayObject):DisplayObject; + + } +} \ No newline at end of file diff --git a/trunk/finger-chart-core-lib/src/main/flex/com/riameeting/finger/display/container/ChartGraphicContainer.as b/trunk/finger-chart-core-lib/src/main/flex/com/riameeting/finger/display/container/ChartGraphicContainer.as new file mode 100644 index 0000000..b64b919 --- /dev/null +++ b/trunk/finger-chart-core-lib/src/main/flex/com/riameeting/finger/display/container/ChartGraphicContainer.as @@ -0,0 +1,367 @@ +package com.riameeting.finger.display.container +{ + import com.riameeting.finger.config.ChartGlobal; + import com.riameeting.finger.display.chart.IChart; + import com.riameeting.finger.display.graphic.IChartGraphic; + import com.riameeting.finger.effect.IEffect; + import com.riameeting.finger.events.ChartEvent; + import com.riameeting.finger.factory.ObjectFactory; + import com.riameeting.finger.vo.DatasetVO; + + import flash.display.DisplayObject; + import flash.display.Sprite; + import flash.events.Event; + import flash.events.MouseEvent; + import flash.external.ExternalInterface; + import flash.filters.DropShadowFilter; + import flash.geom.Rectangle; + + /** + * 图形容器类 + * @author Finger + * + */ + public class ChartGraphicContainer extends Sprite implements IChartGraphicContainer + { + private var _dataset:DatasetVO; + private var _graphicClass:Class; + private var _graphicKey:String; + private var _yFields:Array; + private var _benchmark:Array; + private var _graphicsCollection:Array; + private var _seriesCollection:Array; + private var _seriesMode:Object = {}; + private var _style:Object = {color:0x000000,benchmarkColor:0x999999,lineWidth:4,dotWidth:2,lineMode:"bezier",shadow:true}; + private var _benchmarkClass:Class; + private var _graphicShowEffect:IEffect; + private var _graphicHideEffect:IEffect; + private var _chartRef:IChart; + private var _differentColors:Boolean; + /** + * 遮罩 + */ + protected var maskRect:Sprite = new Sprite(); + /** + * 是否开启动画模式 + */ + public var useAnimation:Boolean = true; + /** + * 对Chart的 引用 + * @return + * + */ + public function get chartRef():IChart {return _chartRef;} + public function set chartRef(value:IChart):void {_chartRef=value;} + /** + * 是否开启多色彩模式(每个图形使用单独的色彩) + * @return 布尔量 + * + */ + public function get differentColors():Boolean{return _differentColors;} + public function set differentColors(value:Boolean):void{_differentColors = value;} + /** + * 图形显示的特效 + * @return + * + */ + public function get graphicShowEffect():IEffect{return _graphicShowEffect;} + public function set graphicShowEffect(value:IEffect):void{_graphicShowEffect = value;} + /** + * 图形隐藏的特效 + * @return + * + */ + public function get graphicHideEffect():IEffect{return _graphicHideEffect;} + public function set graphicHideEffect(value:IEffect):void{_graphicHideEffect = value;} + /** + * 参考线类 + * @return 类 + * + */ + public function get benchmarkClass():Class{return _benchmarkClass;} + public function set benchmarkClass(value:Class):void{_benchmarkClass = value;} + /** + * CSS样式定义 + * @return 对象 + * + */ + public function get style():Object{return _style;} + public function set style(value:Object):void{_style = value;} + /** + * 图形类 + * @return 类 + * + */ + public function get graphicClass():Class{return _graphicClass;} + public function set graphicClass(value:Class):void{_graphicClass = value;} + /** + * 对数据源的引用 + * @return DatasetVO引用 + * + */ + public function get dataset():DatasetVO{return _dataset;} + public function set dataset(value:DatasetVO):void + { + _dataset = value; + yFields = value.config["yField"].split(","); + if(value.config["benchmark"] != null) benchmark = value.config["benchmark"].split(","); + } + /** + * Y轴定义的数据显示字段,可以为1个或多个 + * @return 数组 + * + */ + public function get yFields():Array{return _yFields;} + public function set yFields(value:Array):void{_yFields = value;} + /** + * Y轴定义的参考线显示字段,可以为1个或多个 + * @return 数组 + * + */ + public function get benchmark():Array {return _benchmark;} + public function set benchmark(value:Array):void {_benchmark = value;} + /** + * 构造方法 + * @param graphicClass 图形类 + * @param benchmarkClass 参考线类 + * @param differentColors 不同色彩模式 + * @param showEffect 显示特效 + * @param hideEffect 隐藏特效 + * + */ + public function ChartGraphicContainer(chartRef:IChart,graphicClass:Class,graphicKey:String,benchmarkClass:Class,differentColors:Boolean,showEffect:IEffect,hideEffect:IEffect) + { + super(); + _chartRef = chartRef; + _graphicClass = graphicClass; + _graphicKey = graphicKey; + _benchmarkClass = benchmarkClass; + _differentColors = differentColors; + graphicShowEffect = showEffect; + graphicHideEffect = hideEffect; + this.cacheAsBitmap = true; + mouseChildren = false; + mouseEnabled = false; + //FIXME:因为禁用了鼠标交互,ITEM_CLICK事件需要使用其它机制抛出 + addEventListener(ChartEvent.ITEM_CLICK,itemClickHanlder); + } + /** + * 更新显示列表的方法,当Flash场景尺寸发生改变,将调用此方法进行重绘 + * @param width 宽度 + * @param height 高度 + * + */ + public function updateDisplayList(width:uint,height:uint):void { + clear(); + //shadow + if(style["shadow"] != null) + this.filters = [new DropShadowFilter(4,45,0x000000,0.3)]; + for(var i:uint=0;i -1) { + graphic = ObjectFactory.produce(_benchmarkClass,"BenchmarkClass",[chartRef]) as IChartGraphic; + } else { + graphic = ObjectFactory.produce(_graphicClass,_graphicKey,[chartRef]) as IChartGraphic; + } + graphic.data = dataset.collection[j]; + graphic.style = style; + if(graphic.skin == null) graphic.skin = ChartGlobal.getSkin(graphic.skinName); + if(graphic.data["name"] == null) graphic.data["name"] = graphic.data[dataset.config["categoryField"]]; + graphic.name = graphic.data["name"]; + graphic.yField = yFields[i]; + if(graphic.data[graphic.yField] == "-") { + graphic.enabled = false; + graphic.data.enabled = false; + } else { + graphic.enabled = true; + graphic.data.enabled = true; + } + if(dataset.config["benchmark"] != null && benchmark.indexOf(graphic.yField) > -1) { + graphic.color = style["benchmarkColor"]; + } else { + if(differentColors) { + graphic.color = ChartGlobal.colorCollection[j]; + } else { + graphic.color = ChartGlobal.colorCollection[i]; + } + } + if(graphic.enabled) { + series.addChild(graphic as DisplayObject); + graphic.locate(chartRef.axis.getPoint(graphic.data,graphic.yField)); + _graphicsCollection.push(graphic); + } + } + if(seriesMode[series.name] != false) { + showSeries(series.name); + } else { + hideSeries(series.name); + } + } + //mask + var axisRect:Rectangle = chartRef.axis.getAxisRect(); + maskRect.graphics.clear(); + maskRect.graphics.beginFill(0x000000,1); + maskRect.graphics.drawRect(axisRect.x,axisRect.y,axisRect.width,axisRect.height); + maskRect.graphics.endFill(); + mask = maskRect; + parent.addChild(maskRect); + } + /** + * 显示series(适用于多组数据,比如多条折线) + * @param seriesName 名称 + * + */ + public function showSeries(seriesName:String,animation:Boolean=false):void { + var series:DisplayObject = getChildByName(seriesName); + if(useAnimation) animation = true; + if(animation && graphicShowEffect!=null) { + graphicShowEffect.execute(series,0.5,effectComplete); + (chartRef as Sprite).mouseEnabled = false; + } else { + series.visible = true; + } + } + /** + * 隐藏series(适用于多组数据,比如多条折线) + * @param seriesName 名称 + * + */ + public function hideSeries(seriesName:String,animation:Boolean=false):void { + var series:DisplayObject = getChildByName(seriesName); + if(useAnimation) animation = true; + if(animation && graphicHideEffect!=null) { + graphicHideEffect.execute(series,0.5,effectComplete); + (chartRef as Sprite).mouseEnabled = false; + } else { + series.visible = false; + } + } + /** + * 显示图形 + * @param graphicName 名称 + * + */ + public function showGraphic(graphicName:String,animation:Boolean=false):void { + var g:DisplayObject = getObjByName(graphicName); + if(graphicShowEffect!=null) { + graphicShowEffect.execute(g,0.5,effectComplete); + (chartRef as Sprite).mouseEnabled = false; + } else { + g.visible = true; + } + } + /** + * 隐藏图形 + * @param graphicName 名称 + * + */ + public function hideGraphic(graphicName:String,animation:Boolean=false):void { + var g:DisplayObject = getObjByName(graphicName); + if(graphicHideEffect!=null) { + graphicHideEffect.execute(g,0.5,effectComplete); + (chartRef as Sprite).mouseEnabled = false; + } else { + g.visible = false; + } + } + /** + * 一个包含了所有图形的数组 + * @return 数组 + * + */ + public function get graphicsCollection():Array {return _graphicsCollection;} + /** + * 如果yFields是多个,则将数据分为N个series,series放置到这个数组 + * @return 数组 + * + */ + public function get seriesCollection():Array {return _seriesCollection;} + /** + * 同seriesCollection对应,但存储的是series的状态 + * @return + * + */ + public function get seriesMode():Object {return _seriesMode;} + /** + * 获取容器中的图形 + * @param data 数据对象 + * @param yField Y轴字段 + * @return IChartGraphic + * + */ + public function getGraphic(data:Object,yField:String):IChartGraphic { + var graphic:IChartGraphic; + f:for each(var item:IChartGraphic in _graphicsCollection) { + if(item.data == data && item.yField == yField) { + graphic = item; + break f; + } + } + return graphic; + } + /** + * 图形被点击触发的回调方法 + * @param e 图形点击事件 + * + */ + protected function itemClickHanlder(e:ChartEvent):void { + if(chartRef.chartConfig["callback"] != null && ExternalInterface.available) { + ExternalInterface.call(chartRef.chartConfig["callback"],e.data); + } + } + /** + * 通过名称获取对象的引用 + * @param objName 对象名称 + * @return 对象 + * + */ + protected function getObjByName(objName:String):DisplayObject { + var obj:DisplayObject; + f:for each(var item:DisplayObject in graphicsCollection) { + if(item.name == objName) { + obj = item; + break f; + } + } + return obj; + } + /** + * 特效执行完毕 + * @param e + * + */ + protected function effectComplete():void { + (chartRef as Sprite).mouseEnabled = true; + } + /** + * 执行清理动作 + * + */ + public function clear():void { + graphics.clear(); + _graphicsCollection = []; + _seriesCollection = []; + var series:Sprite; + while(numChildren > 0) { + series = getChildAt(0) as Sprite; + while(series.numChildren > 0) { + (series.getChildAt(0) as IChartGraphic).clear(); + if(benchmark != null &&benchmark.indexOf(series.name) > -1) { + ObjectFactory.reclaim(_benchmarkClass,series.removeChildAt(0),"BenchmarkClass"); + } else { + ObjectFactory.reclaim(_graphicClass,series.removeChildAt(0),_graphicKey); + } + } + series.name = ""; + series.graphics.clear(); + ObjectFactory.reclaim(Sprite,removeChild(series),"Sprite"); + } + } + + } +} \ No newline at end of file diff --git a/trunk/finger-chart-core-lib/src/main/flex/com/riameeting/finger/display/container/IChartGraphicContainer.as b/trunk/finger-chart-core-lib/src/main/flex/com/riameeting/finger/display/container/IChartGraphicContainer.as new file mode 100644 index 0000000..ec382e5 --- /dev/null +++ b/trunk/finger-chart-core-lib/src/main/flex/com/riameeting/finger/display/container/IChartGraphicContainer.as @@ -0,0 +1,149 @@ +package com.riameeting.finger.display.container +{ + import com.riameeting.finger.display.chart.IChart; + import com.riameeting.finger.display.graphic.IChartGraphic; + import com.riameeting.finger.effect.IEffect; + import com.riameeting.finger.vo.DatasetVO; + + /** + * 图形容器接口 + * @author Finger + * + */ + public interface IChartGraphicContainer + { + /** + * 对Chart的 引用 + * @return + * + */ + function get chartRef():IChart; + function set chartRef(value:IChart):void; + /** + * 更新显示列表的方法,当Flash场景尺寸发生改变,将调用此方法进行重绘 + * @param width 宽度 + * @param height 高度 + * + */ + function updateDisplayList(width:uint,height:uint):void; + /** + * 对数据源的引用 + * @return DatasetVO引用 + * + */ + function get dataset():DatasetVO; + function set dataset(value:DatasetVO):void; + /** + * 图形类 + * @return 类 + * + */ + function get graphicClass():Class; + function set graphicClass(value:Class):void; + /** + * 参考线类 + * @return 类 + * + */ + function get benchmarkClass():Class; + function set benchmarkClass(value:Class):void; + /** + * Y轴定义的数据显示字段,可以为1个或多个 + * @return 数组 + * + */ + function get yFields():Array; + function set yFields(value:Array):void; + /** + * Y轴定义的参考线显示字段,可以为1个或多个 + * @return 数组 + * + */ + function get benchmark():Array; + function set benchmark(value:Array):void; + /** + * 是否开启多色彩模式(每个图形使用单独的色彩) + * @return 布尔量 + * + */ + function get differentColors():Boolean; + function set differentColors(value:Boolean):void; + /** + * CSS样式定义 + * @return 对象 + * + */ + function get style():Object; + function set style(value:Object):void; + /** + * 一个包含了所有图形的数组 + * @return 数组 + * + */ + function get graphicsCollection():Array; + /** + * 如果yFields是多个,则将数据分为N个series,series放置到这个数组 + * @return 数组 + * + */ + function get seriesCollection():Array; + /** + * 与seriesCollection对应,存储状态 + * @return Object + * + */ + function get seriesMode():Object; + /** + * 图形显示的特效 + * @return + * + */ + function get graphicShowEffect():IEffect; + function set graphicShowEffect(value:IEffect):void; + /** + * 图形隐藏的特效 + * @return + * + */ + function get graphicHideEffect():IEffect; + function set graphicHideEffect(value:IEffect):void; + /** + * 获取容器中的图形 + * @param data 数据对象 + * @param yField Y轴字段 + * @return IChartGraphic + * + */ + function getGraphic(data:Object,yField:String):IChartGraphic; + /** + * 显示series(适用于多组数据,比如多条折线) + * @param seriesName 名称 + * + */ + function showSeries(seriesName:String,animation:Boolean=false):void; + /** + * 隐藏series(适用于多组数据,比如多条折线) + * @param seriesName 名称 + * + */ + function hideSeries(seriesName:String,animation:Boolean=false):void; + /** + * 显示图形 + * @param graphicName 名称 + * + */ + function showGraphic(graphicName:String,animation:Boolean=false):void; + /** + * 隐藏图形 + * @param graphicName 名称 + * + */ + function hideGraphic(graphicName:String,animation:Boolean=false):void; + /** + * 执行清理动作 + * + */ + function clear():void; + + } +} \ No newline at end of file diff --git a/trunk/finger-chart-core-lib/src/main/flex/com/riameeting/finger/display/container/IPluginContainer.as b/trunk/finger-chart-core-lib/src/main/flex/com/riameeting/finger/display/container/IPluginContainer.as new file mode 100644 index 0000000..4478af0 --- /dev/null +++ b/trunk/finger-chart-core-lib/src/main/flex/com/riameeting/finger/display/container/IPluginContainer.as @@ -0,0 +1,54 @@ +package com.riameeting.finger.display.container +{ + import com.riameeting.finger.display.chart.IChart; + import com.riameeting.finger.vo.DatasetVO; + + /** + * 插件容器接口 + * @author Finger + * + */ + public interface IPluginContainer + { + /** + * 对Chart的 引用 + * @return + * + */ + function get chartRef():IChart; + function set chartRef(value:IChart):void; + /** + * 更新显示列表的方法,当Flash场景尺寸发生改变,将调用此方法重绘图表 + * @param width 宽度 + * @param height 高度 + */ + function updateDisplayList(width:uint,height:uint):void; + /** + * 对数据源的引用 + * @return DatasetVO引用 + * + */ + function get dataset():DatasetVO; + function set dataset(value:DatasetVO):void; + /** + * CSS样式定义 + * @return 对象 + * + */ + function get style():Object; + function set style(value:Object):void; + /** + * 插件数组,即允许同时加载多个插件 + * @return + * + */ + function get pluginCollection():Array; + function set pluginCollection(value:Array):void; + /** + * 执行清理动作 + * + */ + function clear():void; + + } +} \ No newline at end of file diff --git a/trunk/finger-chart-core-lib/src/main/flex/com/riameeting/finger/display/container/ITooltipContainer.as b/trunk/finger-chart-core-lib/src/main/flex/com/riameeting/finger/display/container/ITooltipContainer.as new file mode 100644 index 0000000..22e4ace --- /dev/null +++ b/trunk/finger-chart-core-lib/src/main/flex/com/riameeting/finger/display/container/ITooltipContainer.as @@ -0,0 +1,55 @@ +package com.riameeting.finger.display.container +{ + import com.riameeting.finger.display.chart.IChart; + import com.riameeting.finger.effect.IEffect; + import com.riameeting.finger.vo.DatasetVO; + + /** + * 鼠标提示容器接口 + * @author Finger + * + */ + public interface ITooltipContainer + { + /** + * 对Chart的 引用 + * @return + * + */ + function get chartRef():IChart; + function set chartRef(value:IChart):void; + /** + * 更新显示列表的方法,当Flash场景尺寸发生改变,将调用此方法重绘图表 + * @param width 宽度 + * @param height 高度 + */ + function updateDisplayList(width:uint,height:uint):void; + /** + * 对数据源的引用 + * @return DatasetVO引用 + * + */ + function get dataset():DatasetVO; + function set dataset(value:DatasetVO):void; + /** + * 鼠标提示类 + * @return 类 + * + */ + function get tooltipClass():Class; + function set tooltipClass(value:Class):void; + /** + * CSS样式定义 + * @return 对象 + * + */ + function get style():Object; + function set style(value:Object):void; + /** + * 执行清理动作 + * + */ + function clear():void; + + } +} \ No newline at end of file diff --git a/trunk/finger-chart-core-lib/src/main/flex/com/riameeting/finger/display/container/PluginContainer.as b/trunk/finger-chart-core-lib/src/main/flex/com/riameeting/finger/display/container/PluginContainer.as new file mode 100644 index 0000000..587b897 --- /dev/null +++ b/trunk/finger-chart-core-lib/src/main/flex/com/riameeting/finger/display/container/PluginContainer.as @@ -0,0 +1,114 @@ +package com.riameeting.finger.display.container +{ + import com.adobe.images.PNGEncoder; + import com.riameeting.finger.config.ChartGlobal; + import com.riameeting.finger.display.chart.IChart; + import com.riameeting.finger.plugin.IChartPlugin; + import com.riameeting.finger.vo.DatasetVO; + import com.riameeting.ui.control.Alert; + + import flash.display.Loader; + import flash.display.Sprite; + import flash.events.Event; + import flash.events.IOErrorEvent; + import flash.net.URLRequest; + + /** + * 插件容器类 + * @author Finger + * + */ + public class PluginContainer extends Sprite implements IPluginContainer + { + private var _dataset:DatasetVO; + private var _style:Object; + private var _pluginCollection:Array = []; + private var _chartRef:IChart; + /** + * 对Chart的 引用 + * @return + * + */ + public function get chartRef():IChart {return _chartRef;} + public function set chartRef(value:IChart):void {_chartRef=value;} + /** + * 插件数组,即允许同时加载多个插件 + * @return + * + */ + public function get pluginCollection():Array{return _pluginCollection;} + public function set pluginCollection(value:Array):void{_pluginCollection = value;} + /** + * CSS样式定义 + * @return 对象 + * + */ + public function get style():Object{return _style;} + public function set style(value:Object):void{_style = value;} + /** + * 对数据源的引用 + * @return DatasetVO引用 + * + */ + public function get dataset():DatasetVO{return _dataset;} + public function set dataset(value:DatasetVO):void{ + _dataset = value; + var pluginStr:String = chartRef.chartConfig["plugin"]; + if(pluginStr != null) { + for each(var url:String in pluginStr.split(",")) { + var loader:Loader = new Loader(); + loader.load(new URLRequest(url)); + loader.contentLoaderInfo.addEventListener(Event.COMPLETE,completeHandler); + loader.contentLoaderInfo.addEventListener(IOErrorEvent.IO_ERROR,errorHandler); + addChild(loader); + } + } + } + /** + * 构造方法 + * @param pluginStr 插件地址 + * + */ + public function PluginContainer(chartRef:IChart){ + _chartRef = chartRef; + PNGEncoder; + } + /** + * 插件加载完毕执行的回调方法 + * @param e 事件 + * + */ + protected function completeHandler(e:Event):void { + var plugin:IChartPlugin = e.currentTarget.content as IChartPlugin; + plugin.initPlugin(this); + pluginCollection.push(plugin); + } + /** + * 插件加载错误触发的回调方法 + * @param e IO错误 + * + */ + protected function errorHandler(e:IOErrorEvent):void { + Alert.show(e.toString(),"Error"); + } + /** + * 更新显示列表的方法,当Flash场景尺寸发生改变,将调用此方法重绘图表 + * @param width 宽度 + * @param height 高度 + */ + public function updateDisplayList(w:uint,h:uint):void { + if(pluginCollection == null) return; + for each(var plugin:IChartPlugin in pluginCollection) { + plugin.updateDisplayList(w,h); + } + } + /** + * 执行清理动作 + * + */ + public function clear():void { + + } + + } +} \ No newline at end of file diff --git a/trunk/finger-chart-core-lib/src/main/flex/com/riameeting/finger/display/container/TooltipContainer.as b/trunk/finger-chart-core-lib/src/main/flex/com/riameeting/finger/display/container/TooltipContainer.as new file mode 100644 index 0000000..fd3f244 --- /dev/null +++ b/trunk/finger-chart-core-lib/src/main/flex/com/riameeting/finger/display/container/TooltipContainer.as @@ -0,0 +1,307 @@ +package com.riameeting.finger.display.container +{ + import com.greensock.TweenLite; + import com.riameeting.controler.EventBus; + import com.riameeting.finger.config.ChartGlobal; + import com.riameeting.finger.display.chart.IChart; + import com.riameeting.finger.display.graphic.IChartGraphic; + import com.riameeting.finger.display.tooltip.ITooltip; + import com.riameeting.finger.vo.DatasetVO; + import com.riameeting.utils.NumberTool; + + import flash.display.DisplayObject; + import flash.display.DisplayObjectContainer; + import flash.display.Sprite; + import flash.events.Event; + import flash.events.MouseEvent; + import flash.events.TouchEvent; + import flash.geom.Point; + import flash.geom.Rectangle; + import flash.ui.Multitouch; + + /** + * 鼠标提示容器类 + * @author NeoGuo + * + */ + public class TooltipContainer extends Sprite implements ITooltipContainer + { + private var _dataset:DatasetVO; + private var _tooltipClass:Class; + + private var tooltip:ITooltip; + private var axisRect:Rectangle; + private var graphicsCollection:Array; + private var _style:Object={color: 0x000000, tipbgColor: 0xFFFFFF, tipbgAlpha: 100, borderWidth: 3, borderColor: 0x000000, borderAlpha: 20}; + private var _chartRef:IChart; + /** + * 监测规则 + */ + protected var checkType:String; + + /** + * 对Chart的 引用 + * @return + * + */ + public function get chartRef():IChart + { + return _chartRef; + } + + public function set chartRef(value:IChart):void + { + _chartRef=value; + } + + /** + * CSS样式定义 + * @return 对象 + * + */ + public function get style():Object + { + return _style; + } + + public function set style(value:Object):void + { + _style=value; + } + + /** + * 鼠标提示类 + * @return 类 + * + */ + public function get tooltipClass():Class + { + return _tooltipClass; + } + + public function set tooltipClass(value:Class):void + { + _tooltipClass=value; + } + + /** + * 对数据源的引用 + * @return DatasetVO引用 + * + */ + public function get dataset():DatasetVO + { + return _dataset; + } + + public function set dataset(value:DatasetVO):void + { + _dataset=value; + tooltip.style=style; + tooltip.skin=ChartGlobal.getSkin("skin.TooltipSkin"); + if (Multitouch.supportsTouchEvents) + { + (chartRef as DisplayObjectContainer).addEventListener(MouseEvent.MOUSE_DOWN, containerMouseHandler); + } + else + { + (chartRef as DisplayObjectContainer).addEventListener(MouseEvent.MOUSE_MOVE, containerMouseHandler); + } + if (stage != null) + { + stage.addEventListener(Event.MOUSE_LEAVE, function(e:Event):void + { + clear() + }); + } + } + + /** + * 构造方法 + * @param tooltipClass 鼠标提示类 + * @param unity 是否组合提示字符串 + * @param checkType 可选byx或byy + */ + public function TooltipContainer(chartRef:IChart, tooltipClass:Class, checkType:String="byx") + { + _chartRef=chartRef; + _tooltipClass=tooltipClass; + this.checkType=checkType; + tooltip=new tooltipClass() as ITooltip; + addChild(tooltip as DisplayObject); + tooltip.hide(); + mouseChildren=false; + mouseEnabled=false; + } + + /** + * 更新显示列表的方法,当Flash场景尺寸发生改变,将调用此方法重绘图表 + * @param width 宽度 + * @param height 高度 + */ + public function updateDisplayList(width:uint, height:uint):void + { + axisRect=chartRef.axis.getAxisRect(); + graphicsCollection=chartRef.chartGraphicContainer.graphicsCollection; + } + + /** + * 容器鼠标事件的回调方法 + * @param e 鼠标事件 + * + */ + protected function containerMouseHandler(e:MouseEvent):void + { + if (mouseX < axisRect.x || mouseX > (axisRect.x + axisRect.width) || mouseY < axisRect.y || mouseY > (axisRect.y + axisRect.height)) + { + tooltip.hide(); + clear(); + return; + } + clear(); + if (checkType == "byp") + { + checkValueByPoint(); + return; + } + var i:uint=0, hindex:int=0; + var seriel:Sprite=chartRef.chartGraphicContainer.seriesCollection[0]; + var nearlyGraphic:IChartGraphic=seriel.getChildAt(0) as IChartGraphic; + var nextGraphic:IChartGraphic, mousePoint:Point=new Point(), targetPoint:Point=new Point(), prevPoint:Point=new Point(); + prevPoint.x=nearlyGraphic.x + nearlyGraphic.center.x; + prevPoint.y=nearlyGraphic.y + nearlyGraphic.center.y; + mousePoint.x=mouseX; + mousePoint.y=mouseY; + for (i=0; i < seriel.numChildren; i++) + { + nextGraphic=seriel.getChildAt(i) as IChartGraphic; + targetPoint.x=nextGraphic.x + nextGraphic.center.x; + targetPoint.y=nextGraphic.y + nextGraphic.center.y; + if (checkType == "byx") + { + if (Math.abs(mousePoint.x - targetPoint.x) < Math.abs(mousePoint.x - prevPoint.x)) + { + nearlyGraphic=nextGraphic; + prevPoint.x=nearlyGraphic.x + nearlyGraphic.center.x; + prevPoint.y=nearlyGraphic.y + nearlyGraphic.center.y; + hindex=i; + } + } + else if (checkType == "byy") + { + if (Math.abs(mousePoint.y - targetPoint.y) < Math.abs(mousePoint.y - prevPoint.y)) + { + nearlyGraphic=nextGraphic; + prevPoint.x=nearlyGraphic.x + nearlyGraphic.center.x; + prevPoint.y=nearlyGraphic.y + nearlyGraphic.center.y; + hindex=i; + } + } + } + for (i=0; i < chartRef.chartGraphicContainer.seriesCollection.length; i++) + { + nextGraphic=chartRef.chartGraphicContainer.seriesCollection[i].getChildByName(nearlyGraphic.name) as IChartGraphic; + targetPoint.x=nextGraphic.x + nextGraphic.center.x; + targetPoint.y=nextGraphic.y + nextGraphic.center.y; + if (checkType == "byx") + { + if (Math.abs(mousePoint.y - targetPoint.y) < Math.abs(mousePoint.y - prevPoint.y)) + { + nearlyGraphic=nextGraphic; + prevPoint.x=nearlyGraphic.x + nearlyGraphic.center.x; + prevPoint.y=nearlyGraphic.y + nearlyGraphic.center.y; + } + } + else if (checkType == "byy") + { + if (Math.abs(mousePoint.x - targetPoint.x) < Math.abs(mousePoint.x - prevPoint.x)) + { + nearlyGraphic=nextGraphic; + prevPoint.x=nearlyGraphic.x + nearlyGraphic.center.x; + prevPoint.y=nearlyGraphic.y + nearlyGraphic.center.y; + } + } + } + nearlyGraphic.state=MouseEvent.MOUSE_OVER; + seriel=(nearlyGraphic as DisplayObject).parent as Sprite; + seriel.swapChildren(nearlyGraphic as DisplayObject, seriel.getChildAt(seriel.numChildren - 1)); + var tipStr:String=nearlyGraphic.data.tipString[nearlyGraphic.yField]; + tooltip.show(tipStr); + locateTooltip(nearlyGraphic.x + nearlyGraphic.center.x, nearlyGraphic.y + nearlyGraphic.center.y); + } + + /** + * 如果设置类型是byp,则调用此方法监测坐标 + * + */ + protected function checkValueByPoint():void + { + var nearlyGraphic:IChartGraphic=graphicsCollection[0]; + var nextGraphic:IChartGraphic, mousePoint:Point=new Point(), targetPoint:Point=new Point(), prevPoint:Point=new Point(); + prevPoint.x=nearlyGraphic.x + nearlyGraphic.center.x; + prevPoint.y=nearlyGraphic.y + nearlyGraphic.center.y; + for each (nextGraphic in graphicsCollection) + { + nextGraphic.state=MouseEvent.MOUSE_OUT; + mousePoint.x=mouseX; + mousePoint.y=mouseY; + targetPoint.x=nextGraphic.x + nextGraphic.center.x; + targetPoint.y=nextGraphic.y + nextGraphic.center.y; + if (NumberTool.getPointDistance(mousePoint, targetPoint) < NumberTool.getPointDistance(mousePoint, prevPoint)) + { + nearlyGraphic=nextGraphic; + prevPoint.x=nearlyGraphic.x + nearlyGraphic.center.x; + prevPoint.y=nearlyGraphic.y + nearlyGraphic.center.y; + } + } + nearlyGraphic.state=MouseEvent.MOUSE_OVER; + var seriel:Sprite=(nearlyGraphic as DisplayObject).parent as Sprite; + seriel.swapChildren(nearlyGraphic as DisplayObject, seriel.getChildAt(seriel.numChildren - 1)); + var tipStr:String=nearlyGraphic.data.tipString[nearlyGraphic.yField]; + tooltip.show(tipStr); + locateTooltip(nearlyGraphic.x + nearlyGraphic.center.x, nearlyGraphic.y + nearlyGraphic.center.y); + } + + /** + * 将鼠标提示定位到相应的位置 + * @param xValue x值 + * @param yValue y值 + * + */ + protected function locateTooltip(xValue:Number, yValue:Number):void + { + if (tooltip.x == 0 && tooltip.y == 0) + { + tooltip.x=xValue; + tooltip.y=yValue; + } + var targetX:Number=xValue; + var targetY:Number=yValue; + if (targetX + tooltip.width > axisRect.x + axisRect.width) + { + targetX=xValue - tooltip.width - 20; + } + if (targetY + tooltip.height > axisRect.y + axisRect.height) + { + targetY=axisRect.y + axisRect.height - tooltip.height; + } + TweenLite.to(tooltip, 0.2, {x: targetX, y: targetY}); + } + + /** + * 执行清理动作 + * + */ + public function clear():void + { + tooltip.hide(); + graphics.clear(); + var nextGraphic:IChartGraphic; + for each (nextGraphic in graphicsCollection) + { + nextGraphic.state=MouseEvent.MOUSE_OUT; + } + } + + } +} diff --git a/trunk/finger-chart-core-lib/src/main/flex/com/riameeting/finger/display/graphic/AreaGraphic.as b/trunk/finger-chart-core-lib/src/main/flex/com/riameeting/finger/display/graphic/AreaGraphic.as new file mode 100644 index 0000000..4a6a6ae --- /dev/null +++ b/trunk/finger-chart-core-lib/src/main/flex/com/riameeting/finger/display/graphic/AreaGraphic.as @@ -0,0 +1,77 @@ +package com.riameeting.finger.display.graphic +{ + import com.cartogrammar.drawing.CubicBezier; + import com.riameeting.finger.display.chart.IChart; + import com.riameeting.utils.ColorUtils; + + import flash.display.GradientType; + import flash.display.Sprite; + import flash.geom.Matrix; + import flash.geom.Point; + + /** + * 区域图图形 + * @author Finger + * + */ + public class AreaGraphic extends LineGraphic + { + /** + * 构造方法 + * @param chartRef + * + */ + public function AreaGraphic(chartRef:IChart) + { + super(chartRef); + } + /** + * 执行定位方法,确定图形的位置 + * @param value 坐标值 + * @param offset 偏移量 + * + */ + override public function locate(value:Point=null,offset:uint=10):void { + super.locate(value,offset); + var prevIndex:int = chartRef.dataset.collection.indexOf(data)-1; + var axisRectHeight:uint = chartRef.axis.getAxisRect().y + chartRef.axis.getAxisRect().height; + var prevObject:Object,prevPoint:Point; + var points:Array = []; + var i:uint = 0; + var matix:Matrix =new Matrix(); + if(prevIndex != -1) { + prevObject = chartRef.dataset.collection[prevIndex]; + prevPoint = chartRef.axis.getPoint(prevObject,yField); + if(style["lineMode"] == "line") { + if(prevObject.enabled) { + (parent as Sprite).graphics.lineStyle(); + matix.createGradientBox(x-prevPoint.x, axisRectHeight, Math.PI/2, 0, 0); + (parent as Sprite).graphics.beginGradientFill(GradientType.LINEAR,[ColorUtils.fadeColor(color,0xFFFFFF,0.2),color],[1,1],[0x00,0xFF],matix); + (parent as Sprite).graphics.moveTo(x+1,y-style.lineWidth); + (parent as Sprite).graphics.lineTo(prevPoint.x,prevPoint.y-style.lineWidth); + (parent as Sprite).graphics.lineTo(prevPoint.x,axisRectHeight); + (parent as Sprite).graphics.lineTo(x+1,axisRectHeight); + (parent as Sprite).graphics.lineTo(x+1,y-style.lineWidth); + (parent as Sprite).graphics.endFill(); + } + } else { + if(prevIndex == chartRef.dataset.collection.length-2) { + for(;i maxZValue) { + maxZValue = obj[zField]; + } + } + } + } + /** + * 构造方法 + * + */ + public function BubbleGraphic(chartRef:IChart) + { + super(chartRef); + } + /** + * 执行定位方法,确定图形的位置 + * @param value 坐标值 + * @param offset 偏移量 + * + */ + override public function locate(value:Point=null, offset:uint=10):void { + super.locate(value,offset); + var prevIndex:int = chartRef.dataset.collection.indexOf(data)-1; + var axis:IAxis = chartRef.axis; + if(prevIndex != -1) { + (parent as Sprite).graphics.clear(); + } + var r:uint = minRadius+(maxRadius-minRadius)*((data[zField]-minZValue))/(maxZValue-minZValue); + skin.width = skin.height = r+3; + //tip str + if(data["tipString"] == null) data["tipString"] = {}; + data["tipString"][yField] = ""+data.name+"
"; + var xField:String = chartRef.dataset.config["xField"]; + data["tipString"][yField] += xField+" : "+data[xField]+"
"; + var yTitle:String; + yTitle = chartRef.dataset.config["yTitle"]; + data["tipString"][yField] += yField+" : "+data[yField]+"
"; + data["tipString"][yField] += zField+" : "+data[zField]; + if(chartRef.dataset.config["qualifier"] != null) { + data["tipString"][yField] += chartRef.dataset.config["qualifier"]; + } + } + } +} \ No newline at end of file diff --git a/trunk/finger-chart-core-lib/src/main/flex/com/riameeting/finger/display/graphic/ColumnGraphic.as b/trunk/finger-chart-core-lib/src/main/flex/com/riameeting/finger/display/graphic/ColumnGraphic.as new file mode 100644 index 0000000..e92755b --- /dev/null +++ b/trunk/finger-chart-core-lib/src/main/flex/com/riameeting/finger/display/graphic/ColumnGraphic.as @@ -0,0 +1,53 @@ +package com.riameeting.finger.display.graphic +{ + import com.riameeting.finger.config.ChartGlobal; + import com.riameeting.finger.display.axis.IAxis; + import com.riameeting.finger.display.chart.IChart; + + import flash.display.DisplayObject; + import flash.display.Sprite; + import flash.geom.Point; + import flash.geom.Rectangle; + + /** + * 柱状图图形类 + * @author Finger + * + */ + public class ColumnGraphic extends LineGraphic + { + protected var columnOffset:Number = 5; + override public function set color(value:uint):void{ + _color = value; + } + /** + * 构造方法 + * + */ + public function ColumnGraphic(chartRef:IChart) + { + super(chartRef); + skinName = "skin.ColumnGraphic"; + } + /** + * 执行定位方法,确定图形的位置 + * @param value 坐标值 + * @param offset 偏移量 + * + */ + override public function locate(value:Point=null, offset:uint=10):void { + super.locate(value,offset); + var prevIndex:int = chartRef.dataset.collection.indexOf(data)-1; + var axis:IAxis = chartRef.axis; + if(prevIndex != -1) { + (parent as Sprite).graphics.clear(); + } + var axisRect:Rectangle = axis.getAxisRect(); + var columnWidth:Number = axisRect.width/(axis.dataset.collection.length+2) - columnOffset; + var columnItemWidth:Number = columnWidth/(axis.dataset.config["yField"].split(",").length-(axis.dataset.config["benchmark"]!=null?axis.dataset.config["benchmark"].split(",").length:0)); + var yFieldIndex:int = axis.dataset.config["yField"].split(",").indexOf(yField); + x += -(columnWidth)/2+columnItemWidth*yFieldIndex+columnItemWidth/2; + skin.updateDisplayList({width:columnItemWidth,height:axisRect.y+axisRect.height-y,color:_color}); + } + } +} \ No newline at end of file diff --git a/trunk/finger-chart-core-lib/src/main/flex/com/riameeting/finger/display/graphic/IChartGraphic.as b/trunk/finger-chart-core-lib/src/main/flex/com/riameeting/finger/display/graphic/IChartGraphic.as new file mode 100644 index 0000000..ffb5c09 --- /dev/null +++ b/trunk/finger-chart-core-lib/src/main/flex/com/riameeting/finger/display/graphic/IChartGraphic.as @@ -0,0 +1,141 @@ +package com.riameeting.finger.display.graphic +{ + import com.riameeting.finger.display.chart.IChart; + + import flash.display.MovieClip; + import flash.geom.Point; + + /** + * 图形接口 + * @author Finger + * + */ + public interface IChartGraphic + { + /** + * 对Chart的 引用 + * @return + * + */ + function get chartRef():IChart; + function set chartRef(value:IChart):void; + /** + * 数据点对应的定位坐标,一般与x和y一致 + * @return Object + * + */ + function get point():Point; + function set point(value:Point):void; + /** + * 数据对象 + * @return Object + * + */ + function get data():Object; + function set data(value:Object):void; + /** + * Y轴字段 + * @return 字符串 + * + */ + function get yField():String; + function set yField(value:String):void; + /** + * 颜色 + * @return 颜色值 + * + */ + function get color():uint; + function set color(value:uint):void; + /** + * 样式 + * @return + * + */ + function get style():Object; + function set style(value:Object):void; + /** + * 皮肤name + * @return + * + */ + function get skinName():String; + function set skinName(value:String):void; + /** + * 皮肤 + * @return + * + */ + function get skin():MovieClip; + function set skin(value:MovieClip):void; + /** + * 状态 + * @return 状态字符串 + * + */ + function get state():String; + function set state(value:String):void; + /** + * x坐标 + * @return Number + * + */ + function get x():Number; + function set x(value:Number):void; + /** + * y坐标 + * @return Number + * + */ + function get y():Number; + function set y(value:Number):void; + /** + * 宽度 + * @return Number + * + */ + function get width():Number; + function set width(value:Number):void; + /** + * 高度 + * @return Number + * + */ + function get height():Number; + function set height(value:Number):void; + /** + * 名称 + * @return 名称 + * + */ + function get name():String; + function set name(value:String):void; + /** + * 图形的中心点,鼠标提示将判断这个中心点来定位 + * @return 坐标值 + * + */ + function get center():Point; + function set center(value:Point):void; + /** + * 是否禁用 + * @return 布尔量 + * + */ + function get enabled():Boolean; + function set enabled(value:Boolean):void; + /** + * 执行定位方法,确定图形的位置 + * @param value 坐标值 + * @param offset 偏移量 + * + */ + function locate(value:Point=null,offset:uint=10):void; + /** + * 执行清理动作 + * + */ + function clear():void; + + } +} \ No newline at end of file diff --git a/trunk/finger-chart-core-lib/src/main/flex/com/riameeting/finger/display/graphic/LineGraphic.as b/trunk/finger-chart-core-lib/src/main/flex/com/riameeting/finger/display/graphic/LineGraphic.as new file mode 100644 index 0000000..0ef90fc --- /dev/null +++ b/trunk/finger-chart-core-lib/src/main/flex/com/riameeting/finger/display/graphic/LineGraphic.as @@ -0,0 +1,222 @@ +package com.riameeting.finger.display.graphic +{ + import com.cartogrammar.drawing.CubicBezier; + import com.riameeting.finger.config.ChartGlobal; + import com.riameeting.finger.display.chart.IChart; + import com.riameeting.finger.display.container.IChartGraphicContainer; + import com.riameeting.finger.events.ChartEvent; + + import flash.display.DisplayObject; + import flash.display.MovieClip; + import flash.display.Sprite; + import flash.events.MouseEvent; + import flash.filters.DropShadowFilter; + import flash.filters.GlowFilter; + import flash.geom.Point; + import flash.utils.setTimeout; + + /** + * 线状图图形类 + * @author Finger + * + */ + public class LineGraphic extends Sprite implements IChartGraphic + { + private var _data:Object; + private var _yField:String; + protected var _color:uint; + private var _state:String; + private var _style:Object; + private var _skinName:String; + private var _skin:MovieClip; + /** + * 鼠标提示字符串 + */ + protected var tipStr:String; + private var _point:Point; + private var _center:Point; + private var _enabled:Boolean = true; + private var _chartRef:IChart; + /** + * 对Chart的 引用 + * @return + * + */ + public function get chartRef():IChart {return _chartRef;} + public function set chartRef(value:IChart):void {_chartRef=value;} + /** + * 是否禁用 + * @return 布尔量 + * + */ + public function get enabled():Boolean{return _enabled;} + public function set enabled(value:Boolean):void{_enabled = value;} + /** + * 数据点对应的定位坐标,一般与x和y一致 + * @return Object + * + */ + public function get point():Point {return _point;}; + public function set point(value:Point):void {_point = value;}; + /** + * 图形的中心点,鼠标提示将判断这个中心点来定位 + * @return 坐标值 + * + */ + public function get center():Point{return _center;} + public function set center(value:Point):void{_center = value;} + /** + * 颜色 + * @return 颜色值 + * + */ + public function get color():uint{return _color;} + public function set color(value:uint):void{_color = value;skin.updateDisplayList({color:value})} + /** + * 样式 + * @return + * + */ + public function get style():Object {return _style}; + public function set style(value:Object):void {_style = value;}; + /** + * 皮肤name + * @return + * + */ + public function get skinName():String {return _skinName}; + public function set skinName(value:String):void {_skinName = value}; + /** + * 皮肤 + * @return + * + */ + public function get skin():MovieClip {return _skin}; + public function set skin(value:MovieClip):void {if(_skin != null) removeChild(_skin);_skin = value;_skin.hostComponent=this;addChildAt(_skin,0)}; + /** + * 数据对象 + * @return Object + * + */ + public function get data():Object{return _data;} + public function set data(value:Object):void{_data = value;} + /** + * Y轴字段 + * @return 字符串 + * + */ + public function get yField():String{return _yField;} + public function set yField(value:String):void{_yField = value;} + /** + * 状态 + * @return 状态字符串 + * + */ + public function get state():String{return _state;} + public function set state(value:String):void + { + _state = value; + if(skin == null) return; + graphics.clear(); + if(value == MouseEvent.MOUSE_OVER) { + skin.gotoAndStop(2); + } else if(value == MouseEvent.MOUSE_OUT) { + skin.gotoAndStop(1); + } + } + /** + * 构造方法 + * + */ + public function LineGraphic(chartRef:IChart) + { + super(); + _chartRef = chartRef; + addEventListener(MouseEvent.MOUSE_OVER,mouseHandler); + addEventListener(MouseEvent.MOUSE_OUT,mouseHandler); + addEventListener(MouseEvent.CLICK,mouseHandler); + mouseChildren = false; + buttonMode = true; + cacheAsBitmap = true; + _center = new Point(0,0); + _skinName = "skin.DotGraphic"; + } + /** + * 执行定位方法,确定图形的位置 + * @param value 坐标值 + * @param offset 偏移量 + * + */ + public function locate(value:Point=null,offset:uint=10):void { + if(value != null) _point = value; + x = _point.x; + y = _point.y; + var prevIndex:int = chartRef.dataset.collection.indexOf(data)-1; + if(style["lineMode"] == "line") { + if(prevIndex != -1) { + var prevObject:Object = chartRef.dataset.collection[prevIndex]; + if(prevObject.enabled) { + var prevPoint:Point = chartRef.axis.getPoint(prevObject,yField); + (parent as Sprite).graphics.lineStyle(style["lineWidth"],color); + (parent as Sprite).graphics.moveTo(x-0.5,y); + (parent as Sprite).graphics.lineTo(prevPoint.x,prevPoint.y); + } + } + } else { + if(prevIndex == chartRef.dataset.collection.length-2) { + var points:Array = []; + var i:uint = 0; + for(;i"+_yField+"
"; + var categoryField:String = chartRef.dataset.config["categoryField"]; + data["tipString"][_yField] += categoryField+" : "+data[categoryField]+"
"; + var yTitle:String = chartRef.dataset.config["yTitle"]; + data["tipString"][_yField] += yTitle+" : "+data[_yField]; + if(chartRef.dataset.config["qualifier"] != null) { + data["tipString"][_yField] += chartRef.dataset.config["qualifier"]; + } + } + /** + * 执行清理动作 + * + */ + public function clear():void { + graphics.clear(); + } + /** + * 响应鼠标事件的回调方法 + * @param e 鼠标事件 + * + */ + protected function mouseHandler(e:MouseEvent):void { + var itemEvt:ChartEvent; + switch(e.type) { + case MouseEvent.MOUSE_OVER: + itemEvt = new ChartEvent(ChartEvent.ITEM_MOUSE_OVER); + break; + case MouseEvent.MOUSE_OUT: + itemEvt = new ChartEvent(ChartEvent.ITEM_MOUSE_OUT); + break; + case MouseEvent.CLICK: + itemEvt = new ChartEvent(ChartEvent.ITEM_CLICK); + break; + } + //event dispatch + itemEvt.point = new Point(x,y); + itemEvt.data = data; + itemEvt.yField = yField; + dispatchEvent(itemEvt); + } + + } +} \ No newline at end of file diff --git a/trunk/finger-chart-core-lib/src/main/flex/com/riameeting/finger/display/graphic/PieGraphic.as b/trunk/finger-chart-core-lib/src/main/flex/com/riameeting/finger/display/graphic/PieGraphic.as new file mode 100644 index 0000000..fc63753 --- /dev/null +++ b/trunk/finger-chart-core-lib/src/main/flex/com/riameeting/finger/display/graphic/PieGraphic.as @@ -0,0 +1,111 @@ +package com.riameeting.finger.display.graphic +{ + import com.riameeting.finger.display.axis.IAxis; + import com.riameeting.finger.display.chart.IChart; + import com.riameeting.ui.control.Label; + import com.riameeting.utils.DrawTool; + + import flash.display.MovieClip; + import flash.events.MouseEvent; + import flash.geom.Point; + import flash.geom.Rectangle; + + /** + * 饼图图形 + * @author Finger + * + */ + public class PieGraphic extends LineGraphic + { + /** + * 定位坐标点 + */ + protected var locatePoint:Point; + /** + * 文本显示标签 + */ + protected var label:Label = new Label(false); + /** + * Pie无需Skin + * @param value + * + */ + override public function set skin(value:MovieClip):void {} + /** + * 设置颜色 + * @param value + * + */ + override public function set color(value:uint):void{_color = value} + /** + * 状态 + * @return 状态字符串 + * + */ + override public function set state(value:String):void{ + super.state = value; + if(value == MouseEvent.MOUSE_OVER) { + x+=center.x/10; + y+=center.y/10; + } else if(value == MouseEvent.MOUSE_OUT) { + filters = null; + x = locatePoint.x; + y = locatePoint.y; + } + } + /** + * 构造方法 + * @param chartRef + * + */ + public function PieGraphic(chartRef:IChart) + { + super(chartRef); + addChild(label); + } + /** + * 执行定位方法,确定图形的位置 + * @param value 坐标值 + * @param offset 偏移量 + * + */ + override public function locate(value:Point=null,offset:uint=0):void + { + if(value != null) point = value; + x = point.x; + y = point.y; + locatePoint = value; + var axis:IAxis = chartRef.axis; + var axisRect:Rectangle = chartRef.axis.getAxisRect(); + //sector + var angleObj:Object = axis.getAngle(data,yField); + var r:Number = (axisRect.width"+data[categoryField]+"
"; + var yTitle:String = chartRef.dataset.config["yTitle"]; + data["tipString"][yField] += yTitle+" : "+((angleObj.angle/360)*100).toFixed(2) + "%"; + if(chartRef.chartConfig["graphicLabel"] != "hidden") { + if(chartRef.chartConfig["graphicLabel"] == "first" && chartRef.dataset.collection.indexOf(data) != 0) { + return; + } + graphics.lineStyle(1,0x000000,1); + graphics.moveTo(center.x*2,center.y*2); + graphics.lineTo(center.x*2.1,center.y*2.1); + label.x = center.x*2.1; + label.y = center.y*2.1 - label.height; + label.text = data[categoryField]; + label.visible = true; + if(center.x > 0) { + graphics.lineTo(center.x*2.1+label.width,center.y*2.1); + } else { + label.x -= label.width; + graphics.lineTo(center.x*2.1-label.width,center.y*2.1); + } + } + } + } +} \ No newline at end of file diff --git a/trunk/finger-chart-core-lib/src/main/flex/com/riameeting/finger/display/graphic/PlotGraphic.as b/trunk/finger-chart-core-lib/src/main/flex/com/riameeting/finger/display/graphic/PlotGraphic.as new file mode 100644 index 0000000..30ded11 --- /dev/null +++ b/trunk/finger-chart-core-lib/src/main/flex/com/riameeting/finger/display/graphic/PlotGraphic.as @@ -0,0 +1,63 @@ +package com.riameeting.finger.display.graphic +{ + import com.riameeting.finger.config.ChartGlobal; + import com.riameeting.finger.display.axis.IAxis; + import com.riameeting.finger.display.chart.IChart; + + import flash.display.DisplayObject; + import flash.display.MovieClip; + import flash.display.Sprite; + import flash.geom.Point; + import flash.geom.Rectangle; + + /** + * 散点图图形类 + * @author Finger + * + */ + public class PlotGraphic extends LineGraphic + { + /** + * 皮肤 + * @return + * + */ + override public function set skin(value:MovieClip):void { + super.skin = value; + value.scaleX = value.scaleY = 1.5; + } + /** + * 构造方法 + * + */ + public function PlotGraphic(chartRef:IChart) + { + super(chartRef); + } + /** + * 执行定位方法,确定图形的位置 + * @param value 坐标值 + * @param offset 偏移量 + * + */ + override public function locate(value:Point=null, offset:uint=10):void { + super.locate(value,offset); + var prevIndex:int = chartRef.dataset.collection.indexOf(data)-1; + var axis:IAxis = chartRef.axis; + if(prevIndex != -1) { + (parent as Sprite).graphics.clear(); + } + //tip str + if(data["tipString"] == null) data["tipString"] = {}; + data["tipString"][yField] = ""+data.name+"
"; + var xField:String = chartRef.dataset.config["xField"]; + data["tipString"][yField] += xField+" : "+data[xField]+"
"; + var yTitle:String; + yTitle = chartRef.dataset.config["yTitle"]; + data["tipString"][yField] += yField+" : "+data[yField]; + if(chartRef.dataset.config["qualifier"] != null) { + data["tipString"][yField] += chartRef.dataset.config["qualifier"]; + } + } + } +} \ No newline at end of file diff --git a/trunk/finger-chart-core-lib/src/main/flex/com/riameeting/finger/display/legend/ILegend.as b/trunk/finger-chart-core-lib/src/main/flex/com/riameeting/finger/display/legend/ILegend.as new file mode 100644 index 0000000..256270f --- /dev/null +++ b/trunk/finger-chart-core-lib/src/main/flex/com/riameeting/finger/display/legend/ILegend.as @@ -0,0 +1,84 @@ +package com.riameeting.finger.display.legend +{ + import com.riameeting.finger.display.chart.IChart; + import com.riameeting.finger.vo.DatasetVO; + + /** + * 图表说明接口 + * @author Finger + * + */ + public interface ILegend + { + /** + * 对Chart的 引用 + * @return + * + */ + function get chartRef():IChart; + function set chartRef(value:IChart):void; + /** + * 名称 + * @return 字符串 + * + */ + function get name():String; + function set name(value:String):void; + /** + * x坐标值 + * @return + * + */ + function get x():Number; + function set x(value:Number):void; + /** + * y坐标值 + * @return + * + */ + function get y():Number; + function set y(value:Number):void; + /** + * 对数据源的引用 + * @return DatasetVO引用 + * + */ + function get dataset():DatasetVO; + function set dataset(value:DatasetVO):void; + /** + * CSS样式定义 + * @return 对象 + * + */ + function get style():Object; + function set style(value:Object):void; + /** + * 图表说明的类型 + * @return + * + */ + function get legendMode():String; + function set legendMode(value:String):void; + /** + * 图表说明宽度 + * @return + * + */ + function get width():Number; + function set width(value:Number):void; + /** + * 图表说明高度 + * @return + * + */ + function get height():Number; + function set height(value:Number):void; + /** + * 更新显示列表的方法,当Flash场景尺寸发生改变,将调用此方法重绘图表 + * @param width 宽度 + * @param height 高度 + */ + function updateDisplayList(w:uint,h:uint):void; + + } +} \ No newline at end of file diff --git a/trunk/finger-chart-core-lib/src/main/flex/com/riameeting/finger/display/legend/SelectableLegend.as b/trunk/finger-chart-core-lib/src/main/flex/com/riameeting/finger/display/legend/SelectableLegend.as new file mode 100644 index 0000000..32ff566 --- /dev/null +++ b/trunk/finger-chart-core-lib/src/main/flex/com/riameeting/finger/display/legend/SelectableLegend.as @@ -0,0 +1,85 @@ +package com.riameeting.finger.display.legend +{ + import flash.display.DisplayObject; + import flash.display.Sprite; + import flash.events.MouseEvent; + + import com.riameeting.finger.config.ChartGlobal; + import com.riameeting.finger.display.chart.IChart; + import com.riameeting.ui.control.CheckBox; + import com.riameeting.finger.display.graphic.IChartGraphic; + /** + * 可选择的图表说明类 + * @author Finger + * + */ + public class SelectableLegend extends SimpleLegend + { + /** + * 用于显示复选框的容器 + */ + protected var checkboxContainer:Sprite = new Sprite(); + /** + * 构造方法 + * @param legendMode 模式 + * @param legendWidth 宽度 + * @param legendHeight 高度 + * + */ + public function SelectableLegend(chartRef:IChart,legendMode:String,legendWidth:Number,legendHeight:Number) + { + super(chartRef,legendMode,legendWidth,legendHeight); + addChild(checkboxContainer); + } + /** + * 重写创建标签的方法 + * + */ + override public function createLabel():void + { + super.createLabel(); + labelContainer.x += 20; + var yFiledArr:Array = dataset.config["yField"].split(","); + var checkBox:CheckBox; + for(var i:uint=0;i -1) { + label = new GraphicLabel(false,style["benchmarkColor"],"line"); + } else { + label = new GraphicLabel(false,ChartGlobal.colorCollection[i],legendMode); + } + label.color = style["color"]; + label.y = i*label.height; + label.text = yFiledArr[i]; + labelContainer.addChild(label); + } + labelContainer.x = style["paddingLeft"]; + labelContainer.y = style["paddingTop"]; + } + /** + * 更新显示列表的方法,当Flash场景尺寸发生改变,将调用此方法重绘图表 + * @param width 宽度 + * @param height 高度 + */ + public function updateDisplayList(w:uint,h:uint):void { + graphics.clear(); + if(style != null && style["bgColor"] != null) { + graphics.lineStyle(1,0x000000,0.3); + graphics.beginFill(style["bgColor"],style["bgAlpha"]/100); + graphics.drawRect(0,0,w,h); + graphics.endFill(); + } + } + + } +} \ No newline at end of file diff --git a/trunk/finger-chart-core-lib/src/main/flex/com/riameeting/finger/display/legend/SlideLegend.as b/trunk/finger-chart-core-lib/src/main/flex/com/riameeting/finger/display/legend/SlideLegend.as new file mode 100644 index 0000000..a021170 --- /dev/null +++ b/trunk/finger-chart-core-lib/src/main/flex/com/riameeting/finger/display/legend/SlideLegend.as @@ -0,0 +1,368 @@ +package com.riameeting.finger.display.legend +{ + import com.adobe.lighthouse.controls.DraggableVerticalContainer; + import com.riameeting.finger.config.ChartGlobal; + import com.riameeting.finger.display.chart.IChart; + import com.riameeting.finger.vo.DatasetVO; + import com.riameeting.ui.control.CheckBox; + import com.riameeting.ui.control.GraphicLabel; + + import flash.display.Bitmap; + import flash.display.Sprite; + import flash.events.MouseEvent; + + import mx.charts.LegendItem; + + /** + * 专用于移动设备的图例说明 + * @author Finger + * + */ + public class SlideLegend extends Sprite implements ILegend + { + private var _dataset:DatasetVO; + private var _style:Object={color: 0xFFFFFF, paddingTop: 0, paddingLeft: 0, benchmarkColor: 0xCCCCCC, bgColor: 0x000000, bgAlpha: 80}; + /** + * 标签容器 + */ + protected var labelContainer:Sprite=new Sprite(); + protected var draggableContainer:DraggableVerticalContainer; + private var _legendMode:String; + + [Embed(source="../../../../../../resources/legend_button.png")] + private var SlideButtonClass:Class; + [Embed(source="../../../../../../resources/close.png")] + private var CloseButtonClass:Class; + private var slideImage:Bitmap; + private var closeImage:Bitmap; + private var _chartRef:IChart; + /** + * 控制图例显示的按钮 + */ + protected var slideButton:Sprite=new Sprite(); + /** + * 控制图例关闭的按钮 + */ + protected var closeButton:Sprite=new Sprite(); + /** + * 当前状态,open or close + */ + protected var currentState:String; + + /** + * 对Chart的 引用 + * @return + * + */ + public function get chartRef():IChart + { + return _chartRef; + } + + public function set chartRef(value:IChart):void + { + _chartRef=value; + } + + /** + * 图表说明宽度 + * @return + * + */ + override public function get width():Number + { + return 0; + } + + override public function set width(value:Number):void + { + // + } + + /** + * 图表说明高度 + * @return + * + */ + override public function get height():Number + { + return 0; + } + + override public function set height(value:Number):void + { + + } + + /** + * 图表说明的类型 + * @return + * + */ + public function get legendMode():String + { + return _legendMode; + } + + public function set legendMode(value:String):void + { + _legendMode=value; + } + + /** + * CSS样式定义 + * @return 对象 + * + */ + public function get style():Object + { + return _style; + } + + public function set style(value:Object):void + { + _style=value; + } + + /** + * 对数据源的引用 + * @return DatasetVO引用 + * + */ + public function get dataset():DatasetVO + { + return _dataset; + } + + public function set dataset(value:DatasetVO):void + { + _dataset=value; + createLabel(); + updateDisplayList(_chartRef.width, _chartRef.height); + } + + /** + * 构造方法 + * + */ + public function SlideLegend(chartRef:IChart, legendModeStr:String, w:int, h:int) + { + _chartRef=chartRef; + _legendMode=legendModeStr; + slideImage=new SlideButtonClass(); + slideButton.buttonMode=true; + slideButton.addChild(slideImage); + addChild(slideButton); + closeImage=new CloseButtonClass(); + closeButton.graphics.beginFill(0xFF0000,0); + closeButton.graphics.drawCircle(15,15,30); + closeButton.graphics.endFill(); + closeButton.buttonMode=true; + closeButton.addChild(closeImage); + slideButton.addEventListener(MouseEvent.MOUSE_DOWN, slideButtonHandler); + closeButton.addEventListener(MouseEvent.MOUSE_DOWN,closeButtonHandler); + // + draggableContainer = new DraggableVerticalContainer(0,0x333333,false,0,0,0,0); + draggableContainer.addChild(labelContainer); + } + + /** + * 创建标签 + * + */ + public function createLabel():void + { + var yFiledArr:Array=dataset.config["yField"].split(","); + var benchmarkArr:Array; + if (dataset.config["benchmark"] != null) + benchmarkArr=dataset.config["benchmark"].split(","); + var label:GraphicLabel, checkBox:CheckBox; + for (var i:uint=0; i < yFiledArr.length; i++) + { + //container + var legendItem:LegendItem=new LegendItem(100,64); + legendItem.y=i * legendItem.height; + legendItem.addEventListener(MouseEvent.CLICK, refrishChart); + labelContainer.addChild(legendItem); + //label + if (benchmarkArr != null && benchmarkArr.indexOf(yFiledArr[i]) > -1) + { + label=new GraphicLabel(false, style["benchmarkColor"], "line"); + } + else + { + label=new GraphicLabel(false, ChartGlobal.colorCollection[i], legendMode); + } + label.color=style["color"]; + label.x=50; + label.y=24; + label.text=yFiledArr[i]; + legendItem.addChild(label); + //check box + checkBox=new CheckBox(); + checkBox.x=10; + checkBox.y=24; + checkBox.name=yFiledArr[i]; + checkBox.selected=true; + legendItem.addChild(checkBox); + } + } + + /** + * 点击按钮后触发的方法 + * @param e + * + */ + protected function slideButtonHandler(e:MouseEvent):void + { + currentState = "open"; + _chartRef.addChild(draggableContainer); + updateDisplayList(_chartRef.width, _chartRef.height); + } + + /** + * 点击关闭按钮后触发的方法 + * @param e + * + */ + protected function closeButtonHandler(e:MouseEvent):void + { + currentState = "close"; + _chartRef.removeChild(draggableContainer); + _chartRef.removeChild(closeButton); + updateDisplayList(_chartRef.width, _chartRef.height); + } + + /** + * 刷新图表 + * @param e + * + */ + protected function refrishChart(e:MouseEvent):void + { + var currentCheckbox:CheckBox=(e.target.getChildAt(1)) as CheckBox; + currentCheckbox.selected=!currentCheckbox.selected; + var currentYField:String=currentCheckbox.name; + displayGraphics(currentCheckbox.selected, currentYField); + } + + /** + * 控制去显示某个图形 + * @param show 显示还是隐藏 + * @param yField y轴字段 + * + */ + protected function displayGraphics(show:Boolean, yField:String):void + { + var seriesArr:Array=chartRef.chartGraphicContainer.seriesCollection; + var seriesMode:Object=chartRef.chartGraphicContainer.seriesMode; + for each (var item:Sprite in seriesArr) + { + if (item.name == yField) + { + if (show) + { + seriesMode[item.name]=null; + chartRef.chartGraphicContainer.showSeries(item.name, true); + } + else + { + seriesMode[item.name]=false; + chartRef.chartGraphicContainer.hideSeries(item.name, true); + } + } + } + } + + /** + * 更新显示列表的方法,当Flash场景尺寸发生改变,将调用此方法重绘图表 + * @param width 宽度 + * @param height 高度 + */ + public function updateDisplayList(w:uint, h:uint):void + { + var pupedWidth:Number = w - 40; + var pupedHeight:Number = h - 40; + if(currentState == "open") + { + labelContainer.graphics.clear(); + labelContainer.graphics.beginFill(0x000000,0); + labelContainer.graphics.drawRect(0,0,pupedWidth,pupedHeight+1); + labelContainer.graphics.endFill(); + draggableContainer.x = 20; + draggableContainer.y = 20; + draggableContainer.width = pupedWidth; + draggableContainer.height = pupedHeight; + draggableContainer.refreshView(false); + for (var i:int = 0; i < labelContainer.numChildren; i++) + { + var legendItem:LegendItem = labelContainer.getChildAt(i) as LegendItem; + legendItem.width = pupedWidth; + } + _chartRef.addChild(closeButton); + closeButton.x = w - 60; + closeButton.y = 30; + } + slideButton.x=-slideImage.width; + slideButton.graphics.clear(); + slideButton.graphics.beginFill(0x000000, 0); + slideButton.graphics.drawRect(-10, 0, slideButton.width + 10, h); + slideButton.graphics.endFill(); + slideImage.y=(h - slideImage.height) / 2; + } + } +} +import flash.display.GradientType; +import flash.display.Sprite; +import flash.geom.Matrix; + +class LegendItem extends Sprite +{ + private var __width:Number = 0; + private var __height:Number = 0; + + override public function get width():Number + { + return __width; + } + + override public function set width(value:Number):void + { + __width = value; + updateDisplayList(__width,__height); + } + + override public function get height():Number + { + return __height; + } + + override public function set height(value:Number):void + { + __height = value; + updateDisplayList(__width,__height); + } + + public function LegendItem(w:int,h:int) + { + __width = w; + __height = h; + updateDisplayList(w,h); + } + + private function updateDisplayList(w:int,h:int):void + { + if(w == 0 || h == 0) + return; + this.graphics.clear(); + this.graphics.beginFill(0x000000, 1); + this.graphics.drawRect(0, 0, w, h); + this.graphics.endFill(); + this.graphics.lineStyle(2, 0xFFFFFF, 0.2); + this.graphics.moveTo(0, h); + this.graphics.lineTo(w, h); + mouseChildren=false; + buttonMode=true; + } + +} diff --git a/trunk/finger-chart-core-lib/src/main/flex/com/riameeting/finger/display/skin/AxisSkin.as b/trunk/finger-chart-core-lib/src/main/flex/com/riameeting/finger/display/skin/AxisSkin.as new file mode 100644 index 0000000..7f9ae0d --- /dev/null +++ b/trunk/finger-chart-core-lib/src/main/flex/com/riameeting/finger/display/skin/AxisSkin.as @@ -0,0 +1,199 @@ +package com.riameeting.finger.display.skin +{ + import com.riameeting.finger.display.axis.ReversalAxis; + import com.riameeting.finger.factory.ObjectFactory; + import com.riameeting.ui.control.Label; + import com.riameeting.utils.ColorUtils; + + import flash.display.GradientType; + import flash.display.MovieClip; + import flash.display.Sprite; + import flash.geom.Matrix; + import flash.geom.Rectangle; + + /** + * 默认的坐标系皮肤 + * @author RIAMeeting + * + */ + public class AxisSkin extends MovieClip implements ISkin + { + /** + * 计算底部标签的宽度总和,用于宽度超出的时候,进行优化处理 + */ + public var allBottomLabelWidth:uint; + /** + * 左上角显示的标签 + */ + public var titleL:Label=new Label(true); + /** + * 底部显示的标签 + */ + public var titleB:Label=new Label(true); + /** + * 标签的显示容器 + */ + protected var labelContainer:Sprite=new Sprite(); + private var _hostComponent:Object; + + /** + * 组件引用 + * @return + * + */ + public function get hostComponent():Object + { + return _hostComponent; + } + + public function set hostComponent(value:Object):void + { + _hostComponent=value; + } + + /** + * 构造方法 + * + */ + public function AxisSkin() + { + super(); + addChild(titleL); + addChild(titleB); + addChild(labelContainer); + } + + /** + * 更新显示列表 + * @param parm + * @param style + * + */ + public function updateDisplayList(parms:Object=null):void + { + var style:Object=_hostComponent.style; + var w:Number=_hostComponent.axisWidth, h:Number=_hostComponent.axisHeight; + var value:Object=_hostComponent.dataset; + titleL.text="" + value.config["yTitle"] + ""; + if (_hostComponent.xField != null) + { + titleB.text="" + _hostComponent.xField + ""; + } + else + { + titleB.text="" + value.config["categoryField"] + ""; + } + //reset location + titleB.x=(w - titleB.width) / 2; + titleB.y=h - titleB.height; + drawBottomContainer(w, h); + //create label + createLabels(w, h); + } + + /** + * 绘制底部容器 + * @param parm + * @param style + * + */ + protected function drawBottomContainer(w:Number, h:Number):void + { + graphics.clear(); + var style:Object=_hostComponent.style; + var color1:uint=style["lineColors"][0]; + var color2:uint=style["lineColors"][1]; + var alpha1:Number=style["lineAlphas"][0] / 100; + var alpha2:Number=style["lineAlphas"][1] / 100; + var stroke1:uint=style["lineStrokes"][0]; + var stroke2:uint=style["lineStrokes"][1]; + /*var matix:Matrix=new Matrix(); + matix.createGradientBox(w, h, Math.PI / 2); + graphics.beginGradientFill(GradientType.LINEAR, [color1, color2], [colorAlpha1, colorAlpha2], [0x00, 0xFF], matix); + graphics.drawRect(style["paddingLeft"], style["paddingTop"], style["lineWidth"], h - style["paddingTop"] - style["paddingBottom"]); + graphics.drawRect(style["paddingLeft"], h - style["paddingBottom"], w - style["paddingLeft"] - style["paddingRight"], style["lineWidth"]); + graphics.endFill();*/ + graphics.lineStyle(stroke1,color1,alpha1); + graphics.moveTo(style["paddingLeft"], style["paddingTop"]); + graphics.lineTo(style["paddingLeft"], h - style["paddingBottom"]); + graphics.lineTo(w - style["paddingRight"], h - style["paddingBottom"]); + graphics.lineStyle(stroke2,color2,alpha2); + } + + /** + * 创建需要显示的标签 + * + */ + protected function createLabels(w:Number, h:Number):void + { + var style:Object=_hostComponent.style; + //left label + var i:uint=0, currentLabel:Label; + _hostComponent.realGridHeight=_hostComponent.graphicArea.height / _hostComponent.countY; + var currentOffset:Number=_hostComponent.ignoreOffsetV ? style["offsetH"] : style["offsetV"]; + _hostComponent.realGridWidth=(_hostComponent.graphicArea.width - currentOffset * 2) / (_hostComponent.countX - 1); + for (; i < _hostComponent.countY; i++) + { + currentLabel=ObjectFactory.produce(Label, "Label"); + currentLabel.color=style["color"]; + currentLabel.y=int(style["paddingTop"]) + _hostComponent.realGridHeight * i - currentLabel.height / 2; + currentLabel.text=String(_hostComponent.maxValueY - int(((_hostComponent.maxValueY - _hostComponent.minValueY) / _hostComponent.countY) * i)); + labelContainer.addChild(currentLabel); + graphics.moveTo(style["paddingLeft"],currentLabel.y+currentLabel.height/2); + graphics.lineTo(w - style["paddingRight"],currentLabel.y+currentLabel.height/2); + } + //Bottom label + allBottomLabelWidth=0; + for (i=0; i < _hostComponent.countX; i++) + { + currentLabel=ObjectFactory.produce(Label, "Label"); + currentLabel.color=style["color"]; + currentLabel.name="l" + i; + if (_hostComponent.xField != null) + { + currentLabel.text=String(int(((_hostComponent.maxValueX - _hostComponent.minValueX) / (_hostComponent.countX - 1)) * i + _hostComponent.minValueX)); + } + else + { + currentLabel.text=_hostComponent.dataset.collection[i][_hostComponent.dataset.config["categoryField"]]; + } + currentLabel.x=int(style["paddingLeft"]) + _hostComponent.realGridWidth * i + currentOffset - currentLabel.width / 2; + currentLabel.y=_hostComponent.graphicArea.y + _hostComponent.graphicArea.height + 10; + labelContainer.addChild(currentLabel); + allBottomLabelWidth+=currentLabel.width; + } + if (allBottomLabelWidth > _hostComponent.graphicArea.width) + { + var hideIndex:uint=allBottomLabelWidth / _hostComponent.graphicArea.width; + var count:uint=0; + for (i=1; i < _hostComponent.countX; i++) + { + var bottomLabel:Label = labelContainer.getChildByName("l" + i) as Label; + if (count == hideIndex) + { + count=0; + } + else + { + bottomLabel.visible=false; + count++; + } + } + } + } + + /** + * 当需重绘坐标系的时候,调用此方法 + * + */ + public function clear():void + { + this.graphics.clear(); + while (labelContainer.numChildren > 0) + { + (labelContainer.getChildAt(0) as Label).clear(); + ObjectFactory.reclaim(Label, labelContainer.removeChildAt(0), "Label"); + } + } + } +} diff --git a/trunk/finger-chart-core-lib/src/main/flex/com/riameeting/finger/display/skin/BarGraphic.as b/trunk/finger-chart-core-lib/src/main/flex/com/riameeting/finger/display/skin/BarGraphic.as new file mode 100644 index 0000000..1628ba6 --- /dev/null +++ b/trunk/finger-chart-core-lib/src/main/flex/com/riameeting/finger/display/skin/BarGraphic.as @@ -0,0 +1,60 @@ +package com.riameeting.finger.display.skin +{ + import com.riameeting.utils.ColorUtils; + + import flash.display.GradientType; + import flash.display.MovieClip; + import flash.display.Sprite; + import flash.geom.Matrix; + + /** + * 默认的条图皮肤 + * @author RIAMeeting + * + */ + public class BarGraphic extends MovieClip implements ISkin + { + protected var dot:Sprite = new Sprite(); + private var _hostComponent:Object; + /** + * 组件引用 + * @return + * + */ + public function get hostComponent():Object {return _hostComponent}; + public function set hostComponent(value:Object):void {_hostComponent = value}; + public function BarGraphic() + { + super(); + dot.graphics.lineStyle(1,0x000000,1); + dot.graphics.beginFill(0xFFFFFF,1); + dot.graphics.drawCircle(0,0,6); + dot.graphics.endFill(); + dot.graphics.lineStyle(); + dot.graphics.beginFill(0x000000,1); + dot.graphics.drawCircle(0,0,2); + dot.graphics.endFill(); + dot.visible = false; + addChild(dot); + } + + public function updateDisplayList(parms:Object=null):void + { + graphics.clear(); + var matix:Matrix =new Matrix(); + matix.createGradientBox(-parms.height, -parms.width/2, 0, 0, 0); + graphics.beginGradientFill(GradientType.LINEAR,[ColorUtils.fadeColor(parms.color,0xFFFFFF,0.2),parms.color],[1,1],[0x00,0xFF],matix); + graphics.drawRect(-parms.height,-parms.width/2,parms.height,parms.width); + graphics.endFill(); + } + + override public function gotoAndStop(frame:Object, scene:String=null):void { + if(frame == 1) { + dot.visible = false; + } else { + dot.visible = true; + } + } + + } +} \ No newline at end of file diff --git a/trunk/finger-chart-core-lib/src/main/flex/com/riameeting/finger/display/skin/ChartSkin.as b/trunk/finger-chart-core-lib/src/main/flex/com/riameeting/finger/display/skin/ChartSkin.as new file mode 100644 index 0000000..c87e550 --- /dev/null +++ b/trunk/finger-chart-core-lib/src/main/flex/com/riameeting/finger/display/skin/ChartSkin.as @@ -0,0 +1,43 @@ +package com.riameeting.finger.display.skin +{ + import flash.display.GradientType; + import flash.display.MovieClip; + import flash.geom.Matrix; + + /** + * 默认的图表皮肤 + * @author RIAMeeting + * + */ + public class ChartSkin extends MovieClip implements ISkin + { + private var _hostComponent:Object; + /** + * 组件引用 + * @return + * + */ + public function get hostComponent():Object {return _hostComponent}; + public function set hostComponent(value:Object):void {_hostComponent = value}; + public function ChartSkin() + { + super(); + this.cacheAsBitmap = true; + } + + public function updateDisplayList(parm:Object=null):void { + graphics.clear(); + var style:Object = _hostComponent.style; + var color1:uint = style["bgColors"][0]; + var color2:uint = style["bgColors"][1]; + var colorAlpha1:Number = style["bgAlphas"][0]/100; + var colorAlpha2:Number = style["bgAlphas"][1]/100; + var matix:Matrix =new Matrix(); + matix.createGradientBox(parm.width, parm.height, Math.PI/2, 0, 0); + graphics.beginGradientFill(GradientType.LINEAR,[color1,color2],[colorAlpha1,colorAlpha2],[0x00,0xFF],matix); + graphics.drawRect(0,0,parm.width,parm.height); + graphics.endFill(); + } + + } +} \ No newline at end of file diff --git a/trunk/finger-chart-core-lib/src/main/flex/com/riameeting/finger/display/skin/ColumnGraphic.as b/trunk/finger-chart-core-lib/src/main/flex/com/riameeting/finger/display/skin/ColumnGraphic.as new file mode 100644 index 0000000..a803087 --- /dev/null +++ b/trunk/finger-chart-core-lib/src/main/flex/com/riameeting/finger/display/skin/ColumnGraphic.as @@ -0,0 +1,62 @@ +package com.riameeting.finger.display.skin +{ + import com.riameeting.utils.ColorUtils; + + import flash.display.GradientType; + import flash.display.MovieClip; + import flash.display.Sprite; + import flash.geom.Matrix; + + /** + * 默认的柱图图形皮肤 + * @author RIAMeeting + * + */ + public class ColumnGraphic extends MovieClip implements ISkin + { + protected var dot:Sprite = new Sprite(); + + private var _hostComponent:Object; + /** + * 组件引用 + * @return + * + */ + public function get hostComponent():Object {return _hostComponent}; + public function set hostComponent(value:Object):void {_hostComponent = value}; + + public function ColumnGraphic() + { + super(); + dot.graphics.lineStyle(1,0x000000,1); + dot.graphics.beginFill(0xFFFFFF,1); + dot.graphics.drawCircle(0,0,6); + dot.graphics.endFill(); + dot.graphics.lineStyle(); + dot.graphics.beginFill(0x000000,1); + dot.graphics.drawCircle(0,0,2); + dot.graphics.endFill(); + dot.visible = false; + addChild(dot); + } + + public function updateDisplayList(parms:Object=null):void + { + graphics.clear(); + var matix:Matrix =new Matrix(); + matix.createGradientBox(parms.width, parms.height, Math.PI/2, 0, 0); + graphics.beginGradientFill(GradientType.LINEAR,[ColorUtils.fadeColor(parms.color,0x000000,0.5),parms.color],[1,1],[0x00,0xFF],matix); + graphics.drawRect(-parms.width/2,0,parms.width,parms.height); + graphics.endFill(); + } + + override public function gotoAndStop(frame:Object, scene:String=null):void { + if(frame == 1) { + dot.visible = false; + } else { + dot.visible = true; + } + } + + } +} \ No newline at end of file diff --git a/trunk/finger-chart-core-lib/src/main/flex/com/riameeting/finger/display/skin/DotGraphic.as b/trunk/finger-chart-core-lib/src/main/flex/com/riameeting/finger/display/skin/DotGraphic.as new file mode 100644 index 0000000..0add0a0 --- /dev/null +++ b/trunk/finger-chart-core-lib/src/main/flex/com/riameeting/finger/display/skin/DotGraphic.as @@ -0,0 +1,55 @@ +package com.riameeting.finger.display.skin +{ + import flash.display.MovieClip; + /** + * 默认的点图形皮肤 + * @author RIAMeeting + * + */ + public class DotGraphic extends MovieClip implements ISkin + { + private var parms:Object; + + private var _hostComponent:Object; + /** + * 组件引用 + * @return + * + */ + public function get hostComponent():Object {return _hostComponent}; + public function set hostComponent(value:Object):void {_hostComponent = value}; + + public function DotGraphic() + { + super(); + } + + public function updateDisplayList(parms:Object=null):void + { + this.parms = parms; + drawGraphic(1); + } + + override public function gotoAndStop(frame:Object, scene:String=null):void { + drawGraphic(int(frame)); + } + + protected function drawGraphic(frame:int):void { + graphics.clear(); + var dotcolor:uint = parms.color; + var style:Object = _hostComponent.style; + if(frame == 2) { + dotcolor = 0x000000; + graphics.lineStyle(1,0x000000,1); + graphics.beginFill(0xFFFFFF,1); + graphics.drawCircle(0,0,style.dotWidth+4); + graphics.endFill(); + } + graphics.lineStyle(); + graphics.beginFill(dotcolor,1); + graphics.drawCircle(0,0,style.dotWidth); + graphics.endFill(); + } + + } +} \ No newline at end of file diff --git a/trunk/finger-chart-core-lib/src/main/flex/com/riameeting/finger/display/skin/ISkin.as b/trunk/finger-chart-core-lib/src/main/flex/com/riameeting/finger/display/skin/ISkin.as new file mode 100644 index 0000000..cea7653 --- /dev/null +++ b/trunk/finger-chart-core-lib/src/main/flex/com/riameeting/finger/display/skin/ISkin.as @@ -0,0 +1,18 @@ +package com.riameeting.finger.display.skin +{ + /** + * 皮肤元件接口 + * @author RIAMeeting + * + */ + public interface ISkin + { + function get hostComponent():Object; + function set hostComponent(value:Object):void; + /** + * 皮肤应实现这个方法 + * + */ + function updateDisplayList(parms:Object=null):void; + } +} \ No newline at end of file diff --git a/trunk/finger-chart-core-lib/src/main/flex/com/riameeting/finger/display/skin/TooltipSkin.as b/trunk/finger-chart-core-lib/src/main/flex/com/riameeting/finger/display/skin/TooltipSkin.as new file mode 100644 index 0000000..774c24c --- /dev/null +++ b/trunk/finger-chart-core-lib/src/main/flex/com/riameeting/finger/display/skin/TooltipSkin.as @@ -0,0 +1,44 @@ +package com.riameeting.finger.display.skin +{ + import flash.display.MovieClip; + import flash.text.TextField; + /** + * 默认的鼠标提示皮肤 + * @author RIAMeeting + * + */ + public class TooltipSkin extends MovieClip implements ISkin + { + public var label:TextField = new TextField(); + private var _hostComponent:Object; + /** + * 组件引用 + * @return + * + */ + public function get hostComponent():Object {return _hostComponent}; + public function set hostComponent(value:Object):void {_hostComponent = value}; + + public function TooltipSkin() + { + super(); + label.x = label.y = 8; + addChild(label); + } + + public function updateDisplayList(parms:Object=null):void + { + var style:Object = _hostComponent.style; + var color:String = style["color"]; + label.htmlText = "" + parms.value + ""; + label.width = label.textWidth + 4; + label.height = label.textHeight + 4; + graphics.clear(); + graphics.lineStyle(style["borderWidth"],style["borderColor"],style["borderAlpha"]/100); + graphics.beginFill(style["tipbgColor"],1); + graphics.drawRoundRect(10.5,5,label.width+10,label.height+10,8,8); + graphics.endFill(); + } + + } +} \ No newline at end of file diff --git a/trunk/finger-chart-core-lib/src/main/flex/com/riameeting/finger/display/tooltip/ITooltip.as b/trunk/finger-chart-core-lib/src/main/flex/com/riameeting/finger/display/tooltip/ITooltip.as new file mode 100644 index 0000000..5a89c23 --- /dev/null +++ b/trunk/finger-chart-core-lib/src/main/flex/com/riameeting/finger/display/tooltip/ITooltip.as @@ -0,0 +1,73 @@ +package com.riameeting.finger.display.tooltip +{ + import flash.display.MovieClip; + + /** + * 鼠标提示接口 + * @author Finger + * + */ + public interface ITooltip + { + /** + * 设置显示文本 + * @return + * + */ + function get text():String; + function set text(value:String):void; + /** + * 显示文本 + * @param text + * + */ + function show(text:String):void; + /** + * 隐藏 + * + */ + function hide():void; + /** + * x坐标值 + * @return + * + */ + function get x():Number; + function set x(value:Number):void; + /** + * y坐标值 + * @return + * + */ + function get y():Number; + function set y(value:Number):void; + /** + * 宽度 + * @return + * + */ + function get width():Number; + function set width(value:Number):void; + /** + * 高度 + * @return + * + */ + function get height():Number; + function set height(value:Number):void; + /** + * 样式 + * @return + * + */ + function get style():Object; + function set style(value:Object):void; + /** + * 皮肤 + * @return + * + */ + function get skin():MovieClip; + function set skin(value:MovieClip):void; + } +} \ No newline at end of file diff --git a/trunk/finger-chart-core-lib/src/main/flex/com/riameeting/finger/display/tooltip/Tooltip.as b/trunk/finger-chart-core-lib/src/main/flex/com/riameeting/finger/display/tooltip/Tooltip.as new file mode 100644 index 0000000..dd71f91 --- /dev/null +++ b/trunk/finger-chart-core-lib/src/main/flex/com/riameeting/finger/display/tooltip/Tooltip.as @@ -0,0 +1,87 @@ +package com.riameeting.finger.display.tooltip +{ + import com.riameeting.utils.DPIReset; + + import flash.display.MovieClip; + import flash.display.Sprite; + import flash.text.TextField; + import flash.text.TextFieldAutoSize; + import flash.text.TextFormat; + + /** + * 鼠标提示类 + * @author Finger + * + */ + public class Tooltip extends Sprite implements ITooltip + { + private var _text:String; + private var label:TextField; + private var _style:Object; + private var _skin:MovieClip; + /** + * 样式 + * @return + * + */ + public function get style():Object {return _style}; + public function set style(value:Object):void {_style = value;}; + /** + * 皮肤 + * @return + * + */ + public function get skin():MovieClip {return _skin} + public function set skin(value:MovieClip):void { + if(_skin != null) removeChild(_skin); + _skin = value; + _skin.hostComponent=this; + _skin.mouseChildren = false; + _skin.mouseEnabled = false; + addChildAt(_skin,0); + label = _skin.label; + label.multiline = true; + label.autoSize = TextFieldAutoSize.LEFT; + label.wordWrap = false; + var tf:TextFormat = new TextFormat(); + tf.size = DPIReset.getNumber(20); + label.defaultTextFormat = tf; + label.x = 15; + } + /** + * 设置显示文本 + * @return + * + */ + public function get text():String {return _text;} + public function set text(value:String):void { + _text = value; + skin.updateDisplayList({value:value}); + } + /** + * 显示文本 + * @param text + * + */ + public function show(value:String):void { + text = value; + visible = true; + } + /** + * 隐藏 + * + */ + public function hide():void { + visible = false; + } + /** + * 构造方法 + * + */ + public function Tooltip() + { + mouseEnabled = false; + mouseChildren = false; + } + } +} \ No newline at end of file diff --git a/trunk/finger-chart-core-lib/src/main/flex/com/riameeting/finger/effect/FadeIn.as b/trunk/finger-chart-core-lib/src/main/flex/com/riameeting/finger/effect/FadeIn.as new file mode 100644 index 0000000..f48afd1 --- /dev/null +++ b/trunk/finger-chart-core-lib/src/main/flex/com/riameeting/finger/effect/FadeIn.as @@ -0,0 +1,39 @@ +package com.riameeting.finger.effect +{ + import com.greensock.TweenLite; + + import flash.events.Event; + import flash.events.EventDispatcher; + /** + * 透明度渐变进入 + * @author Finger + * + */ + public class FadeIn implements IEffect + { + /** + * 构造方法 + * + */ + public function FadeIn() + { + super(); + } + /** + * 执行 + * @param obj 对象 + * @param time 时长 + * + */ + public function execute(obj:Object,time:Number,callback:Function = null):void + { + obj.alpha = 0; + obj.visible = true; + TweenLite.to(obj,time,{alpha:1,onComplete:callBack}); + function callBack():void { + if(callback != null) callback(); + } + } + + } +} \ No newline at end of file diff --git a/trunk/finger-chart-core-lib/src/main/flex/com/riameeting/finger/effect/FadeOut.as b/trunk/finger-chart-core-lib/src/main/flex/com/riameeting/finger/effect/FadeOut.as new file mode 100644 index 0000000..91883ea --- /dev/null +++ b/trunk/finger-chart-core-lib/src/main/flex/com/riameeting/finger/effect/FadeOut.as @@ -0,0 +1,35 @@ +package com.riameeting.finger.effect +{ + import com.greensock.TweenLite; + + import flash.events.Event; + import flash.events.EventDispatcher; + /** + * 透明度渐变淡出 + * @author Finger + * + */ + public class FadeOut implements IEffect + { + /** + * 构造方法 + * + */ + public function FadeOut() + { + } + /** + * 执行 + * @param obj 对象 + * @param time 时长 + * + */ + public function execute(obj:Object,time:Number,callback:Function=null):void + { + TweenLite.to(obj,time,{alpha:0,onComplete:callBack}); + function callBack():void { + if(callback != null) callback(); + } + } + } +} \ No newline at end of file diff --git a/trunk/finger-chart-core-lib/src/main/flex/com/riameeting/finger/effect/IEffect.as b/trunk/finger-chart-core-lib/src/main/flex/com/riameeting/finger/effect/IEffect.as new file mode 100644 index 0000000..9d4babc --- /dev/null +++ b/trunk/finger-chart-core-lib/src/main/flex/com/riameeting/finger/effect/IEffect.as @@ -0,0 +1,18 @@ +package com.riameeting.finger.effect +{ + /** + * 特效接口 + * @author Finger + * + */ + public interface IEffect + { + /** + * 执行 + * @param obj 对象 + * @param time 时长 + * + */ + function execute(obj:Object,time:Number,callback:Function=null):void; + } +} \ No newline at end of file diff --git a/trunk/finger-chart-core-lib/src/main/flex/com/riameeting/finger/effect/MoveIn.as b/trunk/finger-chart-core-lib/src/main/flex/com/riameeting/finger/effect/MoveIn.as new file mode 100644 index 0000000..a69c4e7 --- /dev/null +++ b/trunk/finger-chart-core-lib/src/main/flex/com/riameeting/finger/effect/MoveIn.as @@ -0,0 +1,61 @@ +package com.riameeting.finger.effect +{ + import com.greensock.TweenLite; + import com.greensock.easing.*; + import com.riameeting.finger.display.graphic.IChartGraphic; + + import flash.display.DisplayObject; + import flash.display.Sprite; + import flash.events.Event; + import flash.events.EventDispatcher; + import flash.events.TimerEvent; + import flash.geom.Point; + import flash.utils.Dictionary; + import flash.utils.Timer; + import flash.utils.setTimeout; + + /** + * 移动进入特效 + * @author Finger + * + */ + public class MoveIn implements IEffect + { + /** + * 对象哈希 + */ + public static var objDic:Dictionary = new Dictionary(); + /** + * 执行 + * @param obj 对象 + * @param time 时长 + * + */ + public function execute(obj:Object, time:Number, callback:Function = null):void + { + var seriel:Sprite = obj as Sprite; + seriel.visible = true; + var child:IChartGraphic; + var childNum:uint = seriel.numChildren; + var splitTime:Number = time/childNum; + var currentIndex:uint = 0; + seriel.graphics.clear(); + setTimeout(callBack,time*1000); + for(var i:uint=0;i= childNum) return; + child = seriel.getChildAt(currentIndex) as IChartGraphic; + child.locate(); + currentIndex++; + } + function callBack(...args):void { + if(callback != null) callback(); + } + } + } +} \ No newline at end of file diff --git a/trunk/finger-chart-core-lib/src/main/flex/com/riameeting/finger/effect/MoveOut.as b/trunk/finger-chart-core-lib/src/main/flex/com/riameeting/finger/effect/MoveOut.as new file mode 100644 index 0000000..24a5672 --- /dev/null +++ b/trunk/finger-chart-core-lib/src/main/flex/com/riameeting/finger/effect/MoveOut.as @@ -0,0 +1,54 @@ +package com.riameeting.finger.effect +{ + import com.greensock.TweenLite; + import com.greensock.easing.*; + import com.riameeting.finger.display.graphic.IChartGraphic; + + import flash.display.DisplayObject; + import flash.display.Sprite; + import flash.events.Event; + import flash.events.EventDispatcher; + import flash.events.TimerEvent; + import flash.geom.Point; + import flash.utils.Dictionary; + import flash.utils.Timer; + import flash.utils.setTimeout; + /** + * 移动淡出特效 + * @author Finger + * + */ + public class MoveOut implements IEffect + { + /** + * 构造方法 + * + */ + public function MoveOut() + { + } + /** + * 执行 + * @param obj 对象 + * @param time 时长 + * + */ + public function execute(obj:Object, time:Number, callback:Function = null):void + { + var seriel:Sprite = obj as Sprite; + var child:IChartGraphic; + var childNum:uint = seriel.numChildren; + var splitTime:Number = time/childNum; + var currentIndex:uint = 0; + seriel.graphics.clear(); + setTimeout(callBack,time*1000); + for(var i:uint=0;i0) { + object = cacheDic[key].shift(); + } else { + if(parms == null) { + object = new clazz(); + } else { + //FIXME:这是一个临时策略,需要修改为完全支持参数传递的方式 + switch(parms.length) { + case 1: + object = new clazz(parms[0]); + break; + case 2: + object = new clazz(parms[0],parms[1]); + break; + case 3: + object = new clazz(parms[0],parms[1],parms[2]); + break; + case 4: + object = new clazz(parms[0],parms[1],parms[2],parms[3]); + break; + case 5: + object = new clazz(parms[0],parms[1],parms[2],parms[3],parms[4]); + break; + } + } + } + return object; + } + /** + * 回收对象 + * @param clazz 类 + * @param object 对象 + * + */ + public static function reclaim(clazz:Class,object:*,key:String):void { + if(cacheDic[key] == null) return; + cacheDic[key].push(object); + } + + } +} \ No newline at end of file diff --git a/trunk/finger-chart-core-lib/src/main/flex/com/riameeting/finger/parser/CSSParser.as b/trunk/finger-chart-core-lib/src/main/flex/com/riameeting/finger/parser/CSSParser.as new file mode 100644 index 0000000..a2bae51 --- /dev/null +++ b/trunk/finger-chart-core-lib/src/main/flex/com/riameeting/finger/parser/CSSParser.as @@ -0,0 +1,100 @@ +package com.riameeting.finger.parser +{ + + import com.riameeting.utils.StringUtils; + + /** + * CSS解析器 + * + */ + public class CSSParser { + + private var _css:Object; + + /** + * 构造方法 + */ + public function CSSParser() { + _css = {}; + } + + /** + * 解析CSS到对象 + * @param cssStr + */ + public function parseCSS(cssStr:String):void { + var cssArr:Array = cssStr.match(/([\w \.:\#]+\{.+?\})/gs); //split all slectors{properties:values} + parseSelectors(cssArr); + } + + /** + * 解析CSS选择器和属性 + * @param cssArr Array + */ + private function parseSelectors(cssArr:Array):void { + var selector:String; + var properties:String; + var n:int = cssArr.length; + for (var i:int = 0; i < n; i++) { + selector = StringUtils.trim(cssArr[i].match(/.+(?=\{)/g)[0]); //everything before { + properties = cssArr[i].match(/(?<=\{).+(?=\})/g)[0]; //everything inside {} + setStyle(selector, parseProperties(properties)); + } + } + + /** + * 转换属性的字符串到对象 + * @param propStr + */ + private function parseProperties(propStr:String):Object { + var result:Object = {}; + var properties:Array = propStr.match(/\b\w[\w-:\#\/ ,]+/g); //split properties + var curProp:Array; + var n:int = properties.length; + for (var j:int = 0; j < n; j++) { + curProp = properties[j].split(":"); + result[StringUtils.toCamelCase(curProp[0])] = StringUtils.trim(curProp[1]); + if(curProp[1].split(" ").length > 1) { + result[StringUtils.toCamelCase(curProp[0])] = []; + for each(var value:String in curProp[1].split(" ")) { + result[StringUtils.toCamelCase(curProp[0])].push(value); + } + } + } + return result; + } + + /** + * 获取所有选择器的引用的数组 + */ + public function get selectors():Array { + var selectors:Array = []; + for (var prop:* in _css) { + selectors.push(prop); + } + return selectors; + } + + /** + * 通过选择器获取一个样式对象的引用 + */ + public function getStyle(selector:String):Object { return _css[selector]; } + + /** + * 设置样式 + * @param selector + * @param styleObj + */ + public function setStyle(selector:String, styleObj:Object):void { + if (_css[selector] === undefined) _css[selector] = { }; + _css[selector] = styleObj; + } + + /** + * 删除所有的选择器和属性 + */ + public function clear():void { _css = {}; } + + } + +} diff --git a/trunk/finger-chart-core-lib/src/main/flex/com/riameeting/finger/parser/CSVParser.as b/trunk/finger-chart-core-lib/src/main/flex/com/riameeting/finger/parser/CSVParser.as new file mode 100644 index 0000000..dbf48eb --- /dev/null +++ b/trunk/finger-chart-core-lib/src/main/flex/com/riameeting/finger/parser/CSVParser.as @@ -0,0 +1,35 @@ +package com.riameeting.finger.parser +{ + import com.riameeting.finger.vo.DatasetVO; + /** + * CSV解析器 + * @author Finger + * + */ + public class CSVParser + { + /** + * 将数据对象转换为CSV格式 + * @param dataset 数据对象 + * @return 字符串 + * + */ + public static function encode(dataset:DatasetVO):String + { + var str:String = dataset.config["categoryField"]; + var yFiled:String; + for each(yFiled in dataset.config["yField"].split(",")) { + str += ","+yFiled; + } + str += "\n"; + for each(var obj:Object in dataset.collection) { + str += obj[dataset.config["categoryField"]]; + for each(yFiled in dataset.config["yField"].split(",")) { + str += ","+obj[yFiled]; + } + str += "\n"; + } + return str; + } + } +} \ No newline at end of file diff --git a/trunk/finger-chart-core-lib/src/main/flex/com/riameeting/finger/parser/IParser.as b/trunk/finger-chart-core-lib/src/main/flex/com/riameeting/finger/parser/IParser.as new file mode 100644 index 0000000..b95069d --- /dev/null +++ b/trunk/finger-chart-core-lib/src/main/flex/com/riameeting/finger/parser/IParser.as @@ -0,0 +1,19 @@ +package com.riameeting.finger.parser +{ + import com.riameeting.finger.vo.DatasetVO; + /** + * 解析器接口 + * @author Finger + * + */ + public interface IParser + { + /** + * 解析 + * @param source 源格式 + * @return 返回转换后的对象 + * + */ + function parse(source:*):DatasetVO; + } +} \ No newline at end of file diff --git a/trunk/finger-chart-core-lib/src/main/flex/com/riameeting/finger/parser/JSONParser.as b/trunk/finger-chart-core-lib/src/main/flex/com/riameeting/finger/parser/JSONParser.as new file mode 100644 index 0000000..0cf300e --- /dev/null +++ b/trunk/finger-chart-core-lib/src/main/flex/com/riameeting/finger/parser/JSONParser.as @@ -0,0 +1,39 @@ +package com.riameeting.finger.parser +{ + import com.adobe.serialization.json.JSONDecoder; + import com.riameeting.finger.vo.DatasetVO; + import com.riameeting.utils.ArrayUtils; + + /** + * JSON解析器 + * @author Finger + * + */ + public class JSONParser implements IParser + { + private var jsonObj:Object; + /** + * 构造方法 + * + */ + public function JSONParser() + { + } + /** + * 解析 + * @param source 源格式 + * @return 返回转换后的对象 + * + */ + public function parse(source:*):DatasetVO + { + var headerObj:Object = {}; + var arr:Array = []; + jsonObj = new JSONDecoder(source).getValue(); + headerObj = jsonObj.config; + arr = jsonObj.dataset; + var arrPrototype:Array = ArrayUtils.clone(arr); + return new DatasetVO(headerObj,arrPrototype,arr); + } + } +} \ No newline at end of file diff --git a/trunk/finger-chart-core-lib/src/main/flex/com/riameeting/finger/parser/XMLParser.as b/trunk/finger-chart-core-lib/src/main/flex/com/riameeting/finger/parser/XMLParser.as new file mode 100644 index 0000000..4350391 --- /dev/null +++ b/trunk/finger-chart-core-lib/src/main/flex/com/riameeting/finger/parser/XMLParser.as @@ -0,0 +1,53 @@ +package com.riameeting.finger.parser +{ + import com.riameeting.finger.vo.DatasetVO; + import com.riameeting.utils.ArrayUtils; + + /** + * XML解析器 + * @author Finger + * + */ + public class XMLParser implements IParser + { + private var xmlSource:XML; + /** + * 构造方法 + * + */ + public function XMLParser() + { + } + /** + * 解析 + * @param source 源格式 + * @return 返回转换后的对象 + * + */ + public function parse(source:*):DatasetVO + { + var headerObj:Object = {}; + var arr:Array = []; + xmlSource = new XML(source); + var header:XML = xmlSource.config[0]; + var dt:String,dd:String,node:XML,nodeAtt:XML; + for each(node in header.attributes()) { + dt = node.localName().toString(); + dd = node.toString(); + headerObj[dt] = dd; + } + var nodes:XMLList = xmlSource.dataset.node; + for each(node in nodes) { + var valueObj:Object = {}; + for each(nodeAtt in node.attributes()) { + dt = nodeAtt.localName().toString(); + dd = nodeAtt.toString(); + valueObj[dt] = dd; + } + arr.push(valueObj); + } + var arrPrototype:Array = ArrayUtils.clone(arr); + return new DatasetVO(headerObj,arrPrototype,arr); + } + } +} \ No newline at end of file diff --git a/trunk/finger-chart-core-lib/src/main/flex/com/riameeting/finger/plugin/IChartPlugin.as b/trunk/finger-chart-core-lib/src/main/flex/com/riameeting/finger/plugin/IChartPlugin.as new file mode 100644 index 0000000..075fa4a --- /dev/null +++ b/trunk/finger-chart-core-lib/src/main/flex/com/riameeting/finger/plugin/IChartPlugin.as @@ -0,0 +1,25 @@ +package com.riameeting.finger.plugin +{ + import com.riameeting.finger.display.container.IPluginContainer; + /** + * 图表插件的接口 + * @author Finger + * + */ + public interface IChartPlugin + { + /** + * 初始化插件 + * @param container 插件容器 + * + */ + function initPlugin(container:IPluginContainer):void; + /** + * 更新显示列表 + * @param width 宽度 + * @param height 高度 + * + */ + function updateDisplayList(width:uint,height:uint):void; + } +} \ No newline at end of file diff --git a/trunk/finger-chart-core-lib/src/main/flex/com/riameeting/finger/vo/DatasetVO.as b/trunk/finger-chart-core-lib/src/main/flex/com/riameeting/finger/vo/DatasetVO.as new file mode 100644 index 0000000..52782a3 --- /dev/null +++ b/trunk/finger-chart-core-lib/src/main/flex/com/riameeting/finger/vo/DatasetVO.as @@ -0,0 +1,67 @@ +package com.riameeting.finger.vo +{ + /** + * 数据对象的封装 + * @author Finger + * + */ + public class DatasetVO + { + /** + * 配置对象 + */ + public var config:Object; + /** + * 数据集合原数据(完整集合,跟过滤无关) + */ + public var collectionPrototype:Array; + /** + * 数据集合,如果设置了dataRange,则会执行过滤 + */ + public var collection:Array; + /** + * 构造方法 + * @param config 配置对象 + * @param collection 数据集合 + * + */ + public function DatasetVO(config:Object, collectionPrototype:Array, collection:Array) + { + this.config = config; + this.collectionPrototype = collectionPrototype; + this.collection = collection; + super(); + } + /** + * 转换为字符串 + * @return + * + */ + public function toString():String + { + return "DatasetVO{config:" + config + ", collection:[" + collection + "]}"; + } + + /** + * 根据数值区间限制过滤数据 + * @param dataRange + * + */ + public function filterByRange(dataRange:Array):void + { + var startIndex:int = 0; + var endIndex:int = collectionPrototype.length-1; + if(dataRange != null && dataRange[0] >= 0 && dataRange[1] < collectionPrototype.length && dataRange[1]>dataRange[0]) + { + startIndex = dataRange[0]; + endIndex = dataRange[1]; + } + collection = []; + for (; startIndex <= endIndex; startIndex++) + { + collection.push(collectionPrototype[startIndex]); + } + } + + } +} \ No newline at end of file diff --git a/trunk/finger-chart-core-lib/src/main/resources/close.png b/trunk/finger-chart-core-lib/src/main/resources/close.png new file mode 100644 index 0000000..57f1c55 Binary files /dev/null and b/trunk/finger-chart-core-lib/src/main/resources/close.png differ diff --git a/trunk/finger-chart-core-lib/src/main/resources/legend_button.png b/trunk/finger-chart-core-lib/src/main/resources/legend_button.png new file mode 100644 index 0000000..1dbbf51 Binary files /dev/null and b/trunk/finger-chart-core-lib/src/main/resources/legend_button.png differ diff --git a/trunk/finger-chart-flex-lib/src/main/flex/com/riameeting/finger/flex/component/AreaChart.as b/trunk/finger-chart-flex-lib/src/main/flex/com/riameeting/finger/flex/component/AreaChart.as new file mode 100644 index 0000000..24e3e3d --- /dev/null +++ b/trunk/finger-chart-flex-lib/src/main/flex/com/riameeting/finger/flex/component/AreaChart.as @@ -0,0 +1,66 @@ +package com.riameeting.finger.flex.component +{ + import com.riameeting.finger.component.LineChart; + + import flash.events.Event; + + import mx.core.UIComponent; + + /** + * 区域图 + * @author NeoGuo + * + */ + public class AreaChart extends UIComponent + { + private var chart:com.riameeting.finger.component.AreaChart; + private var _dataURL:String; + private var dataLoaded:Boolean = false; + + public function get dataURL():String + { + return _dataURL; + } + public function set dataURL(value:String):void + { + _dataURL = value; + } + + public function get chartInstance():com.riameeting.finger.component.AreaChart + { + return chart; + } + + public function AreaChart() + { + super(); + minWidth = 100; + minHeight = 100; + } + + override protected function createChildren():void + { + super.createChildren(); + chart = new com.riameeting.finger.component.AreaChart(minWidth,minHeight); + addChild(chart); + } + + override protected function updateDisplayList(unscaledWidth:Number, unscaledHeight:Number):void + { + super.updateDisplayList(unscaledWidth,unscaledHeight); + chart.width = unscaledWidth; + chart.height = unscaledHeight; + if(!dataLoaded) + { + chart.loadAssets({data:dataURL}); + chart.addEventListener(Event.COMPLETE,dataCompleteHandler); + } + } + + protected function dataCompleteHandler(event:Event):void + { + dataLoaded = true; + } + + } +} \ No newline at end of file diff --git a/trunk/finger-chart-flex-lib/src/main/flex/com/riameeting/finger/flex/component/BubbleChart.as b/trunk/finger-chart-flex-lib/src/main/flex/com/riameeting/finger/flex/component/BubbleChart.as new file mode 100644 index 0000000..043620f --- /dev/null +++ b/trunk/finger-chart-flex-lib/src/main/flex/com/riameeting/finger/flex/component/BubbleChart.as @@ -0,0 +1,66 @@ +package com.riameeting.finger.flex.component +{ + import com.riameeting.finger.component.LineChart; + + import flash.events.Event; + + import mx.core.UIComponent; + + /** + * 气泡图 + * @author NeoGuo + * + */ + public class BubbleChart extends UIComponent + { + private var chart:com.riameeting.finger.component.BubbleChart; + private var _dataURL:String; + private var dataLoaded:Boolean = false; + + public function get dataURL():String + { + return _dataURL; + } + public function set dataURL(value:String):void + { + _dataURL = value; + } + + public function get chartInstance():com.riameeting.finger.component.BubbleChart + { + return chart; + } + + public function BubbleChart() + { + super(); + minWidth = 100; + minHeight = 100; + } + + override protected function createChildren():void + { + super.createChildren(); + chart = new com.riameeting.finger.component.BubbleChart(minWidth,minHeight); + addChild(chart); + } + + override protected function updateDisplayList(unscaledWidth:Number, unscaledHeight:Number):void + { + super.updateDisplayList(unscaledWidth,unscaledHeight); + chart.width = unscaledWidth; + chart.height = unscaledHeight; + if(!dataLoaded) + { + chart.loadAssets({data:dataURL}); + chart.addEventListener(Event.COMPLETE,dataCompleteHandler); + } + } + + protected function dataCompleteHandler(event:Event):void + { + dataLoaded = true; + } + + } +} \ No newline at end of file diff --git a/trunk/finger-chart-flex-lib/src/main/flex/com/riameeting/finger/flex/component/ColumnChart.as b/trunk/finger-chart-flex-lib/src/main/flex/com/riameeting/finger/flex/component/ColumnChart.as new file mode 100644 index 0000000..fac01e8 --- /dev/null +++ b/trunk/finger-chart-flex-lib/src/main/flex/com/riameeting/finger/flex/component/ColumnChart.as @@ -0,0 +1,66 @@ +package com.riameeting.finger.flex.component +{ + import com.riameeting.finger.component.LineChart; + + import flash.events.Event; + + import mx.core.UIComponent; + + /** + * 柱图 + * @author NeoGuo + * + */ + public class ColumnChart extends UIComponent + { + private var chart:com.riameeting.finger.component.ColumnChart; + private var _dataURL:String; + private var dataLoaded:Boolean = false; + + public function get dataURL():String + { + return _dataURL; + } + public function set dataURL(value:String):void + { + _dataURL = value; + } + + public function get chartInstance():com.riameeting.finger.component.ColumnChart + { + return chart; + } + + public function ColumnChart() + { + super(); + minWidth = 100; + minHeight = 100; + } + + override protected function createChildren():void + { + super.createChildren(); + chart = new com.riameeting.finger.component.ColumnChart(minWidth,minHeight); + addChild(chart); + } + + override protected function updateDisplayList(unscaledWidth:Number, unscaledHeight:Number):void + { + super.updateDisplayList(unscaledWidth,unscaledHeight); + chart.width = unscaledWidth; + chart.height = unscaledHeight; + if(!dataLoaded) + { + chart.loadAssets({data:dataURL}); + chart.addEventListener(Event.COMPLETE,dataCompleteHandler); + } + } + + protected function dataCompleteHandler(event:Event):void + { + dataLoaded = true; + } + + } +} \ No newline at end of file diff --git a/trunk/finger-chart-flex-lib/src/main/flex/com/riameeting/finger/flex/component/LineChart.as b/trunk/finger-chart-flex-lib/src/main/flex/com/riameeting/finger/flex/component/LineChart.as new file mode 100644 index 0000000..cf569fb --- /dev/null +++ b/trunk/finger-chart-flex-lib/src/main/flex/com/riameeting/finger/flex/component/LineChart.as @@ -0,0 +1,78 @@ +package com.riameeting.finger.flex.component +{ + import com.riameeting.finger.component.LineChart; + import com.riameeting.finger.display.legend.SlideLegend; + + import flash.events.Event; + + import mx.core.UIComponent; + + /** + * 线图 + * @author NeoGuo + * + */ + public class LineChart extends UIComponent + { + private var chart:com.riameeting.finger.component.LineChart; + private var _dataURL:String; + private var dataLoaded:Boolean = false; + + protected var legend:SlideLegend; + + public var enabledZoom:Boolean = false; + + public function get dataURL():String + { + return _dataURL; + } + public function set dataURL(value:String):void + { + _dataURL = value; + } + + public function get chartInstance():com.riameeting.finger.component.LineChart + { + return chart; + } + + public function LineChart() + { + super(); + minWidth = 100; + minHeight = 100; + } + + override protected function createChildren():void + { + super.createChildren(); + chart = new com.riameeting.finger.component.LineChart(minWidth,minHeight); + addChild(chart); + legend = new SlideLegend(chart,"line",0,0); + addChild(legend); + legend.x = chart.width; + chart.bindLegend(legend); + } + + override protected function updateDisplayList(unscaledWidth:Number, unscaledHeight:Number):void + { + super.updateDisplayList(unscaledWidth,unscaledHeight); + chart.enabledZoom = enabledZoom; + chart.width = unscaledWidth; + chart.height = unscaledHeight; + legend.x = chart.width; + legend.updateDisplayList(unscaledWidth,unscaledHeight); + if(!dataLoaded) + { + chart.loadAssets({data:dataURL}); + chart.addEventListener(Event.COMPLETE,dataCompleteHandler); + } + } + + protected function dataCompleteHandler(event:Event):void + { + dataLoaded = true; + } + + } +} \ No newline at end of file diff --git a/trunk/finger-chart-flex-lib/src/main/flex/com/riameeting/finger/flex/component/PieChart.as b/trunk/finger-chart-flex-lib/src/main/flex/com/riameeting/finger/flex/component/PieChart.as new file mode 100644 index 0000000..7b919a2 --- /dev/null +++ b/trunk/finger-chart-flex-lib/src/main/flex/com/riameeting/finger/flex/component/PieChart.as @@ -0,0 +1,66 @@ +package com.riameeting.finger.flex.component +{ + import com.riameeting.finger.component.LineChart; + + import flash.events.Event; + + import mx.core.UIComponent; + + /** + * 饼图 + * @author NeoGuo + * + */ + public class PieChart extends UIComponent + { + private var chart:com.riameeting.finger.component.PieChart; + private var _dataURL:String; + private var dataLoaded:Boolean = false; + + public function get dataURL():String + { + return _dataURL; + } + public function set dataURL(value:String):void + { + _dataURL = value; + } + + public function get chartInstance():com.riameeting.finger.component.PieChart + { + return chart; + } + + public function PieChart() + { + super(); + minWidth = 100; + minHeight = 100; + } + + override protected function createChildren():void + { + super.createChildren(); + chart = new com.riameeting.finger.component.PieChart(minWidth,minHeight); + addChild(chart); + } + + override protected function updateDisplayList(unscaledWidth:Number, unscaledHeight:Number):void + { + super.updateDisplayList(unscaledWidth,unscaledHeight); + chart.width = unscaledWidth; + chart.height = unscaledHeight; + if(!dataLoaded) + { + chart.loadAssets({data:dataURL}); + chart.addEventListener(Event.COMPLETE,dataCompleteHandler); + } + } + + protected function dataCompleteHandler(event:Event):void + { + dataLoaded = true; + } + + } +} \ No newline at end of file diff --git a/trunk/finger-chart-flex-lib/src/main/flex/com/riameeting/finger/flex/component/PlotChart.as b/trunk/finger-chart-flex-lib/src/main/flex/com/riameeting/finger/flex/component/PlotChart.as new file mode 100644 index 0000000..c0fe3c2 --- /dev/null +++ b/trunk/finger-chart-flex-lib/src/main/flex/com/riameeting/finger/flex/component/PlotChart.as @@ -0,0 +1,66 @@ +package com.riameeting.finger.flex.component +{ + import com.riameeting.finger.component.LineChart; + + import flash.events.Event; + + import mx.core.UIComponent; + + /** + * 散点图 + * @author NeoGuo + * + */ + public class PlotChart extends UIComponent + { + private var chart:com.riameeting.finger.component.PlotChart; + private var _dataURL:String; + private var dataLoaded:Boolean = false; + + public function get dataURL():String + { + return _dataURL; + } + public function set dataURL(value:String):void + { + _dataURL = value; + } + + public function get chartInstance():com.riameeting.finger.component.PlotChart + { + return chart; + } + + public function PlotChart() + { + super(); + minWidth = 100; + minHeight = 100; + } + + override protected function createChildren():void + { + super.createChildren(); + chart = new com.riameeting.finger.component.PlotChart(minWidth,minHeight); + addChild(chart); + } + + override protected function updateDisplayList(unscaledWidth:Number, unscaledHeight:Number):void + { + super.updateDisplayList(unscaledWidth,unscaledHeight); + chart.width = unscaledWidth; + chart.height = unscaledHeight; + if(!dataLoaded) + { + chart.loadAssets({data:dataURL}); + chart.addEventListener(Event.COMPLETE,dataCompleteHandler); + } + } + + protected function dataCompleteHandler(event:Event):void + { + dataLoaded = true; + } + + } +} \ No newline at end of file diff --git a/trunk/finger-chart-flex-lib/src/main/flex/design.xml b/trunk/finger-chart-flex-lib/src/main/flex/design.xml new file mode 100644 index 0000000..fdf2f87 --- /dev/null +++ b/trunk/finger-chart-flex-lib/src/main/flex/design.xml @@ -0,0 +1,21 @@ + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/trunk/finger-chart-flex-lib/src/main/flex/finger-chart-manifest.xml b/trunk/finger-chart-flex-lib/src/main/flex/finger-chart-manifest.xml new file mode 100644 index 0000000..44c88c5 --- /dev/null +++ b/trunk/finger-chart-flex-lib/src/main/flex/finger-chart-manifest.xml @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff --git a/trunk/finger-chart-main/area_chart/pom.xml b/trunk/finger-chart-main/area_chart/pom.xml new file mode 100644 index 0000000..999b44e --- /dev/null +++ b/trunk/finger-chart-main/area_chart/pom.xml @@ -0,0 +1,45 @@ + + + + + com.riameeting.fingerchart + finger-chart-main + 0.8 + + + 4.0.0 + + com.riameeting.fingerchart + area_chart + 0.8 + swf + Area Chart + + + ../src/main/flex + + + org.sonatype.flexmojos + flexmojos-maven-plugin + ${flexmojos.version} + true + + area_chart.as + + target/area_chart-0.8.swf + + + + + com.adobe.flex + compiler + ${flex.version} + pom + + + + + + diff --git a/trunk/finger-chart-main/bubble_chart/pom.xml b/trunk/finger-chart-main/bubble_chart/pom.xml new file mode 100644 index 0000000..bcb871a --- /dev/null +++ b/trunk/finger-chart-main/bubble_chart/pom.xml @@ -0,0 +1,42 @@ + + + + + com.riameeting.fingerchart + finger-chart-main + 0.8 + + + 4.0.0 + + com.riameeting.fingerchart + bubble-chart + 0.8 + swf + Bubble Chart + + + ../src/main/flex + + + org.sonatype.flexmojos + flexmojos-maven-plugin + ${flexmojos.version} + true + + bubble_chart.as + + + + com.adobe.flex + compiler + ${flex.version} + pom + + + + + + diff --git a/trunk/finger-chart-main/column_chart/pom.xml b/trunk/finger-chart-main/column_chart/pom.xml new file mode 100644 index 0000000..fdbe640 --- /dev/null +++ b/trunk/finger-chart-main/column_chart/pom.xml @@ -0,0 +1,42 @@ + + + + + com.riameeting.fingerchart + finger-chart-main + 0.8 + + + 4.0.0 + + com.riameeting.fingerchart + column-chart + 0.8 + swf + Column Chart + + + ../src/main/flex + + + org.sonatype.flexmojos + flexmojos-maven-plugin + ${flexmojos.version} + true + + column_chart.as + + + + com.adobe.flex + compiler + ${flex.version} + pom + + + + + + diff --git a/trunk/finger-chart-main/line_chart/pom.xml b/trunk/finger-chart-main/line_chart/pom.xml new file mode 100644 index 0000000..59fac6c --- /dev/null +++ b/trunk/finger-chart-main/line_chart/pom.xml @@ -0,0 +1,42 @@ + + + + + com.riameeting.fingerchart + finger-chart-main + 0.8 + + + 4.0.0 + + com.riameeting.fingerchart + line-chart + 0.8 + swf + Line Chart + + + ../src/main/flex + + + org.sonatype.flexmojos + flexmojos-maven-plugin + ${flexmojos.version} + true + + line_chart.as + + + + com.adobe.flex + compiler + ${flex.version} + pom + + + + + + diff --git a/trunk/finger-chart-main/pie_chart/pom.xml b/trunk/finger-chart-main/pie_chart/pom.xml new file mode 100644 index 0000000..93caa59 --- /dev/null +++ b/trunk/finger-chart-main/pie_chart/pom.xml @@ -0,0 +1,42 @@ + + + + + com.riameeting.fingerchart + finger-chart-main + 0.8 + + + 4.0.0 + + com.riameeting.fingerchart + pie-chart + 0.8 + swf + Pie Chart + + + ../src/main/flex + + + org.sonatype.flexmojos + flexmojos-maven-plugin + ${flexmojos.version} + true + + pie_chart.as + + + + com.adobe.flex + compiler + ${flex.version} + pom + + + + + + diff --git a/trunk/finger-chart-main/plot_chart/pom.xml b/trunk/finger-chart-main/plot_chart/pom.xml new file mode 100644 index 0000000..4406f8e --- /dev/null +++ b/trunk/finger-chart-main/plot_chart/pom.xml @@ -0,0 +1,42 @@ + + + + + com.riameeting.fingerchart + finger-chart-main + 0.8 + + + 4.0.0 + + com.riameeting.fingerchart + plot-chart + 0.8 + swf + Plot Chart + + + ../src/main/flex + + + org.sonatype.flexmojos + flexmojos-maven-plugin + ${flexmojos.version} + true + + plot_chart.as + + + + com.adobe.flex + compiler + ${flex.version} + pom + + + + + + diff --git a/trunk/finger-chart-main/pom.xml b/trunk/finger-chart-main/pom.xml new file mode 100644 index 0000000..eb4648c --- /dev/null +++ b/trunk/finger-chart-main/pom.xml @@ -0,0 +1,39 @@ + + + + + com.riameeting.fingerchart + finger-chart-superpom + 0.8 + + + 4.0.0 + + com.riameeting.fingerchart + finger-chart-main + 0.8 + pom + Finger Chart Main + + + area_chart + bar_chart + bubble_chart + column_chart + line_chart + pie_chart + plot_chart + + + + + + com.riameeting.fingerchart + finger-chart-core-lib + 0.8 + swc + + + diff --git a/trunk/finger-chart-main/src/main/flex/area_chart.as b/trunk/finger-chart-main/src/main/flex/area_chart.as new file mode 100644 index 0000000..9578533 --- /dev/null +++ b/trunk/finger-chart-main/src/main/flex/area_chart.as @@ -0,0 +1,40 @@ +package +{ + import com.riameeting.finger.component.*; + import com.riameeting.finger.display.legend.*; + + import flash.events.Event; + + + [SWF(backgroundColor="#FFFFFF",pageTitle="AreaChart")] + /** + * 区域图 + * + *

Website:http://www.riameeting.com/fingerchart

+ *

在线交流QQ群:72916285

+ * @author RIAMeeting + * + */ + public class area_chart extends ChartWrapper + { + /** + * 构造方法 + * + */ + public function area_chart() { + super(); + } + /** + * 初始化方法,将创建图表,并加载外部文件 + * @param e + * + */ + override protected function init(e:Event=null):void { + chart = new AreaChart(stage.stageWidth,stage.stageHeight); + if(chartConfig["legend"] != null) { + legend = new SlideLegend(chart,"rect",200,stage.stageHeight); + } + super.init(e); + } + } +} \ No newline at end of file diff --git a/trunk/finger-chart-main/src/main/flex/bubble_chart.as b/trunk/finger-chart-main/src/main/flex/bubble_chart.as new file mode 100644 index 0000000..12d1411 --- /dev/null +++ b/trunk/finger-chart-main/src/main/flex/bubble_chart.as @@ -0,0 +1,37 @@ +package +{ + import com.riameeting.finger.component.*; + import com.riameeting.finger.display.legend.*; + + import flash.events.Event; + + /** + * 气泡图 + * @author RIAMeeting + *

Website:http://www.riameeting.com/fingerchart

+ *

在线交流QQ群:72916285

+ */ + [SWF(backgroundColor="#FFFFFF",pageTitle="BubbleChart")] + public class bubble_chart extends ChartWrapper + { + /** + * 构造方法 + * + */ + public function bubble_chart() { + super(); + } + /** + * 初始化方法,将创建图表,并加载外部文件 + * @param e + * + */ + override protected function init(e:Event=null):void { + chart = new BubbleChart(stage.stageWidth,stage.stageHeight); + if(chartConfig["legend"] != null) { + legend = new SlideLegend(chart,"rect",200,stage.stageHeight); + } + super.init(e); + } + } +} \ No newline at end of file diff --git a/trunk/finger-chart-main/src/main/flex/column_chart.as b/trunk/finger-chart-main/src/main/flex/column_chart.as new file mode 100644 index 0000000..1ea5dd2 --- /dev/null +++ b/trunk/finger-chart-main/src/main/flex/column_chart.as @@ -0,0 +1,37 @@ +package +{ + import com.riameeting.finger.component.*; + import com.riameeting.finger.display.legend.*; + + import flash.events.Event; + + /** + * 柱状图 + * @author RIAMeeting + *

Website:http://www.riameeting.com/fingerchart

+ *

在线交流QQ群:72916285

+ */ + [SWF(backgroundColor="#FFFFFF",pageTitle="ColumnChart")] + public class column_chart extends ChartWrapper + { + /** + * 构造方法 + * + */ + public function column_chart() { + super(); + } + /** + * 初始化方法,将创建图表,并加载外部文件 + * @param e + * + */ + override protected function init(e:Event=null):void { + chart = new ColumnChart(stage.stageWidth,stage.stageHeight); + if(chartConfig["legend"] != null) { + legend = new SlideLegend(chart,"rect",200,stage.stageHeight); + } + super.init(e); + } + } +} \ No newline at end of file diff --git a/trunk/finger-chart-main/src/main/flex/data/json/line_json1.txt b/trunk/finger-chart-main/src/main/flex/data/json/line_json1.txt new file mode 100644 index 0000000..593340d --- /dev/null +++ b/trunk/finger-chart-main/src/main/flex/data/json/line_json1.txt @@ -0,0 +1 @@ +{"config":{"yTitle":"访问量","categoryField":"日期","yField":"频道一,频道二,参考线","benchmark":"参考线"},"dataset":[{"日期":"6月1日","参考线":"300","频道一":"100","频道二":"430"},{"日期":"6月2日","参考线":"300","频道一":"600","频道二":"230"}]} \ No newline at end of file diff --git a/trunk/finger-chart-main/src/main/flex/data/xml/barchart_data1.xml b/trunk/finger-chart-main/src/main/flex/data/xml/barchart_data1.xml new file mode 100644 index 0000000..9d43a38 --- /dev/null +++ b/trunk/finger-chart-main/src/main/flex/data/xml/barchart_data1.xml @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + \ No newline at end of file diff --git a/trunk/finger-chart-main/src/main/flex/data/xml/columnchart_data1.xml b/trunk/finger-chart-main/src/main/flex/data/xml/columnchart_data1.xml new file mode 100644 index 0000000..3dec6b6 --- /dev/null +++ b/trunk/finger-chart-main/src/main/flex/data/xml/columnchart_data1.xml @@ -0,0 +1,19 @@ + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/trunk/finger-chart-main/src/main/flex/data/xml/linechart_data1.xml b/trunk/finger-chart-main/src/main/flex/data/xml/linechart_data1.xml new file mode 100644 index 0000000..2d20fc2 --- /dev/null +++ b/trunk/finger-chart-main/src/main/flex/data/xml/linechart_data1.xml @@ -0,0 +1,19 @@ + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/trunk/finger-chart-main/src/main/flex/data/xml/piechart_data1.xml b/trunk/finger-chart-main/src/main/flex/data/xml/piechart_data1.xml new file mode 100644 index 0000000..48dc938 --- /dev/null +++ b/trunk/finger-chart-main/src/main/flex/data/xml/piechart_data1.xml @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + \ No newline at end of file diff --git a/trunk/finger-chart-main/src/main/flex/data/xml/plotchart_data1.xml b/trunk/finger-chart-main/src/main/flex/data/xml/plotchart_data1.xml new file mode 100644 index 0000000..2c4493c --- /dev/null +++ b/trunk/finger-chart-main/src/main/flex/data/xml/plotchart_data1.xml @@ -0,0 +1,12 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/trunk/finger-chart-main/src/main/flex/line_chart.as b/trunk/finger-chart-main/src/main/flex/line_chart.as new file mode 100644 index 0000000..b9ccd9e --- /dev/null +++ b/trunk/finger-chart-main/src/main/flex/line_chart.as @@ -0,0 +1,37 @@ +package +{ + import com.riameeting.finger.component.*; + import com.riameeting.finger.display.legend.*; + + import flash.events.Event; + + /** + * 线状图 + * @author RIAMeeting + *

Website:http://www.riameeting.com/fingerchart

+ *

在线交流QQ群:72916285

+ */ + [SWF(backgroundColor="#FFFFFF",pageTitle="LineChart")] + public class line_chart extends ChartWrapper + { + /** + * 构造方法 + * + */ + public function line_chart() { + super(); + } + /** + * 初始化方法,将创建图表,并加载外部文件 + * @param e + * + */ + override protected function init(e:Event=null):void { + chart = new LineChart(stage.stageWidth,stage.stageHeight); + if(chartConfig["legend"] != null) { + legend = new SlideLegend(chart,"rect",200,stage.stageHeight); + } + super.init(e); + } + } +} \ No newline at end of file diff --git a/trunk/finger-chart-main/src/main/flex/package-description/package-description.xml b/trunk/finger-chart-main/src/main/flex/package-description/package-description.xml new file mode 100644 index 0000000..03cb738 --- /dev/null +++ b/trunk/finger-chart-main/src/main/flex/package-description/package-description.xml @@ -0,0 +1,28 @@ + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/trunk/finger-chart-main/src/main/flex/pie_chart.as b/trunk/finger-chart-main/src/main/flex/pie_chart.as new file mode 100644 index 0000000..492ca5a --- /dev/null +++ b/trunk/finger-chart-main/src/main/flex/pie_chart.as @@ -0,0 +1,37 @@ +package +{ + import com.riameeting.finger.component.*; + import com.riameeting.finger.display.legend.*; + + import flash.events.Event; + + /** + * 饼图 + * @author RIAMeeting + *

Website:http://www.riameeting.com/fingerchart

+ *

在线交流QQ群:72916285

+ */ + [SWF(backgroundColor="#FFFFFF",pageTitle="PieChart")] + public class pie_chart extends ChartWrapper + { + /** + * 构造方法 + * + */ + public function pie_chart() { + super(); + } + /** + * 初始化方法,将创建图表,并加载外部文件 + * @param e + * + */ + override protected function init(e:Event=null):void { + chart = new PieChart(stage.stageWidth,stage.stageHeight); + if(chartConfig["legend"] != null) { + legend = new SlideLegend(chart,"rect",200,stage.stageHeight); + } + super.init(e); + } + } +} \ No newline at end of file diff --git a/trunk/finger-chart-main/src/main/flex/plot_chart.as b/trunk/finger-chart-main/src/main/flex/plot_chart.as new file mode 100644 index 0000000..46f8c92 --- /dev/null +++ b/trunk/finger-chart-main/src/main/flex/plot_chart.as @@ -0,0 +1,37 @@ +package +{ + import com.riameeting.finger.component.*; + import com.riameeting.finger.display.legend.*; + + import flash.events.Event; + + /** + * 散点图 + * @author RIAMeeting + *

Website:http://www.riameeting.com/fingerchart

+ *

在线交流QQ群:72916285

+ */ + [SWF(backgroundColor="#FFFFFF",pageTitle="PlotChart")] + public class plot_chart extends ChartWrapper + { + /** + * 构造方法 + * + */ + public function plot_chart() { + super(); + } + /** + * 初始化方法,将创建图表,并加载外部文件 + * @param e + * + */ + override protected function init(e:Event=null):void { + chart = new PlotChart(stage.stageWidth,stage.stageHeight); + if(chartConfig["legend"] != null) { + legend = new SlideLegend(chart,"rect",200,stage.stageHeight); + } + super.init(e); + } + } +} \ No newline at end of file diff --git a/trunk/finger-chart-main/src/main/flex/skin/cartoon_skin.swf b/trunk/finger-chart-main/src/main/flex/skin/cartoon_skin.swf new file mode 100644 index 0000000..2430472 Binary files /dev/null and b/trunk/finger-chart-main/src/main/flex/skin/cartoon_skin.swf differ diff --git a/trunk/finger-chart-main/src/main/flex/skin/default_skin.swf b/trunk/finger-chart-main/src/main/flex/skin/default_skin.swf new file mode 100644 index 0000000..3b56b1e Binary files /dev/null and b/trunk/finger-chart-main/src/main/flex/skin/default_skin.swf differ diff --git a/trunk/finger-chart-main/src/test/flex/UITest.as b/trunk/finger-chart-main/src/test/flex/UITest.as new file mode 100644 index 0000000..77f9bb9 --- /dev/null +++ b/trunk/finger-chart-main/src/test/flex/UITest.as @@ -0,0 +1,130 @@ +package +{ + import com.riameeting.finger.component.*; + import com.riameeting.finger.config.ChartGlobal; + import com.riameeting.finger.display.graphic.*; + import com.riameeting.finger.events.ChartEvent; + import com.riameeting.ui.control.Alert; + import com.riameeting.ui.control.CheckBox; + import com.riameeting.ui.control.Label; + + import flash.display.Sprite; + import flash.display.StageAlign; + import flash.display.StageScaleMode; + import flash.events.Event; + + /** + * 测试类:测试UI组件 + * @author Finger + * + */ + public class UITest extends Sprite + { + /** + * 构造方法 + * + */ + public function UITest() + { + Alert.container = this; + stage.scaleMode = StageScaleMode.NO_SCALE; + stage.align = StageAlign.TOP_LEFT; + addEventListener(Event.ENTER_FRAME,checkStage); + } + /** + * 检查Stage是否获取了正确的宽度 + * @param e + * + */ + protected function checkStage(e:Event):void { + if(stage.stageWidth != 0) { + init(); + removeEventListener(Event.ENTER_FRAME,checkStage); + } + } + /** + * 初始化方法 + * + */ + protected function init():void { + //Label test + var t:Label = new Label(true); + addChild(t); + t.text = "Finger Chart UI示例"; + //Label test + var label:Label = new Label(); + addChild(label); + label.x = 200; + label.text = "100000"; + //check box + var checkBox:CheckBox = new CheckBox(); + checkBox.selected = true; + checkBox.y = 30; + checkBox.label = "我是复选框"; + addChild(checkBox); + //linechart + var chartConfig1:Object = {data:"data/xml/linechart_data1.xml",skin:"skin/default_skin.swf",css:"css/default.css",plugin:"plugin/context_menu.swf"}; + var lineChart:LineChart = new LineChart(500,300); + lineChart.chartConfig = chartConfig1; + lineChart.x = 10; + lineChart.y = 70; + lineChart.loadAssets(); + addChild(lineChart); + lineChart.addEventListener(ChartEvent.ITEM_CLICK,itemClickHandler); + //columnchart + var chartConfig2:Object = {data:"data/xml/columnchart_data1.xml",skin:"skin/default_skin.swf",css:"css/default.css",plugin:"plugin/context_menu.swf"}; + var columnChart:ColumnChart = new ColumnChart(500,300); + columnChart.chartConfig = chartConfig2; + columnChart.x = 520; + columnChart.y = 70; + columnChart.loadAssets(); + addChild(columnChart); + //barchart + var chartConfig3:Object = {data:"data/xml/barchart_data1.xml",skin:"skin/default_skin.swf",css:"css/default.css",plugin:"plugin/context_menu.swf"}; + var barChart:BarChart = new BarChart(500,300); + barChart.chartConfig = chartConfig3; + barChart.x = 10; + barChart.y = 380; + barChart.loadAssets(); + addChild(barChart); + //piechart + var chartConfig4:Object = {data:"data/xml/piechart_data1.xml",skin:"skin/default_skin.swf",css:"css/default.css",plugin:"plugin/context_menu.swf"}; + var pieChart:PieChart = new PieChart(500,300); + pieChart.chartConfig = chartConfig4; + pieChart.x = 520; + pieChart.y = 380; + pieChart.loadAssets(); + addChild(pieChart); + //areachart + var chartConfig5:Object = {data:"data/xml/linechart_data1.xml",skin:"skin/default_skin.swf",css:"css/default.css",plugin:"plugin/context_menu.swf"}; + var areaChart:AreaChart = new AreaChart(500,300); + areaChart.chartConfig = chartConfig5; + areaChart.x = 1020; + areaChart.y = 70; + areaChart.loadAssets(); + addChild(areaChart); + //plotchart + var chartConfig6:Object = {data:"data/xml/plotchart_data1.xml",skin:"skin/default_skin.swf",css:"css/default.css",plugin:"plugin/context_menu.swf"}; + var plotChart:PlotChart = new PlotChart(500,300); + plotChart.chartConfig = chartConfig6; + plotChart.x = 1020; + plotChart.y = 380; + plotChart.loadAssets(); + addChild(plotChart); + //bubblechart + var chartConfig7:Object = {data:"data/xml/plotchart_data1.xml",skin:"skin/default_skin.swf",css:"css/default.css",plugin:"plugin/context_menu.swf"}; + var bubbleChart:BubbleChart = new BubbleChart(500,300); + bubbleChart.chartConfig = chartConfig7; + bubbleChart.x = 10; + bubbleChart.y = 700; + bubbleChart.loadAssets(); + addChild(bubbleChart); + //Alert test + Alert.show("警告信息","hello"); + } + + private function itemClickHandler(e:ChartEvent):void { + Alert.show(e.data[e.yField]); + } + } +} \ No newline at end of file