赞
踩
vizhub上实现的代码:
https://vizhub.com/Edward-Elric233/53807a1b35d94329b3689081cd2ea945
https://vizhub.com/Edward-Elric233/b9647d50899a4a0e8e917f913cd0a53a
https://vizhub.com/Edward-Elric233/8c6b50cd81a04f048f490f48e4fe6264
由前面的柱状图,我们对图形进行一定的修改就可以得到散点图:
只要将绑定数据以后enter进行添加矩形的操作换成圆形就可以了,不过需要注意的是不能够y坐标再使用scaleBand
了,而应该使用scalePoint
,如果继续使用scaleBand
的话需要调整圆的坐标(y坐标是Categorical的)。注意圆形的属性是cx,cy,r
分别表示圆心的坐标和半径。
index.html
<!DOCTYPE html> <html> <head> <title>Scatter Plot</title> <link rel="stylesheet" href="./styles.css"> <script src="https://unpkg.com/d3@5.7.0/dist/d3.min.js"></script> <!-- find D3 file on UNPKG d3.min.js--> </head> <body> <svg width="960" height="500"></svg> <script src="./index.js"> // console.log(d3); test whether you have imported d3.js or not </script> </body> </html>
index.js
const svg = d3.select('svg'); // svg.style('background-color', 'red'); test const width = +svg.attr('width'); const height = +svg.attr('height'); const render = data => { const xValue = d => d.population; const yValue = d => d.country; const margin = { top: 60, right: 20, bottom: 80, left: 150 }; const innerWidth = width - margin.left - margin.right; const innerHeight = height - margin.top - margin.bottom; const xScale = d3.scaleLinear() .domain([0, d3.max(data, xValue)]) .range([0, innerWidth]) .nice(); //作用是如果值域的最大值不够整齐可以变得整齐 // const yScale = scaleBand() const yScale = d3.scalePoint() .domain(data.map(yValue)) .range([0, innerHeight]) .padding(0.5); const xAxisTickFormat = number => d3.format('.3s')(number).replace('G', 'B'); const yAxis = d3.axisLeft(yScale) .tickSize(-innerWidth);; const xAxis = d3.axisBottom(xScale) .tickFormat(xAxisTickFormat) .tickSize(-innerHeight); //设置tick-line的长度 const g = svg.append('g') .attr('transform', `translate(${margin.left},${margin.top})`); //yAxis(g.append('g')); const yAxisG = g.append('g').call(yAxis).selectAll('.domain').remove(); const xAxisG = g.append('g').call(xAxis) .attr('transform', `translate(0,${innerHeight})`); xAxisG.selectAll('.domain').remove(); xAxisG.append('text') .attr('class', 'axis-label') .attr('y', 60) .attr('x', innerWidth / 2) .attr('fill', 'black') .text('populiation'); let colorSet = ['#eb2617', '#ffaa00', '#4dff00', '#00fbff', '#bb00ff', '#eeff00']; const createGetColor = (idx) => { var i = idx || -1; return { get: () => { i = (i + 1) % colorSet.length; return colorSet[i]; } }; }; const getColor = createGetColor(); g.selectAll('circle').data(data) .enter().append('circle') .attr('cy', d => yScale(yValue(d))) .attr('cx', d => xScale(xValue(d))) .attr('r', 15) .attr('fill', getColor.get); g.append('text') .attr('class', 'title') .attr('y', -20) .text('Top 10 Most Population Countries'); }; d3.csv("https://gist.githubusercontent.com/Edward-Elric233/23f3024c472ffd7e34e6a5ac04bad26c/raw/6ced2249ea6f5d12f72c1eb00b8c1278d2c86e95/every%2520countries'%2520population").then(data => { data.forEach(d => { d.population = +d.population * 1000; }); render(data); // console.log(data); });
styles.css
body { margin: 0px; overflow: hidden; font-family: manosapce; } text { font-family: sans-serif; } .tick text { font-size: 2em; fill: #8E8883 } .axis-label { fill: #8E8883; font-size: 2.5em } .title { font-size: 3em; fill: #8E8883 }
虽然大概实现了散点图,但是上面的数据不适合用散点图来进行表示。因此我们不妨更换数据,使用更适合的数据。
这里因为y坐标也是Quantitative的,所以应该使用scaleLinear
。画的时候注意坐标的方向,如果方向不对应的画可以调整scaleLinear
的domain
或者range
(反向即可)。这里因为圆形比较密集就设置了一下圆形的透明度opacity
,看起来比较好看。
index.html
<!DOCTYPE html> <html> <head> <title>Cars Scatter Plot</title> <link rel="stylesheet" href="./styles.css"> <script src="https://unpkg.com/d3@5.7.0/dist/d3.min.js"></script> <!-- find D3 file on UNPKG d3.min.js--> </head> <body> <svg width="960" height="500"></svg> <script src="./index.js"> // console.log(d3); test whether you have imported d3.js or not </script> </body> </html>
index.js
const svg = d3.select('svg'); // svg.style('background-color', 'red'); test const width = +svg.attr('width'); const height = +svg.attr('height'); //mpg cylinders displacement horsepower weight acceleration year origin name const render = data => { const title = 'Cars: Mpg vs. Horsepower'; const xValue = d => d.mpg; const xAxisLabel = 'Mpg'; const yValue = d => d.horsepower; const yAxisLabel = 'Horsepower'; const margin = { top: 60, right: 20, bottom: 80, left: 100 }; const innerWidth = width - margin.left - margin.right; const innerHeight = height - margin.top - margin.bottom; const circleRadius = 10; const xScale = d3.scaleLinear() //.domain([min(data, xValue), max(data, xValue)]) //和下面的写法等价 .domain(d3.extent(data, xValue)) .range([0, innerWidth]) .nice(); //作用是如果值域的最大值不够整齐可以变得整齐 // const yScale = scaleBand() const yScale = d3.scaleLinear() .domain([d3.max(data, yValue), d3.min(data, yValue)]) .range([0, innerHeight]) .nice(); //const xAxisTickFormat = number => format('.3s')(number).replace('G','B'); const yAxis = d3.axisLeft(yScale) .tickSize(-innerWidth) .tickPadding(15); const xAxis = d3.axisBottom(xScale) //.tickFormat(xAxisTickFormat) .tickSize(-innerHeight) //设置tick-line的长度 .tickPadding(15); //通过设置Padding让x轴的数字离远一点 const g = svg.append('g') .attr('transform', `translate(${margin.left},${margin.top})`); //yAxis(g.append('g')); const yAxisG = g.append('g').call(yAxis); yAxisG.selectAll('.domain').remove(); yAxisG.append('text') .attr('class', 'axis-label') .attr('y', -70) .attr('x', -innerHeight / 2) .attr('fill', 'black') .attr('transform', `rotate(-90)`) .attr('text-anchor', 'middle') //设置锚点在中心 .text(yAxisLabel); const xAxisG = g.append('g').call(xAxis) .attr('transform', `translate(0,${innerHeight})`); xAxisG.selectAll('.domain').remove(); xAxisG.append('text') .attr('class', 'axis-label') .attr('y', 60) .attr('x', innerWidth / 2) .attr('fill', 'black') .text(xAxisLabel); let colorSet = ['#eb2617', '#ffaa00', '#4dff00', '#00fbff', '#bb00ff', '#eeff00']; const createGetColor = (idx) => { var i = idx || -1; return { get: () => { i = (i + 1) % colorSet.length; return colorSet[i]; } }; }; const getColor = createGetColor(); g.selectAll('circle').data(data) .enter().append('circle') .attr('cy', d => yScale(yValue(d))) .attr('cx', d => xScale(xValue(d))) .attr('r', circleRadius) .attr('fill', getColor.get); g.append('text') .attr('class', 'title') .attr('y', -20) .attr('x', innerWidth / 2) .attr('text-anchor', 'middle') .text(title); }; d3.csv('https://vizhub.com/curran/datasets/auto-mpg.csv').then(data => { data.forEach(d => { //得到的数据默认每个属性的值都是字符串,因此需要进行转换 d.mpg = +d.mpg; d.cylinders = +d.cylinders; d.displacement = +d.displacement; d.horsepower = +d.horsepower; d.weight = +d.weight; d.acceleration = +d.acceleration; d.year = +d.year; }); render(data); // console.log(data); });
styles.css
body { margin: 0px; overflow:hidden; font-family: manosapce; } circle { opacity : 0.5; } text { font-family : sans-serif; } .tick text { font-size : 2em; fill : #8E8883 } .tick line { stroke : #E5E2E0 } .axis-label { fill : #8E8883; font-size: 2.5em } .title { font-size : 3em; fill : #8E8883 }
对于时间轴的处理可以使用scaleTime
index.html
<!DOCTYPE html> <html> <head> <title>Temperature in San Francisc Scatter Plot</title> <link rel="stylesheet" href="./styles.css"> <script src="https://unpkg.com/d3@5.7.0/dist/d3.min.js"></script> <!-- find D3 file on UNPKG d3.min.js--> </head> <body> <svg width="960" height="500"></svg> <script src="./index.js"> // console.log(d3); test whether you have imported d3.js or not </script> </body> </html>
html.js
const svg = d3.select('svg'); // svg.style('background-color', 'red'); test const width = +svg.attr('width'); const height = +svg.attr('height'); const render = data => { const title = 'A week in San Francisco'; const xValue = d => d.timestamp; const xAxisLabel = 'Time'; const yValue = d => d.temperature; const yAxisLabel = 'Temperature'; const margin = { top: 60, right: 20, bottom: 80, left: 100 }; const innerWidth = width - margin.left - margin.right; const innerHeight = height - margin.top - margin.bottom; const circleRadius = 6; const xScale = d3.scaleTime() //.domain([min(data, xValue), max(data, xValue)]) //和下面的写法等价 .domain(d3.extent(data, xValue)) .range([0, innerWidth]) .nice(); //作用是如果值域的最大值不够整齐可以变得整齐 // const yScale = scaleBand() const yScale = d3.scaleLinear() .domain([d3.max(data, yValue), d3.min(data, yValue)]) .range([0, innerHeight]) .nice(); //const xAxisTickFormat = number => format('.3s')(number).replace('G','B'); const yAxis = d3.axisLeft(yScale) .tickSize(-innerWidth) .tickPadding(15); const xAxis = d3.axisBottom(xScale) //.tickFormat(xAxisTickFormat) .tickSize(-innerHeight) //设置tick-line的长度 .tickPadding(15); //通过设置Padding让x轴的数字离远一点 const g = svg.append('g') .attr('transform', `translate(${margin.left},${margin.top})`); //yAxis(g.append('g')); const yAxisG = g.append('g').call(yAxis); yAxisG.selectAll('.domain').remove(); yAxisG.append('text') .attr('class', 'axis-label') .attr('y', -70) .attr('x', -innerHeight / 2) .attr('fill', 'black') .attr('transform', `rotate(-90)`) .attr('text-anchor', 'middle') //设置锚点在中心 .text(yAxisLabel); const xAxisG = g.append('g').call(xAxis) .attr('transform', `translate(0,${innerHeight})`); xAxisG.selectAll('.domain').remove(); xAxisG.append('text') .attr('class', 'axis-label') .attr('y', 60) .attr('x', innerWidth / 2) .attr('fill', 'black') .text(xAxisLabel); let colorSet = ['#eb2617', '#ffaa00', '#4dff00', '#00fbff', '#bb00ff', '#eeff00']; const createGetColor = (idx) => { var i = idx || -1; return { get: () => { i = (i + 1) % colorSet.length; return colorSet[i]; } }; }; const getColor = createGetColor(); g.selectAll('circle').data(data) .enter().append('circle') .attr('cy', d => yScale(yValue(d))) .attr('cx', d => xScale(xValue(d))) .attr('r', circleRadius) .attr('fill', 'red'); g.append('text') .attr('class', 'title') .attr('y', -20) .attr('x', innerWidth / 2) .attr('text-anchor', 'middle') .text(title); }; d3.csv('https://vizhub.com/curran/datasets/temperature-in-san-francisco.csv').then(data => { // console.log(data); data.forEach(d => { //得到的数据默认每个属性的值都是字符串,因此需要进行转换 d.temperature = +d.temperature; d.timestamp = new Date(d.timestamp); }); render(data); });
styles.css
body { margin: 0px; overflow: hidden; font-family: manosapce; } circle { opacity: 0.5; } text { font-family: sans-serif; } .tick text { font-size: 2em; fill: #8E8883 } .tick line { stroke: #E5E2E0 } .axis-label { fill: #8E8883; font-size: 2.5em } .title { font-size: 3em; fill: #8E8883 }
赞
踩
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。