<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>鱼常游而忘飞</title>
	<atom:link href="http://www.oulan.com/feed" rel="self" type="application/rss+xml" />
	<link>http://www.oulan.com</link>
	<description>+++仿佛轻云应笑我--相携水岸弄朝霞--此生只为听天籁--坐拥书城看落花+++</description>
	<lastBuildDate>Sun, 22 Jan 2012 12:18:34 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title></title>
		<link>http://www.oulan.com/topics/2804.html</link>
		<comments>http://www.oulan.com/topics/2804.html#comments</comments>
		<pubDate>Sun, 22 Jan 2012 12:18:34 +0000</pubDate>
		<dc:creator>Ou Lanhui</dc:creator>
				<category><![CDATA[随笔]]></category>

		<guid isPermaLink="false">http://www.oulan.com/?p=2804</guid>
		<description><![CDATA[爆竹声中一岁除，跃马腾龙展宏图。]]></description>
			<content:encoded><![CDATA[<img style='float: left; margin-right: 10px; border: none;' src='http://www.gravatar.com/avatar.php?gravatar_id=c8f148a6de1f018f5cc1b362eaa3b62e&amp;default=http://www.oulan.com/wp-content/uploads/2009/06/38903.jpg' alt='No Gravatar' width=40 height=40/><p>爆竹声中一岁除，跃马腾龙展宏图。</p>
]]></content:encoded>
			<wfw:commentRss>http://www.oulan.com/topics/2804.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>跨越浏览器的d3.js图表显示</title>
		<link>http://www.oulan.com/topics/d3_js_with_more_browsers.html</link>
		<comments>http://www.oulan.com/topics/d3_js_with_more_browsers.html#comments</comments>
		<pubDate>Sun, 22 Jan 2012 12:07:45 +0000</pubDate>
		<dc:creator>Ou Lanhui</dc:creator>
				<category><![CDATA[Coding]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[Ubuntu]]></category>
		<category><![CDATA[技巧]]></category>
		<category><![CDATA[d3.js]]></category>
		<category><![CDATA[node.js]]></category>

		<guid isPermaLink="false">http://www.oulan.com/?p=2801</guid>
		<description><![CDATA[最近一段时间对正在采用的图表组件不满意了。看过d3.js之后，别的图表显示确实很难入眼。问题的难度是d3.js采用的SVG技术导致它只能在几种浏览器里使用，在我们客户大量使用的IE，特别是IE6的客户里很难显示正常。SVG之于IE的问题要想解决有几个思路： 一个可以想像的方式是采用svgweb，不过在调试的时候发现IE在加载d3.js经常出非常小且2的问题。比如一个函数里使用了两次while(++i &#60; j)之后，d3.js就不能正常载入，提示的错误居然是“缺少&#8217;)'”。 二一个是在后端生成图片，这样就不存在SVG格式的问题了。这个世界近两年来流行的node.js可以在后台执行javascript，这让人有柳暗花明的感觉。 第三个方式是我们后端生成svg文件，前端使用svgweb加载。 沿着第一个思路太耗费时间，不符合想快速解决问题的思路。所以第二、三个方法做了重点测试。 首先可以参照的方法是d3.js里自带的node-canvas例子us-counties。如果将这个图片通过http输出到客户端第二个方法的技术问题就解决了。 然后是@mattbaker提交的gist 1511770，这个例子通过node.js完成了svg文件的生成。加上svgweb，在IE里显示svg图表的问题也就完全不存在了。 @mattbaker提供的gist 1509145提供了直接通过http输出png图片的例子。 我们聊加改造，其实是去除了一些功能就可以得到如下代码： var http = require('http'), url = require('url'), jsdom = require('jsdom'), child_proc = require('child_process'), w = 400, h = 400, scripts = ["file://"+__dirname+"/../d3.min.js", "file://"+__dirname+"/../d3.layout.min.js", "file://"+__dirname+"/pie.js"], htmlStub = '&#60;!DOCTYPE html&#62;&#60;div id="pie" style="width:'+w+'px;height:'+h+'px;"&#62;&#60;/div&#62;'; http.createServer(function (req, res) { var values = (url.parse(req.url, true).query['values'] &#124;&#124; ".5,.5") .split(",") [...]]]></description>
			<content:encoded><![CDATA[<img style='float: left; margin-right: 10px; border: none;' src='http://www.gravatar.com/avatar.php?gravatar_id=c8f148a6de1f018f5cc1b362eaa3b62e&amp;default=http://www.oulan.com/wp-content/uploads/2009/06/38903.jpg' alt='No Gravatar' width=40 height=40/><p>最近一段时间对正在采用的图表组件不满意了。看过<a href="http://mbostock.github.com/d3/">d3.js</a>之后，别的图表显示确实很难入眼。问题的难度是d3.js采用的SVG技术导致它只能在几种浏览器里使用，在我们客户大量使用的IE，特别是IE6的客户里很难显示正常。SVG之于IE的问题要想解决有几个思路：<br />
一个可以想像的方式是采用<a href="http://code.google.com/p/svgweb/">svgweb</a>，不过在调试的时候发现IE在加载d3.js经常出非常小且2的问题。比如一个函数里使用了两次while(++i &lt; j)之后，d3.js就不能正常载入，提示的错误居然是“缺少&#8217;)'”。<br />
二一个是在后端生成图片，这样就不存在SVG格式的问题了。这个世界近两年来流行的<a href="http://nodejs.org/">node.js</a>可以在后台执行javascript，这让人有柳暗花明的感觉。<br />
第三个方式是我们后端生成svg文件，前端使用svgweb加载。<br />
<a href="http://picplz.com/zmJLf"><img src="http://s0.i1.picplzthumbs.com/upload/img/23/c6/c8/23c6c84da01075f2418e97b0a6e92d644bc1166a_wmeg.jpg" alt="" /></a></p>
<p>沿着第一个思路太耗费时间，不符合想快速解决问题的思路。所以第二、三个方法做了重点测试。<br />
首先可以参照的方法是d3.js里自带的node-canvas例子<a href="https://github.com/mbostock/d3/blob/master/examples/node-canvas/us-counties.js">us-counties</a>。如果将这个图片通过http输出到客户端第二个方法的技术问题就解决了。<br />
然后是@mattbaker提交的<a href="https://gist.github.com/1511770">gist 1511770</a>，这个例子通过node.js完成了svg文件的生成。加上svgweb，在IE里显示svg图表的问题也就完全不存在了。<br />
@mattbaker提供的<a href="https://gist.github.com/1509145">gist 1509145</a>提供了直接通过http输出png图片的例子。<br />
我们聊加改造，其实是去除了一些功能就可以得到如下代码：</p>
<pre class="brush:js">var http = require('http'),
    url = require('url'),
    jsdom = require('jsdom'),
    child_proc = require('child_process'),
    w = 400,
    h = 400,
    scripts = ["file://"+__dirname+"/../d3.min.js",
               "file://"+__dirname+"/../d3.layout.min.js",
               "file://"+__dirname+"/pie.js"],
    htmlStub = '&lt;!DOCTYPE html&gt;&lt;div id="pie" style="width:'+w+'px;height:'+h+'px;"&gt;&lt;/div&gt;';

http.createServer(function (req, res) {
  var values = (url.parse(req.url, true).query['values'] || ".5,.5")
        .split(",")
        .map(function(v){return parseFloat(v)});
  // 去除生成图片的代码
  //convert.stdout.on('data', function (data) {
  //  res.write(data);
  //});
  //convert.on('exit', function(code) {
  //  res.end();
  //});

  jsdom.env({features:{QuerySelector:true}, html:htmlStub, scripts:scripts, done:function(errors, window) {
    var svgsrc = window.insertPie("#pie", w, h, values).innerHTML;
    //jsdom's domToHTML will lowercase element names
    svgsrc = svgsrc.replace(/radialgradient/g,'radialGradient');
    res.writeHead(200, {'Content-Type': 'image/svg+xml'});
    res.write(svgsrc);
    res.end();
  // 去除生成图片的代码
  //  convert.stdin.write(svgsrc);
  //  convert.stdin.end();
  }});
}).listen(8888, "0.0.0.0");

console.log('Pie SVG server running at http://127.0.0.1:8888/');
console.log('ex. http://127.0.0.1:8888/?values=.4,.3,.2,.1');</pre>
<p>用node.js运行后，使用下面页面即可：</p>
<pre class="brush:css">&lt;!DOCTYPE html&gt;
&lt;html&gt;
  &lt;!-- Tests using the OBJECT syntax to embed an SVG file --&gt;

  &lt;head&gt;

    &lt;!-- Optional meta tag; if left off, we default to only using the Flash
         renderer for Internet Explorer and using native support on other
         browsers. You can force the Flash renderer for all browsers by
         setting the META tag below to true. --&gt;
    &lt;!-- meta name="svg.render.forceflash" content="true" / --&gt;  &lt;!-- disabled  --&gt;

    &lt;script src="../../src/svg.js" data-path="../../src/"&gt;&lt;/script&gt;
  &lt;/head&gt;

  &lt;body&gt;
    &lt;h1&gt;Tests using the OBJECT syntax to embed an SVG file&lt;/h1&gt;

    &lt;!--[if !IE]&gt;--&gt;
      &lt;object data="http://localhost:8888/?values=.4,.3,.2,.1" type="image/svg+xml"
              width="1250" height="750" id="mySVGObject"&gt; &lt;!--&lt;![endif]--&gt;
    &lt;!--[if lt IE 9]&gt;
      &lt;object src="http://localhost:8888/?values=.4,.3,.2,.1" classid="image/svg+xml"
              width="1250" height="750" id="mySVGObject"&gt; &lt;![endif]--&gt;
    &lt;!--[if gte IE 9]&gt;
      &lt;object data="http://localhost:8888/?values=.4,.3,.2,.1" type="image/svg+xml"
              width="1250" height="750" id="mySVGObject"&gt; &lt;![endif]--&gt;
      &lt;/object&gt;

    &lt;h1&gt;Test HTML H1&lt;/h1&gt;
  &lt;/body&gt;
&lt;/html&gt;</pre>
<p>龙年将至，发文记之，期待腾飞。</p>
]]></content:encoded>
			<wfw:commentRss>http://www.oulan.com/topics/d3_js_with_more_browsers.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>倚天出笼记</title>
		<link>http://www.oulan.com/topics/how-we-make-a-sword.html</link>
		<comments>http://www.oulan.com/topics/how-we-make-a-sword.html#comments</comments>
		<pubDate>Sun, 22 Jan 2012 05:14:56 +0000</pubDate>
		<dc:creator>Ou Lanhui</dc:creator>
				<category><![CDATA[Coding]]></category>
		<category><![CDATA[Frameworks]]></category>
		<category><![CDATA[技术]]></category>
		<category><![CDATA[随笔]]></category>
		<category><![CDATA[agile]]></category>
		<category><![CDATA[CodeIgniter]]></category>
		<category><![CDATA[Piwik]]></category>
		<category><![CDATA[Play]]></category>
		<category><![CDATA[Redmine]]></category>
		<category><![CDATA[Subversion]]></category>
		<category><![CDATA[Ubuntu]]></category>

		<guid isPermaLink="false">http://www.oulan.com/?p=2793</guid>
		<description><![CDATA[持利器，事半而功倍。所以IT界以发明各种轮子为主要乐事。若器成则功利倍，没有人可以拒绝。在开始打造我们开发的目标团队之时，虽然还是孤身一人，但对各种使用利器之法也是有所耳闻。那段时间赋闲在家，研究一些好玩的技术，算是为某些事做准备，也可以调整自己的心态，积累精神。 一、高可用的管理平台 版本管理什么的以前都比较习惯了。从CVS到SVN一路走来，就是在一个人编码的时候也在使用SVN。管理方面还对比过Trac和Redmine。虽然一直对Python的好感多于Ruby，但是经过比较之后还是觉得Redmine更好一些。就这样，其实在加入新公司之前，各种管理工具通过选择就已经确定了以redmine/Subversion为基础。这两种工具的结合有很多优点： * Redmine的权限管理可以于Subversion集成。 * Subversion提交的内容与Redmine的问题可以有效地连接。 * Redmine还可以提供简单的BUG管理功能。 从某种意义上来说，我是“拒绝文档控”。一直以来想鼓吹的就是没有文档的软件开发、没有说明书的软件操作方式。但是计划还是要有的，对进度的控制也要在合理的范围内。Redmine正好提供了详细的管理能力。除了可以对项目提供计划和实施管理之外，它的问题条目还可以详细或者粗略地提供开发时间的一些细节。如果可以，使用它也可以生成项目的开发或者设计文档。 二、高可用的硬件 而且那段时间一直使用Ubuntu做为Desktop，两个显示器使用起来，调代码、测试输出效率非常高。以致于当时大致每天下午可以有一两个小时出去骑会自行车散心。所以团队组建初期就提了硬件的指标，这个配置现在看来水平也不算低。每台开发用的电脑都是4核心CPU/8G内存，显示器的概算是每个人都是双显。后来因为我们还要与其他部门一块办公，大致的双显比例是1/2强。原来的开发机都是台式机，在项目逐渐增多后后续的配置都是移动性较强的笔记本了。 我在与之前一些朋友的探讨过程中，他们不是十分理解为什么配置这么好。最多的质疑是这好的配置要多花钱，但是这个说法非常经不起推敲，以一台电脑三年的预算使用期来算，就算是花费6,000元来配置一台开发用机，一年的成本也只有2000，平均到每个月只有非常少的费用。而采用好工具对开发人员带来的，恐怕用这些钱是换不来的。比如： * 心情的舒畅 * 工作效率的提高 * 对工作条件的满意程度 没经历过用烂机器开发过程的人永远也不能懂得执行编译似卡死的时候的那种感觉，特别是项目Deadline临近。 三、敏捷的开发框架 使用敏捷框架是必然会在突发的、时间有限的项目中被采用的。特别是新团队，原始积累不够丰富的团队。 我们常用的这两个CodeIgniter/Play框架基本上都是沿着这个思路来的。 选择CI是为了将来在虚拟主机上使用。选择Play则是由于客户要求使用Java。不过我们用ab和siege的测试结果PHP的还要好一些。 四、模板，一定要有的模板 对于我们来说模板程序员和美工最好的沟通工具。我们的美工甚至已经可以在程序员参与之前，就可以根据需要打造好用户的界面。以至于有个项目的甲方说这个系统你们是不是设计得太简单了？这么快就做好了？ 模板系统在为我们以原型驱动的开发过程打造了一个良好的基础，客户可以更好的理解我们的想法，并给我们最真实的意见反馈。 CodeIgniter里采用Smarty模板、Play里采用了自带的Grails模板，虽然还有可以同时用于Java和PHP，甚至当我们使用了Python/Ruby都可以用得上的Mustache模板系统，但是指望一个模板系统在不同的语言下都完全保持一致是不可能的。特别是Play里那些@之类。 五、Flash，IE Killer 如果愿意享受，软件开发的乐趣非常多。但是注意有很多烦恼。我们目前最大的烦恼来自于IE6。当初我们在给客户展示图表的时候，一开始使用了HighCharts，一个基于JavaScript的图表系统，在展示单个图表的时候问题不大，但是多图表展示一度让我们怀疑系统出现了致命的问题。应该说在这个问题上Flash成为了我们开发时IE6的Killer。 六、有效的工具 有效的工具我们用过的真是很多，下面几个是常用的但不限于： *]]></description>
			<content:encoded><![CDATA[<img style='float: left; margin-right: 10px; border: none;' src='http://www.gravatar.com/avatar.php?gravatar_id=c8f148a6de1f018f5cc1b362eaa3b62e&amp;default=http://www.oulan.com/wp-content/uploads/2009/06/38903.jpg' alt='No Gravatar' width=40 height=40/><p>持利器，事半而功倍。所以IT界以发明各种轮子为主要乐事。若器成则功利倍，没有人可以拒绝。在开始打造我们开发的目标团队之时，虽然还是孤身一人，但对各种使用利器之法也是有所耳闻。那段时间赋闲在家，研究一些好玩的技术，算是为某些事做准备，也可以调整自己的心态，积累精神。<br />
<a href="http://picplz.com/zmJ7G"><img src="http://s1.i1.picplzthumbs.com/upload/img/8e/ca/ff/8ecaff29be466aff48debcba9a6049bf6f21ee70_wmeg.jpg" alt="" /></a></p>
<p>一、高可用的管理平台<br />
版本管理什么的以前都比较习惯了。从<a href="http://cvs.nongnu.org/">CVS</a>到<a href="http://subversion.apache.org/">SVN</a>一路走来，就是在一个人编码的时候也在使用SVN。管理方面还对比过<a href="http://trac.edgewall.org/">Trac</a>和<a href="http://www.redmine.org/">Redmine</a>。虽然一直对Python的好感多于Ruby，但是经过比较之后还是觉得Redmine更好一些。就这样，其实在加入新公司之前，各种管理工具通过选择就已经确定了以redmine/Subversion为基础。这两种工具的结合有很多优点：<br />
* Redmine的权限管理可以于Subversion集成。<br />
* Subversion提交的内容与Redmine的问题可以有效地连接。<br />
* Redmine还可以提供简单的BUG管理功能。<br />
从某种意义上来说，我是“拒绝文档控”。一直以来想鼓吹的就是没有文档的软件开发、没有说明书的软件操作方式。但是计划还是要有的，对进度的控制也要在合理的范围内。Redmine正好提供了详细的管理能力。除了可以对项目提供计划和实施管理之外，它的问题条目还可以详细或者粗略地提供开发时间的一些细节。如果可以，使用它也可以生成项目的开发或者设计文档。</p>
<p>二、高可用的硬件<br />
而且那段时间一直使用<a href="http://www.ubuntu.com/">Ubuntu</a>做为Desktop，两个显示器使用起来，调代码、测试输出效率非常高。以致于当时大致每天下午可以有一两个小时出去骑会自行车散心。所以团队组建初期就提了硬件的指标，这个配置现在看来水平也不算低。每台开发用的电脑都是4核心CPU/8G内存，显示器的概算是每个人都是双显。后来因为我们还要与其他部门一块办公，大致的双显比例是1/2强。原来的开发机都是台式机，在项目逐渐增多后后续的配置都是移动性较强的笔记本了。<br />
我在与之前一些朋友的探讨过程中，他们不是十分理解为什么配置这么好。最多的质疑是这好的配置要多花钱，但是这个说法非常经不起推敲，以一台电脑三年的预算使用期来算，就算是花费6,000元来配置一台开发用机，一年的成本也只有2000，平均到每个月只有非常少的费用。而采用好工具对开发人员带来的，恐怕用这些钱是换不来的。比如：<br />
* 心情的舒畅<br />
* 工作效率的提高<br />
* 对工作条件的满意程度<br />
没经历过用烂机器开发过程的人永远也不能懂得执行编译似卡死的时候的那种感觉，特别是项目Deadline临近。</p>
<p>三、敏捷的开发框架<br />
使用敏捷框架是必然会在突发的、时间有限的项目中被采用的。特别是新团队，原始积累不够丰富的团队。<br />
我们常用的这两个<a href="http://codeigniter.com/">CodeIgniter</a>/<a href="http://www.playframework.org/">Play</a>框架基本上都是沿着这个思路来的。<br />
选择CI是为了将来在虚拟主机上使用。选择Play则是由于客户要求使用Java。不过我们用<a href="http://httpd.apache.org/docs/2.0/programs/ab.html">ab</a>和<a href="http://www.joedog.org/index/siege-home">siege</a>的测试结果PHP的还要好一些。</p>
<p>四、模板，一定要有的模板<br />
对于我们来说模板程序员和美工最好的沟通工具。我们的美工甚至已经可以在程序员参与之前，就可以根据需要打造好用户的界面。以至于有个项目的甲方说这个系统你们是不是设计得太简单了？这么快就做好了？<br />
模板系统在为我们以原型驱动的开发过程打造了一个良好的基础，客户可以更好的理解我们的想法，并给我们最真实的意见反馈。<br />
CodeIgniter里采用Smarty模板、Play里采用了自带的Grails模板，虽然还有可以同时用于Java和PHP，甚至当我们使用了Python/Ruby都可以用得上的<a href="http://mustache.github.com/">Mustache</a>模板系统，但是指望一个模板系统在不同的语言下都完全保持一致是不可能的。特别是Play里那些@之类。</p>
<p>五、Flash，IE Killer<br />
如果愿意享受，软件开发的乐趣非常多。但是注意有很多烦恼。我们目前最大的烦恼来自于IE6。当初我们在给客户展示图表的时候，一开始使用了<a href="http://www.highcharts.com/">HighCharts</a>，一个基于JavaScript的图表系统，在展示单个图表的时候问题不大，但是多图表展示一度让我们怀疑系统出现了致命的问题。应该说在这个问题上Flash成为了我们开发时IE6的Killer。</p>
<p>六、有效的工具<br />
有效的工具我们用过的真是很多，下面几个是常用的但不限于：<br />
* <a href="http://getfirebug.com/>Firebug/<a href="https://addons.mozilla.org/zh-cn/firefox/addon/httpfox/">Httpfox</a>（Web调试）<br />
* <a href="http://notepad-plus-plus.org/">Notepad++</a>（HTML开发的利器）<br />
* <a href="http://piwik.org/">Piwik</a>（用来分析客户行为）<br />
* <a href="http://netbeans.org/">Netbeans</a><br />
* <a href="http://www.eclipse.org/">Eclipse</a></p>
<p>我们还在打造基于node.js和d3.js的图表系统。工具的便利，让我们开发时的倚天剑日趋成熟。<br />
利器在手，快乐我有。</p>
]]></content:encoded>
			<wfw:commentRss>http://www.oulan.com/topics/how-we-make-a-sword.html/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
	</channel>
</rss>

