“比例尺是一组把输入或映射为输出范围的函数”。-----Mike Bostock
一般而言,任意数据集中的值不可能刚好与图表中的像素尺度一一对应。而D3中,比例尺要做的就是将数据值映射为可视图形中的可替代值得手段。
D3中,比例尺是一种函数,带参数。你可以定义任意多个比例尺函数。
本节中,我们将讨论线性比例尺。当然,还有序数、对数、平方根比例尺等等,但这里我们不做讨论,大家可以以线性比例尺为参考,以此类推。
(1)概念
首先,我们先定义一个数据集:
let dataset = [100,200,300,400,500];
在使用比例尺之前,我们需要理解两个概念:
- 输入值域:指可能的输入值的范围。即最大值与最小值范围。例如100-500;
- 输出范围:指输出可能的范围,一般以用于显示的像素为单位;
我们用一幅图来表示:
例如输入值域为[100,500],输出范围[10,350]
接着,我们来创建比例尺:
D3有一个比例尺生成函数 d3.scale。
例如,let scale = d3.scale.linear();
接着,设定输入值域与输出范围:
let scale = d3.scale.linear().domain([100,500]).range([10,350]);
传参:
scale(100);//返回10
一般而言,我们会在attr()或其他类似方法中调用比例尺函数,而不会像这样独立调用它;下面我们将它应用到散点图中。
(2)应用
你很可能不想给值域设定固定的值,通过d3.min()和d3.max()
能帮助你。
例如:
d3.max(dataset,function(d){ return d[0]; //返嵌套数组中第一个,最大的一个值 });
下面是完整示例:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>Document</title> <style> div.bar { display: inline-block; width: 20px; height: 75px; margin-right: 2px; background-color: teal; } </style> </head> <body> <script src="https://cdn.bootcss.com/jquery/3.2.1/jquery.js"></script> <script src="https://d3js.org/d3.v3.js"></script> <script> //D3.js code let w = 600; let h = 100; let padding = 20; let svg = d3.select("body").append("svg").attr("width",w).attr("height",h);//把append()返回的新元素保存在了变量svg中 let dataset = [ [5,20],[480,90],[250,50],[100,33],[330,95],[410,12],[475,44],[25,67],[85,21],[220,88] ]; let xScale = d3.scale.linear() .domain([0,d3.max(dataset,function(d){return d[0];})]) .range([padding,w-padding*2]) .nice();//nice()告诉比例尺取得为range()设置的任何值域,把两端的值扩展到最接近的整数。如[0.2000011166,0.99999943]优化为[0.2,1] let yScale = d3.scale.linear() .domain([0,d3.max(dataset,function(d){return d[1];})]) .range([h-padding,padding]) .nice(); let rScale = d3.scale.linear() .domain([0,d3.max(dataset,function(d){return d[1];})]) .range([2,5]) .nice(); svg.selectAll("circle") .data(dataset) .enter() .append("circle") .attr("cx",function(d,i){ return xScale(d[0]); //返回缩放后的值 }) .attr("cy",function(d){ return yScale(d[1]); }) .attr("r",function(d){ return rScale(d[1]); }); //添加标签 svg.selectAll("text") .data(dataset) .enter() .append('text') .text(function(d){ return d[0]+ "," + d[1];//设置标签内容 }) .attr({ fill : "black", x : function(d) {return xScale(d[0])+10;},//将标签与散点位置一一对应 y : function(d) {return yScale(d[1]);} }) .style("font-size", "11px"); </script> </body> </html>
(3)其他比例尺
- sqrt 平方根比例尺;
- pow 幂比例尺,适合值以指数级变化的数据集;
- log 对数比例尺;
- quantize 输出范围为独立的值得线性比例尺,适合想把数据分类的情形;
- quantile 适合已经对数据分类的情形;
- ordinal 使用非定量值(如类名)作为输出的序数比例尺;
- d3.time.scale() 针对日期和时间值得一个比例尺方法,可以对日期刻度作特殊处理;
- category10\category20\category20b\category20c 能够输出10-20种类别颜色的预设序数比例尺;
(4)下节预告
本节内容就到这里,但是你一定还是觉得缺了些什么。下一节中,我们会给散点图添加上数轴坐标,更形象地从二维视角表现散点图。