Archive for the 'RIA' Category

可视化中的两色渐变颜色映射

colorGradient
在做可视化项目的时候,我们经常会用颜色表示信息,例如:红白之间,越红表示越热门,越白表示越冷清。
本文主要解决这个问题:

假设我们有一个数值数组,要用红白之间的颜色表示各数。

算法:

color = (value – minValue) / (maxValue – minValue) * (endColor – startColor) + startColor
value:数组中一个元素
color:value的映射颜色值
minValue:数组中最小的值
maxValue:数组中最大的值
startColor:起点颜色
endColor:终点颜色

但是,颜色色值是用RGB三色十六进制数表示,比如红色0xff0000,白色0xffffff。不能直接在0xff0000与0xffffff之间映射。必须r,g,b三种颜色分别映射。即,先拆开r,g,b三色,分别对三色进行映射,再组合。
对应的函数为:

public static function caculateColor(value:Number,startColor:uint,endColor:uint,startValue:Number,endValue:Number):uint
{
	var rs:uint = startColor >> 16 & 0xff;
	var gs:uint = startColor >> 8 & 0xff;
	var bs:uint = startColor & 0xff;
	var re:uint = endColor >> 16 & 0xff;
	var ge:uint = endColor >> 8 & 0xff;
	var be:uint = endColor & 0xff;
 
	var rx:uint = ColorUtil.mappingColor(value,rs,re,startValue,endValue);
	var gx:uint = ColorUtil.mappingColor(value,gs,ge,startValue,endValue);
	var bx:uint = ColorUtil.mappingColor(value,bs,be,startValue,endValue);
 
	return rx << 16 | gx << 8 | bx;
}
 
private static function mappingColor(value:Number,startColor:uint,endColor:uint,startValue:Number,endValue:Number):uint
{
	return (value - startValue) / (endValue - startValue) * (endColor - startColor) + startColor;
}

求出数组中的最大值和最小值就不讨论了。

Flash中国地图开源项目flash-china-map

Flash 中国地图
Flash中国地图,以Object为数据源,便于实现基于中国地图的可视化项目。

特征:

  • swc,便于导入到Flex项目中
  • 数据源为Object,比静态XML更方便
  • 数据驱动的地图块颜色和Hover颜色
  • 可配置是否显示省份名

Code License: Apache 2.0
Author: ComingX Jingle
Download: Git Repo
Demo Show:

使用方法:

  • 创建Flex项目,拷贝ChinaMap.swc至项目libs目录下
  • map = new Map()

Flex导入地图

