Chart.js でX軸の軸ラベル(ticks)を「縦書き」にする一撃必殺技

# なにがしたい？

見たまんまです。これがゴール。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/129854/a731248e-6411-ba0f-a20c-f6d4c68b3cb6.png)


# 結論

ラベルを…

```javascript
labels: [
  'いちい', 'あすなろ', 'いちょう', 'うめ', 'かき',
  'オリーブ', 'かや', 'カリン', 'クロマツ', 'キンモクセイ',
  'くるみ', 'さくら', 'しい', 'すいかずら', 'センリョウ',
  'タイサンボク', 'つばき', 'ときわまんさく', 'ひのき', 'ぶな',
  'プラタナス', 'もみじ', 'もくれん', 'メタセコイア', 'ブルーベリー',
  'やつで', 'ユーカリ', 'ライラック',
],
```


こうしてください。

```javascript
labels: [
  'いちい', 'あすなろ', 'いちょう', 'うめ', 'かき',
  'オリーブ', 'かや', 'カリン', 'クロマツ', 'キンモクセイ',
  'くるみ', 'さくら', 'しい', 'すいかずら', 'センリョウ',
  'タイサンボク', 'つばき', 'ときわまんさく', 'ひのき', 'ぶな',
  'プラタナス', 'もみじ', 'もくれん', 'メタセコイア', 'ブルーベリー',
  'やつで', 'ユーカリ', 'ライラック',
].map((v)=>v.split("")),            // ← 一撃必殺！！
```

IE系ではこうですね。

```javascript
].map( function(v) { return v.split("") } ), 
```

## おまけ

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/129854/05c22778-2e27-95f6-2f00-d390c21dd90e.png)


「なんでやねん、長音が横向きやんけ」

と、遠い空からツッコミが……。

そこはローテクに置き換えてくださいね。

```javascript
  'やつで', 'ユーカリ', 'ライラック',
].map((v)=>v.replace('ー','丨').split("")), // 長音を「いちぼう」に置き換え
```

他にもカッコとかいろいろ対応に迫られることもあります。

「一撃必殺ちゃうやんけ」

……う、うるさい。言いたかっただけなんだ。


# 解説

Chart.jsは英語文化圏のライブラリなので「縦書き」という特殊ローカル言語圏の作法に対応しているはずないじゃないか。と、長いこと思っていました……。

## デフォルト

何もしないとこのような表示。回転してくれます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/129854/7da25a36-5271-0d83-da1f-9d187a0d107a.png)


## 90°回転

「待て待て、回転せんでええから。縦に真っ直ぐにしといて。」

そんなケースは世界中で発生するようで、Stackoverflowにも回答例がたくさんあります。

```javascript
scales: {
  xAxes: [{
    ticks: {
      maxRotation: 90, // 自動的に回転する角度を固定
      minRotation: 90,
    }
  }],
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/129854/859d084c-63e7-ca87-20f6-244439785bd5.png)


## 改造しかない？

「待てコラ。なんやこれ？ 顔を横にして読むんか！？」

まったくだ。ここは日本なんだ。
縦に横書きする人なんていないんだ！

と、お客様の怒りの矛先をライブラリに向けてもお客様は全然納得してくれません……。

しょうがないなー。検索しても出てこないし。
こりゃライブラリを改造するしかないな、とソースコードを開いてみたら、なんとそれっぽいのがあるじゃないですか！？

```javascript:Chart.min.js
var n = t.label
, a = t.textOffset;
if (ut.isArray(n)) // ラベルが array だったら
  for (var o = 0; o < n.length; ++o)
      s.fillText("" + n[o], 0, a), // ずらしながら表示？
      a += k;
else
  s.fillText(n, 0, a);
```

で、ためしにラベルを1文字ずつ分割して与えてみたら

```javascript
labels: [
  ['い','ち','い'], ['あ','す','な','ろ'], ...
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/129854/a731248e-6411-ba0f-a20c-f6d4c68b3cb6.png)


できちゃった！というお話です。

## たぶん

「複数行」表示するための機能じゃないかな、と思います。

