用d3js创建一个简单的矩形图

用d3js创建一个简单的矩形

前言

本文并不是针对初学者的教程, 而是对矩形图绘制的基本流程做一个总结, 整理一下d3的基本工作流程.

demo地址

正文

用d3创建矩形图一般分为下面几个步骤

flow.png
bar_chart_1.png

[图片上传失败...(image-61825a-1543910014177)]

通过这几个步骤就可以创建出一个完整的矩形图, 接下来我们从具体代码,一步步看看要如何

生成数据源

为了显示方便, 我们先生成一些测试数据, 我们先定义数据格式为26个字母以及他们的值, 比如{'key': 'A', 'value': 65}

var i = 0;
sampleData = new Array(26).fill(undefined).map(function(){
  i += 1;
  return {
    key: String.fromCharCode(64+i),
    value: Math.random()*80+10
  }
})

这里我用了一个比较高级的写法创建了一个数组,数组中包含了我们想要的格式。这个函数我就不过多的解释了, 主要用了map这个高阶函数。

准备svg和布局参数

这个是一个简单的html文件, 包含了一个svg

index.html

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <script src="./node_modules/d3/dist/d3.min.js" charset="utf-8"></script>
    <title></title>
  </head>
  <body>
    <svg id="bar-chart" width="860" height="500">

    </svg>
  </body>
</html>
<script src="./main.js" charset="utf-8"></script>

然后我们定义这个真正的chart显示的区域,它与上下左右一般需要有一定的边距, 预留一些空间,为了美观和兼容。然后计算出我们图表的长和宽在后面使用。

var margin = {
  top: 20,
  left: 40,
  bottom: 20,
  right: 0
}

var barChart = d3.select('#bar-chart')

var width = barChart.attr('width') - margin.left - margin.right;
var height = barChart.attr('height') - margin.top - margin.bottom;
bar_layout.png

生成比例尺

我们需要两个比例尺,一个将key映射到水平范围, 一个将value映射到高度范围

xScale将key映射到水平范围, key是离散值, 所以我们选用scaleBand(序数比例尺),它将离散值映射到连续值, 所以domain对应的是每一个key, 他的range是我们的宽度范围. 这里我们顺便设置了每个矩形之间的padding参数, 这样比例尺能够自动帮我们计算每个矩形所占的实际宽度, 我们后面可以用bandwidth去获取这个宽度。

yScale 将key 映射到垂直范围,这是一个连续范围, 所以我们选用scaleLinear(线性比例尺),输入域(domain)是0到数据源的最大值,这样value就只会在高度范围内显示

高度的输出域比较特殊, 因为在svg中,左上角才是原点, 所以value越大的其y值应该越小。所以range是从height到0, 而不是从0到height.

var xScale = d3.scaleBand()
           .domain(_data.map(function(d){
             return d.key
           }))
           .range([0, width])
           .padding(0.5)


// 生成y轴比例尺
var maxValue = d3.max(_data, function(d){  // 获取数据源最大值
  return d.value
});

yScale = d3.scaleLinear()
               .domain([0, maxValue])
               .range([height, 0])

生成坐标系

因为d3直接提供了方便的坐标系绘制函数,我们可以通过提供比例尺来创建一个坐标系

// 根据x轴比例尺生成x轴坐标系
var xAxis = d3.axisBottom(xScale);
// 根据y轴比例尺生成y轴坐标系
var yAxis = d3.axisLeft(yScale);

当然坐标系还有一些参数使可以调整的,我们暂时先不管。

绘制坐标系

绘制坐标系时我们只需要对添加的svgElement对象调用坐标系函数call(axis)即可, 同时我们对坐标轴的位置进行设置。添加class 是为了将来自定义坐标轴方便。

// 绘制坐标轴
barChart.append('g')
        .attr('class', 'x-axis')
        .attr('transform', 'translate('+margin.left+','+(margin.top + height)+')')
        .call(xAxis)

barChart.append('g')
        .attr('class', 'y-axis')
        .attr('transform', 'translate('+ margin.left+','+margin.top+')')
        .call(yAxis);

现在我们已经能看到一个雏形了, 继续绘制我们的矩形吧

bar_chart_2.png

绘制矩形

矩形的参数要考虑参数的比较多,我们用导图来方便记忆, 下面也只是我当前用到的基本参数

rect.png
// 绘制矩形
barChart.append('g')
        .attr('class', 'bars')
        .selectAll('rect')
        .data(_data)
        .enter()
        .append('rect')
        .attr('width', xScale.bandwidth())
        .attr('x', function(d){
            return xScale(d.key)
        })
        .attr('y', function(d){
          return yScale(d.value);
        })
        .attr('height', function(d){
          return height - yScale(d.value);
        })
        .attr('transform', 'translate('+margin.left+','+margin.top+')')
        .attr('fill', 'steelblue')

总结

把整个流程整理下来,会发现其实d3创建矩形图的整个过程十分的清晰明了, 不用觉得d3有多么困难。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 157,298评论 4 360
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 66,701评论 1 290
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 107,078评论 0 237
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,687评论 0 202
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,018评论 3 286
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,410评论 1 211
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,729评论 2 310
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,412评论 0 194
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,124评论 1 239
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,379评论 2 242
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 31,903评论 1 257
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,268评论 2 251
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 32,894评论 3 233
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,014评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,770评论 0 192
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,435评论 2 269
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,312评论 2 260