d3.js多个坐标轴柱状图

Posted daixinet

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了d3.js多个坐标轴柱状图相关的知识,希望对你有一定的参考价值。

最终效果图镇楼:

本文通过三个步骤来介绍d3.js。

1、简单的柱状图;

2、多个x轴的柱状图;

3、多个x轴、y轴的柱状图;

 

学习心得:

d3.js入门相对比较困难,一旦掌握了核心思想,不断熟悉API,就可以做出很灵活、实用的图表。

canvas中,d3帮我们计算好了每个图形的位置,我们再一个一个的画上即可。

不要担心代码看起来很多,一个一个的分析出来,就会发现其实还是有套路的。

 

一、简单图表

示意图:

 

代码:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title></title>
</head>
<body>
<canvas id="myCanvas" width="600" height="400"></canvas>
<script src="d3.min.js"></script>
<script>
  "use strict";
  (function () {
    function init() {
      initData();
    }
    function initData() {var oneData = [
        {\'name\': \'办公用品\', \'value\': 100},
        {\'name\': \'家具\', \'value\': 20},
        {\'name\': \'技术\', \'value\': 60}
      ];
      initUI(oneData);
    }
    function initUI(data) {
      var canvas = document.querySelector(\'#myCanvas\');
      var context = canvas.getContext(\'2d\');
      var margin = {top: 20, right: 20, bottom: 30, left: 40};
      var width = canvas.width - margin.left - margin.right;
      var height = canvas.height - margin.top - margin.bottom;
      var x0 = d3.scaleBand()
        .domain(data.map(function (d) {
          return d.name;
        }))
        .rangeRound([0, width])
        .padding(0.5);
      var y0 = d3.scaleLinear()
        .domain([0, d3.max(data, function (d) {
          return d.value;
        })])
        .range([height, 0]);
      context.translate(margin.left, margin.top);
      context.beginPath();
      x0.domain().forEach(function (d) {
        context.moveTo(x0(d) + x0.bandwidth() / 2, height);
        context.lineTo(x0(d) + x0.bandwidth() / 2, height + 6);
      });
      context.strokeStyle = \'black\';
      context.stroke();
      context.textAlign = "center";
      context.textBaseline = "top";
      x0.domain().forEach(function (d) {
        context.fillText(d, x0(d) + x0.bandwidth() / 2, height + 6);
      });
      context.beginPath();
      context.moveTo(0.5, height + 0.5);
      context.lineTo(width + 0.5, height + 0.5);
      context.strokeStyle = "black";
      context.stroke();
      var yTickCount = 10;
      var yTicks = y0.ticks(yTickCount);
      context.beginPath();
      yTicks.forEach(function (d) {
        context.moveTo(0, y0(d) + 0.5);
        context.lineTo(-6, y0(d) + 0 / 5);
      });
      context.strokeStyle = \'black\';
      context.stroke();
      context.textAlign = "right";
      context.textBaseline = "middle";
      yTicks.forEach(function (d) {
        context.fillText(d, -9, y0(d));
      });
      context.beginPath();
      context.moveTo(-6.5, 0 + 0.5);
      context.lineTo(0.5, 0 + 0.5);
      context.lineTo(0.5, height + 0.5);
      context.lineTo(-6.5, height + 0.5);
      context.strokeStyle = "black";
      context.stroke();
      context.fillStyle = "steelblue";
      data.forEach(function (d) {
        context.fillRect(x0(d.name), y0(d.value), x0.bandwidth(), height - y0(d.value));
      });
    }
    init();
  }());
</script>
</body>
</html>

 

二、多个x轴

示意图:

代码:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title></title>
</head>
<body>
<canvas id="myCanvas" width="600" height="400"></canvas>
<script src="d3.min.js"></script>
<script>
  "use strict";
  (function () {
    function init() {
      initData();
    }
    function initData() {var data =
        [
          {
            \'name\': \'东北\',
            \'value\': [
              {\'name\': \'办公用品\', \'value\': 100},
              {\'name\': \'家具\', \'value\': 20},
              {\'name\': \'技术\', \'value\': 60}
            ]
          },
          {
            \'name\': \'华北\',
            \'value\': [
              {\'name\': \'办公用品\', \'value\': 100},
              {\'name\': \'家具\', \'value\': 80},
              {\'name\': \'技术\', \'value\': 60}
            ]
          },
          {
            \'name\': \'西南\',
            \'value\': [
              {\'name\': \'办公用品\', \'value\': 100},
              {\'name\': \'家具\', \'value\': 80},
              {\'name\': \'技术\', \'value\': 60}
            ]
          }
        ];
      initUI(data);
    }
    function initUI(data) {
      var canvas = document.querySelector(\'#myCanvas\');
      var context = canvas.getContext(\'2d\');
      var margin = {top: 20, right: 20, bottom: 45, left: 40};
      var width = canvas.width - margin.left - margin.right;
      var height = canvas.height - margin.top - margin.bottom;
      var xAxis0 = d3.scaleBand()
        .domain(data.map(function (d) {
          return d.name;
        }))
        .rangeRound([0, width]);
      var firstRow = data[0];
      var xAxis1 = d3.scaleBand()
        .domain(firstRow.value.map(function (d) {
          return d.name;
        }))
        .rangeRound([0, xAxis0.bandwidth()])
        .padding(0.5);
      var yAxis0 = d3.scaleLinear()
        .domain([0, d3.max(data, function (d0) {
          return d3.max(d0.value, function (d1) {
            return d1.value;
          })
        })])
        .range([height, 0]);
      context.translate(margin.left, margin.top);
      context.beginPath();
      context.textAlign = "center";
      context.textBaseline = "top";
      xAxis0.domain().forEach(function (d) {
        context.fillText(d, xAxis0(d) + xAxis0.bandwidth() / 2, height + 23);
      });
      data.forEach(function (d0) {
        var pX0 = xAxis0(d0.name);
        d0.value.forEach(function (d1) {
          context.moveTo(pX0 + xAxis1(d1.name) + xAxis1.bandwidth() / 2, height);
          context.lineTo(pX0 + xAxis1(d1.name) + xAxis1.bandwidth() / 2, height + 6);
          context.fillText(d1.name, pX0 + xAxis1(d1.name) + xAxis1.bandwidth() / 2, height + 6);
        });
      });
      context.strokeStyle = \'black\';
      context.stroke();
      context.beginPath();
      context.moveTo(0.5, height + 0.5);
      context.lineTo(width + 0.5, height + 0.5);
      context.strokeStyle = "black";
      context.stroke();
      var yTickCount = 10;
      var yTicks = yAxis0.ti

以上是关于d3.js多个坐标轴柱状图的主要内容,如果未能解决你的问题,请参考以下文章

D3.js的v5版本入门教程(第九章)——完整的柱状图

零基础自学前端 D3.js 初体验03 柱状图+排序

d3.js做的柱状图

D3.js中Stacked-to-Grouped Bars详解

D3.js中Stacked-to-Grouped Bars详解

d3.js 封装一个方法更新柱状图,运用数据模板