見出し画像

震度図自動生成をnode.jsで書いた。

今回のテックブログは、地震が起きた時の報道で使われる「震度図」の自動生成のお話がメインではなく、node.jsでデータを画像化するお話です。

メディア研究開発センターの赤澤が書きます。

本記事をまとめるならば「d3.jsでSVGを作り、sharpで画像変換せよ」以上です。

さて…‥‥。

このような震度図を朝日新聞社は3年前まで手動で作っていました。気象庁が発表した震度情報をデザイン部がグラフィックツールを使って職人芸で超高速で作っていたのです。
今回はそれを自動化したというお話なんですが、そもそもこれは先輩が作ったシステムですでに記事があります。詳細はこちらを読んでください。

今回は「画像を自動生成すること」について書きます。

個人的にnodeでデータを画像化するのであれば、D3.jsでSVGを作り、sharpでpngないしはjpegに変換するのが一番よいかなと思います。
震度図の他にも、いくつかのオープンデータからグラフや表を生成し、画像化する…みたいなことをやってきました。そのほとんどがD3.jsを使って、sharpでSVGからjpeg,pngに変換するという手法を取りました。
プログラムで数値データから画像を作りたいとなったときに一番重要なのは、SVGを理解しているということだと思います。まずはSVGをある程度理解してください。
SVGとD3.jsについてざっくりと学びたい方はこちらの記事がおすすめです。

SVGの仕組みがわかったら、D3.jsでどのようにSVG画像を書くのかを学びましょう。
javascriptで自分が作りたいデザインをD3.jsを使って描けるように様々なトライをしてみてください。
個人的には下記のようにパーツごとに変数へ格納して使い回せるようにしておいたのが、便利だなーと思いました。

const drawEpicenter = (svg, info) => {
  svg.selectAll('.epicenter')
  svg
    .append('path')
    .attr(
      'd',
      'M' + projection([info.epicenter.lng, info.epicenter.lat]) + ' Z'
    )
    .attr('marker-start', 'url(#cross)')
}

SVGが生成できたら、あとはjpegなりpngなり、よく使われている画像拡張子に変換します。


SVGをpng,jpegに変換するライブラリは多数ありますが、個人的にはsharpが好きでよくつかっています。
lambdaで画像を生成してそのままS3にUploadしたい!なんてことは多々あると思います。

const svgBuffer = Buffer.from(svgString)
const pngBuffer = await sharp(svgBuffer).png().toBuffer()
return await uploadImages(
       pngBuffer,
       `earthquake-image.png`
)

このコードのように、Buffer.fromでSVGをBufferにし、sharpでpngのBufferにし、そのままS3にUploadすれば終了です。
とてもかんたんで良いですね。

毎日画像を手動で作っているということはありませんか?

データだけが異なる画像は実は結構かんたんに自動化することができます。
SVG,D3.jsを活用して、ぜひ自動化してみてください。

メディア研究開発センター 赤澤