<?xml version="1.0" encoding="utf-8"?>
<!--
* ComingX.com Business License
* 
* Copyright 2013. All rights reserved.
*
* @Author: Jingle
* @Email: jingdongemail@gmail.com
* @Created date: 2013-6-27
-->
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" 
			   xmlns:s="library://ns.adobe.com/flex/spark" 
			   xmlns:mx="library://ns.adobe.com/flex/mx" minWidth="955" minHeight="600"
			   creationComplete="application1_creationCompleteHandler(event)"
			   >
	<fx:Declarations>
		<!-- 将非可视元素(例如服务、值对象)放在此处 -->
	</fx:Declarations>
	<fx:Script>
		<![CDATA[
			import com.comingx.jingle.chinamap.MapBase;
			import com.comingx.jingle.chinamap.ProvinceItem;
			import com.comingx.jingle.chinamap.domains.InitData;
			import com.comingx.jingle.chinamap.utils.ColorUtil;
 
			import flash.display.Sprite;
 
			import mx.controls.Alert;
			import mx.core.UIComponent;
			import mx.events.FlexEvent;
			private var map:MapBase;
 
			protected function application1_creationCompleteHandler(event:FlexEvent):void
			{
				map = new Map();
 
				map.addEventListener(MouseEvent.CLICK, provinceClicked);
 
				var ui:UIComponent = new UIComponent();
				ui.addChild(map);
				test.addElement(ui);
				var initData:InitData = new InitData();
				initData.isShowProvinceName = false;
				initData.provinceDataArray = [
					{"id":11,"name":"beijing","color":0xff4400,"hoverColor":0xff0000},
					{"id":12,"name":"tianjin","color":0xccffcc,"hoverColor":0xff0000},
					{"id":13,"name":"hebei","color":0xbbffbb,"hoverColor":0xffff00},
					{"id":14,"name":"shanxi","color":0xffee00,"hoverColor":0xff2200},
					{"id":15,"name":"neimenggu","color":0xaaffaa,"hoverColor":0xff2200},
					{"id":21,"name":"liaoning","color":0xddffdd,"hoverColor":0xff2200},
					{"id":22,"name":"jilin","color":0xddffdd,"hoverColor":0xff2200},
					{"id":23,"name":"heilongjiang","color":0xddffdd,"hoverColor":0xff2200},
					{"id":31,"name":"shanghai","color":0xddffdd,"hoverColor":0xff2200},
					{"id":32,"name":"jiangsu","color":0xddffdd,"hoverColor":0xff2200},
					{"id":33,"name":"zhejiang","color":0xddffdd,"hoverColor":0xff2200},
					{"id":34,"name":"anhui","color":0xddffdd,"hoverColor":0xff2200},
					{"id":35,"name":"fujian","color":0xddffdd,"hoverColor":0xff2200},
					{"id":36,"name":"jiangxi","color":0xddffdd,"hoverColor":0xff2200},
					{"id":37,"name":"shandong","color":0xddffdd,"hoverColor":0xff2200},
					{"id":41,"name":"henan","color":0xddffdd,"hoverColor":0xff2200},
					{"id":42,"name":"hubei","color":0xddddff,"hoverColor":0xff2200},
					{"id":43,"name":"hunan","color":0xddffdd,"hoverColor":0xff2200},
					{"id":44,"name":"guangdong","color":0xddffdd,"hoverColor":0xff2200},
					{"id":45,"name":"guangxi","color":0xddeeff,"hoverColor":0xff2200},
					{"id":46,"name":"hainan","color":0xddffdd,"hoverColor":0xff2200},
					{"id":50,"name":"chongqing","color":0xddffdd,"hoverColor":0xff2200},
					{"id":51,"name":"sichuan","color":0xffffdd,"hoverColor":0xff2200},
					{"id":52,"name":"guizhou","color":0xddffdd,"hoverColor":0xff2200},
					{"id":53,"name":"yunnan","color":0xddffdd,"hoverColor":0xff2200},
					{"id":54,"name":"xizang","color":0xddeffe,"hoverColor":0xff2200},
					{"id":61,"name":"shannxi","color":0xddffdd,"hoverColor":0xff2200},
					{"id":62,"name":"gansu","color":0xddffdd,"hoverColor":0xff2200},
					{"id":63,"name":"qinghai","color":0xddffdd,"hoverColor":0xff2200},
					{"id":64,"name":"ningxia","color":0xddffdd,"hoverColor":0xff2200},
					{"id":65,"name":"xinjiang","color":0xddffdd,"hoverColor":0xff2200},
					{"id":71,"name":"taiwan","color":0xddffdd,"hoverColor":0xff2200},
					{"id":81,"name":"xianggang","color":0xddffdd,"hoverColor":0xff2200},
					{"id":82,"name":"aomen","color":0xddffdd,"hoverColor":0xff2200}
				];
				map.init(initData);
 
				for(var i:int = 0; i<9; i++)
				{
					var ui2:UIComponent = new UIComponent();
					ui2.addChild(drawRect(ColorUtil.caculateColor(i*2,0xffffff,0xff0000,0,16)));
					ui2.x = i*20;
					ui2.y = 400;
					this.addElement(ui2);
				}
			}
 
			protected function provinceClicked(evt:MouseEvent):void
			{
				var provinceItem:ProvinceItem = evt.target as ProvinceItem;
				var provinceId:int = provinceItem.province.id;
				var provinceName:String = provinceItem.province.name;
				Alert.show("Province id is " + provinceId +"; Province name is " + provinceName +";");
			}
 
			public function drawRect(color:uint):Shape{
				var shape:Shape = new Shape();
				shape.graphics.beginFill(color);
				shape.graphics.drawRect(0,0,20,20);
				shape.graphics.endFill();
				return shape;
			}
 
		]]>
	</fx:Script>
	<s:Group id="test">
 
	</s:Group>
</s:Application>

Demo下载

Box2D教程5-碰撞检测


之前我们已经了解了如何通过Box2D创建一个物理世界,给刚体添加复杂材质,鼠标交互。在游戏开发里面我们通常要判断两个物体相互碰撞了,然后进行相应的操作。比如“愤怒的小鸟”,当小鸟碰撞到箱子的时候,我们需要知道这两个物体碰撞了,然后判断碰撞的力度(后面的教程会讲),然后对箱子进行操作。这个教程就是用来处理Box2D的碰撞检测问题。
继续阅读 [ Box2D教程5-碰撞检测 ]

Box2D教程4-复杂刚体的复杂外观


继续阅读 [ Box2D教程4-复杂刚体的复杂外观 ]

Box2D教程3-刚体绑定外观


