对比d3官方画廊observablehq在vue里面写直方图

1 首先在vue项目中public文件夹下,放入alphabet.json文件如下

[
  {
    "letter": "A",
    "frequency": 0.08167
  },
  {
    "letter": "B",
    "frequency": 0.01492
  },
  {
    "letter": "C",
    "frequency": 0.02782
  },
  {
    "letter": "D",
    "frequency": 0.04253
  },
  {
    "letter": "E",
    "frequency": 0.12702
  },
  {
    "letter": "F",
    "frequency": 0.02288
  },
  {
    "letter": "G",
    "frequency": 0.02015
  },
  {
    "letter": "H",
    "frequency": 0.06094
  },
  {
    "letter": "I",
    "frequency": 0.06966
  },
  {
    "letter": "J",
    "frequency": 0.00153
  },
  {
    "letter": "K",
    "frequency": 0.00772
  },
  {
    "letter": "L",
    "frequency": 0.04025
  },
  {
    "letter": "M",
    "frequency": 0.02406
  },
  {
    "letter": "N",
    "frequency": 0.06749
  },
  {
    "letter": "O",
    "frequency": 0.07507
  },
  {
    "letter": "P",
    "frequency": 0.01929
  },
  {
    "letter": "Q",
    "frequency": 0.00095
  },
  {
    "letter": "R",
    "frequency": 0.05987
  },
  {
    "letter": "S",
    "frequency": 0.06327
  },
  {
    "letter": "T",
    "frequency": 0.09056
  },
  {
    "letter": "U",
    "frequency": 0.02758
  },
  {
    "letter": "V",
    "frequency": 0.00978
  },
  {
    "letter": "W",
    "frequency": 0.0236
  },
  {
    "letter": "X",
    "frequency": 0.0015
  },
  {
    "letter": "Y",
    "frequency": 0.01974
  },
  {
    "letter": "Z",
    "frequency": 0.00074
  }
]

<template>
    <div id="bar-chart-container"></div>
</template>
<script>
    import * as d3 from 'd3';
    import axios from "axios";
    export default {
        data() {
          return {
            color: "steelblue",
            margin: { top: 30, right: 0, bottom: 30, left: 40 },
          };
        },
        /**
         * 在挂载后即开始执行
         */
        mounted() {
          axios.get("./alphabet.json").then((res) => {
            const barChartData = Object.assign(this.formatData(res.data), {
              format: "%",
              y: "↑ Frequency",
            });
            this.drawBarChart(barChartData);
          });
        },
        methods: {
          /**
           * 格式化数据
           */
          formatData(data) {
            return data
              .map(({ letter, frequency }) => {
                return { name: letter, value: frequency };
              })
              .sort((a, b) => d3.descending(a.value, b.value));
          },
          /**
           * 绘制直方图
           */
          drawBarChart(data) {
            const margin = this.margin;
            const width = 800;
            const height = 500;
            // 初始化 SVG 元素
            const svg = d3
              .select("#bar-chart-container")
              .append("svg")
              .attr("class", "bar-chart")
              .attr("viewBox", `0 0 ${width} ${height}`)
              .attr("width", width)
              .attr("height", height)
              .append("g");

            // https://observablehq.com/@d3/d3-scaleband
            // x 轴的缩放比例尺
            const x = d3
              .scaleBand()
              .domain(d3.range(data.length))
              .range([margin.left, width - margin.right])
              .padding(0.1);
            // y 轴的缩放比例尺
            const y = d3
              .scaleLinear()
              .domain([0, d3.max(data, (d) => d.value)])
              .nice()
              .range([height - margin.bottom, margin.top]);
            // x 坐标轴
            // tickSizeOuter(0) 移除 0 处初始的标记
            // tickFormat https://github.com/d3/d3-scale/blob/master/README.md#tickFormat
            const xAxis = (g) =>
              g.attr("transform", `translate(0,${height - margin.bottom})`).call(
                d3
                  .axisBottom(x)
                  .tickFormat((i) => data[i].name)
                  .tickSizeOuter(0)
              );
            // y 坐标轴
            const yAxis = (g) =>
              g
                .attr("transform", `translate(${margin.left},0)`)
                .call(d3.axisLeft(y).ticks(null, data.format))
                // 移除区域间的竖线
                .call((g) => g.select(".domain").remove())
                .call((g) =>
                  g
                    .append("text")
                    .attr("x", -margin.left)
                    .attr("y", 10)
                    .attr("fill", "currentColor")
                    .attr("text-anchor", "start")
                    .text(data.y)
                );
            svg
              .append("g")
              .attr("fill", this.color)
              .selectAll("rect")
              .data(data)
              .join("rect")
              .attr("x", (d, i) => x(i))
              .attr("y", (d) => y(d.value))
              .attr("height", (d) => y(0) - y(d.value))
              .attr("width", x.bandwidth());
            // 绘制到 SVG
            svg.append("g").call(xAxis);
            svg.append("g").call(yAxis);
          }
        }
    }
</script>
<style scoped>
</style>

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值