D3 v4.x学习(1-11)—— 分区图(普通和圆形)

本章实现的是分区图

预告一下下一章会研究堆栈图,下下章最终章是地图探究,第一阶段的内容会在地图探究后结束,结束后就将进入第二阶段的优化,以echarts为标准,实现echarts的图形动画效果,实现echarts的交互。有兴趣的童鞋可以关注下后续内容~

分区图代码如下

<template>
  <div id='svgContainer' style="">
    <div class="every">
      <h3>分区图</h3>
      <div class="svg" id="partition"></div>
    </div>
    <div class="every">
      <h3>分区图扩展--圆形</h3>
      <div class="svg" id="partitionR"></div>
    </div>
</template>
<script>
import * as d3 from 'd3'
export default {
  methods: {
    partition () {
      let width = 400
      let height = 400
      let data = {
        'name': '中国',
        'value': '950',
        'children': [
          {
            'name': '浙江',
            'value': '450',
            'children':
            [
              {'name': '杭州', 'value': '150'},
              {'name': '宁波', 'value': '120'},
              {'name': '温州', 'value': '130'},
              {'name': '绍兴', 'value': '150'}
            ]
          },
          {
            'name': '广西',
            'value': '200',
            'children': [
              {'name': '桂林', 'value': '80'},
              {'name': '南宁', 'value': '50'},
              {'name': '柳州', 'value': '30'},
              {'name': '防城港', 'value': '40'}
            ]
          },
          {
            'name': '黑龙江',
            'value': '200',
            'children': [
              {'name': '哈尔滨', 'value': '50'},
              {'name': '齐齐哈尔', 'value': '40'},
              {'name': '牡丹江', 'value': '60'},
              {'name': '大庆', 'value': '50'}
            ]
          },
          {
            'name': '新疆',
            'value': '100',
            'children':
              [
                {'name': '乌鲁木齐', 'value': '30'},
                {'name': '克拉玛依', 'value': '20'},
                {'name': '吐鲁番', 'value': '25'},
                {'name': '哈密', 'value': '25'}
              ]
          }
        ]
      }
      // 公式
      let partition = d3.partition()
        .size([width, height])
      let color = d3.scaleOrdinal(d3.schemeCategory10)
      let hierarchyData = d3.hierarchy(data)
      // 数据转化,取所有节点的数组
      let partitionData = partition(hierarchyData).descendants()
      // 绘图
      let svg = d3.select('#partition')
        .append('svg')
        .attr('width', width)
        .attr('height', height)
      let g = svg.selectAll('g')
        .data(partitionData)
        .enter()
        .append('g')
      g.append('rect')
        .attr('x', function (d) { return d.x0 })
        .attr('y', function (d) { return d.y0 })
        .attr('width', function (d) { return d.x1 - d.x0 })
        .attr('height', function (d) { return d.y1 - d.y0 })
        .style('stroke', '#ccc')
        .style('fill', function (d) { return color(d.data.name) })
      g.append('text')
        .attr('x', function (d) { return d.x0 })
        .attr('y', function (d) { return d.y0 })
        .attr('dx', function (d) { return (d.x1 - d.x0) / 2 }) // 文字水平居中
        .attr('dy', function (d) { return (d.y1 - d.y0) / 2 - d.data.name.length / 2 * 12 }) // 文字垂直居中,有点瑕疵
        .attr('font-size', function (d) { return 12 - d.depth + 'px' }) // 文字按深度缩小
        .attr('writing-mode', 'tb') // 文字从上往下书写
        .text(function (d) { return d.data.name })
    },
    partitionR () {
      let width = 400
      let height = 400
      let data = {
        'name': '中国',
        'value': '950',
        'children': [
          {
            'name': '浙江',
            'value': '450',
            'children':
            [
              {'name': '杭州', 'value': '150'},
              {'name': '宁波', 'value': '120'},
              {'name': '温州', 'value': '130'},
              {'name': '绍兴', 'value': '150'}
            ]
          },
          {
            'name': '广西',
            'value': '200',
            'children': [
              {'name': '桂林', 'value': '80'},
              {'name': '南宁', 'value': '50'},
              {'name': '柳州', 'value': '30'},
              {'name': '防城港', 'value': '40'}
            ]
          },
          {
            'name': '黑龙江',
            'value': '200',
            'children': [
              {'name': '哈尔滨', 'value': '50'},
              {'name': '齐齐哈尔', 'value': '40'},
              {'name': '牡丹江', 'value': '60'},
              {'name': '大庆', 'value': '50'}
            ]
          },
          {
            'name': '新疆',
            'value': '100',
            'children':
              [
                {'name': '乌鲁木齐', 'value': '30'},
                {'name': '克拉玛依', 'value': '20'},
                {'name': '吐鲁番', 'value': '25'},
                {'name': '哈密', 'value': '25'}
              ]
          }
        ]
      }
      // 公式,注意size的参数
      let radius = 200
      let partition = d3.partition()
        .size([2 * Math.PI, radius * radius])
      let color = d3.scaleOrdinal(d3.schemeCategory10)
      let hierarchyData = d3.hierarchy(data)
      // 数据转化,取所有节点的数组
      let partitionData = partition(hierarchyData).descendants()
      // 创建弧生成器
      let arc = d3.arc()
        .innerRadius(function (d) { return Math.sqrt(d.y0) })
        .outerRadius(function (d) { return Math.sqrt(d.y1) })
        .startAngle(function (d) { return d.x0 })
        .endAngle(function (d) { return d.x1 })
      // 绘图
      let svg = d3.select('#partitionR')
        .append('svg')
        .attr('width', width)
        .attr('height', height)
      let g = svg.selectAll('g')
        .data(partitionData)
        .enter()
        .append('g')
        .attr('transform', 'translate(200,200)')
      g.append('path')
        .attr('display', function (d) {
          return d.depth ? null : 'none'
        })// 是否绘制中心,留白好看一些
        .attr('d', arc)
        .style('stroke', '#ccc')
        .style('fill', function (d) { return color(d.data.name) })
      g.append('text')
        .attr('transform', function (d, i) {
          if (i !== 0) {
            let r = (d.x0 + d.x1) / 2
            let angle = Math.PI / 2
            r += r < Math.PI ? (angle - Math.PI) : angle
            r *= 180 / Math.PI
            return 'translate(' + arc.centroid(d) + ')' + 'rotate(' + r + ')'
          }
        })
        .text(function (d) { return d.data.name })
        .attr('font-size', function (d) { return 12 - d.depth + 'px' }) // 文字按深度缩小
        .attr('dy', '.5em')
        .attr('dx', function (d) { return -d.data.name.length / 2 + 'em' }) // 文字居中
    },
  },
  mounted () {
    this.partition()
    this.partitionR()
  }
}
</script>
<style lang="less">
#svgContainer{
  width: 100%;
  height: 100%;
  .every{
    width: 400px;
    height: 425px;
    margin:15px;
    float: left;
    h3{
      margin:0;
      .button{
        float: right;
        margin-right: 20px;
        font-size: 14px;
        cursor: pointer;
        padding: 2px 8px;
        border:1px solid #ccc;
        background: yellowgreen;
        border-radius: 4px;
        &:hover{
          background: violet;
        }
      }
    }
    .svg{
      width: 400px;
      height: 400px;
    }
  }
}
</style>

猜你喜欢

转载自blog.csdn.net/dkr380205984/article/details/81668378