美文网首页
d3.js学习汇总

d3.js学习汇总

作者: 淼一___ | 来源:发表于2019-08-14 18:36 被阅读0次

    近期在做线路图实时刷新的功能,用到的技术主要有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学习汇总

          本文链接:https://www.haomeiwen.com/subject/patyixtx.html