为什么我的文本没有显示在svg轴标签中? (D3保证金约定) [英] Why isn't my text displaying in the svg axis label? (D3 Margin Convention)

查看:53
本文介绍了为什么我的文本没有显示在svg轴标签中? (D3保证金约定)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是一个散点图,显示按体积(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:

首先,像您一样设置边距,并定义widthheight.然后,添加用于设置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.leftmargin.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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