又接了個燙手山芋,在Web頁面實現甘特圖的一種表現形式,需要用到畫線功能。
本想用開源的Web甘特圖項目,卻發現在這一領域開源的都太粗糙了,稍微精緻一點的都是要收費的。
例如:易度甘特圖(雖然有原始碼,可是被混淆了www.edogantt.com),Ext Gantt(使用Extjs實現www.longboo.com)和普加甘特圖(www.plusgantt.com)。
上述都是使用Javascript實現的,不得不感歎現在JS太強了,加上CSS想做什麼效果都可以。
開源的不行,只有自己做了,先攻克畫直線這關。下面是源碼(在IE8下測試OK):
<!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><meta http-equiv="Content-Type" content="text/html; charset=utf-8" /><title>無標題文檔</title><style type="text/css">div.line { position:absolute; z-index:2; width:1px; height:1px; font-size:1px; background-color:#0000FF; overflow:hidden; } </style><script type="text/javascript">function createPoint(container, x, y) { var node = document.createElement("div"); node.className = "line"; node.style.marginTop=y; node.style.marginLeft=x; container.appendChild(node); }function line(startX, startY, endX, endY, container) { if (startX == endX) { if (startY > endY) { var tempY = startY; startY = endY; endY = tempY; } for (var k = startY; k < endY; k++) { createPoint(container, startX, k); }return; } // y = ax + b,這裡深刻體現了數學的重要性啊 var a = (startY - endY) / (startX - endX); var b = startY - ((startY - endY) / (startX - endX)) * startX; if (Math.abs(startX - endX) > Math.abs(startY - endY)) { //這是為了多畫幾個point加的選擇 if (startX > endX) { var tempX = endX; endX = startX; startX = tempX; } for (var i = startX; i <= endX; i++) { createPoint(container, i, a * i + b); } } else { if (startY > endY) { var tempY = startY; startY = endY; endY = tempY; } for (var j = startY; j <= endY; j++) { createPoint(container, (j - b) / a, j); } } }function testLine() { line(88, 2, 88, 88, document.getElementById("container")); } </script></head><body> <div id="container" style="width:400px;height:400px;border:1px solid #000000;margin-left:50px"></div> <input type="button" value="line" onclick="testLine();"></input> </body></html>
雖然儘可能的多畫了幾個point,可是鋸齒還是很嚴重,所以基本放棄這種方式了。
繼續調研,Web頁面上使用JS畫圖可以使用SVG,VML和HTML 5的<canvas>等方法,但是在現階段,貌似都不能相容所有瀏覽器。
靈機一動,jQuery會不會有類似的外掛程式呢?這樣就不用考慮瀏覽器安全色性了,因為jQuery都會幫我們處理。
結果還真被我找到了jqPlot(www.jqplot.com),這是基於HTML 5的canvas標籤的(用Firebug查看產生的Plot可以看到大量的canvas標籤),測試了FF,Chrome,IE8都沒有問題。
參考Example做例子時發現需要對IE系列做例外處理<!--[if lt IE 9]><script language="javascript" type="text/javascript" src="jqPlot/excanvas.js"></script><![endif]-->
如果不加上述聲明,IE8下會報JS錯誤'window.G_vmlCanvasManager'為空白或不是對象。
雖然jqPlot很強大,但是跟我的需求還是相差太遠。回到原點,研究Edo,Plus等產生的甘特圖,發現可以用div產生連接線的樣式,而且上述瀏覽器都相容。
<!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><meta http-equiv="Content-Type" content="text/html; charset=utf-8" /><title>無標題文檔</title><style type="text/css">.linkinfo{ z-index:102;}.point{ position:absolute;background-color:blue;overflow:hidden;}.point-critical{ background-color:Red;}.arrowhead-down{ background:url(../images/arrow_blue_down.gif) top left no-repeat; overflow:hidden; width:10px; height:5px; position:absolute;}.arrowhead-down-critical{ background-image:url(../images/arrow_red_down.gif);//這是一個寬9px,高5px的向下的紅色箭頭}</style></head><body> <div class="linkinfo point point-critical" style="left: 31px; top: 31px; width: 9px; height: 1px;"></div> <div class="linkinfo point point-critical" style="left: 40px; top: 31px; height: 23px; width: 1px;"></div> <div class="linkinfo arrowhead-down arrowhead-down-critical" style="left: 36px; top: 49px;"></div></body></html>
萬裡長徵才走第一步,繼續前進中。