介绍
假如我们在制作柱状图时,不能确定数据的变化范围,或者数据变化过大,就可以使用比例尺。
比例尺,顾名思义,就是把一组数据映射到一个集合中。
具体操作
- 首先我们先说线性映射,即两个集合都是连续的数
预处理
var dataset = [233, 433, 996];
var min = d3.min(dataset);//得到最小值
var max = d3.max(dataset);//得到最大值
var scaleLinear = d3.scaleLinear()
.domain([min,max]) // 要被映射的数据范围, 即原始数据
.range([0, 1000]); // 要被映射到的数据
映射
scaleLinear(300) //此时这个函数就会直接返回映射后的结果
- 此外还有一种非线性映射, 即把两个不是连续的集合之间建立映射关系
<body>
<script>
var index = [0,1,2,3,4];
var color = ["刻晴","优菈","甘雨","胡桃","莫娜"];
var scaleOrdinal = d3.scaleOrdinal()
.domain(index) // 原始数据
.range(color); // 要映射到的集合
document.write("scaleOrdinal(1)输出:"+scaleOrdinal(1));
d3.select("body").append("br");
document.write("scaleOrdinal(2)输出:"+scaleOrdinal(2));
d3.select("body").append("br");
document.write("scaleOrdinal(4)输出:"+scaleOrdinal(4));
</script>
</body>
坐标轴
//为坐标轴定义一个线性比例尺
var xScale = d3.scaleLinear()
.domain([0,d3.max(dataset)])
.range([0,250]);
//定义一个坐标轴
var xAxis = d3.axisBottom(xScale)//定义一个axis,由bottom可知,数字是在坐标轴下方(也就暗示了这是个x轴)
.ticks(7);//设置刻度数目
g.append("g")
.attr("transform","translate("+20+","+(dataset.length*rectHeight)+")")
.call(xAxis);
想要换成y轴也很简单,只需把axisBottom换成axisLeft(数字在坐标轴左侧),或者axisRight(数字在坐标轴右侧)
与此同时,想要改变数字递增的方向也很简单,只需把range中两个数字调换一下位置即可。
示例
<body>
<svg></svg>
<script>
var margin = {top: 80, bottom: 60, left: 70, right: 60};
var dataset = [21893095,13866009,74610235,34915616,24049155,42591407,24073453,31850088,24870895,84748016,64567588,
61027171,41540086,45188635,101527453,99365519,57752557,66444864,126012510,10081232,32054159,38562148,83674866,
47209277,39528999,25019831,5923957,7202654,25823445];
var datax = ['北京','天津','河北','山西','内蒙古','辽宁','吉林','黑龙江','上海','江苏','浙江','安徽','福建',
'江西','山东','河南','湖北','湖南','广东','海南','重庆','贵州','四川','云南','陕西','甘肃','青海','宁夏','新疆'];
var svg = d3.select("svg") // svg画布充斥整个网页
.attr("width", window.innerWidth)
.attr("height", window.innerHeight);
var g = svg.append("g") //设计画布的左上角位置
.attr("transform", "translate(" + margin.top + "," + margin.left + ")");
var height = 0.8 * window.innerHeight, width = 0.9 * window.innerWidth; // 用于计算柱状宽度和长度
var rectWidth = width / dataset.length;
var scaleLinear = d3.scaleLinear() // 比例尺,把高度作为比例尺的起始数据
.domain([0, d3.max(dataset)])
.range([0, height]);
g.selectAll("rect")
.data(dataset)
.enter()
.append("rect")
.attr("x", function (d, i) {
return i * rectWidth;
})
.attr("y", function (d, i){//由于高度是从上往下延伸的,所以柱子y轴开始的地方应该是它的顶端
return height - scaleLinear(d);
})
.attr("width", rectWidth * 0.9)
.attr("height", function (d) {
return scaleLinear(d);
})
.attr("fill", "blue");//颜色
var yScale = d3.scaleLinear() //添加y轴
.domain([0, d3.max(dataset)])
.range([height, 0]); //原本是坐标轴数据从上往下递增的,所以要反着来
var yAxis = d3.axisLeft(yScale)
.ticks(10);
var lineX = 0, lineY = margin.top;
g.append("g")
.attr("transform", "translate(" + lineX + "," + 0 + ")")
.call(yAxis);
</script>
</body>
希望这篇博客对你有所帮助~