简体   繁体   中英

How to Format X-axis tick values in C3.js

Is it possible to change formatting of ticks in c3.js. For example Can I make part of tick bold ? My chart has date and text at x-axis.. how Can I make dates bolder and change the ticks so that the text appears below the date?

change

Feb 01 Primaries and Caucuses 

to

       Feb 01
Primaries and Caucuses

js fiddle:

var chart = c3.generate({
         bindto: '#chart',
    data: {
      x: 'x',
        columns: [
        ["x", "2016-01-04", "2016-01-05", "2016-01-06", "2016-01-07", "2016-01-08", "2016-01-09", "2016-01-10", "2016-01-11", "2016-01-12", "2016-01-13", "2016-01-14", "2016-01-15", "2016-01-16", "2016-01-17", "2016-01-18", "2016-01-19", "2016-01-20", "2016-01-21", "2016-01-22", "2016-01-23", "2016-01-24", "2016-01-25", "2016-01-26", "2016-01-27", "2016-01-28", "2016-01-29", "2016-01-30", "2016-01-31", "2016-02-01", "2016-02-02", "2016-02-03"],
         ["Democrates", 49.85, 49.89, 49.82, 49.51, 49.42, 49.33, 49.24, 49.64, 49.57, 49.57, 49.01, 48.67, 48.7, 48.7, 48.7, 48.63, 48.63, 48.63, 48.63, 48.63, 48.61, 48.61, 48.68, 48.76, 48.84, 48.73, 48.76, 48.79, 48.81, 49.68, 49.63],
         ["Republicans", "50.15", "50.11", "50.18", "50.49", "50.58", "50.67", "50.76", "50.36", "50.43", "50.43", "50.99", "51.33", "51.30", "51.30", "51.30", "51.37", "51.37", "51.37", "51.37", "51.37", "51.39", "51.39", "51.32", "51.24", "51.16", "51.27", "51.24", "51.21", "51.19", "50.32", "50.37"]
        ],
         colors: {
            Democrates: '#4575b4',
            Republicans: '#d73027'
        },
    },
    axis: {
        x: {
            type: 'timeseries',
             max: '2016-11-08',
            tick: {
               values: ["2016-02-01", "2016-06-14", "2016-11-08", "2016-09-26", "2016-10-19", "2016-07-18", "2016-07-28" ],
                format: function (x) {
                  if (x == "Mon Feb 01 2016 00:00:00 GMT+0100 (CET)"){
                  return 'Feb 01' + 'Primaries and Caucuses '
                } else if (x == "Tue Nov 08 2016 00:00:00 GMT+0100 (CET)") {
                   return 'Nov 08 Election Day'

                } else if (x == "Mon Sep 26 2016 00:00:00 GMT+0200 (CEST)") {
                   return ' Sep 26 Start of Presidential Debates'

                } else if (x == "Mon Jul 18 2016 00:00:00 GMT+0200 (CEST)") {
                   return 'Jul 25 Announcement of Nominees'

                } else {
                  var format=  d3.time.format("%b %d");
                                var date = format(x)
                                return date
                }},
                fit: false
        }
        }
    },
    grid: {
     y: {
        lines: [
                {value: 50},

            ]
     },
     x: {
    lines: [
      {value: "2016-01-08", text: "Want to rorate this text in 180 degrees",
      class: "xLineLable", position: "end"}


    ]
  }
  }
});

Disclaimers: this is an incomplete answer, and I've never used c3.js (only d3.js), so I don't know if that changes anything.

Short answer is, no, there's no direct way to do that that I know of (especially since multi-line text is a real pain in svg)

But , if you feel like taking the long road, there is a way:

  • create your ticks as you do now, with the addition of a special character where you want a line-break. (A non-secable space would do the trick).

  • select the tick elements: d3.selectAll(".x .tick text")

  • for each one of them:

    • extract the text into a variable,
    • insert a "<tspan>" at the beginning and "</tspan>" in the end
    • do search & replace to replace your dummy characters by "</tspan><tspan>"
    • insert the new value as html for the tick elements.

