4週間前に投稿

Highchartsで人口ピラミッドグラフの【Ver.積み上げ横棒グラフ】をつくってみた

2021年9月4日

この記事は約 13 分で読めます。

4.5

人口ピラミッドグラフとは、
アイキャッチ画像のような
グラフを指します。
まぁ、よくあるグラフですよね。

ちなみに、
アイキャッチ画像のグラフは、
わたしの住む
群馬県の人口動態グラフです。

アイキャッチ画像 : スクリーンショット

この人口ピラミッドグラフの
積み上げ横棒グラフバージョンを
つくってみました。

経緯

最近よく聞くSDGs
(持続可能な開発目標)、
目標 5 : ジェンダー平等の実現
にて、
「男性はこうだ」とか
「女性はこうあるべき」
とされている役割や行動について、
いちばん解りやすいのは
男性の家事関連時間を女性と比較した
ものがいちばん理解しやすいかな?

と思ったのが事の始まりです。
グラフで表示できればと思いました。

ジェンダーとは

ジェンダーとは、「社会的性別」のこと。
身体的な性別に対して、
社会の中で「男性はこうだ」とか
「女性はこうあるべき」
とされている役割や行動、
考え方や見た目などがあること。
そういう意味では、
人種差別も同じと考えられると思います。

要はグラフをどうしたいのか?

つまりは以下の画像のように
したい訳なのですが、
意外に手こずる事になります。

目指したグラフは

目指したものは、
以下のようなグラフです。
よく見かけるグラフなので
高を括たかをくくって」いましたが、
グラフを描画するライブラリには
同じ Demo はないので、
これは「超」意外でした。

Highcharts のDemo

Highcharts
人口ピラミッドの Demoがありました。
年代の軸が左右にあり、
棒グラフがセンターからミラー状に
左右に伸びています。

