Home > Back-end >  Legend and label not rendering on svg
Legend and label not rendering on svg

Time:01-23

I am creating a visualisation using d3.js and svg images in PowerBi (this uses version 3 of d3).

I have got my visual working, however my legend is not rendering. I tested this in a browser, and the legend items appear in the elements of the page, but just aren't showing up.

enter image description here

My code for the legend items are

var pbi = {
  width:1108,
  height:636,
  colors:[
    "#A70240",
    "#4A2366",
    "#009A44",
    "#A0D081",
    "#01B5BB",
    "#137B88",
    "#5D6771",
    "#CDC8C1"
  ]

var margin = {top: 20, right: 30, bottom: 30, left: 140},
    width = pbi.width - margin.left - margin.right,
    height = pbi.height - margin.top - margin.bottom,
    legendleft = pbi.width - margin.right;

 var ly = d3.scale.ordinal() // For legend
      .rangeRoundBands([0, height], barPad, barOuterPad);


var svg = d3.select("#chart")
    .attr("width", width   margin.left   margin.right)
    .attr("height", height   margin.top   margin.bottom)
  .append("g")
    .attr("transform", "translate("   margin.left   ","   margin.top   ")");

----

ly.domain(rData.map(function(d) { return d.milestone; }));  // Legend

var milestoneMap = {};  // Maps years to colours
var legendArray = [];   // For legend

rData.forEach(function (d) {
  var entry = d.year;
  var rowEntry = {
    entry: entry,               // Axis label
    milestone: d.milestone,      // For colour lookup
    date: d.date,               // For X position of points
    y: y(entry)
  }

  if (!(d.milestone in milestoneMap)) {
    // First occurrence of each year saved to legend 
    legendArray.push({milestone: d.milestone});
    rowArray.push(rowEntry);

var legend = svg.append("g").attr("id", "legend")
    .attr("transform", "translate("   legendleft   ","   margin.top   ")").selectAll(null)
      .data(legendArray)
    .enter();
  
    // Legend agency labels
  legend.append("text")
      .attr("class", "milestoneLabel")
      .attr("x", 25)
      .attr("y", function(d) { return ly(d.milestone) 5; })
      .style("stroke",  "black")
      .style("stroke-width", .3)
      .text(function(d) { return d.milestone; });

  legend.append("circle")
      .attr("class", "legend")
      .attr("cx", 12)
      .attr("cy", function(d) { return ly(d.milestone); })
      .attr("r", 8)
      .style("stroke", "black")
      .style("stroke-width", 1)
      .style("fill", function(d, i) { return milestoneMap[d.milestone]; });

This is omitting code that calculates all other elements.

Why is it that the legend circle and label is appearing as an element on the page but isn't rendering anything?

Thanks

CodePudding user response:

Turns out, I just needed to add my legend left to my svg.

From

var svg = d3.select("#chart")
    .attr("width", width   margin.left   margin.right)
    .attr("height", height   margin.top   margin.bottom)
    .append("g")
    .attr("transform", "translate("   margin.left   ","   margin.top   ")");

to

var svg = d3.select("#chart")
    .attr("width", width   margin.left   margin.right   legendleft)
    .attr("height", height   margin.top   margin.bottom)
    .append("g")
    .attr("transform", "translate("   margin.left   ","   margin.top   ")");
  • Related