D3.js-柱形图
2016-10-08 14:50
302 查看
柱形图,是使用柱形的长短来表示数据变化的图表,也是最简单的图表之一。一般情况下,柱形图包括:矩形、坐标轴和文字。
定义一个SVG,表示绘制区域:
添加SVG后,定义几个变量:
data()的工作过程:
data()能将数组各项分别绑定到选择集的各元素上,并且能指定绑定的规则。当数组长度与元素数量不一致时,data()也能够处理。当数组长度大于元素数量时,为多余数据预留元素位置,以便将来插入新元素;当数组长度小于元素数量时,能够获取多余元素的位置,以便将来删除。
在D3中,根据数组长度和元素数量的关系,分别把各种情况归纳如下:
update:数组长度 = 元素数量;
enter:数组长度 > 元素数量;
exit:数组长度 < 元素数量。
绘制矩形:
绘制文字:
update部分的处理方法是更新属性,enter部分的处理方法是添加元素后再赋予其相应的属性,exit部分的处理方法则是删除掉多余的元素。
矩形:
文字:
有了比例尺后,矩形的位置、长度都要用比例尺来计算。这么做之后,数据和绘制就能完全分开,而且只需要修改比例尺,即可将图表自由伸缩。
等价于
使用call的完整示例
一、矩形和文字
定义一个数组,每个数据项表示矩形的长短:var dataset = [50, 43, 120, 87, 99, 167, 142]; // 数据集
定义一个SVG,表示绘制区域:
var width = 400; // svg可视区域宽度 var height = 400; // svg可视区域高度 var svg = d3.select("body") .append("svg") // 在body中添加SVG .attr("width", width) .attr("height", height);
添加SVG后,定义几个变量:
var padding = {top: 20, right: 20, bottom: 20, left: 20}; // 边距 var rectStep = 35; // 矩形所占宽度(包括空格) var rectWidth = 30; // 矩形所占宽度(不包括空格)
data()的工作过程:
data()能将数组各项分别绑定到选择集的各元素上,并且能指定绑定的规则。当数组长度与元素数量不一致时,data()也能够处理。当数组长度大于元素数量时,为多余数据预留元素位置,以便将来插入新元素;当数组长度小于元素数量时,能够获取多余元素的位置,以便将来删除。
在D3中,根据数组长度和元素数量的关系,分别把各种情况归纳如下:
update:数组长度 = 元素数量;
enter:数组长度 > 元素数量;
exit:数组长度 < 元素数量。
绘制矩形:
/* rect */ var rect = svg.selectAll("rect") .data(dataset) // 绑定数据 .enter() // 获取enter部分 .append("rect") // 添加rect元素,使其与绑定数组的长度一致 .attr("fill", "steelblue") .attr("x", function(d, i){ return padding.left + i * rectStep; }) .attr("y", function(d){ return height - padding.bottom - d; }) .attr("width", rectWidth) .attr("height", function(d){ return d; });
绘制文字:
/* text */ var text = svg.selectAll("text") .data(dataset) // 绑定数据 .enter() // 获取enter部分 .append("text") // 添加text元素,使其与绑定数组的长度一致 .attr("fill", "white") .attr("font-size", "14px").attr("text-anchor", "middle") .attr("x", function(d, i){ return padding.left + i * rectStep; }) .attr("y", function(d){ return height - padding.bottom - d; }) .attr("dx", rectWidth/2).attr("dy", "1em") .text(function(d){ return d; });
二、更新数据
更新数据后,柱形图也得跟着变化。update部分的处理方法是更新属性,enter部分的处理方法是添加元素后再赋予其相应的属性,exit部分的处理方法则是删除掉多余的元素。
矩形:
var updateRect = svg.selectAll("rect").data(dataset); // 错误 d3.selectAll() 出了svg范围 var enterRect = updateRect.enter(); var exitRect = updateRect.exit(); // update处理方法 updateRect.attr("fill", "steelblue") .attr("x", function(d, i){ return padding.left + i * rectStep; }) .attr("y", function(d){ return height - padding.bottom - d; }) .attr("width", rectWidth) .attr("height", function(d){ return d; }); // enter处理方法 enterRect.append("rect").attr("fill", "steelblue") .attr("x", function(d, i){ return padding.left + i * rectStep; }) .attr("y", function(d){ return height - padding.bottom - d; }) .attr("width", rectWidth) .attr("height", function(d){ return d; }); // exit处理方法 exitRect.remove();
文字:
var updateText = svg.selectAll("text").data(dataset); var enterText = updateText.enter(); var exitText = updateText.exit(); // update处理方法 updateText.attr("fill", "white") .attr("font-size", "14px").attr("text-anchor", "middle") .attr("x", function(d, i){ return padding.left + i * rectStep; }) .attr("y", function(d){ return height - padding.bottom - d; }) .attr("dx", rectWidth/2).attr("dy", "1em") .text(function(d){ return d; }); // enter处理方法 enterText.append("text").attr("fill", "white") .attr("font-size", "14px").attr("text-anchor", "middle") .attr("x", function(d, i){ return padding.left + i * rectStep; }) .attr("y", function(d){ return height - padding.bottom - d; }) .attr("dx", rectWidth/2).attr("dy", "1em") .text(function(d){ return d; }); // exit处理方法 exitText.remove();
三、坐标轴
比例尺分为:定量比例尺(定义域是连续的)和序数比例尺(定义域是不连续的)。// 定义柱形图比例尺 var xAxisWidth = 300; // x轴宽度 var yAxisWidth = 300; // y轴宽度 /* x轴比例尺(序数比例尺) */ var xScale = d3.scale.ordinal() .domain(d3.range(dataset.length)) .rangeRoundBands([0, xAxisWidth], 0.2); /* y轴比例尺(线性比例尺) */ var yScale = d3.scale.linear() .domain([0, d3.max(dataset)]) .range([0, yAxisWidth]);
有了比例尺后,矩形的位置、长度都要用比例尺来计算。这么做之后,数据和绘制就能完全分开,而且只需要修改比例尺,即可将图表自由伸缩。
selection.attr("fill", "steelblue") .attr("x", function(d, i){ return padding.left + xScale(i); }) .attr("y", function(d){ return height - padding.bottom - yScale(d); }) .attr("width", xScale.rangeBand()) .attr("height", function(d){ return yScale(d); });
/* 添加坐标轴 */ var xAxis = d3.svg.axis().scale(xScale).orient("bottom"); yScale.range([yAxisWidth, 0]); // 重新设置y轴比例尺的值域,与原来的相反 var yAxis = d3.svg.axis().scale(yScale).orient("left"); svg.append("g").attr("class", "axis") .attr("transform", "translate("+ padding.left +","+ (height - padding.bottom) +")") .call(xAxis); svg.append("g").attr("class", "axis") .attr("transform", "translate("+ padding.left +","+ (height - padding.bottom - yAxisWidth) +")") .call(yAxis);
四、使用call减少冗余
call允许将选择集自身作为参数,传递给某一函数。d3.selectAll("div").call(myfun);
等价于
function myfun(selection){ // 这里进行相关操作 selection.attr("name", "value"); } myfun(d3.selectAll("div"));
使用call的完整示例
var dataset = [50, 43, 120, 87, 99, 167, 142]; // 数据集
var width = 400; // svg可视区域宽度
var height = 400; // svg可视区域高度
var svg = d3.select("body")
.append("svg")
.attr("width", width).attr("height", height);
var padding = {top: 20, right: 20, bottom: 20, left: 50}; // 边距
var xAxisWidth = 300; // x轴宽度
var yAxisWidth = 300; // y轴宽度
/* x轴比例尺(序数比例尺) */
var xScale = d3.scale.ordinal()
.domain(d3.range(dataset.length))
.rangeRoundBands([0, xAxisWidth], 0.2);
/* y轴比例尺(线性比例尺) */
var yScale = d3.scale.linear()
.domain([0, d3.max(dataset)])
.range([0, yAxisWidth]);
/* rect */
var rect = svg.selectAll("rect")
.data(dataset)
.enter()
.append("rect")
.call(rectFun);
/* text */
var text = svg.selectAll("text")
.data(dataset)
.enter()
.append("text")
.call(textFun);
/* 添加坐标轴 */ var xAxis = d3.svg.axis().scale(xScale).orient("bottom"); yScale.range([yAxisWidth, 0]); // 重新设置y轴比例尺的值域,与原来的相反 var yAxis = d3.svg.axis().scale(yScale).orient("left"); svg.append("g").attr("class", "axis") .attr("transform", "translate("+ padding.left +","+ (height - padding.bottom) +")") .call(xAxis); svg.append("g").attr("class", "axis") .attr("transform", "translate("+ padding.left +","+ (height - padding.bottom - yAxisWidth) +")") .call(yAxis);
/* rect处理函数 */
function rectFun(selection) {
selection.attr("fill", "steelblue") .attr("x", function(d, i){ return padding.left + xScale(i); }) .attr("y", function(d){ return height - padding.bottom - yScale(d); }) .attr("width", xScale.rangeBand()) .attr("height", function(d){ return yScale(d); });
}
/* text处理函数 */
function textFun(selection){
selection.attr("fill", "white")
.attr("font-size", "14px").attr("text-anchor", "middle")
.attr("x", function(d, i){
return padding.left + xScale(i);
})
.attr("y", function(d){
return height - padding.bottom - yScale(d);
})
.attr("dx", xScale.rangeBand()/2).attr("dy", "1em")
.text(function(d){
return d;
});
}
相关文章推荐
- D3.js添加了过渡效果的柱形图
- D3.js:完整的柱形图
- XML + XSL + JS 构建小型Web App (十四)
- 给初学者提供几本学习js值得看的书
- XML + XSL + JS 构建小型Web App (十三)
- XML + XSL + JS 构建小型Web App (十)
- XML + XSL + JS 构建小型Web App (十一)
- XML + XSL + JS 构建小型Web App (十二)
- XML + XSL + JS 构建小型Web App (八)
- XML + XSL + JS 构建小型Web App (九)
- XML + XSL + JS 构建小型Web App (二)
- XML + XSL + JS 构建小型Web App (四)
- XML + XSL + JS 构建小型Web App (五)
- XML + XSL + JS 构建小型Web App (六)
- XML + XSL + JS 构建小型Web App (七)
- Node.js(day5)
- ASP+JS时的"""
- XML + XSL + JS 构建小型Web App (十五)
- 真正的 用JS 做的 loading
- JS版常见问题(二)兼容版本的无提示关闭窗口!