Highchartsメモ

これは何か

毎回設定方法を忘れるので、逆引き的なメモを残しておきます。

基本

レシピ

(実際に動くサンプルは一番下にあります)

legendを外したい (c-1)

const config = {
  legend: {
    enabled: false
  },
  // ...
};

高さを変更したい (c-1)

const config = {
  chart: {
    // null(初期値)の場合、描画対象のcontainerの高さが利用される
    // containerの高さが設定されてない場合は400pxになる
    height: '200px'
  },
  // ...
};

crosshair(照準線)を表示 (c-1)

const config = {
  xAxis: {
    crosshair: {
    }
  },
  // ...
};

タイトルを非表示にする (c-2)

const config = {
  title: {
    // 空文字を設定
    text: ''
  },
  // ...
};

Axisを非表示にする (c-2)

const config = {
  xAxis: {
    visible: false
  },
  yAxis: {
    visible: false
  },
  // ...
};

どのAxisタイプを利用すべきか

Categories are groups of items, like for example “Apples”, “Pears” and “Oranges”, or “Red”, “Green”, “Blue”, “Yellow”. These categories have that in common that there are no intermediate values.

If you find that you can skip category labels by the xAxis.labels.step option, chances are that you are better off using a linear or datetime axis.

An xAxis of the linear or datetime type has the advantage that Highcharts is able to determine how close the data labels should be because it knows how to interpolate. The labels will by default be placed with approximately 100px between them, which can be changed in the tickPixelInterval option. If you have predictable categories like “Item1”, “Item2”, “Item3” or “2012-01-01”, “2012-01-02”, “2012-01-03” etc., linear or datetime axis types combined with an xAxis.labels.formatter would probably be a better choice.

Axisに日付を利用したい

  • http://api.highcharts.com/highcharts/xAxis.type
    • The type of axis. Can be one of linear, logarithmic, datetime or category. In a datetime axis, the numbers are given in milliseconds, and tick marks are placed on appropriate values like full hours or days. In a category axis, the point names of the chart’s series are used for categories, if not a categories array is defined. Defaults to linear.

Axisのタイプにdatetimeを設定 (c-3, c-4)

pointStart, pointIntervalを利用

const config = {
  xAxis: {
    type: 'datetime',
  },
  plotOptions: {
    series: {
      pointStart: Date.UTC(2010, 0, 1),
      pointInterval: 24 * 3600 * 1000 // one day
    }
  },
  // ...
};

seriesのdataでx valueを設定
https://www.highcharts.com/docs/chart-concepts/series

const config = {
  xAxis: {
    type: 'datetime',
  },
  series: [{
    name: 'Jane',
    data: [
      [Date.UTC(2010, 0, 1), 1],
      [Date.UTC(2010, 0, 2), 0],
      [Date.UTC(2010, 0, 3), 4]
    ]
  }, {
    name: 'John',
    data: [
      [Date.UTC(2010, 0, 1), 5],
      [Date.UTC(2010, 0, 2), 7],
      [Date.UTC(2010, 0, 3), 3]
    ]
  }]
  // ...
};

Axisのタイプにcategoryを設定 (c-5)

const config = {
  xAxis: {
    categories: [
      '2010-01-01',
      '2010-01-02',
      '2010-01-03',
    ],
  },
  // ...
};

背景部分にテキスト、文字、ラインを表示(非表示)したい (c-6, c-7, c-8)