まぁ、
これでもいいかなって思い、
積み上げグラフ」にしたら、
たちまち崩れてしまいました(汗
(ミラー状から
普通の横棒グラフになってしまう)
これはショック(泣

先人の知恵を借りる

さて、どうしたものか・・・、
グーグル先生に質問してみたところ、
同じような考えがあり、結果を出した
先輩がいる事がわかりました。

以下の画像が、
先輩が試行錯誤して
出した結果です。

どうやら、
グラフを2つ用意して
display: inline-block;
2つのグラフを
横並びさせているようです。

この先輩のコードを借りて、
カスタマイズしていきます。

どのようにカスタマイズするか?

この先輩のコードを
まず、積み上げ横棒グラフに
替えて年代は国の名称にします。
元々グラフを2つ用意しているので、
積み上げ横棒グラフにしても
グラフ自体が崩れる事はありません。

しかし、Series(データ系列)が増えるので
Legend(凡例)の位置とか、
subtitle や axis labels(軸ラベル)など、
詳細な調整と工夫が必要になります。

チャートのさまざまな
パーツやコンポーネントについては
上画像を参照の上、
学習して頂けたら幸いです。

結果

とにかく、
悩ましいのは
Legend(凡例)の位置」です。
チャートの下部に
marginBottom: でスペースを作って、
Legend(凡例)を配置しています。

実際に表示してみた

かなり細部にこだわりましたが、
解る方には解る」と思います。

【図表 6歳未満の子どもをもつ夫婦の育児・家事関連時間(1日当たり)―国際比較―】
(備考)
1.Eurostat “How Europeans Spend Their Time Everyday Life of Women and Men” (2004)、Bureau of Labor Statistics of the U.S.“American Time Use Survey” (2016) 及び総務省「社会生活基本調査」(2016年)より作成。
2.日本の数値は、「夫婦と子供の世帯」に限定した妻・夫の1日当たりの「家事」、「介護・看護」、「育児」及び「買い物」の合計時間(週全体)である

ソースコード

HTML

<div id="cnt">
  <div class="highcharts-description"> 【図表 6歳未満の子どもをもつ夫婦の育児・家事関連時間(1日当たり)―国際比較―】 </div>
  <div id="left"></div>
  <div id="right"></div>
  <div class="description-bottom"> (備考)<br> <span>1.</span>Eurostat “How Europeans Spend Their Time Everyday Life of Women and Men” (2004)、Bureau of Labor Statistics of the U.S.“American Time Use Survey” (2016) 及び総務省「社会生活基本調査」(2016年)より作成。<br> <span>2.</span>日本の数値は、「夫婦と子供の世帯」に限定した妻・夫の1日当たりの「家事」、「介護・看護」、「育児」及び「買い物」の合計時間(週全体)である </div>
</div>

JavaScript (JS)

var categories = ["日本", "米国", "英国", "フランス", "ドイツ", "スウェーデン", "ノルウェー"];
Highcharts.chart("left", {
  chart: {
    type: "bar",
    marginRight: 1,
    marginBottom: 100
  },
  credits: {
    enabled: false
  },
  yAxis: {
    min: 0,
    reversed: true,
    title: {
      enabled: false
    },
    labels: {
      formatter: function () {
        if (this.isFirst) {
          return Highcharts.dateFormat("時間", this.value)
        }
        return this.axis.defaultLabelFormatter.call(this) + " 時間"
      }
    },
    stackLabels: {
      enabled: true,
      align: "left",
      x: -50
    }
  },
  xAxis: {
    visible: false,
    reversed: false,
    categories: categories
  },
  tooltip: {
    headerFormat: '<span style="font-size:10px"><b>{point.key}</b></span><br/>',
    pointFormat: 'Total: {point.stackTotal} 時間<br/><span style="color:{series.color}">{series.name}: </span><b>{point.y} 時間</b>'
  },
  title: {
    text: ""
  },
  subtitle: {
    text: "【妻】",
    align: "left",
    verticalAlign: "top",
    style: {
      color: "#ccaadd",
      fontWeight: "bold",
      fontSize: "14px"
    }
  },
  legend: {
    layout: "vertical",
    align: "left",
    verticalAlign: "bottom",
    x: 0,
    y: 0,
    floating: true,
    backgroundColor: ((Highcharts.theme && Highcharts.theme.legendBackgroundColor) || "#FFFFFF"),
    itemStyle: {
      fontSize: "10px"
    }
  },
  plotOptions: {
    series: {
      stacking: "normal",
      dataLabels: {
        enabled: true
      }
    }
  },
  series: [{
    name: "家事・育児関連時間",
    data: [3.89, 3.22, 3.87, 3.92, 3.93, 3.19, 3.09]
  }, {
    color: "#ccaadd",
    name: "うち育児の時間",
    data: [3.45, 2.18, 2.22, 1.57, 2.18, 2.1, 2.17]
  }]
});
Highcharts.chart("right", {
  chart: {
    type: "bar",
    marginBottom: 100
  },
  credits: {
    enabled: false
  },
  yAxis: {
    min: 0,
    enabled: false,
    title: {
      enabled: false
    },
    labels: {
      formatter: function () {
        if (this.isFirst) {
          return Highcharts.dateFormat("時間", this.value)
        }
        return this.axis.defaultLabelFormatter.call(this) + " 時間"
      }
    },
    stackLabels: {
      enabled: true,
      align: "right"
    }
  },
  xAxis: {
    reversed: false,
    categories: categories,
    tickLength: 0,
    labels: {
      style: {
        fontSize: "10px",
        fontWeight: "bold"
      }
    }
  },
  tooltip: {
    headerFormat: '<span style="font-size:10px"><b>{point.key}</b></span><br/>',
    pointFormat: 'Total: {point.stackTotal} 時間<br/><span style="color:{series.color}">{series.name}: </span><b>{point.y} 時間</b>'
  },
  title: {
    text: ""
  },
  subtitle: {
    text: "【夫】",
    align: "right",
    verticalAlign: "top",
    style: {
      color: "#7cb5ec",
      fontWeight: "bold",
      fontSize: "14px"
    }
  },
  legend: {
    layout: "vertical",
    align: "right",
    verticalAlign: "bottom",
    x: 0,
    y: 0,
    floating: true,
    backgroundColor: ((Highcharts.theme && Highcharts.theme.legendBackgroundColor) || "#FFFFFF"),
    itemStyle: {
      fontSize: "10px"
    }
  },
  plotOptions: {
    series: {
      stacking: "normal",
      dataLabels: {
        enabled: true
      }
    }
  },
  series: [{
    name: "家事・育児関連時間",
    data: [0.74, 1.9, 1.46, 1.9, 2.41, 2.14, 1.99]
  }, {
    color: "#ccaadd",
    name: "うち育児の時間",
    data: [0.49, 1.2, 1, 0.4, 0.59, 1.07, 1.13]
  }]
});

CSS

#left, #right {
  width: 49%;
  display: inline-block;
}

#cnt {
  max-width: 850px;
  margin: 0 auto;
}

.highcharts-legend-box {
  opacity: 0.1;
}

.highcharts-description {
  text-align: center;
  font-size: 14px;
  color: #555;
  width: 100%;
}

.description-bottom {
  font-size: 10px;
  color: #666;
  width: 100%;
  margin-top: 0;
  padding: .5em;
  text-indent: -1em;
}

.description-bottom span {
  display: inline-block;
  width: 2px;
}

最後に

このグラフの
紹介元サイトでも
ゴリ押しです。保守性も悪いので個人的には使いたくないです。
とおっしゃっている通り、
かなり無理やりな部分もありますが、
カスタマイズの箇所は
他のチャートを描く際に
役立つのではないかと思います。

貴重なお時間を割き、
最後まで
ご高覧いただきまして
有難うございました

Highchartsで人口ピラミッドグラフの【Ver.積み上げ横棒グラフ】をつくってみた