D3.js柱状图例子

BarChart案例

demo地址
源码地址

1.案例中接触到的d3知识点

  • 柱状图的绘制;

  • 坐标轴的绘制;

  • 刻度的绘制;

  • 网格线的绘制;

  • 简单的事件


2.代码分析

  • 基本的参数配置

    let data = [50, 40, 120, 80, 99, 167, 142, 21];  //图表所需数据
     let padding = {                                 //图标距离容器上下左右的距离
         top: 40,
         right: 40,
         bottom: 40,
         left: 40 
     };
     let height = 400,                               //容器的宽高
         width = 400;
     let xAxisWidth = 300,                           //两个坐标轴的宽度
         yAxisWidth = 300;

    clipboard.png

  • 创建一个容器

     let svg = d3.select("body").append("svg")  //在body中添加一个svg容器
         .attr("height", height)                //设置宽高  
         .attr("width", width);
    
     let tooltip=d3.select("body")             //添加一个div,主要用来显示数据提示
         .append("div")
         .attr("class","tooltip")              //添加一个类名,方便设置样式
         .style("opacity",0.0);                //设置透明度为0
  • 创建坐标轴

    function draw(data) {……}//我们所有绘制图标的代码均放在draw函数里
    
          let xScale = d3.scale.ordinal()   //创建一个序数尺度
              .domain(d3.range(data.length))  //定义域
              .rangeRoundBands([0, xAxisWidth], 0.2);//设置padding为0.2,设置每个rangeBand的留白长度
    
          let yScale = d3.scale.linear()  //创建一个线性尺度
              .domain([0, d3.max(data)]) //值域
              .range([0, yAxisWidth]);   
              
          let xAxis = d3.svg.axis()   //创建x坐标
              .scale(xScale)           //设定xSacle尺度
              .orient("bottom")        //坐标位置在底部
           
          yScale.range([yAxisWidth, 0]);
          let yAxis = d3.svg.axis()
              .scale(yScale)
              .orient("left");
    
          svg.append("g")         //在容器中添加一个g容器,将x坐标的相关体全部扔进去
              .attr("class", "axis  x-axis") //设置类名
              .attr("transform", "translate(" + padding.left + "," + (height - padding.bottom) + ")") //移动到合适的位置
              .call(xAxis)  //和xAxis绑定上    
                  
           svg.append("g")  //y轴和x轴类似
              .attr("class", "axis y-axis")
              .attr("transform", "translate(" + padding.left + "," + (height - yAxisWidth - padding.top) + ")")
              .call(yAxis)       
    
  • 创建网格线

    d3.selectAll("g.x-axis g.tick") //选择到刻度线
              .append("line")       //添加line,其实这也是网格线的原理
              .classed("grid-line", true)
              .attr("x1", 0) 
              .attr("y1", 0)
              .attr("x2", 0)
              .attr("y2", - (xAxisWidth)); 
              
     d3.selectAll("g.y-axis g.tick") 
              .append("line") 
              .classed("grid-line", true)
              .attr("x1", 0) 
              .attr("y1", 0)
              .attr("x2", yAxisWidth)
              .attr("y2", 0);           
  • 创建柱状图

          let updateRect = svg.selectAll("rect") //更新模式
              .data(data);
          let enterRect = updateRect.enter(); //进入模式
          let exitRect = updateRect.exit();   //退出模式
    
          enterRect.append("rect")
              .attr("fill", "lightseagreen")  //填充颜色
              .attr("x", function (d, i) {   //确定rect的位置,宽度,高度,跟scale绑定动态变化
                  return padding.left + xScale(i)
              })
              .attr("y", function (d) {
                  return height - padding.bottom - yScale(d)
              })
              .attr("width", xScale.rangeBand())  //宽度
              .attr("height", function (d) {
                  return yScale(d)
              })
              .on("mousemove" ,function (d,i) {//绑定鼠标事件,d:数据,i:索引
                  d3.select(this)       //this当前对象
                      .transition()    //动画
                      .duration(100)   //持续事件
                      .attr("fill","green");  //变色
                  tooltip.html(d)    //为数据提示框添加对象对应的数据
                      .style("left",(d3.event.pageX)+"px")//确定数据提示框
                      .style("top",(d3.event.pageY -20)+"px")
                      .style("opacity",.5)
              })
              .on("mouseout",function (d,i) {
                  d3.select(this)
                      .transition()
                      .duration(100)
                      .attr('fill','lightseagreen');
                  tooltip.style("opacity",0.0)
              });
    
          updateRect.attr("fill", "lightseagreen")
              .attr("x", function (d, i) {
                  return padding.left + xScale(i)
              })
              .attr("y", function (d) {
                  return height - padding.bottom - yScale(d)
              })
              .attr("width", xScale.rangeBand())
              .attr("height", function (d) {
                  return yScale(d)
              });
    
          exitRect.remove();
  • 注意

    svg.selectAll('*').remove();//在draw函数添加这行代码,在刷新时候移除svg,否则会覆盖
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值