如何在d3.js中制作带有扩展网格的圆角条形图? [英] How to Make a bar chart with rounded corners with extended grid in d3.js?

查看:163
本文介绍了如何在d3.js中制作带有扩展网格的圆角条形图?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用D3.js创建条形图.条件是条形图应具有固定的宽度和条形图之间的填充,并且应绘制在网格线的中心.

I am trying to create a Bar chart using D3.js. The condition is that Bar should have fixed width and padding between the bars and it should be plot at center of grid lines.

单击时工具提示应显示一条垂直线

Tooltip should appear on click with a vertical line

我能够用绘制的条形图创建网格线,不知何故rx,ry从两侧都是四舍五入的. 我如何获得相同的结果.

I am able to create the grid lines with plotted bar, somehow rx,ry is rounding from both sides. How can i acheive the same sort of result.

var rectCluster = svg.selectAll(".bar")
                    .data(data);

                rectCluster
                    .enter().append("rect")
                    .attr("class", function(d) {
                        return "bar";
                    })
                    .attr(attrs)
                    .attr({ry : (20), rx : 20 })
                    .attr("x", function(d) { return x(d.text); })
                    .attr("y", function(d) {
                        return height;
                    })
                    .style("fill", function(d) {
                        return color(d.text);
                    })
                    .attr("width", x.rangeBand())
                    .attr("height", 0)
                    .transition()
                    .duration(animationDelay)
                    .delay(function(d, i) {
                        return i * animationDelay;
                    })
                    .attr("y", function(d) { return y(d.score); })
                    .attr("height", function(d) { return height - y(d.score) });

                    var attrs = {
    width: function(d, i){
      return o.rangeBand();
    },
    height: function(d, i){
      return yScale(d);
    },
    fill: "#384252",
    x: function(d, i){
      return xScale(i);
    },
    y: function(d, i){
      return height - yScale(d) - margin.bottom;
    }
  };

Js Fiddle

我正在尝试实现这样的目标.

I am trying to achieve like this.

推荐答案

一种选择是使用剪切路径,但是您也可以使用与构建矩形相同的信息来创建简单的路径生成器:x,y,宽度,高度和半径.路径很简单:

One option is to use a clip path, but you can also create a simple path generator using the same information you use to build the rectangles: x,y,width,height, plus radius. The path is fairly simple:

  1. 移动到左下角
  2. 直线到左上角弧的底部
  3. 弧线到左上角弧线的顶部
  4. 直线到右上角的顶部
  5. 弧到右上角的底部.
  6. 直线到右下角
  7. 关闭路径.

其中哪个是类似的东西

  1. M x,y
  2. L x,y-height + radius
  3. 半径,半径,0、0、1,x +半径,y高度
  4. L x + width-r,y-height
  5. 半径,半径,0、0、1,x +宽度,y-高度+半径
  6. L x + width,y
  7. Z

可能看起来像这样(一个相当懒惰的实现):

Which could look like this (a rather lazy implementation):

function bar(x,y,w,h,r,f) {
    // Flag for sweep:
    if(f == undefined) f = 1;
    // x coordinates of top of arcs
    var x0 = x+r;
    var x1 = x+w-r;
    // y coordinates of bottom of arcs
    var y0 = y-h+r;

    // assemble path:
    var parts = [
      "M",x,y,               // step 1
      "L",x,y0,              // step 2
      "A",r,r,0,0,f,x0,y-h,  // step 3
      "L",x1,y-h,            // step 4
      "A",r,r,0,0,f,x+w,y0,  // step 5
      "L",x+w,y,             // step 6
      "Z"                    // step 7
     ];
    return parts.join(" ");
}

我包括了一个可选的扫掠标志(f)-如果设置为0,它将反转弧.

I've included an optional sweep flag (f) - it'll invert the arcs if set to 0.

并应用如下内容:

 .attr("d", function(d) { 
    return bar(x(d),y(0),x.bandwidth(),y(0)-y(d),15);  
  })

放在一起,您可能会得到类似的东西:

Put together you might get something like:

var width = 500;
var height = 200;
var svg = d3.select("body").append("svg").attr("width",width).attr("height",height);
var data = [ 10,20,30,40,20,50,60 ];

var x = d3.scaleBand().domain(d3.range(data.length)).range([10,width-10]).paddingInner(0.1);
var y = d3.scaleLinear().domain([0,60]).range([height-10,10]);

var bars = svg.selectAll(null)
  .data(data)
  .enter()
  .append("path")
  .attr("d", function(d,i) { 
	  return bar(x(i),y(0),x.bandwidth(),y(0)-y(d),10);  
  })
  
function bar(x,y,w,h,r,f) {
	// Flag for sweep:
	if(f == undefined) f = 1;
	
	// x coordinates of top of arcs
	var x0 = x+r;
	var x1 = x+w-r;
	// y coordinates of bottom of arcs
	var y0 = y-h+r;
	// just for convenience (slightly different than above):
	var l = "L", a = "A";

	var parts = ["M",x,y,l,x,y0,a,r,r,0,0,f,x0,y-h,l,x1,y-h,a,r,r,0,0,f,x+w,y0,l,x+w,y,"Z"];
	return parts.join(" ");
}

// Still transitionable:
bars.data(data.reverse())
 .transition()
 .attr("d", function(d,i) { 
  return bar(x(i),y(0),x.bandwidth(),y(0)-y(d),30);  
 })
 .duration(2000)
 .transition()
 .attr("d", function(d,i) { 
  return bar(x(i),y(0),x.bandwidth(),y(0)-y(d),0);  
 })
 .duration(2000)
 .transition()
 .attr("d", function(d,i) { 
  return bar(x(i),y(0),x.bandwidth(),y(0)-y(d),15);  
  })
 .duration(2000);

<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.10.0/d3.min.js"></script>

如果半径超过钢筋高度或宽度的一半,则会得到一些更有趣的结果,对此的完整实现将考虑进行检查,以确保钢筋的半径不会太大

这篇关于如何在d3.js中制作带有扩展网格的圆角条形图?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