dudo博客

在前面的文章中,我分别介绍了基于列表元素柱状图基于表格元素柱状图的实现方法,虽然方法比较简单,但是它却包含了基本的实现原理。在了解了前面两节的基础知识后,我们只以利用它来实现更加复杂的柱状图效果。

一、情景

假设有一家公司,要统计2007年1~4季度南北区域产品的销售状况,那么可能需要做类似下面的这张表:
柱状图效果预览
其中Q1~Q4分别代表1~4季度,橙色和蓝色分别代表北方和南方的产品销售情况。现在我们又把这张Excel统计出来的数据表呈现在网页上。

二、准备

在仔细研究了上面的图形之后,我们发现,大体可以把这个柱状图分为以下几个部分,首先按季度分为四个组,然后再按区域划分两组,也是先分大组再分小组,组内分组。有了这样的印象之后,我们就可以开始构建页面元素。在选择页面元素时,不但要考虑代码片断最优还是考虑代码的语意和可读性。很显然,使用div来实现这样的总局可能不够简洁,因为是组内再分组的情况,而div没有子元素,所以会产生多层div嵌套的情况,因此不能作为首先。综合上面的考虑,我们可以使用列表元素来实现,首先,列表元素有子元素,而且从语意上说也比使用div更符合要求。这里我选择了使用无序列表<ul>(当然,你也可以考虑使用<ol>或者dd dt dl元素)。

三、代码的构架

确定了网页使用的标签元素后,我们可以根据需要来编写下面的HTML代码片断(好的HTML代码结构可以使页面设计达到事半功倍的效果)。

<ul id="q-graph">
 <li id="q1" class="qtr">Q1
 <ul>
  <li class="north bar" style="height:111px;">18</li>
  <li class="south bar" style="height:99px;">16</li>
 </ul></li>
 <li id="q2" class="qtr">Q2
 <ul>
  <li class="north bar" style="height:198px;">32</li>
  <li class="south bar" style="height:210px;">34</li>
 </ul></li>
 <li id="q3" class="qtr">Q3
 <ul>
  <li class="north bar" style="height:260px;">43</li>
  <li class="south bar" style="height:198px;">32</li>
 </ul></li>
 <li id="q4" class="qtr">Q4
 <ul>
  <li class="north bar" style="height:111px;">18</li>
  <li class="south bar" style="height:198px;">32</li>
 </ul></li>
</ul>

上面这代代码的作用就是在一个<ul>中嵌套了另外一个<ul>,这样就实现了两次分组(代码中同时按照比例设定了li的高度)。
注意:在这段代码中,有id和class现时出现的情况,也有同时使用两个class的情况,至于何时使用class、何时使用id请参考这篇CSS Classes vs ID
点击此处查看运行效果

四、有了HTML代码后,我们就可以使用CSS来样式化结构了

1、首先,对Body进行设置如下:

body {
      padding:0;
      margin:40px;
      font-size:9pt;
      font-family:Helvetica,Geneva,sans-serif;
}

代码很简单,只是要说明一点的是,一定要记得在body中指定文字大小和等宽字体,这在含有英文和数字的页面布局中是十分必要的。
2、接下来要做的是,对ul元素进行布局。遵行前面两节布局中使用的相对定位和绝对定位方法:首先把外围元素设置为relative,然后把内层需要定位的元素设置为absolute,此外还需要去除ulli默认的样式(这一点很重要),并设定宽度和高度等:

	/*ul*/
	ul#q-graph {
		border:2px solid #0063be;
		background:#adfe12 url(fade-light.png) repeat-x scroll 0 0;
		height:300px;
		width:600px;
		position:relative;
		list-style:none;
		margin:1.1em 1em 3.5em;
		padding:0;
	}

注意,一定要清除ulli的默认样式,特别是paddingmarging的值,因为在不同的浏览器中他们的值是不一样的,所以在一般情况下都应该是先清除再负值。
接下来,简单设置一下所有的li元素,主要是清空默认样式和使它们服从绝对定位(下面的样式对所有的li元素生效):

	#q-graph li {
		position:absolute;
		text-align:center;
		bottom:0;
		padding:0
		margin:0;
        }

其中,bottom:0;是绝对定位,意即使所有的指定元素底部对齐。
点击此处查看运行结果

3、下面我们要对四个季度进行布局
全Q1~Q4宽度为总体宽度的1/4,即150px,高度正好填满整个ul元素,右边框虚线又进行区分。同时还要用绝对定位把它们一排列开,这只需要设定它们到左侧的距离left的值即可:

	li.qtr {
		width:150px;
		height:300px;
		border-right:1px dotted #41a3e2;
		z-index:2;
	}
	li#q1 {left:0;}
	li#q2 {left:150px;}
	li#q3 {left:300px;}
	li#q4 {left:450px;border-right:none;} /*最后一个不需要边框*/

点击此处查看运行效果

