d3.js学习汇总

近期在做线路图实时刷新的功能,用到的技术主要有d3、svg、websocket。整体思路就是解析线路图json,使用d3动态生成svg矢量图;当出现报警信息时websocket主动向前端推送变化数据,前端监听到数据变化后进行局部刷新及动态展示。感觉d3比较像jq,可以操作dom,但是使用上又区别于jq。svg、d3也是从头开始学的,在这里对d3进行简单总结,有问题希望给予指正。

1、元素选择

select() -- 选择指定元素 例如:标签,也可以是某个具体的id等。但是只能获取到相匹配的第一个

selectAll() -- 选中所有元素  例如:所有p标签

const pageSvg = d3.select('#svgContent')  //获取#svgContent

const body = d3.select(body) // 获取dom中的body

const p = body.selectAll('p') // 获取body中所有的p标签                             

2、数据绑定

data() -- 将一个数组绑定到选择集上

datum() -- 将单个数据绑定到选择集上

ps:请保证dom中body下有四个标签

const dataList = [1,2,3,4]

d3.select("body").selectAll("p").data(this.dataList).text((d,i) => {

    return '第' + i + '个元素是' + d

})

const str = "112"

d3.select("body").selectAll("p").datum(str).text(function(d,i){

    return '第' + i + '个元素是' + d

})

3、理解update、enter、exit

简单理解为  enter() -- 不够就补     exit -- 多了就删

借用一张大神的图大家就很容易理解


update、enter: data会在依次添加到选择集中,当data数据中个数大于选择集个数时,调用enter().append('p') 会自动补齐p标签

const p = d3.select("#svgContent").selectAll('p');

        const update = p.data(this.dataList);

        const enter = update.enter();

        update.text(function(d,i){

            return i + '--------------' + d

        })

        const pEnter = enter.append('p');  //可以根据数量自动添加p

        pEnter.text(function(d,i){

            return i + '-------------' + d

        })

update、exit: data会在依次添加到选择集中,当出现选择集个数大于data数据个数时,自动删除多余的dom标签,相当于remove()

const p = d3.select("#svgContent").selectAll('p');

        const update = p.data(this.dataList);

        const exit = update.exit();

        update.text(function(d,i){

            return i + '--------------' + d

        })

        exit.text(function(d,i){

            return i + '-------------' + d

        })

4、插入、删除元素

在选择集之后插入元素  append()

d3.select("#svgContent").append('div').style('width','200px').style('height','200px').style('background','red')

在选择集之前插入元素 insert()

d3.select("#svgContent").insert('p','.test').text('ceshi ')

删除选中元素 remove()

d3.select("#svgContent").select('p','.test').remove()

5、比例尺

比例尺就是把输入域映射到输出域的函数。比如将0-10映射到0-100。 其中,domain为输入域,range为输出域,即将domain中的数据映射成range中的数据。

这里主要介绍下线性比例尺scaleLinear() 和 序数比例尺scaleOrdinal()

const datasets = [1.1,0.9,3,2.4,3.1]

   const svg = d3.select('#svgContent') //获取画布

          const g = svg.append('g') // 定义装图形的位置,并修改其位置

          .attr('transform','translate('+ this.marge.top +','+ this.marge.left +')')

          const min = d3.min(datasets);

          const max = d3.max(datasets);

          const scaleLinear = d3.scaleLinear().domain([min,max]).range([0,10])  //定义比例尺,将最小值和最大值映射成0-10

          const rectHeight = 30;

          g.selectAll('rect')

          .data(this.dataset)

          .enter()

          .append('rect')

          .attr('x',20)

          .attr('y',function(d,i){

              return i * rectHeight

          })

          .attr('width',function(d){

              return scaleLinear(d)  // 使用比例尺

          })

          .attr('height',rectHeight - 5)

          .attr('fill','red')

const index = [0,1,2,3,4]

const color = ["red","blue","yellow","black","green"]

const scaleOrdinal = d3.scaleOrdinal()

    .domain(index)

    .range(color);

scaleOrdinal(0)  // red

scaleOrdinal(1)  // blue

6、svg+d3绘制柱状图

实现思路:

(1) 获取svg画布,并获取宽度和高度

(2) 定义一个组,用于绘制图形,并设置组的位置。设置组用于整体的放大、缩小、平移等操作

(3) 定义x坐标轴并绘制

// 定义x坐标轴

      const xScale =

      d3.scaleBand()

    .domain(d3.range(this.dataset.length))

    .rangeRound([0,width-this.marge.left-this.marge.right]);

      const xAxis = d3.axisBottom(xScale)

      g.append('g')

      .attr('transform','translate('+0+','+ (height- top1 - bottom1)+')')

(4) 定义y坐标轴并绘制

// 定义y坐标轴

      const yScale =  d3.scaleLinear()

    .domain([0,d3.max(this.dataset)])

    .range([height-this.marge.top-this.marge.bottom,0]);

      const yAxis = d3.axisLeft(yScale)

      g.append('g').attr('transform','translate(0,0)').call(yAxis)

(5) 为每个矩形和文字设置分组

(6) 设置矩形间距

(7) 绘制矩形

(8) 绘制文本

以下案例在vue中写的

// 获取svg画布

      const svg = d3.select('#svgContent')

      // 获取svg的宽度和高度

      const width = svg.attr('width')

      const height = svg.attr('height')

      // 定义图形展示区域,并设置位置

      const g = svg.append('g')

      .attr('transform','translate('+ this.marge.top +','+ this.marge.left +')')

      // 定义x坐标轴

      const xScale =

      d3.scaleBand()

    .domain(d3.range(this.dataset.length))

    .rangeRound([0,width-this.marge.left-this.marge.right]);

      //d3.scaleBand().domain(d3.range(this.dataset.length)).rangeRound([0,width-this.marge.left - this.marge.right])

      const xAxis = d3.axisBottom(xScale)

      // 定义y坐标轴

      const yScale =  d3.scaleLinear()

    .domain([0,d3.max(this.dataset)])

    .range([height-this.marge.top-this.marge.bottom,0]);

      //d3.scaleLinear().domain([0,d3.max(this.dataset)]).range([height-this.marge.top - this.marge.bottom,0])

      const yAxis = d3.axisLeft(yScale)

            const top1 = this.marge.top

      const bottom1 = this.marge.bottom

      g.append('g')

      .attr('transform','translate('+0+','+ (height- top1 - bottom1)+')')

      .call(xAxis)

      g.append('g').attr('transform','translate(0,0)').call(yAxis)

      // 为每个矩形和文字设置分组

      const gs = g.selectAll('.rect').data(this.dataset).enter().append('g')

      //设置矩形间距

      const rectPadding = 20;

      //绘制矩形

      gs.append('rect')

      .attr('x',function(d, i){     

        return  xScale(i) + rectPadding/2;

      })

      .attr('y',function(d,i){

        return yScale(d)

      })

      .attr('width',function(){

        return xScale.step() - rectPadding

      })

      .attr('height',function(d,i){

        return height - top1- bottom1 - yScale(d)

      })

      .attr('fill','blue')

      //绘制文字

      gs.append('text')

      .attr('x',function(d,i){

        return xScale(i);

      })

      .attr('y',function(d,i){

        return yScale(d) - 28

      })

      .attr('dx',function(){

        return (xScale.step()-rectPadding)/2;

      })

      .attr('dy',function(d,i){

        return 20

      })

      .text(function(d){

        return d

      })

你可能感兴趣的:(d3.js学习汇总)