0

I am writing a text element (x axis measure value) for each circle but even after showing text element in inspect in browser its not showing

I have appended the text under circle given same x and y for the circle but its coming through

!DOCTYPE html>
<meta charset="utf-8">

<!-- Load d3.js -->
<script src="https://d3js.org/d3.v4.js"></script>

<!-- Create a div where the graph will take place -->
<div id="my_dataviz"></div>

<script>

// set the dimensions and margins of the graph
var margin = {top: 10, right: 30, bottom: 40, left: 100},
    width = 460 - margin.left - margin.right,
    height = 500 - margin.top - margin.bottom;

// append the svg object to the body of the page
var svg = d3.select("#my_dataviz")
  .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 + ")");

// Parse the Data
d3.csv("https://raw.githubusercontent.com/holtzy/data_to_viz/master/Example_dataset/7_OneCatOneNum_header.csv", function(data) {

// sort data
data.sort(function(b, a) {
  return a.Value - b.Value;
});

// Add X axis
var x = d3.scaleLinear()
  .domain([0, 13000])
  .range([ 0, width]);
svg.append("g")
  .attr("transform", "translate(0," + height + ")")
  .call(d3.axisBottom(x))
  .selectAll("text")
    .attr("transform", "translate(-10,0)rotate(-45)")
    .style("text-anchor", "end");

// Y axis
var y = d3.scaleBand()
  .range([ 0, height ])
  .domain(data.map(function(d) { return d.Country; }))
  .padding(1);
svg.append("g")
  .call(d3.axisLeft(y))

// Lines
svg.selectAll("myline")
  .data(data)
  .enter()
  .append("line")
    .attr("x1", x(0))
    .attr("x2", x(0))
    .attr("y1", function(d) { return y(d.Country); })
    .attr("y2", function(d) { return y(d.Country); })
    .attr("stroke", "grey")

// Circles -> start at X=0
svg.selectAll("mycircle")
  .data(data)
  .enter()
  .append("circle")
    .attr("cx", x(0) )
    .attr("cy", function(d) { return y(d.Country); })
    .attr("r", "7")
    .style("fill", "#69b3a2")
    .attr("stroke", "black")

// Change the X coordinates of line and circle
svg.selectAll("circle")
  .transition()
  .duration(2000)
  .attr("cx", function(d) { return x(d.Value); })

svg.selectAll("line")
  .transition()
  .duration(2000)
  .attr("x1", function(d) { return x(d.Value); })

// this is the line i have added at my end and it showing as well while i do the inspect element.
svg.selectAll("circle")
                .append(Text)
                .attr("x", function (d) { return x(d.Value); })
                .attr("y", function (d) { return y(d.Country); })
                .text(function (d) { return d.Value})
                .attr("font-family", "sans-serif")
                .attr("font-size", "6px")
                .attr("fill", "black")
                .style("text-anchor", "middle")

})

</script>

Would like to show measure value under circle so user dont have to guess the x axis. circle is at 13000 so it should show as 13 in circle divided by 1000

1 Answers1

0

From what I can see there's a couple of things going on.

Firstly, instead of:

...
.append(Text)

which is trying to pass in a variable called Text to the append function, it should be:

...
.append('text')

i.e. append an svg text element.

However, this is still appending text elements to circle elements. If you look at the elements via Chrome Devtools, you can see that there will be a text element inside each circle element, which doesn't actually display anything.

Instead, the label text needs to be rendered separately from the circles using something like.

svg.selectAll("mytext")
  .data(data)
  .enter()
  .append('text')
    .attr("x", function (d) { return x(d.Value) + 10; })
    .attr("y", function (d) { return y(d.Country) + 4; })
    .text(function (d) { return d.Value})
    .attr("font-family", "sans-serif")
    .attr("font-size", "10px")
    .attr("fill", "black")
    .style("text-anchor", "start")
    .style('opacity', 0)
    .transition()
    .delay(1500)
    .duration(500)
    .style('opacity', 1);

I've made the font a bit bigger, and adjusted the x and y values and used text-anchor: start so that now the text appears just off the right of the circles. I've also put in a transition based on opacity with a delay so that the text only appears at the end of the circles' animation.

lemming
  • 1,753
  • 14
  • 12