4、对于季度分组布局完成之后,我们再对区域分组布局。
首先,根据实际情况指定柱状条的宽度,这里我们指定为34px(你可以根据自己设计的样式适当调整),并用不同的颜色区分南北两个区域(sounth和north),这里我们使用了背景图片,并用绝对定位指定left的值:

	/* ul li ul */
	#q-graph ul {list-style:none;}
	/* ul li ul li */
	li.bar {
		width:34px;
		color:#fff;
	}
	li.north {
		left:36px;
		background:#ddd url(http://dudo.org/attachments/month_0804/c2008428195153.gif) no-repeat 0 0;
	}
	li.south {
		left:80px;
		background:#ddd url(http://dudo.org/attachments/month_0804/c2008428195153.gif) no-repeat -34px 0;
	}

注意,north和south样式中的left的都相对于其上一个position:relative元素而言的,这里就是第二层的ul元素。另外还要记住去除默认样式。
点击此处查看运行效果

5、至此,我们已经基本上完成了柱状图的设计,不过还有几处小的问题要处理。
首先,我们使用了png透明图片加强视觉效果,但是这在IE6中是不起作用的;
其次,盒模型的问题,IE6对盒模型的解释存在一定的错误,因此是做一个hack;
不过这两个问题都可以用 !important来解决(请查看最终效果)。

6、加点点缀
在预览图中我们看到了背景有标尺效果,我们下面把它添加上。
首先,在原来的HTML元素中加上下面的代码

 <li id="ticks">
	<div class="ticks"><p>50</p></div>
	<div class="ticks"><p>40</p></div>
	<div class="ticks"><p>30</p></div>
	<div class="ticks"><p>20</p></div>
	<div class="ticks"><p>10</p></div>
</li>

注意:这段代码的位置应该位于第一个ul元素下的子元素。此外,只所以在<div />内又嵌套了<p>元素是因为我们要让这些数字位于一侧,要想对它进行定位就必须把它放在一个容器内。

7、让标尺到相应位置上去
首先让id为ticks的li元素填满整个布局,这个很简单,只需设定他的高度和宽度与父元素的ul相同(高300px、宽600px)就可以了。另外,我们要对<p>元素内的内容进行绝对定位,就必须使其父元素(div)具有position:relative属性:

	/* ul li divs */
	li#ticks {
		left:0;
		height:300px;
		width:100%;
		z-index:1;
	}
	div.ticks {
		position:relative;
		height:60px;
		border-top:1px dotted #41a3e2;
	}
	div.ticks:first-child {border-top:none;}	/*only4 Firefx IE 7+*/
	div.ticks p {
		position:absolute;
		left:103%;
		top:-11pt;
        }

注意:为了让标尺位于柱状图的后面,我们需要设置z-index值,z-index越大说明该越靠表层。此外我们还使用了伪类 :first-child,它的作用是单独为第一个div元素设定样式,这是CSS2.1中规定伪类,不过只有在Internet Explorer 7+、Firefox、Opera等浏览器中有效。如果你想了解:first-child等伪类的使用方法,可以在本站查找[译稿]细说CSS样式选择符(一)——CSS 2.1 Selectors系列文章(共三篇)。
点击此处查看运行效果

8、至此我们的复杂柱状图就完成了,做一下总结:
和前面两篇文章一样,相对定位和绝对定位是关键技术,因此,大家一定要对盒模型的定位有一定的了解;
不同浏览器对于相同元素的默认样式并不一致,这也是为什么我们在CSS的最开始要写 * {padding:0;marging:0};
其它基本知识请参照本文第一节和第二节。
最后,大家可以尝试使用<dd> <dt> <dl>来实现同样的布局

最终效果及源代码



共有(7)条评论

z.Yleo77 发表于 2008-5-26 at 13:13 #1楼

css的妙用 。。。[reply=dudo,2009-04-25 09:30 PM]呵呵,CSS很好很强大[/reply]

[回复]


hauy 发表于 2008-5-26 at 14:37 #2楼

没有css的情况下,我觉得这个html页面看上去会很奇怪。[reply=dudo,2009-04-25 09:30 PM]一点都没错,使用ul语意不好
有老外用Table签来做,效果很好,一会我也发上来[/reply]

[回复]


doggic 发表于 2008-5-26 at 16:39 #3楼


真的很强大
配合js自动设置调度就可以完美应用了[reply=dudo,2009-04-25 09:30 PM]呵呵是啊,不过可以尝试写一个,应该也不会太难[/reply]

[回复]


lijing0033 发表于 2008-5-26 at 19:37 #4楼

现在越来越讲究语义化了[reply=dudo,2009-04-25 09:30 PM]的确,所以用table来定会更合适一点[/reply]

[回复]


Ystar灬龙子 发表于 2008-5-29 at 21:36 #5楼

貌似是蓝色里面的!
[reply=dudo,2009-04-25 09:30 PM]我在BlueIdea里的ID是SivaDu,我在那里发过这两个最终效果 :)
看上面代码里的图片地址就看到了啊,呵呵[/reply]

[回复]


Ystar灬龙子 发表于 2008-5-29 at 22:54 #6楼

哦,那个贴子收藏了!
看来dudo很牛啊!![reply=dudo,2009-04-25 09:30 PM]哪里,其实老外已经研究过了~[/reply]

[回复]


自由人 发表于 2011-10-19 at 09:21 #7楼

这个不错,正要做一个这样的效果,心里有底了

[回复]


随便说两句
名字:
Email:
网站:
内容:

无觅相关文章插件,快速提升流量