这是一个散点图,显示按体积(x)和IBU(y)的酒精含量的啤酒。我无法显示轴标签。我检查了DOM,并且文本在树中,但是由于某种原因,它没有显示在屏幕上。
对于y标签,边距似乎不起作用,对于x,它位于我想要的位置,但是我根本看不到任何文本。
const dataFiles = ['https://raw.githubusercontent.com/inspectordanno/beer_components/master/scatterplot/data/beers.csv', 'https://raw.githubusercontent.com/inspectordanno/beer_components/master/scatterplot/data/breweries.csv']; //data files to be parsed
const promises = []; //empty array which will contain the promises
dataFiles.forEach(url => {
promises.push(d3.csv(url)); //this parses each csv file and pushes it to the array
});
//dimensions and margins of plot
const margin = {
top: 10,
right: 30,
bottom: 30,
left: 60
},
width = 960 - margin.left - margin.right,
height = 500 - margin.top - margin.bottom,
padding = 30;
const svg = d3.select('body')
.append('svg')
.attr('width', width)
.attr('height', height);
Promise.all(promises).then(data => { //here, I am combining the two arrays in the promise into one big array of beer objects
data[0].forEach(beer => {
const breweryid = beer.brewery_id;
data[1].forEach(brewery => {
if (parseInt(breweryid) == parseInt(brewery.id)) {
beer.brewery_name = brewery.name;
beer.brewery_city = brewery.city;
beer.brewery_state = brewery.state;
}
});
});
let beers = data[0]; //beer data
const xScale = d3.scaleLinear()
.domain([0, d3.max(beers, d => d.abv)])
.range([padding, width - padding *2]);
const yScale = d3.scaleLinear()
.domain([0, d3.max(beers, d => d.ibu)])
.range([height - padding, padding]);
const xAxis = d3.axisBottom()
.scale(xScale)
.ticks(10) //ask steven
.tickFormat(d3.format(',.1%'));
const yAxis = d3.axisLeft()
.scale(yScale)
.ticks(10); //ask steven
// .tickFormat
svg.selectAll('circle')
.data(beers)
.enter()
.append('circle')
.attr('cx', d => {
return xScale(d.abv);
})
.attr('cy', d => {
return yScale(d.ibu);
})
.attr('r', 1)
.attr('fill', 'steelblue')
.on('mouseover', d => console.log(d))
//Create X axis
svg.append("g")
.attr("class", "axis")
.attr("transform", "translate(0," + (height - padding) + ")")
.call(xAxis);
//text label for x axis
svg.append("text")
.attr("transform", `translate(${(width/2)}, ${height + margin.top * 4})`)
.style("text-anchor", "middle")
.text("Alcohol by Volume");
// text label for the y axis
svg.append("text")
.attr("transform", "rotate(-90)")
.attr('y', 0 - margin.left * .75)
.attr('x', 0 - (height/2))
.style("text-anchor", "middle")
.text("IBU")
//Create Y axis
svg.append("g")
.attr("class", "axis")
.attr("transform", "translate(" + padding + ",0)")
.call(yAxis);
}) //end .then of promise
.catch(err => console.log(err)); // catching error in promises
<!DOCTYPE html>
<html lang="en" dir="ltr">
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
<script src="https://d3js.org/d3.v5.min.js"></script>
<script src="main.js" charset="utf-8"></script>
</body>
</html>
答案 0 :(得分:3)
处理边距,尺寸,填充和平移的方式毫无意义。例如,您设置了margin
对象的属性,但是SVG的宽度和高度仅减去了这些值。
我个人既不是这种模式的用户,也不是其粉丝(Mike Bostock称margin convention),但这是您可以做到的:
首先,像您一样设置边距,并定义width
和height
。然后,添加用于设置SVG尺寸的边距:
.attr('width', width + margin.left + margin.right)
.attr('height', height + margin.top + margin.bottom)
最后,附加一个<g>
元素,并使用margin.left
和margin.top
对其进行翻译:
.append("g")
.attr("transform", "translate(" + margin.left + ","+ margin.top + ")");
这是您所做的更改(以及更改轴的平移)的代码:
const dataFiles = ['https://raw.githubusercontent.com/inspectordanno/beer_components/master/scatterplot/data/beers.csv', 'https://raw.githubusercontent.com/inspectordanno/beer_components/master/scatterplot/data/breweries.csv']; //data files to be parsed
const promises = []; //empty array which will contain the promises
dataFiles.forEach(url => {
promises.push(d3.csv(url)); //this parses each csv file and pushes it to the array
});
//dimensions and margins of plot
const margin = {
top: 10,
right: 30,
bottom: 200,
left: 100
},
width = 960 - margin.left - margin.right,
height = 500 - margin.top - margin.bottom;
const svg = d3.select('body')
.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 + ")");
Promise.all(promises).then(data => { //here, I am combining the two arrays in the promise into one big array of beer objects
data[0].forEach(beer => {
const breweryid = beer.brewery_id;
data[1].forEach(brewery => {
if (parseInt(breweryid) == parseInt(brewery.id)) {
beer.brewery_name = brewery.name;
beer.brewery_city = brewery.city;
beer.brewery_state = brewery.state;
}
});
});
let beers = data[0]; //beer data
const xScale = d3.scaleLinear()
.domain([0, d3.max(beers, d => d.abv)])
.range([0, width]);
const yScale = d3.scaleLinear()
.domain([0, d3.max(beers, d => d.ibu)])
.range([height, 0]);
const xAxis = d3.axisBottom()
.scale(xScale)
.ticks(10) //ask steven
.tickFormat(d3.format(',.1%'));
const yAxis = d3.axisLeft()
.scale(yScale)
.ticks(10); //ask steven
// .tickFormat
svg.selectAll('circle')
.data(beers)
.enter()
.append('circle')
.attr('cx', d => {
return xScale(d.abv);
})
.attr('cy', d => {
return yScale(d.ibu);
})
.attr('r', 1)
.attr('fill', 'steelblue')
.on('mouseover', d => console.log(d))
//Create X axis
svg.append("g")
.attr("class", "axis")
.attr("transform", "translate(0," + (height) + ")")
.call(xAxis);
//text label for x axis
svg.append("text")
.attr("transform", `translate(${(width/2)}, ${height + margin.top * 4})`)
.style("text-anchor", "middle")
.text("Alcohol by Volume");
// text label for the y axis
svg.append("text")
.attr("transform", "rotate(-90)")
.attr('y', 0 - margin.left * .75)
.attr('x', 0 - (height/2))
.style("text-anchor", "middle")
.text("IBU")
//Create Y axis
svg.append("g")
.attr("class", "axis")
.call(yAxis);
}) //end .then of promise
.catch(err => console.log(err)); // catching error in promises
<!DOCTYPE html>
<html lang="en" dir="ltr">
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
<script src="https://d3js.org/d3.v5.min.js"></script>
<script src="main.js" charset="utf-8"></script>
</body>
</html>