D3.js-柱形图

柱形图,是使用柱形的长短来表示数据变化的图表,也是最简单的图表之一。一般情况下,柱形图包括:矩形、坐标轴和文字。

一、矩形和文字

定义一个数组,每个数据项表示矩形的长短:

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;
            });
}
时间: 2025-01-01 08:50:13

D3.js-柱形图的相关文章

d3.js——给柱形图添加事件出现的问题总结

首先做出一个动态的柱形图(这儿用的d3.js的版本是v3,用v4的话有些函数会发生变化) 效果图: 代码: <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>histogramTransitionEvent</title> <style> .axis path, .axis line{ fill

[3] 用D3.js做一个简单的图表吧!

本人的个人博客为: www.ourd3js.com csdn博客为: blog.csdn.net/lzhlzz 转载请注明出处,谢谢. 前面说了几节,都是对文字进行处理,这一节中将用 D3.js 做一个简单的柱形图. 做柱形图有很多种方法,比如用 HTML 的 div 标签,或用 svg . 推荐用 SVG 来做各种图形.SVG 意为可缩放矢量图形(Scalable Vector Graphics),SVG 使用 XML 格式定义图像,不清楚什么是SVG的朋友请先在 w3cschools 学习下

[4] D3.js中使用scale(比例)

本人的个人博客为: www.ourd3js.com csdn博客为: blog.csdn.net/lzhlzz 转载请注明出处,谢谢. 在上一节中使用了一个很重要的概念 - scale (这个不知道翻译成什么,暂且叫它比例).本节将重点介绍它的相关使用方法. 在介绍 scale 之前,先介绍两个经常和 scale 一起出现的函数,在上一节中也出现了. d3.max() d3.min() 它们用于求一个数组中的最大值和最小值,如果是一维数组,使用方法如下: var dataset = [ 30,

d3.js学习笔记

入门好文:http://www.ourd3js.com/wordpress/?p=51 d3.js和d3.min.js内容一样,后者是压缩过的,适合发行版本,前者适合开发人员. 1.选择集(满足css选择符的要求)主要和数据绑定一起使用 d3.select() d3.selectAll() var body = d3.select("body") 2.数据绑定(实质就是在选择集的元素对象里面添加一个变量,并赋值) p.text(function(d,i)){return d+"

[5.1] D3.js中整合坐标轴 - 图表 - 文字标签

本人的个人博客为: www.ourd3js.com csdn博客为: blog.csdn.net/lzhlzz 转载请注明出处,谢谢. 前面几节讲解了图标.坐标轴.比例等等,这一节整合这些内容做一个实用的图表.结果图如下: 代码如下所示: <html> <head> <meta charset="utf-8"> <title>Chart</title> </head> <style> .axis pat

【 D3.js 入门系列 --- 9 】 常见可视化图形

本人的个人博客为: www.ourd3js.com csdn博客为: blog.csdn.net/lzhlzz 转载请注明出处,谢谢. Layout ,直译为"布局,安排".但在 D3 中不是这个意思. D3 中有很多 Layout 函数,它们不是为了在画面中布局什么,在 D3 中是对输入的数据进行转换,转换成比较容易进行可视化的数据.实际进行可视化时,需要其他的代码.我们可以简单地把 Layout 理解为"制作常见图形的函数",比如饼状图等等. D3 中一共提供了

【 D3.js 选择集与数据详解 — 5 】 处理模板的应用

在[选择集与数据 - 4]一文中,介绍了一个update.enter.exit的处理模板,这个模板很常用,本文将通过一个例子来讲解其使用方法. 1. 模板 复习一下上一章提到的模板. //绑定数据后,分别返回update.enter.exit部分 var update = selection.data(dataset); var enter = update.enter(); var exit = update.exit(); //1.update部分的处理方法 update.text( fun

[5] D3.js中如何添加坐标轴

本人的个人博客为: www.ourd3js.com csdn博客为: blog.csdn.net/lzhlzz 转载请注明出处,谢谢.      第3节中做了一个图标,但没有为它添加一个相应的坐标轴,这样不知道每一个柱形到底有多长.这一节做一个坐标轴. D3中的坐标轴都是以 svg 图的形式出现的,这也是为什么在第3节中要使用 svg 的方法做柱形图的原因.第4节里我们讲解了 scale (比例)的用法,在做坐标轴的时候也需要用到比例.第4节中,我们说到scale 是一个函数,这一节中的坐标轴也

D3.js系列 --- 初识

D3.js(Data-Driven Documents)即被数据驱动的文档,它是一个用于根据数据来操作文档的JavaScript库.相比于echart, antv等其他图表库,它算是一个比较底层的数据可视化工具.它不提供任何一种现成的图表,只做最基础的东西,所有的图表都需要我们在它的库里挑选合适的方法进行构建.在一切即数据的今天,我们更需要做到让数据活起来,展现数据之美. 简介 犹抱琵琶半遮面,千呼万唤中终于要接触数据可视化了.数据可视化越来越流行,让复杂的数据和文字变得十分容易理解.作为其中的

d3.js学习

画svg图像 1.添加svg元素 2.添加g元素,g元素是一个分组的元素,相当于html中的div元素 3.画图像 4.画坐标轴 ----------------------------------------------------------------------------- d3画闲线性曲线例子 html: <!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8&