```javascript
labels: [
['いちい','にい','さんい'], 'あすなろ', 'いちょう', 'うめ', 'かき',
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/129854/c3718050-8957-4c5e-c0d6-d28ceed432c0.png)



## 追加オプションと全体のコード

これだけでもちゃんと表示されますが、データが増えても向きと表示を保つように下記オプションを入れておきましょう。

```javascript
scales: {
    xAxes: [{ // ★ 推奨オプション
      ticks: {
        autoSkip: false, // 狭くてもラベルを省略しない
        maxRotation: 0,  // 縦書きなので縦向きに固定
        minRotation: 0,
      }
    }],
```

元のコードは、「 [chart.js で複数軸の複合グラフを描く](https://qiita.com/kd9951/items/aece80abe0bd42b3b5d3) 」で作ったものです。★が変更箇所。


```html:sample_chart.html
<!-- ★ Ver.2.5にアップ -->
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.5.0/Chart.bundle.min.js"></script>


<div class="container" style="width:100%">
    <canvas id="canvas"></canvas>
</div>



<script>
window.onload = function() {
    ctx = document.getElementById("canvas").getContext("2d");
    window.myBar = new Chart(ctx, {
        type: 'bar',
        data: barChartData,
        options: complexChartOption
    });
};
</script>



<script>
// とある4週間分のデータログ
var barChartData = {
    labels: [
      'いちい', 'あすなろ', 'いちょう', 'うめ', 'かき',
      'オリーブ', 'かや', 'カリン', 'クロマツ', 'キンモクセイ',
      'くるみ', 'さくら', 'しい', 'すいかずら', 'センリョウ',
      'タイサンボク', 'つばき', 'ときわまんさく', 'ひのき', 'ぶな',
      'プラタナス', 'もみじ', 'もくれん', 'メタセコイア', 'ブルーベリー',
      'やつで', 'ユーカリ', 'ライラック',
     ].map((v)=>v.replace('ー','丨').split("")), // ★ 長音をいちぼうに置き換えながら分割
    datasets: [
    {
        type: 'line',
        label: 'sample-line',
        data: ['0.155','0.118','0.121','0.068','0.083','0.060','0.067',
            '0.121','0.121','0.150','0.118','0.097','0.078','0.127',
            '0.155','0.140','0.101','0.140','0.041','0.093','0.189',
            '0.146','0.134','0.127','0.116','0.111','0.125','0.116'
        ],
        borderColor : "rgba(254,97,132,0.8)",
                pointBackgroundColor    : "rgba(254,97,132,0.8)",
                fill: false,
        yAxisID: "y-axis-1",
    },
    {
        type: 'bar',
        label: 'sample-bar',
        data: ['0.3','0.1','0.1','0.3','0.4','0.2','0.0',
            '0.2','0.3','0.11','0.5','0.2','0.5','0.4',
            '0.0','0.3','0.7','0.3','0.6','0.4','0.9',
            '0.7','0.4','0.8','0.7','0.4','0.7','0.8'
        ],
        borderColor : "rgba(54,164,235,0.8)",
        backgroundColor : "rgba(54,164,235,0.5)",
        yAxisID: "y-axis-2",
    },
    ],
};
</script>



<script>
var complexChartOption = {
    responsive: true,
    scales: {
        xAxes: [{ // ★ 推奨オプション
           ticks: {
            autoSkip: false,
            maxRotation: 0,
            minRotation: 0,
          }
        }],
        yAxes: [{
            id: "y-axis-1",
            type: "linear", 
            position: "left",
            ticks: {
                max: 0.2,
                min: 0,
                stepSize: 0.1
            },
        }, {
            id: "y-axis-2",
            type: "linear", 
            position: "right",
            ticks: {
                max: 1.5,
                min: 0,
                stepSize: .5
            },
            gridLines: {
                drawOnChartArea: false, 
            },
        }],
    }
};
</script>
```


ちなみに、Chart.jsのバージョンが2.5未満だと、縦書きは出来るけど上揃えになりません。新しいバージョンを使いましょう。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/129854/f767c34a-471e-cbff-eb54-86d24931abcf.png)


# 感想

Google先生が知らないこと＝世界中の誰も知らない事、のような気がしてしまうけど、その未知の世界は難攻不落の未解決問題ではなく、やってみたらあっけなく解決してしまうようなことだったりすることもあります。

穴埋め係冥利に尽きる課題でした。ありがとうございます☺

＃あまりにあっけなさすぎるので「そんなのは世の中の常識！知らないのはオマエだけ！」（Google先生含めて世界中の人が僕をダマそうとしている？！）という気がしてならないのですが、もしそうだったとしてもそっとしておいてやってください……。