D3实现分片柱状图

来源:互联网 发布:java随机数生成1到3 编辑:程序博客网 时间:2024/05/08 10:59

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; });


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



0 0
原创粉丝点击