您的位置:首页 > Web前端 > JavaScript

D3js-堆栈图

2015-07-06 08:47 666 查看
效果图:



源代码:

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<base href="<%=basePath%>">

<title>D3 -堆栈图</title>
<style type="text/css">
.axis path,
.axis line{
fill: none;
stroke: black;
shape-rendering: crispEdges;

}
.axis text {
font-family: sans-serif;
font-size: 14px;
font-weight: bold;
}
</style>
</head>

<body>
<script type="text/javascript" src="js/d3/d3.js"></script>
<script type="text/javascript" src="js/d3/d3.min.js"></script>
<script type="text/javascript">

var width = 750;
var height = 500;
var padding ={left:80 ,top:50,right:100,bottom:30};

var svg = d3.select("body").append("svg")
.attr("width",width)
.attr("height",height);
//数据
var dataset = [
{ name: "PC" ,
sales: [	{ year:2005, profit: 3000 },
{ year:2006, profit: 1300 },
{ year:2007, profit: 3700 },
{ year:2008, profit: 4900 },
{ year:2009, profit: 700 },
{ year:2010, profit: 700 }] },
{ name: "SmartPhone" ,
sales: [	{ year:2005, profit: 2000 },
{ year:2006, profit: 4000 },
{ year:2007, profit: 1810 },
{ year:2008, profit: 6540 },
{ year:2009, profit: 2820 },
{ year:2010, profit: 1000 }] },
{ name: "Software" ,
sales: [	{ year:2005, profit: 1100 },
{ year:2006, profit: 1700 },
{ year:2007, profit: 1680 },
{ year:2008, profit: 4000 },
{ year:2009, profit: 4900 },
{ year:2010, profit: 700 }] }
];

//layout转换数据,转换成适合堆栈图的数据
var stack = d3.layout.stack()
.values(function(d){//获取或设置每个系列值的访问器函数
return d.sales;
})
.x(function(d){//获取或设置x轴访问器函数
return d.year;
})
.y(function(d)//获取或设置y轴访问器函数
{
return d.profit;
});
var data =stack(dataset);

console.log(data);//输出数据,可以查看到y0和y

//x轴比例尺
var xRange = width-padding.left-padding.right;
//序列比例尺 (设置x轴上每个节点(年份)所显示的位置)
var xScale =d3.scale.ordinal()
.domain(data[0].sales.map(function(d){ //设置比例尺的定义域  (在x轴要显示的数据)
return d.year;
}))
.rangeBands([0,xRange],0.3);//为离散的块划分值域,(设置图表适合页面的宽度,显示位置)

//Y轴比例尺
//获得定义域最大值  (data[data.length-1]是最上面那个矩形,位于最高层,所以他的sales中的y0+y是最大的)
var bigProfit = d3.max(data[data.length-1].sales,function(d)
{
return d.y+d.y0; //y0即该层起始坐标,y是高度
});
//获得值域最大值
var yRange =height-padding.top-padding.bottom;
//线性比例尺
var yScale = d3.scale.linear()
.domain([0,bigProfit])   //定义域
.range([0,yRange]); //值域

//颜色比例尺
var color = d3.scale.category20();

//添加分组g标签 并设置颜色
var groupRect = svg.selectAll("g")
.data(data)
.enter()
.append("g")
.attr("fill",function(d,i)
{
return color(i);
});

//添加矩形
var rects = groupRect.selectAll("rect")
.data(function(d)
{
return d.sales;
})
.enter()
.append("rect")
.attr("x",function(d,i){
return xScale(d.year); //x轴上坐标的位置
})
.attr("y",function(d,i){
return yRange-(yScale(d.y0+d.y));//Y轴上坐标的高度
})
.attr("width",function(d,i)
{
return xScale.rangeBand(); //rangeBand()取得离散块的宽度,即x轴上各个矩形的宽度
})
.attr("height",function(d,i)
{
return yScale(d.y); //y为矩形的高度
})
//堆栈图偏移位置,即具体页面左边和顶部的位置
.attr("transform","translate("+padding.left+","+padding.top+")");

//添加 x轴
var xAxis = d3.svg.axis()
.scale(xScale)//取得比例尺
.orient("bottom");//设置显示的方位

svg.append("g")
.attr("class","axis")
.attr("transform",function(d,i) //坐标位置
{
return "translate("+padding.left+","+(height-padding.bottom)+")";
})
.call(xAxis)
//x轴坐标说明
.append("text")
.attr("x",function(d)
{
return width-padding.left-padding.right;
})
.text("year");

//添加y轴
yScale.range([yRange,0]); //y轴上数据是从上到下递减

var yAxis = d3.svg.axis()
.scale(yScale)
.orient("left");

svg.append("g")
.attr("class","axis")
.attr("transform",function(d,i) //坐标位置
{
return "translate("+padding.left+","+(height-padding.bottom-yRange)+")";
})
.call(yAxis)
//y轴坐标说明
.append("text")
.text("profit")
.attr("x",function(d)
{
return -20;
});

//分组标签
var labHeight=50;
var labRadius=10;
//圆形标识
var labelCircle = groupRect.append("circle")
.attr("cx",function(d)
{
return width-padding.right*0.98;
})
.attr("cy",function(d,i)
{
return padding.top*2+labHeight*i*0.5;
})
.attr("r",labRadius);
//文本文字
var labelText = groupRect.append("text")
.attr("x",function(d)
{
return width-padding.right*0.8;
})
.attr("y",function(d,i)
{
return padding.top*2+labHeight*i*0.5;
})
//dy使 文字显示和圆形的圆心在同一行
.attr("dy",function(d)
{
return labRadius/2;
})
.text(function(d)
{
return d.name;
});
</script>

</body>
</html>


其中y和y0的介绍:y表示矩形(柱状体)的高度,y0表示这个柱状体的起始高度(即这个矩形从哪里开始绘制)





解释一下上图:(以绘制的第一排柱状体为例)

绘制出来是下面这个效果



第一个矩形(最下面那个蓝色矩形)起始位置y0是0,它的高度y(也就是数据中profit的值)是3000;中间那个矩形它在第一个矩形上面所以它的起始高度y0是3000,而它的高度y是2000;最上面那层矩形它的起始高度是下面两个矩形的高度和就是5000,它的高度y是1100。这就是y和y0所表示的意思。

来源网站:http://www.ourd3js.com/wordpress/?p=1007
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: