d3js在多行上写标签

时间:2017-08-30 06:51:33

标签: javascript d3.js charts

我正在研究图形,我在图表上遇到了一些困难。我想画一个饼图(或甜甜圈),并以两行或更多行显示标签,以便为图形获得更多空间。

这是我的代码

var dataGroupPotential = [];
var pieGroup;
var svg;

processData("pieGPChart");

function processData(chartDivId) {
  $("#pieGPLegend").text("Title : myTitle");

  //Construction du tableau data

  dataGroupPotential.push({
    label: "long text 1 : 100 000 000",
    value: 100000000
  });
  dataGroupPotential.push({
    label: "long text 2 : 200 000 000",
    value: 200000000
  });
  dataGroupPotential.push({
    label: "long text 3 : 300 000 000",
    value: 300000000
  });


  var width = $("#" + chartDivId).width();
  var dividor = 2.75;
  var height = width / dividor;

  //Ajout des éléments svg pour tracer le graphique
  svg = d3.select("#" + chartDivId).append("svg")
    .attr("width", '100%')
    .attr("height", '100%')
    .attr('viewBox', '0 0 ' + Math.min(width, height) + ' ' + Math.min(width, height))
    .attr('preserveAspectRatio', 'xMinYMin')
    .append("g")
    .attr("transform", "translate(" + width / 2 + "," + height / 2 + ")");;

  svg.append("g").attr("class", "slices");
  svg.append("g").attr("class", "labels");
  svg.append("g").attr("class", "lines");

  $("#" + chartDivId).height(height);

  drawMyPie(svg, dataGroupPotential, width, height);

  window.addEventListener('resize', function(event) {
    // do stuff here
    var chartDivId = "pieGPChart";
    var width = $("#" + chartDivId).width();
    var dividor = 2.75;
    var height = width / dividor;
    $("#" + chartDivId).height(height);

    drawMyPie(svg, dataGroupPotential, width, height);
  });
}



