将每个矩形和文本分组到D3中

时间:2016-12-16 22:59:35

标签: javascript html d3.js

我正在使用 d3.js 创建条形图。在每个栏的顶部,我将显示一些文字。当用户将鼠标悬停在栏上时,它应显示文本。当它们悬停时,文本将消失。为此,我需要将<text><rect>元素分组到<g>元素中。

示例

<g class="gbar">
    <rect x="0" y="50" width="10" height="50" />
    <text x="15" y="40">A</text>
</g>
<g class="gbar">
    <rect x="11" y="75" width="10" height="25" />
    <text x="16" y="65">B</text>
</g>
<g class="gbar">
    <rect x="22" y="25" width="10" height="75" />
    <text x="27" y="35">C</text>
</g>

所以这样,我可以使用.gbar:hover rect, .gbar:hover text { ... } CSS样式来更改<rect><text>元素的颜色和不透明度。对于每个数据项,如何使用 d3.js <rect><text>元素放在<g>元素中?

由于

编辑:要添加更多内容,这是我到目前为止所拥有的...

var svg = d3.select('.mygraph')
            .append('svg')
            .attr('height', 100);

svg.selectAll('rect')
   .data(dataSet)
   .enter()
   .append('rect')
   .attr('x', calcX)
   .attr('y', calcY)
   .attr('width', 10)
   .attr('height', calcH);

svg.selectAll('text')
   .data(dataSet)
   .enter()
   .append('text')
   .text(function (d) {
       return d.Text;
   })
   .attr('x', textX)
   .attr('y', textY);

该代码产生:

<svg>
    <rect x="0" y="50" width="10" height="50" />
    <rect x="11" y="75" width="10" height="25" />
    <rect x="22" y="25" width="10" height="75" />
    <text x="15" y="40">A</text>
    <text x="16" y="65">B</text>
    <text x="27" y="35">C</text>
</svg>

我仍然是 d3.js 的新手。

2 个答案:

答案 0 :(得分:6)

这是标准方法。

首先,使用“输入”选项附加select SUM(CASE WHEN totals.newVisits IS NULL THEN 1 ELSE 0 END) AS Return_Visitors FROM `table` where totals.visits = 1 and date = '20161109' 元素:

<g>

然后,使用该选项附加矩形和文本:

var groups = svg.selectAll(".groups")
    .data(dataset)
    .enter()
    .append("g")
    .attr("class", "gbar");

这样做,你的每个对的矩形和文本都在同一个groups.append('rect') .attr('x', calcX) .attr('y', calcY) .attr('width', 10) .attr('height', calcH); groups.append('text') .text(function (d) { return d.Text; }) .attr('x', textX) .attr('y', textY); 元素内。

这是一个简单的演示(一个非常简单的代码,充满魔法数字)。将鼠标悬停在条形图或文本上:

<g>
var data = d3.range(8).map(()=>~~(Math.random()*130));

var svg = d3.select("svg")

var groups = svg.selectAll(".groups")
	.data(data)
	.enter()
	.append("g")
    .attr("class", "gbar");
	
groups.append("rect")
	.attr("x", (d,i)=> i*40)
	.attr("width", 20)
	.attr("y", d=> 150 - d)
	.attr("height", d=> d)
	.attr("fill", "teal");
	
groups.append("text")
	.attr("x", (d,i)=> i*40)
	.attr("y", d=> 145 - d)
	.text(d=>d)
.gbar:hover rect{
  fill:brown;
  }

.gbar:hover text{
  fill:brown;
  font-weight:700;
  }

如果您检查此代码段创建的SVG,则会得到以下内容:

<script src="https://d3js.org/d3.v4.min.js"></script>
<svg></svg>

答案 1 :(得分:2)

我使用群组&#34; g&#34;处理这个问题:每对条形和标签都存储在一个组中。每次单击一个组时,都要在标签和条上执行排序功能。

&#13;
&#13;
var w = 600;
var h = 250;

var dataset = [ 5, 10, 13, 19, 21, 25, 22, 18, 15, 13,
				11, 12, 15, 20, 18, 17, 16, 18, 23, 25 ];

var xScale = d3.scale.ordinal()
				.domain(d3.range(dataset.length))
				.rangeRoundBands([0, w], 0.05);

var yScale = d3.scale.linear()
				.domain([0, d3.max(dataset)])
				.range([0, h]);


var svg = d3.select("body")
			.append("svg")
			.attr("width", w)
			.attr("height", h);


var groups = svg.selectAll("g")
      .data(dataset)
      .enter()
      .append("g");


groups.append("rect")
   .attr("x", function(d, i) {
   		return xScale(i);
   })
   .attr("y", function(d) {
   		return h - yScale(d);
   })
   .attr("width", xScale.rangeBand())
   .attr("height", function(d) {
   		return yScale(d);
   })
   .attr("fill", function(d) {
		return "rgb(0, 0, " + (d * 10) + ")";
   })
   .on("mouseover", function() {
   		d3.select(this)
   			.attr("fill", "orange");
   })
   .on("mouseout", function(d) {
	   d3.select(this)
	   		.transition()
	   		.duration(250)
			.attr("fill", "rgb(0, 0, " + (d * 10) + ")");
   })
   ;


 groups.append("text")
    .text(function(d) {
       return d;
    })
    .attr("text-anchor", "middle")
    .attr("x", function(d, i) {
       return xScale(i) + xScale.rangeBand() / 2;
    })
    .attr("y", function(d) {
       return h - yScale(d) + 14;
    })
    .attr("font-family", "sans-serif")
    .attr("font-size", "11px")
    .attr("fill", "white");
    groups.on("click", function(){
      sortBars();
    })
    ;


var sortBars = function() {
  svg.selectAll("rect")
     .sort(function(a, b) {
       return d3.ascending(a, b);
      })
     .transition()
     .duration(1000)
     .attr("x", function(d, i) {
        return xScale(i);});


  svg.selectAll("text")
     .sort(function(a, b) {
       return d3.ascending(a, b);
      })
     .transition()
     .duration(1000)
     .attr("x", function(d, i) {
        return xScale(i) + xScale.rangeBand() / 2;
     });

};
&#13;
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>
&#13;
&#13;
&#13;