const config = {
  yAxis: {
    // 横線を隠す
    gridLineWidth: 0
  },
  // ...
};
const config = {
  xAxis, {
    // 特定エリアに塗りとテキストと追加
    plotBands: [{
      color: 'rgba(0,0,255,.05)',
      from: -0.5,
      to: 0.5,
      label: {
        text: 'test'
      }
    }],
  // ...
};
const config = {
  xAxis, {
    // 特定の位置にラインを追加
    plotLines: [{
      color: '#f00',
      value: 0.5,
      width: 2,
    }],
  // ...
};
const config = {
  xAxis, {
    // xAxisにもグリッドラインを追加
    gridLineWidth: 2,
    tickInterval:1,

    // この設定は状況に合わせて(カテゴリーかどうか)
    tickmarkPlacement: 'on',
  // ...
  }
};

c-0 - c-2

c-3 - c-5

c-6 - c-8

FlexboxとAuto marginを組み合わせる

f:id:ryotah:20170721204657p:plain

こんな感じでコンテンツを左右(上下)に配置する時に便利。


以下のような問題(仕様)があるので、Flexboxを入れ子にした場合かつ、上下揃えをした場合は注意が必要。
css - Chrome / Safari not filling 100% height of flex parent - Stack Overflow

f:id:ryotah:20170721210737p:plain

  • キャプチャの左がChrome、右はSafari
  • 一番左のパターンは「Flexboxで伸びている高さ = height: 100%」という前提のもの
    • Chromeでは動く。ただしflex-basisを0にしないとこのような結果にはならない
  • 二番目はposition: absoluteを利用
  • 三番目はheight: 100%を利用せずにflex-growを活用するパターン
    • これがよさそう

ブロック要素にリンク(a tag)をつける

  1. ブロック要素内のaタグを、要素いっぱいに広げる
    • text-indent: -999px; などでテキストを非表示にする必要がある
  2. シンプルにaタグでブロック要素を包む
    • ブロック要素内のテキストがリンクテキストと同じスタイルにならないように調整する(必要ならば)
    • a { color: inherit; text-decoration: none; } など

複数行をTruncate

f:id:ryotah:20170718210942p:plain

  • ブラウザが限られている(Safari, Chrome)
  • そのうち使えなくなるかもしれない
  • heightで制限しているので、対象ブラウザ以外でもレイアウトが崩れることはない、はず
.note {
  font-size: 16px;
  line-height: 1.25;
  width: 100px;
  border: 1px solid #000;
  overflow: hidden;
  word-wrap: break-word;
  
  -webkit-line-clamp: 3;
  -webkit-box-orient: vertical;
  display: -webkit-box;

  height: calc(16px * 1.25 * 3);
}

ユーザーからのフィードバックをSlackで受け取る

f:id:ryotah:20170713131031p:plain

f:id:ryotah:20170713131027p:plain

こういうやつを作りました。


Node.js用のSlack SDKを利用したら簡単にできました。

GitHub - slackapi/node-slack-sdk: Slack Developer Kit for Node.js

以下、Webhook URL発行前提の話です。

const IncomingWebhook = require('@slack/client').IncomingWebhook;
const webhook = new IncomingWebhook(SLACK_WEBHOOK_URL);

router.get('/send', (req, res) => {

  // ...

  new Promise((resolve, reject) => {
    webhook.send({
      attachments: createAttachments({
        id: '00001',
        name: '名前',
        text: '本文が入ります。本文が入ります。本文が入ります。本文が入ります。本文が入ります。',
        title: 'タイトル',
      })
    }, (err, header, statusCode, body) => {
      if (err) {
        reject(err);
      } else {
        resolve('ok');
      }
    })
  })
  .then((result) => {
    res.json(result);
  })
  .catch((err) => {
    // エラー処理
  });
});

function createAttachments(params) {
  return [{
      color: '#03A9F4',
      pretext: 'ユーザーからのフィードバックです',
      author_name: params.name,
      title: params.title,
      text: params.text,
      fields: [{
        title: 'User ID',
        value: params.id
      }],
      ts: Math.floor(Date.now() / 1000)
    }
  ];
}

参考URL

カラーコードの変換 (Hex -> RGB)

例えば#ff0000rgb(255,0,0)に変換したい場合。

  1. カラーコード(文字列)を2文字ずつに分ける
  2. 16進法を10進法に変換する
import compose from 'lodash/fp/compose';
import map from 'lodash/fp/map';

function hexToRgb(hex: string): string {
  return compose(
    (decimals) => `rgb(${decimals.join(',')})`,

    // hex to decimal
    map((hex) => parseInt(hex, 16)),

    // split string every 2 characters
    //   e.g. 'ff0000' -> ['ff', '00', '00']
    (hex) => hex.match(/.{1,2}/g),

    // remove `#`
    (hex) => hex.substr(1),

  )(hex);
}

console.error(hexToRgb('#ff0000'));
// -> 'rgb(255,0,0)'

split正規表現が使えた。文字を分割する処理に関してはsplitでもできそう。

String.prototype.split() - JavaScript | MDN