function drawMyPie(svg, data, width, height) {
  var radius = Math.min(width, height) / 2;

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

  var arc = d3.arc()
    .outerRadius(radius * 0.8)
    .innerRadius(radius * 0.4);

  var outerArc = d3.arc()
    .innerRadius(radius * 0.9)
    .outerRadius(radius * 0.9);

  //svg.attr("transform", "translate(" + width / 2 + "," + height / 2 + ")");

  var key = function(d) {
    return d.data.label;
  };

  var color = d3.scaleOrdinal(d3.schemeCategory20);
  change(data);

  function mergeWithFirstEqualZero(first, second) {
    var secondSet = d3.set();
    second.forEach(function(d) {
      secondSet.add(d.label);
    });

    var onlyFirst = first
      .filter(function(d) {
        return !secondSet.has(d.label)
      })
      .map(function(d) {
        return {
          label: d.label,
          value: 0
        };
      });
    return d3.merge([second, onlyFirst])
      .sort(function(a, b) {
        return d3.ascending(a.label, b.label);
      });
  }

  function change(data) {
    var duration = 3000;
    var data0 = svg.select(".slices").selectAll("path.slice")
      .data().map(function(d) {
        return d.data
      });
    if (data0.length == 0) data0 = data;
    var was = mergeWithFirstEqualZero(data, data0);
    var is = mergeWithFirstEqualZero(data0, data);

    /* ------- SLICE ARCS -------*/

    var slice = svg.select(".slices").selectAll("path.slice")
      .data(pie(was), key);

    slice.enter()
      .insert("path")
      .attr("class", "slice")
      .style("fill", function(d) {
        return color(d.data.label);
      })
      .each(function(d) {
        this._current = d;
      });

    slice = svg.select(".slices").selectAll("path.slice")
      .data(pie(is), key);

    slice
      .transition().duration(duration)
      .attrTween("d", function(d) {
        var interpolate = d3.interpolate(this._current, d);
        var _this = this;
        return function(t) {
          _this._current = interpolate(t);
          return arc(_this._current);
        };
      });

    slice = svg.select(".slices").selectAll("path.slice")
      .data(pie(data), key);

    slice
      .exit().transition().delay(duration).duration(0)
      .remove();

    /* ------- TEXT LABELS -------*/

    var text = svg.select(".labels").selectAll("text")
      .data(pie(was), key);

    text.enter()
      .append("text")
      .attr("dy", ".35em")
      .style("opacity", 0)
      .text(function(d) {
        return d.data.label;
      })
      .each(function(d) {
        this._current = d;
      });

    //var legend = text.enter();

    //text.append("text")
    //    .attr("dy", "-10")
    //    .style("opacity", 0)
    //    .text(function (d) {
    //        return d.data.label;
    //    })
    //.each(function (d) {
    //    this._current = d;
    //});
    //text.append("text")
    //    .attr("dy", "10")
    //    .style("opacity", 0)
    //    .text(function (d) {
    //        return d.data.label;
    //    })
    //.each(function (d) {
    //    this._current = d;
    //});

    function midAngle(d) {
      return d.startAngle + (d.endAngle - d.startAngle) / 2;
    }

    text = svg.select(".labels").selectAll("text")
      .data(pie(is), key);

    text.transition().duration(duration)
      .style("opacity", function(d) {
        return d.data.value == 0 ? 0 : 1;
      })
      .attrTween("transform", function(d) {
        var interpolate = d3.interpolate(this._current, d);
        var _this = this;
        return function(t) {
          var d2 = interpolate(t);
          _this._current = d2;
          var pos = outerArc.centroid(d2);
          pos[0] = radius * (midAngle(d2) < Math.PI ? 1 : -1);
          return "translate(" + pos + ")";
        };
      })
      .styleTween("text-anchor", function(d) {
        var interpolate = d3.interpolate(this._current, d);
        return function(t) {
          var d2 = interpolate(t);
          return midAngle(d2) < Math.PI ? "start" : "end";
        };
      });

    text = svg.select(".labels").selectAll("text")
      .data(pie(data), key);

    text
      .exit().transition().delay(duration)
      .remove();

    /* ------- SLICE TO TEXT POLYLINES -------*/

    var polyline = svg.select(".lines").selectAll("polyline")
      .data(pie(was), key);

    polyline.enter()
      .append("polyline")
      .style("opacity", 0)
      .each(function(d) {
        this._current = d;
      });

    polyline = svg.select(".lines").selectAll("polyline")
      .data(pie(is), key);

    polyline.transition().duration(duration)
      .style("opacity", function(d) {
        return d.data.value == 0 ? 0 : .5;
      })
      .attrTween("points", function(d) {
        this._current = this._current;
        var interpolate = d3.interpolate(this._current, d);
        var _this = this;
        return function(t) {
          var d2 = interpolate(t);
          _this._current = d2;
          var pos = outerArc.centroid(d2);
          pos[0] = radius * 0.95 * (midAngle(d2) < Math.PI ? 1 : -1);
          return [arc.centroid(d2), outerArc.centroid(d2), pos];
        };
      });

    polyline = svg.select(".lines").selectAll("polyline")
      .data(pie(data), key);

    polyline
      .exit().transition().delay(duration)
      .remove();
  };
}
    svg {
        width: 100%;
        height: 100%;
    }

    path.slice {
        stroke-width: 2px;
    }

    polyline {
        opacity: .3;
        stroke: black;
        stroke-width: 2px;
        fill: none;
    }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.7/js/bootstrap.js"></script>
<link href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.7/css/bootstrap.css" rel="stylesheet"/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.10.0/d3.js"></script>


<div class="panel panel-default">
  <div class="panel-body">
    <div style="text-align:center;" class="row">
      <h4 id="pieGPLegend"></h4>
      <div id="pieGPChart"></div>
    </div>
  </div>
</div>

对于标签,我希望有类似的东西

long text 1
100 000 000

我已经尝试了一些东西,但没有用。这是我尝试但我仍然困惑与d3js

var legend = text.enter();

text.append("text")
    .attr("dy", "-10")
    .style("opacity", 0)
    .text(function (d) {
        return d.data.label;
    })
