效果图:
源码:
<%@ 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