建立形状 SVG
d3.js图表实际上是svg放在一起的一组形状。
<!DOCTYPE html>
<!-- Add a title -->
<h1>First html document</h1>
<!-- Add a bit of text -->
<p>This is my first sentence</p>
<!-- Add a svg shape -->
<svg>
<circle style="fill: #69b3a2" stroke="black" cx=50 cy=50 r=40></circle>
</svg>
尝试使用下面的备忘单绘制另一种形状
<line x1="0" y1="0" x2="10" y2="10" stroke="black"></line>
<rect x="0" y="0" width="10" height="10"></rect>
<circle cx="5" cy="5" r="5"></circle>
<ellipse cx="10" cy="5" rx="10" ry="5"></ellipse>
<polygon points="0,0 10,5 20,0 20,20 10,15 0,20"></polygon>
<polyline points="0,0 10,5 20,0 20,20 10,15 0,20" stroke="black"></polyline>
<path d="M65,10 a50,25 0 1,0 50,25"></path>
坐标系
创建d3.js图表首先要创建一个svg元素。该元素具有awidth和a height(以像素为单位)。
重要的是要了解左上角的坐标为x=0和y=0。左下角的坐标为x=0和y=height。右上角有坐标x=width和height=0
<!DOCTYPE html>
<!-- Add a svg area, empty -->
<svg id="dataviz_area" height=200 width=450></svg>
<!-- Load d3.js -->
<script src="https://d3js.org/d3.v4.js"></script>
<script>
var svg = d3.select("#dataviz_area")
svg.append("circle")
.attr("cx", 2).attr("cy", 2).attr("r", 40).style("fill", "blue");
svg.append("circle")
.attr("cx", 140).attr("cy", 70).attr("r", 40).style("fill", "red");
svg.append("circle")
.attr("cx", 300).attr("cy", 100).attr("r", 40).style("fill", "green");
</script>
数据绑定
将数据绑定到svg元素是完成散点图所需的最后一步。我认为这也是最难理解的部分。
它始终遵循相同的步骤:
svg:这将选择图表发生的svg区域
.selectAll(“whatever”):选择所有尚未创建的元素,我知道这很奇怪。
.data(data):指定要使用的数据。
.enter():启动数据循环。以下代码将应用于data[0],data[1]依此类推。
.append(“circle”):对于每次迭代,添加一个圆圈。
.attr(“cx”, function(d){ return x(d.x) }):给出x圆的位置。这d将是data[0],然后data[1]依此类推。因此,d.x是的值x,并且x(d.x)是通过所找到的像素中的对应位置x scale。
<!DOCTYPE html>
<!-- Add a svg area, empty -->
<div id="scatter_area"></div>
<!-- Load d3.js -->
<script src="https://d3js.org/d3.v4.js"></script>
<script>
// set the dimensions and margins of the graph
var margin = {top: 10, right: 40, bottom: 30, left: 30},
width = 450 - margin.left - margin.right,
height = 400 - margin.top - margin.bottom;
// append the svg object to the body of the page
var svG = d3.select("#scatter_area")
.append("svg")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom)
.append("g")
.attr("transform",
"translate(" + margin.left + "," + margin.top + ")");
// Create data
var data = [ {x:10, y:20}, {x:40, y:90}, {x:80, y:50} ]
// X scale and Axis
var x = d3.scaleLinear()
.domain([0, 100]) // This is the min and the max of the data: 0 to 100 if percentages
.range([0, width]); // This is the corresponding value I want in Pixel
svG
.append('g')
.attr("transform", "translate(0," + height + ")")
.call(d3.axisBottom(x));
// X scale and Axis
var y = d3.scaleLinear()
.domain([0, 100]) // This is the min and the max of the data: 0 to 100 if percentages
.range([height, 0]); // This is the corresponding value I want in Pixel
svG
.append('g')
.call(d3.axisLeft(y));
// Add 3 dots for 0, 50 and 100%
svG
.selectAll("whatever")
.data(data)
.enter()
.append("circle")
.attr("cx", function(d){ return x(d.x) })
.attr("cy", function(d){ return y(d.y) })
.attr("r", 7)
</script>
创建地图
GeoJSON(一种用于指定地理数据的基于JSON的格式)
project(将纬度/经度坐标转换为x和y坐标的函数)
地理路径生成器(将GeoJSON形状转换为SVG或Canvas路径的功能)
var projection = d3.geoEquirectangular();
var geoGenerator = d3.geoPath()
.projection(projection);
var geoJson = {
"type": "Feature",
"properties": {
"name": "Africa"
},
"geometry": {
"type": "Polygon",
"coordinates": [[[-6, 36], [33, 30], ... , [-6, 36]]]
}
}
geoGenerator(geoJson);