.each(function (d) {
    this._current = d;
});
text.append("text")
    .attr("dy", "10")
    .style("opacity", 0)
    .text(function (d) {
        return d.data.label;
    })
.each(function (d) {
    this._current = d;
});

欢迎任何帮助,建议,评论!谢谢

达明

1 个答案:

答案 0 :(得分:0)

如果你想在冒号后总是打破文本,最简单的方法是使用= B37 * VLOOKUP(B36,A2:B5,2,FALSE)

<tspan>

以下是您更改的代码:

&#13;
&#13;
.append("tspan")
.attr("x", 0)
.attr("dy", "1.3em")
.text(function(d) {
    return d.data.label.split(":")[1];
})
&#13;
var dataGroupPotential = [];
var pieGroup;
var svg;

processData("pieGPChart");

function processData(chartDivId) {
  $("#pieGPLegend").text("Title : myTitle");

  //Construction du tableau data

  dataGroupPotential.push({
    label: "long text 1 : 100 000 000",
    value: 100000000
  });
  dataGroupPotential.push({
    label: "long text 2 : 200 000 000",
    value: 200000000
  });
  dataGroupPotential.push({
    label: "long text 3 : 300 000 000",
    value: 300000000
  });


  var width = $("#" + chartDivId).width();
  var dividor = 2.75;
  var height = width / dividor;

  //Ajout des éléments svg pour tracer le graphique
  svg = d3.select("#" + chartDivId).append("svg")
    .attr("width", '100%')
    .attr("height", '100%')
    .attr('viewBox', '0 0 ' + Math.min(width, height) + ' ' + Math.min(width, height))
    .attr('preserveAspectRatio', 'xMinYMin')
    .append("g")
    .attr("transform", "translate(" + width / 2 + "," + height / 2 + ")");;

  svg.append("g").attr("class", "slices");
  svg.append("g").attr("class", "labels");
  svg.append("g").attr("class", "lines");

  $("#" + chartDivId).height(height);

  drawMyPie(svg, dataGroupPotential, width, height);

  window.addEventListener('resize', function(event) {
    // do stuff here
    var chartDivId = "pieGPChart";
    var width = $("#" + chartDivId).width();
    var dividor = 2.75;
    var height = width / dividor;
    $("#" + chartDivId).height(height);

    drawMyPie(svg, dataGroupPotential, width, height);
  });
}



