Stéphane Laurent
Stéphane Laurent

Reputation: 84529

Title for keys in nvd3 multiBarChart

Is it possible to have a legend for the "key" variable in a nvd3 multibarchart?

The keys appear at the top right corner, "In progress" and "Complete" in the example below.

I mean I'd like to add a title, say "Status", to these two items. Something like:

Status
o Complete   o In progress

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8" />
    <link
      href="https://cdnjs.cloudflare.com/ajax/libs/nvd3/1.8.6/nv.d3.min.css"
      rel="stylesheet"
      type="text/css"
    />
    <script
      src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.17/d3.min.js"
      charset="utf-8"
    ></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/nvd3/1.8.6/nv.d3.min.js"></script>

    <style>
      text {
        font: 12px sans-serif;
      }
      svg {
        display: block;
      }
      html, body, #chart1, svg {
        margin: 0px;
        padding: 0px;
        height: 100%;
        width: 100%;
      }
    </style>
  </head>
  <body>
    <div id="chart1">
      <svg></svg>
    </div>

    <script>
      var selector = "#chart1 svg";
      var XaxisLabel = "Project";
      var YaxisLabel = "Count";
      var Data = [
        {
          key: "Complete",
          values: [
            {
              label: "Pr1",
              value: 2
            },
            {
              label: "Pr2",
              value: 2
            },
            {
              label: "Pr3",
              value: 2
            }
          ],
          color: "blue"
        },
        {
          key: "In progress",
          values: [
            {
              label: "Pr1",
              value: 2
            },
            {
              label: "Pr2",
              value: 1
            },
            {
              label: "Pr3",
              value: 1
            }
          ],
          color: "red"
        }
      ];

      nv.addGraph(function () {
        var chart = nv.models
          .multiBarChart()
          .x(function (d) {
            return d.label;
          })
          .y(function (d) {
            return d.value;
          })
          .duration(1300)
          .margin({ bottom: 100, left: 70 })
          .rotateLabels(0)
          .groupSpacing(0.1);

        chart.reduceXTicks(false).staggerLabels(false);

        chart.xAxis
          .axisLabel(XaxisLabel)
          .axisLabelDistance(35);

        chart.yAxis
          .axisLabel(YaxisLabel)
          .axisLabelDistance(-5)
          .showMaxMin(false);

        d3.select(selector).datum(Data).call(chart);

        nv.utils.windowResize(chart.update);

        return chart;
      });
    </script>
  </body>
</html>

Upvotes: 2

Views: 58

Answers (1)

Robson
Robson

Reputation: 2032

Within the addGraph function we could append text to the left of the legend:

d3.select('.nv-legend g')
          .append("g")
          .attr("transform", "translate(-40,5)")
          .append("text")
          .attr("dy", ".32em")
          .attr("dx", 8)
          .attr("class", "nv-legend-text")
          .attr("text-anchor", "end")
          .text("Status:"); 

Within the original code that would be:

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8" />
    <link
      href="https://cdnjs.cloudflare.com/ajax/libs/nvd3/1.8.6/nv.d3.min.css"
      rel="stylesheet"
      type="text/css"
    />
    <script
      src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.17/d3.min.js"
      charset="utf-8"
    ></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/nvd3/1.8.6/nv.d3.min.js"></script>

    <style>
      text {
        font: 12px sans-serif;
      }
      svg {
        display: block;
      }
      html, body, #chart1, svg {
        margin: 0px;
        padding: 0px;
        height: 100%;
        width: 100%;
      }
    </style>
  </head>
  <body>
    <div id="chart1">
      <svg></svg>
    </div>

    <script>
      var selector = "#chart1 svg";
      var XaxisLabel = "Project";
      var YaxisLabel = "Count";
      var Data = [
        {
          key: "Complete",
          values: [
            {
              label: "Pr1",
              value: 2
            },
            {
              label: "Pr2",
              value: 2
            },
            {
              label: "Pr3",
              value: 2
            }
          ],
          color: "blue"
        },
        {
          key: "In progress",
          values: [
            {
              label: "Pr1",
              value: 2
            },
            {
              label: "Pr2",
              value: 1
            },
            {
              label: "Pr3",
              value: 1
            }
          ],
          color: "red"
        }
      ];

      nv.addGraph(function () {
        var chart = nv.models
          .multiBarChart()
          .x(function (d) {
            return d.label;
          })
          .y(function (d) {
            return d.value;
          })
          .duration(1300)
          .margin({ bottom: 100, left: 70 })
          .rotateLabels(0)
          .groupSpacing(0.1);

        chart.reduceXTicks(false).staggerLabels(false);

        chart.xAxis
          .axisLabel(XaxisLabel)
          .axisLabelDistance(35);

        chart.yAxis
          .axisLabel(YaxisLabel)
          .axisLabelDistance(-5)
          .showMaxMin(false);

        d3.select(selector).datum(Data).call(chart);

        nv.utils.windowResize(chart.update);
        
        d3.select('.nv-legend g')
          .append("g")
          .attr("transform", "translate(-40,5)")
          .append("text")
          .attr("dy", ".32em")
          .attr("dx", 8)
          .attr("class", "nv-legend-text")
          .attr("text-anchor", "end")
          .text("Status:"); 

        return chart;
      });

    </script>
  </body>
</html>

That works correctly when resizing the browser.

You can change the -40 to make it nearer/further from the legend.

Upvotes: 4

Related Questions