D3实现分片柱状图

1.简要

在集成项目上做开发是,用到第三方提供的组件,组件不能满足X轴自定义的需求,于是被委派研究一下D3,看看D3有没有什么解决方案。

纵观D3的template,发现官方提供的模板并不能满足需求,D3的基本组件做的不是很好,或者说我研究的不够透彻,毕竟现在很多情况下

我们都是拿来主义,一旦一个组件能被使用便管不了许多,又由于项目赶时间,所以也就半透半熟的拿过来改吧改吧,先看一看效果图,由于

整个集成项目的背景和框架,这种风格还比较适合整个界面的风格,先看一看效果图


2.实现方法

D3提供的很多数据格式大部分都是通过CSV文件读取的,而这个文件在我们项目开发的时候不可能去单独创建生成这个文件,我们一般使用的都是实时从后台获取的数据(从后台读取在写到csv文件,前端再去读取这个文件,纯属是脱掉裤子放屁,多此一举。尽管D3提供了直接读取csv文件的方法,但是操作性太差,倒不如我们自己可以提供一种自己根据stack柱状图的格式要求在定义自己的返回格式,这样对于前后台的数据处理就相对来说简单多了)。下面就跟来看一下这种封装格式:
var dataset = [
                { name: "Success" ,
                  numbers: [	{ name:"Guest", value: 200 },
                        { name:"BYOD", value: 251 },
                        { name:"Corporate", value: 211 },
                        { name:"Unknown", value: 151 }
                        ] },
                { name: "Failure" ,    
		numbers: [{ name:"Guest", value: 354 },
{ name:"BYOD", value: 61 }, { name:"Corporate", value: 123 }, { name:"Unknown", value: 105 }] } ];

有没有感觉这种json的格式要比官方提供的csv格式的要舒服的多
书归正传,开始D3的stack之旅。

2.1 引入js文件

<script src="https://d3js.org/d3.v4.min.js"></script>
这个文件可以用官网的,也可以下载之后引入到html页面中

2.2 定义div

<div id="authentication_id"></div>

2.3 定义dataset 

//
      var width  = 1000;	//SVG width
      var height = 700;	//SVG height

      var svg = d3.select("#"+id)			//select div id
          .append("svg")
          .attr("width", width)	//set <svg> width
          .attr("height", height);//set <svg>height

      //1. init dataset
      var dataset = [
          { name: "Success" ,
              sales: [	{ year:"Guest", profit: 150 },
                  { year:"BYOD", profit: 321 },
                  { year:"Corporate", profit: 54 },
                  { year:"Unknown", profit: 123 }
                  ] },
          { name: "Failure" ,
              sales: [	{ year:"Guest", profit: 432 },
                  { year:"BYOD", profit: 321 },
                  { year:"Corporate", profit: 54 },
                  { year:"Unknown", profit: 105 }] }
      ];


      //2. change the data format which stack support
      var stack = d3.layout.stack()
          .values(function(d){ return d.sales; })
          .x(function(d){ return d.year; })
          .y(function(d){ return d.profit; });

      var data = stack(dataset);



      //3. draw

      //the outside border
      var padding = { left:150, right:100, top:30, bottom:30 };

      //set X-axis scale
      var xRangeWidth = width - padding.left - padding.right;

      var xScale = d3.scale.ordinal()
          .domain(data[0].sales.map(function(d){ return d.year; }))
          .rangeBands([0, xRangeWidth],0.3);

      //set y-axis scale

      //set Domain most value
      var maxProfit = d3.max(data[data.length-1].sales, function(d){
          return d.y0 + d.y;
      });

      //set range most value
      var yRangeWidth = height - padding.top - padding.bottom;

      var yScale = d3.scale.linear()
          .domain([0, maxProfit])		//Domain
          .range([0, yRangeWidth]);	//range


      //set color scale
      var color = d3.scale.category10();

      //add group element
      var groups = svg.selectAll("g")
          .data(data)
          .enter()
          .append("g")
          .style("fill",function(d,i){ return color(i); });

      //add rectangle
      var rects = groups.selectAll("rect")
          .data(function(d){ return d.sales; })
          .enter()
          .append("rect")
          .attr("x",function(d){ return xScale(d.year); })
          .attr("y",function(d){ return yRangeWidth - yScale( d.y0 + d.y ); })
          .attr("width",function(d){ return xScale.rangeBand(); })
          .attr("height",function(d){ return yScale(d.y); })
          .attr("transform","translate(" + padding.left + "," + padding.top + ")");

      //add axis
      var xAxis = d3.svg.axis()
          .scale(xScale)
          .orient("bottom");

      yScale.range([yRangeWidth, 0]);

      var yAxis = d3.svg.axis()
          .scale(yScale)
          .orient("left");

      svg.append("g")
          .attr("class","axis")
          .attr("transform","translate(" + padding.left + "," + (height - padding.bottom) +  ")")
          .call(xAxis);

      svg.append("g")
          .attr("class","axis")
          .attr("transform","translate(" + padding.left + "," + (height - padding.bottom - yRangeWidth) +  ")")
          .call(yAxis);

      //add group tabs
      var labHeight = 50;
      var labRadius = 10;

      var labelCircle = groups.append("circle")
          .attr("cx",function(d){ return width - padding.right*0.98; })
          .attr("cy",function(d,i){ return padding.top * 2 + labHeight * i; })
          .attr("r",labRadius);

      var labelText = groups.append("text")
          .attr("x",function(d){ return width - padding.right*0.8; })
          .attr("y",function(d,i){ return padding.top * 2 + labHeight * i; })
          .attr("dy",labRadius/2)
          .text(function(d){ return d.name; });


这样就可以实现我们要的效果



  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
 你手头有一些数据,想做成漂亮的图表放到网站上?好主意,通过浏览器来跨平台实现数据可视化是正确的选择。什么,你还想让图表能够响应用户操作?没问题,交互式图表比静态图片更能吸引人去探究本源。好啦,要生成通过浏览器展示的动态图表,目前热门的Web数据可视化库——D3。   《图灵程序设计丛书·数据可视化实战:使用D3设计交互式图表》这本书很有意思,而且对读者要求不高。不需要知道什么是数据可视化,也不用有太多Web开发背景就能看懂它。不信?翻一翻就知道这是一本既好玩又实用的动手指南啦!看完这本书你会怎么样呢?   掌握必要的HTML、CSS、JavaScript和SVG基础知识;   学会基于数据在网页里生成元素和为它们设置样式的技巧;   能够生成条形图、散点图、饼图、堆叠条形图和力导向图;   使用平滑的过渡动画来展示数据的变化;   赋予图表动态交互能力,响应用户从不同角度探索数据的请求;   收集数据和创建自定义的地图;   另外,《图灵程序设计丛书·数据可视化实战:使用D3设计交互式图表》100多个代码示例都可以在线浏览! 【电子版来自互联网,仅供预览及学习交流 使用,不可用于商业用途,如有版权问题,请联系删除,支持正版,喜欢的 请购买正版书籍: https://e.jd.com/30336473.html】

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值