通过D3添加的DOM元素未显示

时间:2018-10-10 12:35:45

标签: javascript d3.js dom charts

我正在尝试向图表(createLegend())中添加一些文本。

http://jsfiddle.net/gs6rehnx/2045/

<button type="button" onclick="createPie()">Click Me First!</button>
<button type="button" onclick="updatePie()">Update Diagram!</button>
<div class='foo'></div>


const width = 260;
const height = 260;
const thickness = 40;
const duration = 750;

const radius = Math.min(width, height) / 2;
const color = d3.scaleOrdinal(d3.schemeCategory10);

const arc = d3
  .arc()
  .innerRadius(radius - thickness)
  .outerRadius(radius);

const pie = d3
  .pie()
  .value(function(d) {
    return d.value;
  })
  .sort(null);


const create = function(data) {
  const svg = d3
    .select('.foo')
    .append('svg')
    .attr('class', 'pie')
    .attr('width', width)
    .attr('height', height)
    .attr('id', 'svgClass');

  svg
    .append('g')
    .attr('transform', 'translate(' + width / 2 + ',' + height / 2 + ')')
    .attr('id', 'bar');
    createLegend();
  draw(data);
}

const draw = function(data) {
  const path = d3.select('#bar')
    .selectAll('path')
    .data(pie(data))

  path
    .enter()
    .append('g')
    .append('path')
    .attr('d', arc)
    .attr('fill', (d, i) => color(i));

  path
    .transition()
    .duration(duration)
    .attrTween('d', function(d) {
      const interpolate = d3.interpolate({
        startAngle: 0,
        endAngle: 0
      }, d);
      return function(t) {
        return arc(interpolate(t));
      };
    });
};

const createLegend = function() {
    d3.select('#svgClass')
  .append('text')
  .text('foo bar')
  .attr('position', 'relative')
  .attr('background-color', 'red')
  .attr('top', '50px')
  .attr('left', '50px')
}


const data = [{
    name: 'USA',
    value: 50
  },
  {
    name: 'UK',
    value: 5
  },
  {
    name: 'Canada',
    value: 5
  },
  {
    name: 'Maxico',
    value: 40
  }
]

function createPie() {
  create(data)
}

const newData = [{
    name: 'USA',
    value: 40
  },
  {
    name: 'UK',
    value: 20
  },
  {
    name: 'Canada',
    value: 30
  },
  {
    name: 'Maxico',
    value: 10
  }
];

function updatePie() {
  draw(newData)
}

当我查看图表时,它显示在DOM tree中。但是,它没有显示在网站上。为什么会这样?

2 个答案:

答案 0 :(得分:1)

请务必阅读SVG text docs,以了解如何将定位应用于text

您没有看到文字的原因是它完全超出了范围。 CSS定位不是定位文本的方法。使用属性xy或使用transformSVG transform)。

这是更改后的createLegend代码:

d3.select('#svgClass')
  .append('text')
  .text('foo bar')
  .attr('x', width/2).attr('y', height/2).style('fill', 'red');

现在,我看到您正在尝试向文本中添加background-color,对于 SVG ,可以使用文本后面的rect完成。这是一个示例:d3 way of adding a background to texts

代码段:

const width = 260;
const height = 260;
const thickness = 40;
const duration = 750;

const radius = Math.min(width, height) / 2;
const color = d3.scaleOrdinal(d3.schemeCategory10);

const arc = d3
  .arc()
  .innerRadius(radius - thickness)
  .outerRadius(radius);

const pie = d3
  .pie()
  .value(function(d) {
    return d.value;
  })
  .sort(null);


const create = function(data) {
  const svg = d3
    .select('.foo')
    .append('svg')
    .attr('class', 'pie')
    .attr('width', width)
    .attr('height', height)
    .attr('id', 'svgClass');

  svg
    .append('g')
    .attr('transform', 'translate(' + width / 2 + ',' + height / 2 + ')')
    .attr('id', 'bar');
	createLegend();
  draw(data);
}

const draw = function(data) {
  const path = d3.select('#bar')
    .selectAll('path')
    .data(pie(data))

  path
    .enter()
    .append('g')
    .append('path')
    .attr('d', arc)
    .attr('fill', (d, i) => color(i));

  path
    .transition()
    .duration(duration)
    .attrTween('d', function(d) {
      const interpolate = d3.interpolate({
        startAngle: 0,
        endAngle: 0
      }, d);
      return function(t) {
        return arc(interpolate(t));
      };
    });
};

const createLegend = function() {
	d3.select('#svgClass')
  .append('text')
  .text('foo bar').attr('x', width/2).attr('y', height/2).style('fill', 'red');
}


const data = [{
    name: 'USA',
    value: 50
  },
  {
    name: 'UK',
    value: 5
  },
  {
    name: 'Canada',
    value: 5
  },
  {
    name: 'Maxico',
    value: 40
  }
]

function createPie() {
  create(data)
}

const newData = [{
    name: 'USA',
    value: 40
  },
  {
    name: 'UK',
    value: 20
  },
  {
    name: 'Canada',
    value: 30
  },
  {
    name: 'Maxico',
    value: 10
  }
];

function updatePie() {
  draw(newData)
}
<script src="https://d3js.org/d3.v4.min.js"></script>

<button type="button" onclick="createPie()">Click Me First!</button>
<button type="button" onclick="updatePie()">Update Diagram!</button>
<div class='foo'></div>

希望这会有所帮助。

答案 1 :(得分:0)

这全都归结为HTML和SVG之间的差异。不幸的是,您需要使用一些不同的属性。

首先lefttop不正确,您想分别使用xy

第二,background-color不起作用,而是尝试对文本应用strokefill