为什么我的文本没有显示在svg轴标签中? (D3保证金约定) [英] Why isn't my text displaying in the svg axis label? (D3 Margin Convention)
问题描述
这是一个散点图,显示按体积(x)和IBU(y)的酒精含量啤酒.我无法显示轴标签.我检查了DOM,并且文本在树中,但是由于某种原因,它没有显示在屏幕上.
This is a scatterplot displaying beer by alcohol by volume (x) and IBU (y). I cannot get the axis labels to display. I checked the DOM, and the text is in the tree, but for some reason, it is not displaying on the screen.
对于y标签,边距似乎不起作用,对于x,它位于我想要的位置,但是我根本看不到任何文本.
For the y-label, the margins don't seem to be working, and for the x, it is positioned where I want it to be, but I simply cannot see any text.
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>
推荐答案
处理边距,尺寸,填充和平移的方式毫无意义.例如,您设置了margin
对象的属性,但是SVG的宽度和高度仅减去了这些值.
The way you're dealing with the margins, dimensions, paddings and translates makes little sense. For instance, you set the properties of the margin
object, but your SVG has a width and height that simply subtracts those values.
我个人既不是该模式的用户,也不是该模式的粉丝(Mike Bostock称保证金约定),但这是您可以这样做的方法:
I'm not personally neither a user nor a fan of that pattern (that Mike Bostock calls margin convention), but this is how you can do it:
首先,像您一样设置边距,并定义width
和height
.然后,添加用于设置SVG尺寸的边距:
First, set the margins, as you did, and define the width
and height
. Then, add the margins for setting the SVG dimensions:
.attr('width', width + margin.left + margin.right)
.attr('height', height + margin.top + margin.bottom)
最后,添加一个<g>
元素,并使用margin.left
和margin.top
对其进行翻译:
Finally, append a <g>
element, translating it using margin.left
and margin.top
:
.append("g")
.attr("transform", "translate(" + margin.left + ","+ margin.top + ")");
这是您所做的更改(以及更改轴的平移)的代码:
Here is your code with that change (and changing the translate for the axes as well):
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>
这篇关于为什么我的文本没有显示在svg轴标签中? (D3保证金约定)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!