This is not sufficient in itself, since tspans need to come with a whole system of coordinates and alignment (that I don't understand well enough to put in an answer), plus if you want some bold text you need to apply text style.... but one day or another it will get you there...(good luck!)

In order to do this, we can use d3 selections or another library to force the line break, format the first line and subsequent lines.

data.axis.x.tick.multiline = false forces the original c3.generate() to single lines, we use our code to fix this.

fixLabels() is called multiple times to avoid problems with window resizing. I'm sure this could be improved upon.

Please note, I forced the label checking to YYYYMMDD format, to allow for multiple timezones. The original code didn't work for me, as I'm in BST.

 var splitter = "~"; // choose a character unlikely to appear in your label var chart = c3.generate({ bindto: '#chart', data: { x: 'x', columns: [ ["x", "2016-01-04", "2016-01-05", "2016-01-06", "2016-01-07", "2016-01-08", "2016-01-09", "2016-01-10", "2016-01-11", "2016-01-12", "2016-01-13", "2016-01-14", "2016-01-15", "2016-01-16", "2016-01-17", "2016-01-18", "2016-01-19", "2016-01-20", "2016-01-21", "2016-01-22", "2016-01-23", "2016-01-24", "2016-01-25", "2016-01-26", "2016-01-27", "2016-01-28", "2016-01-29", "2016-01-30", "2016-01-31", "2016-02-01", "2016-02-02", "2016-02-03"], ["Democrates", 49.85, 49.89, 49.82, 49.51, 49.42, 49.33, 49.24, 49.64, 49.57, 49.57, 49.01, 48.67, 48.7, 48.7, 48.7, 48.63, 48.63, 48.63, 48.63, 48.63, 48.61, 48.61, 48.68, 48.76, 48.84, 48.73, 48.76, 48.79, 48.81, 49.68, 49.63], ["Republicans", "50.15", "50.11", "50.18", "50.49", "50.58", "50.67", "50.76", "50.36", "50.43", "50.43", "50.99", "51.33", "51.30", "51.30", "51.30", "51.37", "51.37", "51.37", "51.37", "51.37", "51.39", "51.39", "51.32", "51.24", "51.16", "51.27", "51.24", "51.21", "51.19", "50.32", "50.37"] ], colors: { Democrates: '#4575b4', Republicans: '#d73027' }, }, axis: { x: { type: 'timeseries', max: '2016-12-08', tick: { values: ["2016-02-01", "2016-06-14", "2016-11-08", "2016-09-26", "2016-10-19", "2016-07-28" ], format: function (x) { // calling this here may seem odd. This forces // re-format of the labels even on window or container resize. fixLabels(); var Ymdformat = d3.time.format("%Y%m%d"); if (Ymdformat(x) == "20160201"){ return 'Feb 01' + splitter + 'Primaries and Caucuses' } else if (Ymdformat(x) == "20161108") { return 'Nov 08' + splitter + 'Election Day' } else if (Ymdformat(x) == "20160926") { return 'Sep 26' + splitter + 'Start of Presidential Debates' } else if (Ymdformat(x) == "20160728") { return 'Jul 28' + splitter + 'Announcement of Nominees' } else { var format = d3.time.format('%b %d'); var date = format(x) return date } }, fit: false, multiline: false } } }, grid: { y: { lines: [ {value: 50}, ] }, x: { lines: [ {value: "2016-01-08", text: "Want to rorate this text in 180 degrees", class: "xLineLable", position: "end"} ] } } }); function fixLabels() { d3.selectAll("text[y='9'] tspan:not(.added)").each(function() { // Get the original label including splitter character(s) text_to_split = this.innerHTML; // Split into an array text_array = text_to_split.split(splitter); // Set first tspan to original label date this.innerHTML = text_array[0]; // Set first tspan to bold text d3.select(this).style("font-weight",600); // Add additional tspans as necessary for ( i = 1; i < text_array.length; i++ ) { d3.select(d3.select(this).node().parentNode) .append("tspan") .attr('x',0) .attr('dy','1em') .attr('dx',0) .attr('class','added') .attr('font-style','italic') .text(text_array[i]); } }); } 
 <script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script> <link href="https://cdnjs.cloudflare.com/ajax/libs/c3/0.4.11/c3.css" rel="stylesheet"/> <script src="https://cdnjs.cloudflare.com/ajax/libs/c3/0.4.11/c3.js"></script> <div id="chart"></div> 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM