LoginSignup
27
15

More than 3 years have passed since last update.

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

Last updated at Posted at 2019-04-26

なにがしたい?

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

image.png

結論

ラベルを…

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

こうしてください。

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

IE系ではこうですね。

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

おまけ

image.png

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

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

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

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

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

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

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

解説

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

デフォルト

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

image.png

90°回転

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

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

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

image.png

改造しかない?

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

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

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

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

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文字ずつ分割して与えてみたら

labels: [
  ['','',''], ['','','',''], ...

image.png

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

たぶん

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

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

image.png

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

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

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

元のコードは、「 chart.js で複数軸の複合グラフを描く 」で作ったものです。★が変更箇所。

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

感想

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

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

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

27
15
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
27
15