diff --git a/spec/axis-spec.js b/spec/axis-spec.js index f56534f..6463fe2 100644 --- a/spec/axis-spec.js +++ b/spec/axis-spec.js @@ -522,6 +522,31 @@ describe('c3 chart axis', function () { }); }); }); + + describe('with multilineMax', function() { + beforeAll(function() { + args.axis.x.tick = { + multiline: true, + multilineMax: 2, + }; + }); + + it('should ellipsify x tick properly', function() { + var tick = chart.internal.main.select('.c3-axis-x').select('g.tick'); + var tspans = tick.selectAll('tspan'); + var expectedTickText = [ + 'this is a very long', + 'tick text on categ...', + ]; + + expect(tspans.size()).toBe(2); + + tspans.each(function (d, i) { + var tspan = d3.select(this); + expect(tspan.text()).toBe(expectedTickText[i]); + }); + }); + }); }); }); diff --git a/src/axis.js b/src/axis.js index eed5a97..93d1562 100644 --- a/src/axis.js +++ b/src/axis.js @@ -111,6 +111,11 @@ c3_axis_internal_fn.isVertical = function () { c3_axis_internal_fn.tspanData = function (d, i, ticks, scale) { var internal = this; var splitted = internal.params.tickMultiline ? internal.splitTickText(d, ticks, scale) : [].concat(internal.textFormatted(d)); + + if (internal.params.tickMultiline && internal.params.tickMultilineMax > 0) { + splitted = internal.ellipsify(splitted, internal.params.tickMultilineMax); + } + return splitted.map(function (s) { return { index: i, splitted: s, length: splitted.length }; }); @@ -150,6 +155,27 @@ c3_axis_internal_fn.splitTickText = function (d, ticks, scale) { return split(splitted, tickText + ""); }; +c3_axis_internal_fn.ellipsify = function(splitted, max) { + if (splitted.length <= max) { + return splitted; + } + + var ellipsified = splitted.slice(0, max); + var remaining = 3; + for (var i = max-1 ; i >= 0 ; i--) { + var available = ellipsified[i].length; + + ellipsified[i] = ellipsified[i].substr(0, available-remaining).padEnd(available, '.'); + + remaining -= available; + + if (remaining <= 0) { + break; + } + } + + return ellipsified; +}; c3_axis_internal_fn.updateTickLength = function () { var internal = this; internal.tickLength = Math.max(internal.innerTickSize, 0) + internal.tickPadding; @@ -422,6 +448,7 @@ c3_axis_fn.getXAxis = function getXAxis(scale, orient, tickFormat, tickValues, w isCategory: $$.isCategorized(), withOuterTick: withOuterTick, tickMultiline: config.axis_x_tick_multiline, + tickMultilineMax: config.axis_x_tick_multiline ? Number(config.axis_x_tick_multilineMax) : 0, tickWidth: config.axis_x_tick_width, tickTextRotate: withoutRotateTickText ? 0 : config.axis_x_tick_rotate, withoutTransition: withoutTransition, diff --git a/src/config.js b/src/config.js index 9d89b8b..ca6e414 100644 --- a/src/config.js +++ b/src/config.js @@ -107,6 +107,7 @@ c3_chart_internal_fn.getDefaultConfig = function () { axis_x_tick_rotate: 0, axis_x_tick_outer: true, axis_x_tick_multiline: true, + axis_x_tick_multilineMax: 0, axis_x_tick_width: null, axis_x_max: undefined, axis_x_min: undefined, diff --git a/src/polyfill.js b/src/polyfill.js index 741cb6e..6678d7d 100644 --- a/src/polyfill.js +++ b/src/polyfill.js @@ -871,4 +871,25 @@ if (!Function.prototype.bind) { } }()); +// String.padEnd polyfill for IE11 +// +// https://github.com/uxitten/polyfill/blob/master/string.polyfill.js +// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/padEnd +if (!String.prototype.padEnd) { + String.prototype.padEnd = function padEnd(targetLength,padString) { + targetLength = targetLength>>0; //floor if number or convert non-number to 0; + padString = String((typeof padString !== 'undefined' ? padString : ' ')); + if (this.length > targetLength) { + return String(this); + } + else { + targetLength = targetLength-this.length; + if (targetLength > padString.length) { + padString += padString.repeat(targetLength/padString.length); //append to original to ensure we are longer than needed + } + return String(this) + padString.slice(0,targetLength); + } + }; +} + /* jshint ignore:end */