响应式D3条形图在调整大小时附加新的<text>

时间:2017-01-06 04:53:31

标签: javascript css d3.js svg

尝试创建响应式d3图表。 我创造了五个功能。

  1. 的init();
  2. updataScale();
  3. updateBar();
  4. updateLegends();
  5. 调整大小()
  6. 在updateBar()下, d3文本元素的问题在代码中引用(plotGroupText.selectAll(&#34; text.grpTxt&#34;))。

    每当我调整窗口大小时,我都会尝试使用图表中的文本值更新图表。 在线上更新文本时,它会创建更多的文本节点,而不是在同一个地方覆盖。 http://jsfiddle.net/mR16/8fc24g4y/2/

    &#13;
    &#13;
    (function() {
      console.clear();
    
      var chartContainer = d3.select("#chart");
    
    
      var layout = {
        w: 950,
        h: 906
      };
    
    
      var margin = {
        top: 50,
        left: 200,
        right: 50,
        bottom: 10
      }
    
      var data;
      var labels;
      var legendLabels;
    
      /////chart specific/////
      //height of chart//
      var maxPoint;
      var array;
      //svg element // 
    
      var svgElem;
    
      // group Elements
      var barGroup;
      var legendGroup;
      var plotGroupLine;
      var plotGroupOne;
      var plotGroupTwo;
      var plotGroupText;
      var plotGroupLabel;
      var legendIcon;
      var legendIconLabel;
      var scaleX;
      var scaleY;
    
    
    
      function init() {
        //get Data 
        data = getData();
        legendLabels = ["Aggregate Student Usage", "Aggregate ATI Recommended Usage"]
        labels = data.map(function(d) {
          return d[0];
        });
    
        //filter the data to determine the max of the array value 
        array = data.map(function(d, i) {
          return parseInt(i * 31 * 2)
        })
        maxpoint = d3.max(array) + 120;
    
    
        svgElem = chartContainer.append("svg")
        svgElem.attr("width", layout.w)
          .attr("height", layout.h)
          .attr("class", "svgElem")
    
    
    
        barGroup = svgElem.append("g")
          .attr("transform", "translate(" + margin.left + "," + margin.top + ")");
    
    
        plotGroupLine = barGroup.append("g");
        plotGroupOne = barGroup.append("g");
        plotGroupTwo = barGroup.append("g");
        plotGroupText = barGroup.append("g");
        plotGroupLabel = barGroup.append("g");
    
    
        legendGroup = svgElem.append("g")
          .attr("transform", "translate(" + margin.left * 1.5 + "," + margin.top / 2 + ")");
    
        legendIcon = legendGroup.append("g");
        legendIconLabel = legendGroup.append("g")
    
    
    
      }
    
    
    
    
    
    
    
    
    
    
      d3.select(window).on('resize', resize);
    
      function resize() {
        console.log("resize width");
        layout.w = parseInt(d3.select('#chart').style('width'), 10);
        console.log(layout.w)
    
        updataScale();
        updateBar();
      }
    
    
      function updataScale() {
        scaleX = d3.scale.linear().domain([0, 100])
          .range([0, layout.w - (margin.left + margin.right)])
    
        scaleY = d3.scale.ordinal()
          .domain(labels).rangeBands([0, layout.h - margin.top - margin.bottom], 0.5)
      }
    
      function updateBar() {
    
    
    
        var lines = plotGroupLine.selectAll("line")
          .data(scaleX.ticks(10));
    
        lines.enter()
          .append("line")
    
        lines.exit()
          .remove();
        lines.attr("x1", function(d, i) {
            return scaleX(d)
          })
          .attr("y1", function(d, i) {
            return scaleY.rangeBand() / 2 - 31
          })
          .attr("x2", function(d, i) {
            return scaleX(d)
          })
          .attr("y2", function(d, i) {
            return layout.h - scaleY.rangeBand() - margin.top + margin.bottom / 2
    
          })
          .attr("class", "lineStroke")
    
    
    
        //////////////////////////////////
        /////// Plot bar one ///////////
        //////////////////////////////////
    
    
        var barOne = plotGroupOne.selectAll("rect.grpOne")
          .data(data);
        barOne.enter()
          .append("rect");
    
        barOne.attr("x", 0)
          .attr("y", function(d, i) {
            return i * 31 * 2
          })
          .attr("width", function(d, i) {
            return scaleX(d[1])
          })
          .attr("height", function(d, i) {
            return 31
          })
          .attr("class", "grpOne")
    
        //////////////////////////////////
        /////// Plot bar two ///////////
        //////////////////////////////////
    
        var barTwo = plotGroupTwo.selectAll("rect.grpTwo")
          .data(data)
        barTwo.enter()
          .append("rect")
    
        barTwo
          .attr("x", 0)
          .attr("y", function(d, i) {
            return i * 31 * 2
          })
          .attr("width", function(d, i) {
            return scaleX(d[2])
          })
          .attr("height", function(d, i) {
            return 31
          })
          .attr("class", "grpTwo")
    
    
    
        //////////////////////////////////
        /////// Plot bar text ///////////
        //////////////////////////////////
    
    
        var barLineText = plotGroupText.selectAll("text.grpTxt")
          .data(scaleX.ticks(10))
        barLineText.enter()
          .append("text")
          .text(function(d) {
            return d + "%"
          })
    
        barLineText.exit()
          .remove();
    
        barLineText.attr("x", function(d, i) {
            return scaleX(d)
          })
          .attr("y", function(d, i) {
            return 32 / 2 - 31
          })
          .attr("dx", -5)
          .attr("dy", -5)
          .attr('font-size', "12")
          .attr("fill", "rgb(126,126,126)")
    
    
    
    
        //////////////////////////////////
        /////// Plot bar label ///////////
        //////////////////////////////////
    
        var sideLabel = plotGroupLabel.selectAll("text.grpLabel")
          .data(data)
        sideLabel
          .enter()
          .append("text")
        sideLabel
          .text(function(d) {
            return d[0];
          })
          .attr("x", 0)
          .attr("y", function(d, i) {
            return i * 2 * 31
          })
          .attr("text-anchor", "end")
          .attr('font-size', "12")
          .attr("fill", "rgb(126,126,126)")
          .attr("dx", -15)
          .attr("dy", 1)
          .call(wrapText, 160)
      }
    
    
    
    
    
      //////////////////////////////////
      ///////group the Plot area/////////
      //////////////////////////////////
    
    
    
    
    
      function wrapText(text, width) {
        text.each(function() {
          var textEl = d3.select(this),
            words = textEl.text().split(/\s+/).reverse(),
            word,
            line = [],
            linenumber = 0,
            lineHeight = 1.1, // ems
            y = textEl.attr('y'),
            dx = parseFloat(textEl.attr('dx') || 0),
            dy = parseFloat(textEl.attr('dy') || 0),
            tspan = textEl.text(null).append('tspan').attr('x', 0).attr('y', y).attr('dy', dy + 'em');
    
          while (word = words.pop()) {
            line.push(word);
            tspan.text(line.join(' '));
            if (tspan.node().getComputedTextLength() > width) {
              line.pop();
              tspan.text(line.join(' '));
              line = [word];
              tspan = textEl.append('tspan').attr('x', 0).attr('y', y).attr('dx', dx).attr('dy', ++linenumber * lineHeight + dy + 'em').text(word);
            }
          }
        });
      }
    
    
    
    
    
      //////////////////////////////////
      /////// legend Icons  ///////////
      //////////////////////////////////
    
      var legendColors = ["rgb(91, 155, 213)", "rgb(164, 208, 233)"]
    
    
      function updateLegends() {
        legendIcon.selectAll("rect.legendIcon")
          .data(legendLabels)
          .enter()
          .append("rect")
          .attr("x", function(d, i) {
            return (i) * 200
          })
          .attr("y", 0)
          .attr("width", 10)
          .attr("height", 10)
          .attr("fill", function(d, i) {
            return legendColors[i]
          })
    
    
        //////////////////////////////////
        /////// legend labels ///////////
        //////////////////////////////////
    
    
        legendIconLabel.selectAll("text.legendLabel")
          .data(legendLabels)
          .enter()
          .append("text")
          .text(String)
          .attr("x", function(d, i) {
            return (i) * 200
          })
          .attr("y", 10)
          .attr('font-size', "10")
          .attr("dx", 15)
          .attr("dy", 1)
          .on("click", function(d, i) {
    
            var elem = d3.select(this);
            var flagOne = false;
            var flagTwo = false;
    
            if (i == 0) {
              if (flagTwo == false) {
                if (elem.attr("text-decoration") == "none") {
                  elem.attr("text-decoration", "line-through")
                  svgElem.selectAll("rect.grpTwo").style("fill", "none");
                  flagOne = true;
                } else {
                  elem.attr("text-decoration", "none")
                  svgElem.selectAll("rect.grpTwo").style("fill", " rgb(91, 155, 213)")
                  flagOne = false;
                }
              }
    
            }
            if (i == 1) {
              if (flagOne == false) {
                if (elem.attr("text-decoration") == "none") {
                  elem.attr("text-decoration", "line-through")
                  svgElem.selectAll("rect.grpOne").style("fill", "none");
                  flagTwo = true;
                } else {
                  elem.attr("text-decoration", "none")
                  svgElem.selectAll("rect.grpOne").style("fill", " rgb(164, 208, 233)")
                  flagTwo = false;
                }
              }
    
            }
    
          })
    
    
      }
    
    
      init();
      updataScale();
      updateBar();
      updateLegends();
    
      function getData() {
        return [
          [
            "Adult Medical Surgical-(160minutes / 180minutes)",
            100,
            84
          ],
          [
            "Fundamentals-(1minutes / 60minutes)",
            100,
            2
          ],
          [
            "Getting Started with ATI-(1minutes / 28minutes)",
            100,
            4
          ],
          [
            "Leadership and Management-(124minutes / 120minutes)",
            100,
            100
          ],
          [
            "NCLEX-(628minutes / 600minutes)",
            100,
            100
          ],
          [
            "Pharm & Dosage Calculation-(242minutes / 120minutes)",
            100,
            100
          ],
          [
            "1Adult Medical Surgical-(160minutes / 180minutes)",
            100,
            84
          ],
          [
            "1Fundamentals-(1minutes / 60minutes)",
            100,
            2
          ],
          [
            "1Getting Started with ATI-(1minutes / 28minutes)",
            100,
            4
          ],
          [
            "1Leadership and Management-(124minutes / 120minutes)",
            100,
            100
          ],
          [
            "1NCLEX-(628minutes / 600minutes)",
            100,
            100
          ],
          [
            "1Pharm & Dosage Calculation-(242minutes / 120minutes)",
            100,
            100
          ]
        ]
    
    
      }
    
    
    
    
    
    
    
    
    
    
    })()
    &#13;
    <script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.7/d3.min.js"></script>
    &#13;
    &#13;
    &#13;

    &#13;
    &#13;
    (function() {
        console.clear();
    
        var chartContainer = d3.select("#chart");
    
    
        var layout = {
            w: 950,
            h: 906
        };
    
    
        var margin = {
            top: 50,
            left: 200,
            right: 50,
            bottom: 10
        }
    
        var data;
        var labels;
        var legendLabels;
    
        /////chart specific/////
        //height of chart//
        var maxPoint;
        var array;
        //svg element // 
    
        var svgElem;
    
        // group Elements
        var barGroup;
        var legendGroup;
        var plotGroupLine;
        var plotGroupOne;
        var plotGroupTwo;
        var plotGroupText;
        var plotGroupLabel;
        var legendIcon;
        var legendIconLabel;
        var scaleX;
        var scaleY;
    
    
    
        function init() {
            //get Data 
            data = getData();
            legendLabels = ["Aggregate Student Usage", "Aggregate ATI Recommended Usage"]
            labels = data.map(function(d) {
                return d[0];
            });
    
            //filter the data to determine the max of the array value 
            array = data.map(function(d, i) {
                return parseInt(i * 31 * 2)
            })
            maxpoint = d3.max(array) + 120;
    
    
            svgElem = chartContainer.append("svg")
            svgElem.attr("width", layout.w)
                .attr("height", layout.h)
                .attr("class", "svgElem")
    
    
    
            barGroup = svgElem.append("g")
                .attr("transform", "translate(" + margin.left + "," + margin.top + ")");
    
    
            plotGroupLine = barGroup.append("g");
            plotGroupOne = barGroup.append("g");
            plotGroupTwo = barGroup.append("g");
            plotGroupText = barGroup.append("g");
            plotGroupLabel = barGroup.append("g");
    
    
            legendGroup = svgElem.append("g")
                .attr("transform", "translate(" + margin.left * 1.5 + "," + margin.top / 2 + ")");
    
            legendIcon = legendGroup.append("g");
            legendIconLabel = legendGroup.append("g")
    
    
    
        }
    
    
    
    
        d3.select(window).on('resize', resize);
    
        function resize() {
            console.log("resize width");
            layout.w = parseInt(d3.select('#chart').style('width'), 10);
            console.log(layout.w)
    
            updataScale();
            updateBar();
        }
    
    
        function updataScale() {
            scaleX = d3.scale.linear().domain([0, 100])
                .range([0, layout.w - (margin.left + margin.right)])
    
            scaleY = d3.scale.ordinal()
                .domain(labels).rangeBands([0, layout.h - margin.top - margin.bottom], 0.5)
        }
    
        function updateBar() {
    
    
    
            var lines = plotGroupLine.selectAll("line")
                .data(scaleX.ticks(10));
    
            lines.enter()
                .append("line")
    
            lines.exit()
                .remove();
            lines.attr("x1", function(d, i) {
                    return scaleX(d)
                })
                .attr("y1", function(d, i) {
                    return scaleY.rangeBand() / 2 - 31
                })
                .attr("x2", function(d, i) {
                    return scaleX(d)
                })
                .attr("y2", function(d, i) {
                    return layout.h - scaleY.rangeBand() - margin.top + margin.bottom / 2
    
                })
                .attr("class", "lineStroke")
    
    
    
            //////////////////////////////////
            /////// Plot bar one ///////////
            //////////////////////////////////
    
    
            var barOne = plotGroupOne.selectAll("rect.grpOne")
                .data(data);
            barOne.enter()
                .append("rect");
    
            barOne.attr("x", 0)
                .attr("y", function(d, i) {
                    return i * 31 * 2
                })
                .attr("width", function(d, i) {
                    return scaleX(d[1])
                })
                .attr("height", function(d, i) {
                    return 31
                })
                .attr("class", "grpOne")
    
            //////////////////////////////////
            /////// Plot bar two ///////////
            //////////////////////////////////
    
            var barTwo = plotGroupTwo.selectAll("rect.grpTwo")
                .data(data)
            barTwo.enter()
                .append("rect")
    
            barTwo
                .attr("x", 0)
                .attr("y", function(d, i) {
                    return i * 31 * 2
                })
                .attr("width", function(d, i) {
                    return scaleX(d[2])
                })
                .attr("height", function(d, i) {
                    return 31
                })
                .attr("class", "grpTwo")
    
    
    
            //////////////////////////////////
            /////// Plot bar text ///////////
            //////////////////////////////////
    
    
            var barLineText = plotGroupText.selectAll("text.grpTxt")
                .data(scaleX.ticks(10))
            barLineText.enter()
                .append("text")
                .text(function(d) {
                    return d + "%"
                })
    
            barLineText.exit()
                .remove();
    
            barLineText.attr("x", function(d, i) {
                    return scaleX(d)
                })
                .attr("y", function(d, i) {
                    return 32 / 2 - 31
                })
                .attr("dx", -5)
                .attr("dy", -5)
                .attr('font-size', "12")
                .attr("fill", "rgb(126,126,126)")
    
    
    
    
            //////////////////////////////////
            /////// Plot bar label ///////////
            //////////////////////////////////
    
            var sideLabel = plotGroupLabel.selectAll("text.grpLabel")
                .data(data)
            sideLabel
                .enter()
                .append("text")
            sideLabel
                .text(function(d) {
                    return d[0];
                })
                .attr("x", 0)
                .attr("y", function(d, i) {
                    return i * 2 * 31
                })
                .attr("text-anchor", "end")
                .attr('font-size', "12")
                .attr("fill", "rgb(126,126,126)")
                .attr("dx", -15)
                .attr("dy", 1)
                .call(wrapText, 160)
        }
    
    
    
    
        //////////////////////////////////
        ///////group the Plot area/////////
        //////////////////////////////////
    
    
    
    
        function wrapText(text, width) {
            text.each(function() {
                var textEl = d3.select(this),
                    words = textEl.text().split(/\s+/).reverse(),
                    word,
                    line = [],
                    linenumber = 0,
                    lineHeight = 1.1, // ems
                    y = textEl.attr('y'),
                    dx = parseFloat(textEl.attr('dx') || 0),
                    dy = parseFloat(textEl.attr('dy') || 0),
                    tspan = textEl.text(null).append('tspan').attr('x', 0).attr('y', y).attr('dy', dy + 'em');
    
                while (word = words.pop()) {
                    line.push(word);
                    tspan.text(line.join(' '));
                    if (tspan.node().getComputedTextLength() > width) {
                        line.pop();
                        tspan.text(line.join(' '));
                        line = [word];
                        tspan = textEl.append('tspan').attr('x', 0).attr('y', y).attr('dx', dx).attr('dy', ++linenumber * lineHeight + dy + 'em').text(word);
                    }
                }
            });
        }
    
    
    
    
        //////////////////////////////////
        /////// legend Icons  ///////////
        //////////////////////////////////
    
        var legendColors = ["rgb(91, 155, 213)", "rgb(164, 208, 233)"]
    
    
        function updateLegends() {
            legendIcon.selectAll("rect.legendIcon")
                .data(legendLabels)
                .enter()
                .append("rect")
                .attr("x", function(d, i) {
                    return (i) * 200
                })
                .attr("y", 0)
                .attr("width", 10)
                .attr("height", 10)
                .attr("fill", function(d, i) {
                    return legendColors[i]
                })
    
    
            //////////////////////////////////
            /////// legend labels ///////////
            //////////////////////////////////
    
    
            legendIconLabel.selectAll("text.legendLabel")
                .data(legendLabels)
                .enter()
                .append("text")
                .text(String)
                .attr("x", function(d, i) {
                    return (i) * 200
                })
                .attr("y", 10)
                .attr('font-size', "10")
                .attr("dx", 15)
                .attr("dy", 1)
                .on("click", function(d, i) {
    
                    var elem = d3.select(this);
                    var flagOne = false;
                    var flagTwo = false;
    
                    if (i == 0) {
                        if (flagTwo == false) {
                            if (elem.attr("text-decoration") == "none") {
                                elem.attr("text-decoration", "line-through")
                                svgElem.selectAll("rect.grpTwo").style("fill", "none");
                                flagOne = true;
                            } else {
                                elem.attr("text-decoration", "none")
                                svgElem.selectAll("rect.grpTwo").style("fill", " rgb(91, 155, 213)")
                                flagOne = false;
                            }
                        }
    
                    }
                    if (i == 1) {
                        if (flagOne == false) {
                            if (elem.attr("text-decoration") == "none") {
                                elem.attr("text-decoration", "line-through")
                                svgElem.selectAll("rect.grpOne").style("fill", "none");
                                flagTwo = true;
                            } else {
                                elem.attr("text-decoration", "none")
                                svgElem.selectAll("rect.grpOne").style("fill", " rgb(164, 208, 233)")
                                flagTwo = false;
                            }
                        }
    
                    }
    
                })
    
    
        }
    
    
        init();
        updataScale();
        updateBar();
        updateLegends();
    
        function getData() {
            return [
                [
                    "Adult Medical Surgical-(160minutes / 180minutes)",
                    100,
                    84
                ],
                [
                    "Fundamentals-(1minutes / 60minutes)",
                    100,
                    2
                ],
                [
                    "Getting Started with ATI-(1minutes / 28minutes)",
                    100,
                    4
                ],
                [
                    "Leadership and Management-(124minutes / 120minutes)",
                    100,
                    100
                ],
                [
                    "NCLEX-(628minutes / 600minutes)",
                    100,
                    100
                ],
                [
                    "Pharm & Dosage Calculation-(242minutes / 120minutes)",
                    100,
                    100
                ],
                [
                    "1Adult Medical Surgical-(160minutes / 180minutes)",
                    100,
                    84
                ],
                [
                    "1Fundamentals-(1minutes / 60minutes)",
                    100,
                    2
                ],
                [
                    "1Getting Started with ATI-(1minutes / 28minutes)",
                    100,
                    4
                ],
                [
                    "1Leadership and Management-(124minutes / 120minutes)",
                    100,
                    100
                ],
                [
                    "1NCLEX-(628minutes / 600minutes)",
                    100,
                    100
                ],
                [
                    "1Pharm & Dosage Calculation-(242minutes / 120minutes)",
                    100,
                    100
                ]
            ]
    
    
        }
    
    
    
    
    })()
    &#13;
    .svgElem{
      border: 1px solid 
    }
    
    .grpOne{
     fill: rgb(164, 208, 233);
    }
    
    .grpTwo{
    fill: rgb(91, 155, 213)
    }
    
    .lineStroke{
      stroke:#ccc
    }
    &#13;
    <script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.7/d3.min.js"></script>
    <div id="chart">
    </div>
    &#13;
    &#13;
    &#13;

    我在图片中表示

    问题 enter image description here 我多么想要 enter image description here

1 个答案:

答案 0 :(得分:0)

由于您按班级选择:

 var barLineText = plotGroupText.selectAll("text.grpTxt")

您必须为文本元素设置相同的类:

.attr("class", "grpTxt")

否则,您将有非空的输入选择。对.grpLabel执行相同的操作。

这是您更新的小提琴:http://jsfiddle.net/68Lp0L4x/

或查看代码段:

&#13;
&#13;
(function() {
  console.clear();

  var chartContainer = d3.select("#chart");


  var layout = {
    w: 950,
    h: 906
  };


  var margin = {
    top: 50,
    left: 200,
    right: 50,
    bottom: 10
  }

  var data;
  var labels;
  var legendLabels;

  /////chart specific/////
  //height of chart//
  var maxPoint;
  var array;
  //svg element // 

  var svgElem;

  // group Elements
  var barGroup;
  var legendGroup;
  var plotGroupLine;
  var plotGroupOne;
  var plotGroupTwo;
  var plotGroupText;
  var plotGroupLabel;
  var legendIcon;
  var legendIconLabel;
  var scaleX;
  var scaleY;



  function init() {
    //get Data 
    data = getData();
    legendLabels = ["Aggregate Student Usage", "Aggregate ATI Recommended Usage"]
    labels = data.map(function(d) {
      return d[0];
    });

    //filter the data to determine the max of the array value 
    array = data.map(function(d, i) {
      return parseInt(i * 31 * 2)
    })
    maxpoint = d3.max(array) + 120;


    svgElem = chartContainer.append("svg")
    svgElem.attr("width", layout.w)
      .attr("height", layout.h)
      .attr("class", "svgElem")



    barGroup = svgElem.append("g")
      .attr("transform", "translate(" + margin.left + "," + margin.top + ")");


    plotGroupLine = barGroup.append("g");
    plotGroupOne = barGroup.append("g");
    plotGroupTwo = barGroup.append("g");
    plotGroupText = barGroup.append("g");
    plotGroupLabel = barGroup.append("g");


    legendGroup = svgElem.append("g")
      .attr("transform", "translate(" + margin.left * 1.5 + "," + margin.top / 2 + ")");

    legendIcon = legendGroup.append("g");
    legendIconLabel = legendGroup.append("g")



  }










  d3.select(window).on('resize', resize);

  function resize() {
    console.log("resize width");
    layout.w = parseInt(d3.select('#chart').style('width'), 10);
    console.log(layout.w)

    updataScale();
    updateBar();
  }


  function updataScale() {
    scaleX = d3.scale.linear().domain([0, 100])
      .range([0, layout.w - (margin.left + margin.right)])

    scaleY = d3.scale.ordinal()
      .domain(labels).rangeBands([0, layout.h - margin.top - margin.bottom], 0.5)
  }

  function updateBar() {



    var lines = plotGroupLine.selectAll("line")
      .data(scaleX.ticks(10));

    lines.enter()
      .append("line")

    lines.exit()
      .remove();
    lines.attr("x1", function(d, i) {
        return scaleX(d)
      })
      .attr("y1", function(d, i) {
        return scaleY.rangeBand() / 2 - 31
      })
      .attr("x2", function(d, i) {
        return scaleX(d)
      })
      .attr("y2", function(d, i) {
        return layout.h - scaleY.rangeBand() - margin.top + margin.bottom / 2

      })
      .attr("class", "lineStroke")



    //////////////////////////////////
    /////// Plot bar one ///////////
    //////////////////////////////////


    var barOne = plotGroupOne.selectAll("rect.grpOne")
      .data(data);
    barOne.enter()
      .append("rect");

    barOne.attr("x", 0)
      .attr("y", function(d, i) {
        return i * 31 * 2
      })
      .attr("width", function(d, i) {
        return scaleX(d[1])
      })
      .attr("height", function(d, i) {
        return 31
      })
      .attr("class", "grpOne")

    //////////////////////////////////
    /////// Plot bar two ///////////
    //////////////////////////////////

    var barTwo = plotGroupTwo.selectAll("rect.grpTwo")
      .data(data)
    barTwo.enter()
      .append("rect")

    barTwo
      .attr("x", 0)
      .attr("y", function(d, i) {
        return i * 31 * 2
      })
      .attr("width", function(d, i) {
        return scaleX(d[2])
      })
      .attr("height", function(d, i) {
        return 31
      })
      .attr("class", "grpTwo")



    //////////////////////////////////
    /////// Plot bar text ///////////
    //////////////////////////////////


    var barLineText = plotGroupText.selectAll("text.grpTxt")
      .data(scaleX.ticks(10))
    barLineText.enter()
      .append("text")
      .attr("class", "grpTxt")
      .text(function(d) {
        return d + "%"
      })

    barLineText.exit()
      .remove();

    barLineText.attr("x", function(d, i) {
        return scaleX(d)
      })
      .attr("y", function(d, i) {
        return 32 / 2 - 31
      })
      .attr("dx", -5)
      .attr("dy", -5)
      .attr('font-size', "12")
      .attr("fill", "rgb(126,126,126)")




    //////////////////////////////////
    /////// Plot bar label ///////////
    //////////////////////////////////

    var sideLabel = plotGroupLabel.selectAll("text.grpLabel")
      .data(data)
    sideLabel
      .enter()
      .append("text")
    sideLabel
      .text(function(d) {
        return d[0];
      })
      .attr("class", "grpLabel")
      .attr("x", 0)
      .attr("y", function(d, i) {
        return i * 2 * 31
      })
      .attr("text-anchor", "end")
      .attr('font-size', "12")
      .attr("fill", "rgb(126,126,126)")
      .attr("dx", -15)
      .attr("dy", 1)
      .call(wrapText, 160)
  }





  //////////////////////////////////
  ///////group the Plot area/////////
  //////////////////////////////////





  function wrapText(text, width) {
    text.each(function() {
      var textEl = d3.select(this),
        words = textEl.text().split(/\s+/).reverse(),
        word,
        line = [],
        linenumber = 0,
        lineHeight = 1.1, // ems
        y = textEl.attr('y'),
        dx = parseFloat(textEl.attr('dx') || 0),
        dy = parseFloat(textEl.attr('dy') || 0),
        tspan = textEl.text(null).append('tspan').attr('x', 0).attr('y', y).attr('dy', dy + 'em');

      while (word = words.pop()) {
        line.push(word);
        tspan.text(line.join(' '));
        if (tspan.node().getComputedTextLength() > width) {
          line.pop();
          tspan.text(line.join(' '));
          line = [word];
          tspan = textEl.append('tspan').attr('x', 0).attr('y', y).attr('dx', dx).attr('dy', ++linenumber * lineHeight + dy + 'em').text(word);
        }
      }
    });
  }





  //////////////////////////////////
  /////// legend Icons  ///////////
  //////////////////////////////////

  var legendColors = ["rgb(91, 155, 213)", "rgb(164, 208, 233)"]


  function updateLegends() {
    legendIcon.selectAll("rect.legendIcon")
      .data(legendLabels)
      .enter()
      .append("rect")
      .attr("x", function(d, i) {
        return (i) * 200
      })
      .attr("y", 0)
      .attr("width", 10)
      .attr("height", 10)
      .attr("fill", function(d, i) {
        return legendColors[i]
      })


    //////////////////////////////////
    /////// legend labels ///////////
    //////////////////////////////////


    legendIconLabel.selectAll("text.legendLabel")
      .data(legendLabels)
      .enter()
      .append("text")
      .text(String)
      .attr("x", function(d, i) {
        return (i) * 200
      })
      .attr("y", 10)
      .attr('font-size', "10")
      .attr("dx", 15)
      .attr("dy", 1)
      .on("click", function(d, i) {

        var elem = d3.select(this);
        var flagOne = false;
        var flagTwo = false;

        if (i == 0) {
          if (flagTwo == false) {
            if (elem.attr("text-decoration") == "none") {
              elem.attr("text-decoration", "line-through")
              svgElem.selectAll("rect.grpTwo").style("fill", "none");
              flagOne = true;
            } else {
              elem.attr("text-decoration", "none")
              svgElem.selectAll("rect.grpTwo").style("fill", " rgb(91, 155, 213)")
              flagOne = false;
            }
          }

        }
        if (i == 1) {
          if (flagOne == false) {
            if (elem.attr("text-decoration") == "none") {
              elem.attr("text-decoration", "line-through")
              svgElem.selectAll("rect.grpOne").style("fill", "none");
              flagTwo = true;
            } else {
              elem.attr("text-decoration", "none")
              svgElem.selectAll("rect.grpOne").style("fill", " rgb(164, 208, 233)")
              flagTwo = false;
            }
          }

        }

      })


  }


  init();
  updataScale();
  updateBar();
  updateLegends();

  function getData() {
    return [
      [
        "Adult Medical Surgical-(160minutes / 180minutes)",
        100,
        84
      ],
      [
        "Fundamentals-(1minutes / 60minutes)",
        100,
        2
      ],
      [
        "Getting Started with ATI-(1minutes / 28minutes)",
        100,
        4
      ],
      [
        "Leadership and Management-(124minutes / 120minutes)",
        100,
        100
      ],
      [
        "NCLEX-(628minutes / 600minutes)",
        100,
        100
      ],
      [
        "Pharm & Dosage Calculation-(242minutes / 120minutes)",
        100,
        100
      ],
      [
        "1Adult Medical Surgical-(160minutes / 180minutes)",
        100,
        84
      ],
      [
        "1Fundamentals-(1minutes / 60minutes)",
        100,
        2
      ],
      [
        "1Getting Started with ATI-(1minutes / 28minutes)",
        100,
        4
      ],
      [
        "1Leadership and Management-(124minutes / 120minutes)",
        100,
        100
      ],
      [
        "1NCLEX-(628minutes / 600minutes)",
        100,
        100
      ],
      [
        "1Pharm & Dosage Calculation-(242minutes / 120minutes)",
        100,
        100
      ]
    ]


  }










})()
&#13;
.svgElem {
  border: 1px solid
}

.grpOne {
  fill: rgb(164, 208, 233);
}

.grpTwo {
  fill: rgb(91, 155, 213)
}

.lineStroke {
  stroke: #ccc
}
&#13;
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>
<div id="chart">
</div>
&#13;
&#13;
&#13;