继续阅读 [ Box2D教程3-刚体绑定外观 ]

Box2D教程2-鼠标交互


继续阅读 [ Box2D教程2-鼠标交互 ]

Box2D教程1-创建碰撞世界


继续阅读 [ Box2D教程1-创建碰撞世界 ]

box2D实例[Helloworld,鼠标交互,绑定元件]

此实例基于Box2D 2.1a,涉及到HelloWorld,鼠标交互,绑定自定义外观,绘制复杂外观。效果如下:

继续阅读 [ box2D实例[Helloworld,鼠标交互,绑定元件] ]

Flex4 的 Scroller Viewport

Flex4提供了一个IViewport接口,所有可滚动组件必须实现它,而Scroller就是用来使可滚动组件实现滚动交互的组件。这种滚动交互在图形化界面里面很常见,Flex4的Scroller相比Flex3能够更加高效率。

许多Flex组件,像List, TextArea等组件在其皮肤中已经包含了Scroller和viewport,所以开发者不用担心是否可以滚动。这篇文章为了说明IViewport接口的工作原理,并包含一个简单的Scroller实例。如果你想创建自己的滚动组件或者想更好的理解Flex的滚动组件工作原理,继续阅读。
继续阅读 [ Flex4 的 Scroller Viewport ]

ActionScript RGB HSL转换类

package color{
	public class HslRgb{
	public function HslRgb(){
	}
	public static function toHex(n:Number) {
		var c=n.toString(16)
		switch (c.length) {
			case 1:
			c="00000"+c;
			 break;
			case 2:
			c="0000"+c;
			 break;
			 case 3:
			c="000"+c;
			 break;
			 case 4:
			c="00"+c;
			 break;
			 case 5:
			c="0"+c;
			 break;
			}
		return c.toUpperCase();
	}
	public static function rgbToRGB(r,g,b){
		return Math.round(r)*256*256+Math.round(g)*256+Math.round(b);
		}
	public static function hexToRgb(val:Number)     
		{     
		var col:Array=new Array(3);     
		col.r = (val >> 16) & 0xFF;
		col.g = (val >> 8) & 0xFF;
		col.b = val & 0xFF;
		return col;
		}
		//H=0~360,S=0-1,L=0-1
	public static function hslToRgb(H:Number, S:Number, L:Number) {
		var p1:Number, p2:Number;
		var rgb:Array = new Array(3);
		if (L<=0.5) {
			p2 = L*(1+S);
		} else {
			p2 = L+S-(L*S);
		}
		p1 = 2*L-p2;
		if (S == 0) {
			rgb.r = L;
			rgb.g = L;
			rgb.b = L;
		} else {
			rgb.r = toRgb(p1, p2, H+120);
			rgb.g = toRgb(p1, p2, H);
			rgb.b = toRgb(p1, p2, H-120);
		}
		rgb.r *= 255;
		rgb.g *= 255;
		rgb.b *= 255;
		return rgb;
	}
	public static function toRgb(q1:Number, q2:Number, hue:Number) {
		if (hue>360) {
			hue = hue-360;
		}
		if (hue<0) {
			hue = hue+360;
		}
		if (hue<60) {
			return (q1+(q2-q1)*hue/60);
		} else if (hue<180) {
			return (q2);
		} else if (hue<240) {
			return (q1+(q2-q1)*(240-hue)/60);
		} else {
			return (q1);
		}
	}
	public static function rgbToHsl(R:Number, G:Number, B:Number) {
		R /= 255;
		G /= 255;
		B /= 255;
		var max:Number, min:Number, diff:Number, r_dist:Number, g_dist:Number, b_dist:Number;
		var hsl:Array = new Array(3);
		max = Math.max(Math.max(R, G), B);
		min = Math.min(Math.min(R, G), B);
		diff = max-min;
		hsl.l = (max+min)/2;
		if (diff == 0) {
			hsl.h = 0;
			hsl.s = 0;
		} else {
			if (hsl.l<0.5) {
			hsl.s = diff/(max+min);
		} else {
			hsl.s = diff/(2-max-min);
		}
		r_dist = (max-R)/diff;
		g_dist = (max-G)/diff;
		b_dist = (max-B)/diff;
		if (R == max) {
			hsl.h = b_dist-g_dist;
		} else if (G == max) {
			hsl.h = 2+r_dist-b_dist;
		} else if (B == max) {
			hsl.h = 4+g_dist-r_dist;
			}
		hsl.h *= 60;
		if (hsl.h<0) {
			hsl.h += 360;
			}
		if (hsl.h>=360) {
			hsl.h -= 360;
			}
		}
		return hsl;
		}
		}
	}