Commit 949e1951 authored by Evgeny's avatar Evgeny

Improve x axis label positioning

parent ed58b5c2
...@@ -2816,7 +2816,7 @@ ...@@ -2816,7 +2816,7 @@
if (axisId === 'y2' && !config.axis_y2_show) { return $$.rotated_padding_top; } if (axisId === 'y2' && !config.axis_y2_show) { return $$.rotated_padding_top; }
// Calculate x axis height when tick rotated // Calculate x axis height when tick rotated
if (axisId === 'x' && !config.axis_rotated && config.axis_x_tick_rotate) { if (axisId === 'x' && !config.axis_rotated && config.axis_x_tick_rotate) {
h = $$.getMaxTickWidthAllowed(axisId) * Math.sin(Math.PI * Math.abs(config.axis_x_tick_rotate) / 180); h = $$.getMaxTickWidth(axisId) * Math.sin(Math.PI * Math.abs(config.axis_x_tick_rotate) / 180) + 45;
} }
return h + ($$.getAxisLabelPositionById(axisId).isInner ? 10 : 15) + (axisId === 'y2' ? -10 : 0); return h + ($$.getAxisLabelPositionById(axisId).isInner ? 10 : 15) + (axisId === 'y2' ? -10 : 0);
}; };
...@@ -4875,6 +4875,8 @@ ...@@ -4875,6 +4875,8 @@
if (config.axis_rotated) { if (config.axis_rotated) {
return position.isInner ? "1.2em" : -15 - $$.getMaxTickWidth('x'); return position.isInner ? "1.2em" : -15 - $$.getMaxTickWidth('x');
} else { } else {
var defaultValue = 35;
if(position.isInner){ if(position.isInner){
return "-0.5em"; return "-0.5em";
} }
...@@ -4884,12 +4886,11 @@ ...@@ -4884,12 +4886,11 @@
} }
if(config.axis_x_tick_rotate !== 0){ if(config.axis_x_tick_rotate !== 0){
var coef = $$.getCurrentHeight() / 12; var height = $$.getHorizontalAxisHeight('x');
var v = $$.getMaxTickWidth('x')*Math.sin(Math.abs(Math.PI * config.axis_x_tick_rotate / 180)) + coef; return height - 20;
return v;
} }
return 35; return defaultValue;
} }
}; };
...@@ -4963,6 +4964,9 @@ ...@@ -4963,6 +4964,9 @@
if($$.config.axis_x_tick_format){ if($$.config.axis_x_tick_format){
ticks = ticks.map($$.config.axis_x_tick_format); ticks = ticks.map($$.config.axis_x_tick_format);
} }
ticks = ticks.map($$.shorten.bind($$));
ticks.forEach(function(tick){ ticks.forEach(function(tick){
m = Math.max(m, tick.toString().length); m = Math.max(m, tick.toString().length);
}); });
...@@ -5081,37 +5085,44 @@ ...@@ -5081,37 +5085,44 @@
return; return;
} }
var ticks = $$.getXAxisTickValues(); var ticks = $$.getXAxisTickValues() || [];
var widthForTick = $$.getCurrentWidth() / ticks.length; var widthForTick = $$.getCurrentWidth() / ticks.length;
var maxTickWidth = $$.getMaxTickWidth('x'); var maxTickWidth = $$.getMaxTickWidth('x');
// No overlapping // No overlapping
if(maxTickWidth <= widthForTick){ if(maxTickWidth <= widthForTick){
$$.api.axis.rotateTicks('x', 0, true); $$.config.axis_x_tick_rotate = 0;
return; return;
} }
// No overlapping for rotation 45 // No overlapping for rotation 45
if(45 < widthForTick){ if(45 < widthForTick){
$$.api.axis.rotateTicks('x', -45, true); $$.config.axis_x_tick_rotate = -45;
return; return;
} }
// No overlapping for rotation 90 // No overlapping for rotation 90
if(true){ if(true){
$$.api.axis.rotateTicks('x', -90, true); $$.config.axis_x_tick_rotate = -90;
return; return;
} }
}; };
c3_chart_internal_fn.getMaxTickWidthAllowed = function(){ c3_chart_internal_fn.getMaxTickWidthAllowed = function(){
var $$ = this; var $$ = this;
var widthCoef, heightCoef;
var width = $$.getCurrentWidth();
var ticks = $$.getXAxisTickValues() || [];
var ticksNum = ticks.length;
widthCoef = width / ticksNum;
// Excel shortens ticks the way so they don't take more than half of all chart // Excel shortens ticks the way so they don't take more than half of all chart
var padding = -10; var padding = -10;
var maxWidth = $$.getCurrentHeight()/2 + padding; heightCoef = $$.getCurrentHeight()/2 + padding;
return maxWidth; return Math.max(widthCoef, heightCoef);
}; };
c3_chart_internal_fn.tuneAxis = function(sync, callback){ c3_chart_internal_fn.tuneAxis = function(sync, callback){
...@@ -5306,6 +5317,20 @@ ...@@ -5306,6 +5317,20 @@
$$.cachedRedraw({withLegend: true}); $$.cachedRedraw({withLegend: true});
}; };
c3_chart_internal_fn.shorten = function(text){
var $$ = this;
text = text.toString();
var maxTicks = $$.getMaxTickWidthAllowed() / 11.5;
if(text.length <= maxTicks){
return text;
} else {
return text.slice(0, maxTicks-3) + '...';
}
};
c3_chart_internal_fn.getClipPath = function (id) { c3_chart_internal_fn.getClipPath = function (id) {
return "url(" + (isNode() ? "" : document.URL.split('#')[0]) + "#" + id + ")"; return "url(" + (isNode() ? "" : document.URL.split('#')[0]) + "#" + id + ")";
...@@ -8062,6 +8087,21 @@ ...@@ -8062,6 +8087,21 @@
} }
}; };
c3_chart_fn.axis.rotateTicks = function(axisId, degrees, withoutRedraw){
var $$ = this.internal, config = $$.config;
if(axisId === 'x'){
config.axis_x_tick_rotate = degrees;
} else if(axisId === 'y'){
config.axis_y_tick_rotate = degrees;
} else {
throw new Error("Can't rotate ticks for axis " + axisId);
}
if(!withoutRedraw){
this.flush();
}
};
c3_chart_fn.axis.xFormat = function(value){ c3_chart_fn.axis.xFormat = function(value){
var $$ = this.internal, config = $$.config; var $$ = this.internal, config = $$.config;
...@@ -8123,21 +8163,6 @@ ...@@ -8123,21 +8163,6 @@
$$.redraw(); $$.redraw();
}; };
c3_chart_fn.axis.rotateTicks = function(axisId, degrees, withoutRedraw){
var $$ = this.internal, config = $$.config;
if(axisId === 'x'){
config.axis_x_tick_rotate = degrees;
} else if(axisId === 'y'){
config.axis_y_tick_rotate = degrees;
} else {
throw new Error("Can't rotate ticks for axis " + axisId);
}
if(!withoutRedraw){
this.flush();
}
};
c3_chart_fn.legend = function () {}; c3_chart_fn.legend = function () {};
c3_chart_fn.legend.show = function (targetIds) { c3_chart_fn.legend.show = function (targetIds) {
...@@ -8331,18 +8356,6 @@ ...@@ -8331,18 +8356,6 @@
var start = domain[0], stop = domain[domain.length - 1]; var start = domain[0], stop = domain[domain.length - 1];
return start < stop ? [ start, stop ] : [ stop, start ]; return start < stop ? [ start, stop ] : [ stop, start ];
} }
function shorten(text){
var maxTicks = $$.getMaxTickWidthAllowed() / 11.5;
if(text.length <= maxTicks){
return text;
} else {
return text.slice(0, maxTicks-3) + '...';
}
}
function shouldDrawTickText(id){ function shouldDrawTickText(id){
var heightLimits = [ var heightLimits = [
// Left is width, right is n // Left is width, right is n
...@@ -8494,7 +8507,7 @@ ...@@ -8494,7 +8507,7 @@
tickText = tickText.toString(); tickText = tickText.toString();
tickText = shorten(tickText); tickText = $$.shorten(tickText);
return [tickText]; return [tickText];
} }
...@@ -8533,11 +8546,12 @@ ...@@ -8533,11 +8546,12 @@
tspan.exit().remove(); tspan.exit().remove();
var fontSize = parseFloat(getStyleValue($$, '.c3-axis-y .tick', 'font-size')); var fontSize = parseFloat(getStyleValue($$, '.c3-axis-y .tick', 'font-size'));
var axisId = $$.isXAxis(orient) ? 'x' : 'y';
tspan.text(function (d) { tspan.text(function (d) {
if (d.splitted.length) { if (d.splitted.length) {
var axisId = $$.isXAxis(orient) ? 'x' : 'y';
var rotate = $$.config.axis_x_tick_rotate; var rotate = $$.config.axis_x_tick_rotate;
...@@ -8545,6 +8559,7 @@ ...@@ -8545,6 +8559,7 @@
$$.config.maxTickTextWidth[axisId] || 0, $$.config.maxTickTextWidth[axisId] || 0,
d.splitted.length * fontSize / $$.config.text_h_to_w * Math.cos(rotate) + fontSize * Math.sin(rotate) d.splitted.length * fontSize / $$.config.text_h_to_w * Math.cos(rotate) + fontSize * Math.sin(rotate)
); );
} }
return d.splitted; return d.splitted;
......
This source diff could not be displayed because it is too large. You can view the blob instead.
...@@ -358,51 +358,6 @@ describe('c3 chart axis', function () { ...@@ -358,51 +358,6 @@ describe('c3 chart axis', function () {
}); });
describe('axis.x.tick.rotate', function () {
describe('not rotated', function () {
it('should update args successfully', function () {
args = {
data: {
x: 'x',
columns: [
['x', 'category 1', 'category 2', 'category 3', 'category 4', 'category 5', 'category 6'],
['data1', 30, 200, 100, 400, 150, 250],
['data2', 50, 20, 10, 40, 15, 25]
]
},
axis: {
x: {
type: 'category',
tick: {
rotate: 60
}
}
}
};
expect(true).toBeTruthy();
});
it('should rotate tick texts', function () {
chart.internal.main.selectAll('.c3-axis-x g.tick').each(function () {
var tick = d3.select(this),
text = tick.select('text'),
tspan = text.select('tspan');
expect(text.attr('transform')).toBe('rotate(60)');
expect(text.attr('y')).toBe('1.5');
expect(tspan.attr('dx')).toBe('6.928203230275509');
});
});
it('should have automatically calculated x axis height', function () {
var box = chart.internal.main.select('.c3-axis-x').node().getBoundingClientRect();
expect(box.height).toBeGreaterThan(50);
});
});
});
describe('axis.x.tick.fit', function () { describe('axis.x.tick.fit', function () {
describe('axis.x.tick.fit = true', function () { describe('axis.x.tick.fit = true', function () {
......
...@@ -59,6 +59,21 @@ c3_chart_fn.axis.range = function (range) { ...@@ -59,6 +59,21 @@ c3_chart_fn.axis.range = function (range) {
} }
}; };
c3_chart_fn.axis.rotateTicks = function(axisId, degrees, withoutRedraw){
var $$ = this.internal, config = $$.config;
if(axisId === 'x'){
config.axis_x_tick_rotate = degrees;
} else if(axisId === 'y'){
config.axis_y_tick_rotate = degrees;
} else {
throw new Error("Can't rotate ticks for axis " + axisId);
}
if(!withoutRedraw){
this.flush();
}
};
c3_chart_fn.axis.xFormat = function(value){ c3_chart_fn.axis.xFormat = function(value){
var $$ = this.internal, config = $$.config; var $$ = this.internal, config = $$.config;
...@@ -120,18 +135,3 @@ c3_chart_fn.axisY2 = function(value){ ...@@ -120,18 +135,3 @@ c3_chart_fn.axisY2 = function(value){
$$.redraw(); $$.redraw();
}; };
c3_chart_fn.axis.rotateTicks = function(axisId, degrees, withoutRedraw){
var $$ = this.internal, config = $$.config;
if(axisId === 'x'){
config.axis_x_tick_rotate = degrees;
} else if(axisId === 'y'){
config.axis_y_tick_rotate = degrees;
} else {
throw new Error("Can't rotate ticks for axis " + axisId);
}
if(!withoutRedraw){
this.flush();
}
};
...@@ -253,6 +253,8 @@ c3_chart_internal_fn.dyForXAxisLabel = function () { ...@@ -253,6 +253,8 @@ c3_chart_internal_fn.dyForXAxisLabel = function () {
if (config.axis_rotated) { if (config.axis_rotated) {
return position.isInner ? "1.2em" : -15 - $$.getMaxTickWidth('x'); return position.isInner ? "1.2em" : -15 - $$.getMaxTickWidth('x');
} else { } else {
var defaultValue = 35;
if(position.isInner){ if(position.isInner){
return "-0.5em"; return "-0.5em";
} }
...@@ -262,12 +264,11 @@ c3_chart_internal_fn.dyForXAxisLabel = function () { ...@@ -262,12 +264,11 @@ c3_chart_internal_fn.dyForXAxisLabel = function () {
} }
if(config.axis_x_tick_rotate !== 0){ if(config.axis_x_tick_rotate !== 0){
var coef = $$.getCurrentHeight() / 12; var height = $$.getHorizontalAxisHeight('x');
var v = $$.getMaxTickWidth('x')*Math.sin(Math.abs(Math.PI * config.axis_x_tick_rotate / 180)) + coef; return height - 20;
return v;
} }
return 35; return defaultValue;
} }
}; };
...@@ -341,6 +342,9 @@ c3_chart_internal_fn.getMaxTickWidth = function (id) { ...@@ -341,6 +342,9 @@ c3_chart_internal_fn.getMaxTickWidth = function (id) {
if($$.config.axis_x_tick_format){ if($$.config.axis_x_tick_format){
ticks = ticks.map($$.config.axis_x_tick_format); ticks = ticks.map($$.config.axis_x_tick_format);
} }
ticks = ticks.map($$.shorten.bind($$));
ticks.forEach(function(tick){ ticks.forEach(function(tick){
m = Math.max(m, tick.toString().length); m = Math.max(m, tick.toString().length);
}); });
...@@ -459,37 +463,44 @@ c3_chart_internal_fn.tuneAxisTicks = function(){ ...@@ -459,37 +463,44 @@ c3_chart_internal_fn.tuneAxisTicks = function(){
return; return;
} }
var ticks = $$.getXAxisTickValues(); var ticks = $$.getXAxisTickValues() || [];
var widthForTick = $$.getCurrentWidth() / ticks.length; var widthForTick = $$.getCurrentWidth() / ticks.length;
var maxTickWidth = $$.getMaxTickWidth('x'); var maxTickWidth = $$.getMaxTickWidth('x');
// No overlapping // No overlapping
if(maxTickWidth <= widthForTick){ if(maxTickWidth <= widthForTick){
$$.api.axis.rotateTicks('x', 0, true); $$.config.axis_x_tick_rotate = 0;
return; return;
} }
// No overlapping for rotation 45 // No overlapping for rotation 45
if(45 < widthForTick){ if(45 < widthForTick){
$$.api.axis.rotateTicks('x', -45, true); $$.config.axis_x_tick_rotate = -45;
return; return;
} }
// No overlapping for rotation 90 // No overlapping for rotation 90
if(true){ if(true){
$$.api.axis.rotateTicks('x', -90, true); $$.config.axis_x_tick_rotate = -90;
return; return;
} }
}; };
c3_chart_internal_fn.getMaxTickWidthAllowed = function(){ c3_chart_internal_fn.getMaxTickWidthAllowed = function(){
var $$ = this; var $$ = this;
var widthCoef, heightCoef;
var width = $$.getCurrentWidth();
var ticks = $$.getXAxisTickValues() || [];
var ticksNum = ticks.length;
widthCoef = width / ticksNum;
// Excel shortens ticks the way so they don't take more than half of all chart // Excel shortens ticks the way so they don't take more than half of all chart
var padding = -10; var padding = -10;
var maxWidth = $$.getCurrentHeight()/2 + padding; heightCoef = $$.getCurrentHeight()/2 + padding;
return maxWidth; return Math.max(widthCoef, heightCoef);
}; };
c3_chart_internal_fn.tuneAxis = function(sync, callback){ c3_chart_internal_fn.tuneAxis = function(sync, callback){
...@@ -684,3 +695,17 @@ c3_chart_fn.axisLabelY = function(label) { ...@@ -684,3 +695,17 @@ c3_chart_fn.axisLabelY = function(label) {
$$.cachedRedraw({withLegend: true}); $$.cachedRedraw({withLegend: true});
}; };
c3_chart_internal_fn.shorten = function(text){
var $$ = this;
text = text.toString();
var maxTicks = $$.getMaxTickWidthAllowed() / 11.5;
if(text.length <= maxTicks){
return text;
} else {
return text.slice(0, maxTicks-3) + '...';
}
};
...@@ -34,18 +34,6 @@ function c3_axis(d3, params, $$) { ...@@ -34,18 +34,6 @@ function c3_axis(d3, params, $$) {
var start = domain[0], stop = domain[domain.length - 1]; var start = domain[0], stop = domain[domain.length - 1];
return start < stop ? [ start, stop ] : [ stop, start ]; return start < stop ? [ start, stop ] : [ stop, start ];
} }
function shorten(text){
var maxTicks = $$.getMaxTickWidthAllowed() / 11.5;
if(text.length <= maxTicks){
return text;
} else {
return text.slice(0, maxTicks-3) + '...';
}
}
function shouldDrawTickText(id){ function shouldDrawTickText(id){
var heightLimits = [ var heightLimits = [
// Left is width, right is n // Left is width, right is n
...@@ -197,7 +185,7 @@ function c3_axis(d3, params, $$) { ...@@ -197,7 +185,7 @@ function c3_axis(d3, params, $$) {
tickText = tickText.toString(); tickText = tickText.toString();
tickText = shorten(tickText); tickText = $$.shorten(tickText);
return [tickText]; return [tickText];
} }
...@@ -236,11 +224,12 @@ function c3_axis(d3, params, $$) { ...@@ -236,11 +224,12 @@ function c3_axis(d3, params, $$) {
tspan.exit().remove(); tspan.exit().remove();
var fontSize = parseFloat(getStyleValue($$, '.c3-axis-y .tick', 'font-size')); var fontSize = parseFloat(getStyleValue($$, '.c3-axis-y .tick', 'font-size'));
var axisId = $$.isXAxis(orient) ? 'x' : 'y';
tspan.text(function (d) { tspan.text(function (d) {
if (d.splitted.length) { if (d.splitted.length) {
var axisId = $$.isXAxis(orient) ? 'x' : 'y';
var rotate = $$.config.axis_x_tick_rotate; var rotate = $$.config.axis_x_tick_rotate;
...@@ -248,6 +237,7 @@ function c3_axis(d3, params, $$) { ...@@ -248,6 +237,7 @@ function c3_axis(d3, params, $$) {
$$.config.maxTickTextWidth[axisId] || 0, $$.config.maxTickTextWidth[axisId] || 0,
d.splitted.length * fontSize / $$.config.text_h_to_w * Math.cos(rotate) + fontSize * Math.sin(rotate) d.splitted.length * fontSize / $$.config.text_h_to_w * Math.cos(rotate) + fontSize * Math.sin(rotate)
); );
} }
return d.splitted; return d.splitted;
......
...@@ -86,7 +86,7 @@ c3_chart_internal_fn.getHorizontalAxisHeight = function (axisId) { ...@@ -86,7 +86,7 @@ c3_chart_internal_fn.getHorizontalAxisHeight = function (axisId) {
if (axisId === 'y2' && !config.axis_y2_show) { return $$.rotated_padding_top; } if (axisId === 'y2' && !config.axis_y2_show) { return $$.rotated_padding_top; }
// Calculate x axis height when tick rotated // Calculate x axis height when tick rotated
if (axisId === 'x' && !config.axis_rotated && config.axis_x_tick_rotate) { if (axisId === 'x' && !config.axis_rotated && config.axis_x_tick_rotate) {
h = $$.getMaxTickWidthAllowed(axisId) * Math.sin(Math.PI * Math.abs(config.axis_x_tick_rotate) / 180); h = $$.getMaxTickWidth(axisId) * Math.sin(Math.PI * Math.abs(config.axis_x_tick_rotate) / 180) + 45;
} }
return h + ($$.getAxisLabelPositionById(axisId).isInner ? 10 : 15) + (axisId === 'y2' ? -10 : 0); return h + ($$.getAxisLabelPositionById(axisId).isInner ? 10 : 15) + (axisId === 'y2' ? -10 : 0);
}; };
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment