Fix ogg/oga not play in Firefox 3.6

Native audio support was introduced in since Firefox 3.5 . Ogg is one of the media format supported by Firefox. However, sometimes you may find it doesn’t work even if you set the right source path. And you just check the network status of audio element:

document.getElementsByTagName(“audio”)[0].networkState

Then you get the constant of a 4, which is HTMLMediaElement.NETWORK_NO_SOURCE.

This is because firefox checks the Content-Type header to make sure it’s a media file. (Webkit based browsers don’t have this restriction.) However, ogg format is not configured on most http servers. You can check the content type by:
curl -I <url-to-media-file>

Take Apache as example, you can add following content to your configuration file:
AddType audio/ogg .oga
AddType video/ogg .ogv .ogg

For more, check this article:
https://developer.mozilla.org/en/Configuring_servers_for_Ogg_media

HTML5 Form in Opera 11

严格意义上我现在已经不能算是个web guy了,不过托Web开放的特性,咱也能评论一下。最近做个小的界面,考虑到要面向未来,HTML5又提供了丰富的表单增强。这些特性中,Firefox 3.6基本上还没有支持,Chromium 8.0有少部分支持,而真正支持比较完整的是Opera 11.

autofocus
页面载入后自动将焦点转到某个input,就如以前的onload时候xxx.focus()

required
指定某个input为必填,提交时会有validation,在Opera11里还会给你这样的警告并且禁止提交:
Screenshot - 01122011 - 10:53:41 PM

email / url
指定某个input的特殊类型,提交时也会有对应的格式检查:
Screenshot - 01122011 - 10:54:41 PM

这样的提示可能满足不了你的替用户着想的产品经理,但是你清楚他帮你省了多少事情。而且,在DiveInfoHtml5里提到,iphone甚至为这个input做了优化,在软件盘上把空格键变得很小(因为输入邮件地址用不着),并且提供了一个@键;这就是工程师的用户体验啊。

placeholder
在input里显示提示文本:
Screenshot - 01122011 - 10:52:18 PM

注意到后面的红色星号了吗。这本来是我设计的一个workaround,既然Firefox 3都还不支持required validation,那么我们通过CSS来显示一个必填的提示:

input[required="required"]:after {
    content: '(*)';
    color: #F00;
}

结果这个伪类最后只有在Opera里实现了预期的效果,看在Stackoverflow上的讨论才得知input的:after和:before伪类只有Opera支持。

HTML5 Form这部分是一个真正务实的标准,你可以看到几乎每一个特性都是我们日常每时每刻都需要,几乎每个网站的JS都要实现的功能。标准是沟通上下游(浏览器和应用开发人员)的契约,一个真正反应相互需求的标准才是有实际价值的。

Sunng's Canvas based Heatmap API

Glad to announce my works this morning: A simple heatmap API based on HTML5 canvas.
canvas

The programming interface is rather simple now. To create such a heatmap, you just new a heatmap object by:

<canvas width="300" height="215" id="canv"></canvas>
heatmap = new HeatMap("canv");

Then read your dataset and push data into the heatmap:

heatmap.push(x, y, value);

At last, spread the data and get the canvas rendered:

heatmap.spread();
heatmap.render();

Now you got it.

For advanced usage, you can specify the resolution of heatmap by px:

heatmap = new HeatMap("canv", 2);

Large value will gain performance with low image quality.

Also, you can specify a value to define the attenuation value of each px.

heatmap.spread(5);

Finally, there is an option to use your own color schema for heatmap generation.

heatmap.render(function(value, maxValue){
    var light = value / maxValue * 100;
    return "hsl(20, 75%, "+light+"%)";
});

The parameters passed in are current pixel value and max value in whole context.

That’s all the toolkit. More functionality and options might be added in future. Grab it from my bitbucket page:
http://bitbucket.org/sunng/daily-coding/src/tip/canvas-heatmap/

There is a demo page which you can test the api by clicking canvas:
canvas-raw
then click heatmap button!
canvas2

This is the new year gift for my readers and my dear friends !

Open Source Charting Toolkits in JavaScript

项目的下一阶段,需要做一些数据展现方面的工作,处于对Adobe产品的抵触情绪,我个人还是倾向于用JavaScript来完成。今天找了几个画Chart的库,比较一下功能和编程接口的使用,为接下来的开发做一些准备。

dojox.charting

(BSD License)
没什么悬念,第一个想到的就是曾经用过的dojo。之前实习时候用dojo画chart也算是积累了一些心得。dojox.charting的最主要优点是编程接口完善、全面,可以配置的项目很多,接口易于编程,易于动态地生成、操作Chart。而另一方面最主要的问题就是文档比较匮乏,不了解的人可能问了,doc.dojotoolkit.org好强大,怎么会文档匮乏呢。其实是dojo和mootools类似,都很喜欢用option object来传递可选参数,但是这些option object在文档中没有任何涉及,很多关键的属性都在其中但是却没有办法查到,算是美中一大不足。

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml">

<head>

	<script src="dojo-release-1.3.2/dojo/dojo.js" djConfig="isDebug: true"></script>

	<title>Dojo</title>

	<script type="text/javascript">

		dojo.require("dojox.charting.Chart2D");

	</script>

</head>