function drawMyPie(svg, data, width, height) {
  var radius = Math.min(width, height) / 2;

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

  var arc = d3.arc()
    .outerRadius(radius * 0.8)
    .innerRadius(radius * 0.4);

  var outerArc = d3.arc()
    .innerRadius(radius * 0.9)
    .outerRadius(radius * 0.9);

  //svg.attr("transform", "translate(" + width / 2 + "," + height / 2 + ")");

  var key = function(d) {
    return d.data.label;
  };

  var color = d3.scaleOrdinal(d3.schemeCategory20);
  change(data);

  function mergeWithFirstEqualZero(first, second) {
    var secondSet = d3.set();
    second.forEach(function(d) {
      secondSet.add(d.label);
    });

    var onlyFirst = first
      .filter(function(d) {
        return !secondSet.has(d.label)
      })
      .map(function(d) {
        return {
          label: d.label,
          value: 0
        };
      });
    return d3.merge([second, onlyFirst])
      .sort(function(a, b) {
        return d3.ascending(a.label, b.label);
      });
  }

  function change(data) {
    var duration = 3000;
    var data0 = svg.select(".slices").selectAll("path.slice")
      .data().map(function(d) {
        return d.data
      });
    if (data0.length == 0) data0 = data;
    var was = mergeWithFirstEqualZero(data, data0);
    var is = mergeWithFirstEqualZero(data0, data);

    /* ------- SLICE ARCS -------*/

    var slice = svg.select(".slices").selectAll("path.slice")
      .data(pie(was), key);

    slice.enter()
      .insert("path")
      .attr("class", "slice")
      .style("fill", function(d) {
        return color(d.data.label);
      })
      .each(function(d) {
        this._current = d;
      });

    slice = svg.select(".slices").selectAll("path.slice")
      .data(pie(is), key);

    slice
      .transition().duration(duration)
      .attrTween("d", function(d) {
        var interpolate = d3.interpolate(this._current, d);
        var _this = this;
        return function(t) {
          _this._current = interpolate(t);
          return arc(_this._current);
        };
      });

    slice = svg.select(".slices").selectAll("path.slice")
      .data(pie(data), key);

    slice
      .exit().transition().delay(duration).duration(0)
      .remove();

    /* ------- TEXT LABELS -------*/

    var text = svg.select(".labels").selectAll("text")
      .data(pie(was), key);

    text.enter()
      .append("text")
      .attr("dy", ".35em")
      .style("opacity", 0)
      .text(function(d) {
        return d.data.label.split(":")[0] + ":";
      })
      .each(function(d) {
        this._current = d;
      })
      .append("tspan")
      .attr("x", 0)
      .attr("dy", "1.3em")
      .text(function(d) {
        return d.data.label.split(":")[1];
      })
      .each(function(d) {
        this._current = d;
      });

    //var legend = text.enter();

    //text.append("text")
    //    .attr("dy", "-10")
    //    .style("opacity", 0)
    //    .text(function (d) {
    //        return d.data.label;
    //    })
    //.each(function (d) {
    //    this._current = d;
    //});
    //text.append("text")
    //    .attr("dy", "10")
    //    .style("opacity", 0)
    //    .text(function (d) {
    //        return d.data.label;
    //    })
    //.each(function (d) {
    //    this._current = d;
    //});

    function midAngle(d) {
      return d.startAngle + (d.endAngle - d.startAngle) / 2;
    }

    text = svg.select(".labels").selectAll("text")
      .data(pie(is), key);

    text.transition().duration(duration)
      .style("opacity", function(d) {
        return d.data.value == 0 ? 0 : 1;
      })
      .attrTween("transform", function(d) {
        var interpolate = d3.interpolate(this._current, d);
        var _this = this;
        return function(t) {
          var d2 = interpolate(t);
          _this._current = d2;
          var pos = outerArc.centroid(d2);
          pos[0] = radius * (midAngle(d2) < Math.PI ? 1 : -1);
          return "translate(" + pos + ")";
        };
      })
      .styleTween("text-anchor", function(d) {
        var interpolate = d3.interpolate(this._current, d);
        return function(t) {
          var d2 = interpolate(t);
          return midAngle(d2) < Math.PI ? "start" : "end";
        };
      });

    text = svg.select(".labels").selectAll("text")
      .data(pie(data), key);

    text
      .exit().transition().delay(duration)
      .remove();

    /* ------- SLICE TO TEXT POLYLINES -------*/

    var polyline = svg.select(".lines").selectAll("polyline")
      .data(pie(was), key);

    polyline.enter()
      .append("polyline")
      .style("opacity", 0)
      .each(function(d) {
        this._current = d;
      });

    polyline = svg.select(".lines").selectAll("polyline")
      .data(pie(is), key);

    polyline.transition().duration(duration)
      .style("opacity", function(d) {
        return d.data.value == 0 ? 0 : .5;
      })
      .attrTween("points", function(d) {
        this._current = this._current;
        var interpolate = d3.interpolate(this._current, d);
        var _this = this;
        return function(t) {
          var d2 = interpolate(t);
          _this._current = d2;
          var pos = outerArc.centroid(d2);
          pos[0] = radius * 0.95 * (midAngle(d2) < Math.PI ? 1 : -1);
          return [arc.centroid(d2), outerArc.centroid(d2), pos];
        };
      });

    polyline = svg.select(".lines").selectAll("polyline")
      .data(pie(data), key);

    polyline
      .exit().transition().delay(duration)
      .remove();
  };
}
&#13;
svg {
        width: 100%;
        height: 100%;
    }

    path.slice {
        stroke-width: 2px;
    }

    polyline {
        opacity: .3;
        stroke: black;
        stroke-width: 2px;
        fill: none;
    }
&#13;
&#13;
&#13;