<body>

	<h1>Dojox.charting</h1>

	<div id="charting" style="width:400px; height:250px;">

	</div>

	<script type="text/javascript">

		(function charting(){

			dojo.empty("charting");

			var data = [2,4,5,7,7,4,4,7];

			var chart = new dojox.charting.Chart2D("charting");

			chart.addPlot("default", {type: "Lines", markers: true, shadows: {dw:2, dy:2, dx:2}});

			chart.addPlot("additional", {type: "Areas"});

			chart.addPlot("other", {type: "ClusteredColumns"})

			chart.addAxis("x");

			chart.addAxis("y", {vertical: true, min:0, max: 10});

			chart.addSeries("Testing Data 1", data);

			chart.addSeries("Average", dojo.map(data, function(it){return (Math.sin(it)+Math.random())*4}), {

				fill: "rgba(145, 213, 100, 0.5)", plot:"additional"

			});

			chart.addSeries("All Random", dojo.map(data, function(it){return (Math.random()*5)}), {

				plot: "other", fill: "#AEC6E2", stroke:{color:"#333", width:1}

			});

			chart.render();

		})();

	</script>

</body>

</html>

Protovis

(BSD License)
Protovis,看域名就知道是斯坦福的项目,Protovis是在prototype基础上,不仅有charting的功能,还包括其他可视化方法的实现。看了Demo会发现它真的很不错,不过Protovis的本意似乎只是借助浏览器的图形功能实现可视化,它并没有提供超出可视化范畴的其他东西,甚至看过实例的代码你会发现,作者是不折不扣的函数式编程和链式方法的爱好者,Protovis的代码算是出神入化了,如果你想看看学术的JavaScript是如何写的,那就看看这个发表了论文的JavaScript库吧。
看起来是很出神入化,可是这样的编程接口如果要用在动态的数据展现上,实在是难以想象。况且,pv.Panel居然没有传入dom对象的接口,无从控制chart的生成位置。说白了,Protovis并不是一个满足项目需要的Library,不过它的功能和代码还是值得多看几眼的。

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml">

<head>

	<script src="protovis-3.1/protovis-r3.1.js"></script>

</head>

<body>

	<div id="page">

		<h1>Protovis</h1>

		<div style="border:1px #CCC solid;">

			<script type="text/javascript">

				var width = 300;

				var height = 225;

				var data = [1,2,3,4,6,7,5,8,9];

				var dataMax = data[0];

				for(var i=1; i<data.length; i++){

					dataMax = dataMax > data[i] ? dataMax : data[i];

				}

				var x = pv.Scale.linear(0, dataMax).range(0, width);

				var y = pv.Scale.ordinal(pv.range(10)).splitBanded(0, height, 0.9);

				var charting = new pv.Panel();

				charting.width(width).height(height).left(20).top(20);

				var bar = charting.add(pv.Bar);

				bar.data(data).top(function() y(this.index)).height(y.range().band).left(0).width(x);

				bar.anchor("center").add(pv.Label)

					.textStyle("white")

					.textAlign("center")

					.text(function(d) d.toFixed(1));

				charting.add(pv.Rule)

					.data(x.ticks())

					.left(function(d) Math.round(x(d)) - .5)

					.strokeStyle(function(d) d ? "rgba(255,255,255,.3)" : "#000")

				.add(pv.Rule)

					.bottom(0)

					.height(5)

					.strokeStyle("#C00")

					.anchor("bottom").add(pv.Label)

					.text(function(d) d);

				charting.render();

			</script>

		</div>

	</div>

</body>

</html>

Flotr

(MIT License)
不同于上面两个库通过SVG绘图,Flotr是用canvas api来完成绘制的。与dojo相比,Flotr的API比较简单,主要只有一个Flotr.draw方法,可以传入三个参数:目标DOM对象,数据和绘图选项。和dojo不同,Flotr的文档里关于这个option object有非常明确的文档。另外强大的是Flotr还提供了一些交互的功能,支持事件绑定。

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml">

<head>

	<script src="flotr-0.2.0-alpha/flotr/lib/prototype-1.6.0.2.js"></script>

	<script src="flotr-0.2.0-alpha/flotr/flotr-0.2.0-alpha.js"></script>

	<title>Flotr</title>

	<script type="text/javascript">

	</script>

</head>

<body>

	<h1>Flotr</h1>

	<div id="charting" style="width:400px; height:250px;">

	</div>

	<script type="text/javascript">

		(function d(){

			var series1 = {data: (function(){

				var d = [];

				for(var i=0; i<10; i+=0.5){

					d.push([i, Math.random()-0.5+Math.sin(i)*3]);

				}

				return d;

			})(), label:"d1", lines:{fill:true}};

			var series2 = {data: (function(){

				var d = [];

				for(var i=0; i<10; i+=0.5){

					d.push([i, (Math.random()-0.5)*2+Math.cos(i)*2]);

				}

				return d;

			})(), label: "s2", points:{show:true}, lines:{show:true}};

			Flotr.draw($("charting"), [series1, series2], {

				legend: {position :"se"},

				yaxis: {min: -3.5, max:3.5}

			});

		})();

	</script>

</body>

</html>

此外,还有一个与Flotr很类似的Protochart,后者的网站上写自己是motivated by Flotr,不过我很难想象功能几乎相同是如何motivated的。

MilkChart

(Apache License 2.0)
MilkChart是一个建立在Mootools上的Charting库,采用canvas api绘图。它的特点是把HTML Table的数据绘制成Chart,如果场景允许,倒是省去了不少构建数组的麻烦。这个项目目前规模还不大,并且在作者积极的开发中,可以参考它的Wiki获得详细的使用方法。