Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
C
c3-closed
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
charts
c3-closed
Commits
e1e3ddcf
Commit
e1e3ddcf
authored
Oct 27, 2014
by
Masayuki Tanaka
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Support multiple lines tick text on category axis - #139
parent
1f4e2228
Hide whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
538 additions
and
33 deletions
+538
-33
Gruntfile.coffee
Gruntfile.coffee
+1
-0
c3.js
c3.js
+96
-15
c3.min.js
c3.min.js
+0
-0
axis-spec.js
spec/axis-spec.js
+344
-2
legend-spec.js
spec/legend-spec.js
+1
-1
axis.js
src/axis.js
+6
-2
c3.axis.js
src/c3.axis.js
+89
-13
config.js
src/config.js
+1
-0
No files found.
Gruntfile.coffee
View file @
e1e3ddcf
...
...
@@ -85,6 +85,7 @@ module.exports = (grunt) ->
options
:
specs
:
'spec/*-spec.js'
helpers
:
'spec/*-helper.js'
styles
:
'c3.css'
vendor
:
'http://d3js.org/d3.v3.min.js'
uglify
:
...
...
c3.js
View file @
e1e3ddcf
...
...
@@ -975,6 +975,7 @@
axis_x_tick_values
:
null
,
axis_x_tick_rotate
:
undefined
,
axis_x_tick_outer
:
true
,
axis_x_tick_width
:
80
,
axis_x_max
:
undefined
,
axis_x_min
:
undefined
,
axis_x_padding
:
{},
...
...
@@ -3893,7 +3894,11 @@
};
c3_chart_internal_fn
.
getXAxis
=
function
(
scale
,
orient
,
tickFormat
,
tickValues
,
withOuterTick
)
{
var
$$
=
this
,
config
=
$$
.
config
,
axisParams
=
{
isCategory
:
$$
.
isCategorized
(),
withOuterTick
:
withOuterTick
},
axisParams
=
{
isCategory
:
$$
.
isCategorized
(),
withOuterTick
:
withOuterTick
,
tickWidth
:
$$
.
isCategorized
()
?
config
.
axis_x_tick_width
:
undefined
},
axis
=
c3_axis
(
$$
.
d3
,
axisParams
).
scale
(
scale
).
orient
(
orient
);
if
(
$$
.
isTimeSeries
()
&&
tickValues
)
{
...
...
@@ -4129,7 +4134,7 @@
axis
=
$$
.
getXAxis
(
scale
,
$$
.
xOrient
,
$$
.
getXAxisTickFormat
(),
$$
.
getXAxisTickValues
());
}
$$
.
d3
.
select
(
'body'
).
append
(
"g"
).
style
(
'visibility'
,
'hidden'
).
call
(
axis
).
each
(
function
()
{
$$
.
d3
.
select
(
this
).
selectAll
(
'text'
).
each
(
function
()
{
$$
.
d3
.
select
(
this
).
selectAll
(
'text
tspan
'
).
each
(
function
()
{
var
box
=
this
.
getBoundingClientRect
();
if
(
box
.
left
>
0
&&
maxWidth
<
box
.
width
)
{
maxWidth
=
box
.
width
;
}
});
...
...
@@ -6343,6 +6348,23 @@
function
textFormatted
(
v
)
{
return
tickFormat
?
tickFormat
(
v
)
:
v
;
}
function
getSizeFor1Char
(
tick
)
{
var
size
=
{
h
:
11.5
,
w
:
5.5
};
tick
.
select
(
'text'
).
text
(
textFormatted
).
each
(
function
(
d
)
{
var
box
=
this
.
getBoundingClientRect
(),
text
=
textFormatted
(
d
),
h
=
box
.
height
,
w
=
text
?
(
box
.
width
/
text
.
length
)
:
undefined
;
if
(
h
&&
w
)
{
size
.
h
=
h
;
size
.
w
=
w
;
}
}).
text
(
''
);
return
size
;
}
function
axis
(
g
)
{
g
.
each
(
function
()
{
var
g
=
d3
.
select
(
this
);
...
...
@@ -6364,7 +6386,6 @@
var
lineEnter
=
tickEnter
.
select
(
"line"
),
lineUpdate
=
tickUpdate
.
select
(
"line"
),
text
=
tick
.
select
(
"text"
).
text
(
textFormatted
),
textEnter
=
tickEnter
.
select
(
"text"
),
textUpdate
=
tickUpdate
.
select
(
"text"
);
...
...
@@ -6376,20 +6397,77 @@
tickOffset
=
tickX
=
0
;
}
var
text
,
tspan
,
sizeFor1Char
=
getSizeFor1Char
(
tick
),
counts
=
[];
var
tickLength
=
Math
.
max
(
innerTickSize
,
0
)
+
tickPadding
,
isVertical
=
orient
===
'left'
||
orient
===
'right'
;
// this should be called only when category axis
function
splitTickText
(
d
)
{
var
tickText
=
textFormatted
(
d
)
+
""
,
maxWidth
=
isVertical
?
params
.
tickWidth
:
tickOffset
*
2
-
10
,
subtext
,
spaceIndex
,
textWidth
,
splitted
=
[];
function
split
(
splitted
,
text
)
{
spaceIndex
=
undefined
;
for
(
var
i
=
0
;
i
<
text
.
length
;
i
++
)
{
if
(
text
.
charAt
(
i
)
===
' '
)
{
spaceIndex
=
i
;
}
subtext
=
text
.
substr
(
0
,
i
+
1
);
textWidth
=
sizeFor1Char
.
w
*
subtext
.
length
;
// if text width gets over tick width, split by space index or crrent index
if
(
maxWidth
<
textWidth
)
{
return
split
(
splitted
.
concat
(
text
.
substr
(
0
,
spaceIndex
?
spaceIndex
:
i
)),
text
.
slice
(
spaceIndex
?
spaceIndex
+
1
:
i
)
);
}
}
return
splitted
.
concat
(
text
);
}
return
split
(
splitted
,
tickText
);
}
function
tspanDy
(
d
,
i
)
{
var
dy
=
sizeFor1Char
.
h
;
if
(
i
===
0
)
{
if
(
orient
===
'left'
||
orient
===
'right'
)
{
dy
=
-
((
counts
[
d
.
index
]
-
1
)
*
(
sizeFor1Char
.
h
/
2
)
-
(
params
.
isCategory
?
2
:
3
));
}
else
{
dy
=
params
.
isCategory
?
".40em"
:
".71em"
;
}
}
return
dy
;
}
function
tickSize
(
d
)
{
var
tickPosition
=
scale
(
d
)
+
tickOffset
;
return
range
[
0
]
<
tickPosition
&&
tickPosition
<
range
[
1
]
?
innerTickSize
:
0
;
}
text
=
tick
.
select
(
"text"
);
tspan
=
text
.
selectAll
(
'tspan'
)
.
data
(
function
(
d
,
i
)
{
var
splitted
=
params
.
tickWidth
?
splitTickText
(
d
)
:
[
textFormatted
(
d
)];
counts
[
i
]
=
splitted
.
length
;
return
splitted
.
map
(
function
(
s
)
{
return
{
index
:
i
,
splitted
:
s
};
});
})
.
enter
().
append
(
'tspan'
)
.
text
(
function
(
d
)
{
return
d
.
splitted
;
});
switch
(
orient
)
{
case
"bottom"
:
{
tickTransform
=
axisX
;
lineEnter
.
attr
(
"y2"
,
innerTickSize
);
textEnter
.
attr
(
"y"
,
Math
.
max
(
innerTickSize
,
0
)
+
tickPadding
);
textEnter
.
attr
(
"y"
,
tickLength
);
lineUpdate
.
attr
(
"x1"
,
tickX
).
attr
(
"x2"
,
tickX
).
attr
(
"y2"
,
tickSize
);
textUpdate
.
attr
(
"x"
,
0
).
attr
(
"y"
,
Math
.
max
(
innerTickSize
,
0
)
+
tickPadding
);
text
.
attr
(
"dy"
,
".71em"
).
style
(
"text-anchor"
,
"middle"
);
textUpdate
.
attr
(
"x"
,
0
).
attr
(
"y"
,
tickLength
);
text
.
style
(
"text-anchor"
,
"middle"
);
tspan
.
attr
(
'x'
,
0
).
attr
(
"dy"
,
tspanDy
);
pathUpdate
.
attr
(
"d"
,
"M"
+
range
[
0
]
+
","
+
outerTickSize
+
"V0H"
+
range
[
1
]
+
"V"
+
outerTickSize
);
break
;
}
...
...
@@ -6397,10 +6475,11 @@
{
tickTransform
=
axisX
;
lineEnter
.
attr
(
"y2"
,
-
innerTickSize
);
textEnter
.
attr
(
"y"
,
-
(
Math
.
max
(
innerTickSize
,
0
)
+
tickPadding
)
);
textEnter
.
attr
(
"y"
,
-
tickLength
);
lineUpdate
.
attr
(
"x2"
,
0
).
attr
(
"y2"
,
-
innerTickSize
);
textUpdate
.
attr
(
"x"
,
0
).
attr
(
"y"
,
-
(
Math
.
max
(
innerTickSize
,
0
)
+
tickPadding
));
text
.
attr
(
"dy"
,
"0em"
).
style
(
"text-anchor"
,
"middle"
);
textUpdate
.
attr
(
"x"
,
0
).
attr
(
"y"
,
-
tickLength
);
text
.
style
(
"text-anchor"
,
"middle"
);
tspan
.
attr
(
'x'
,
0
).
attr
(
"dy"
,
"0em"
);
pathUpdate
.
attr
(
"d"
,
"M"
+
range
[
0
]
+
","
+
-
outerTickSize
+
"V0H"
+
range
[
1
]
+
"V"
+
-
outerTickSize
);
break
;
}
...
...
@@ -6408,10 +6487,11 @@
{
tickTransform
=
axisY
;
lineEnter
.
attr
(
"x2"
,
-
innerTickSize
);
textEnter
.
attr
(
"x"
,
-
(
Math
.
max
(
innerTickSize
,
0
)
+
tickPadding
)
);
textEnter
.
attr
(
"x"
,
-
tickLength
);
lineUpdate
.
attr
(
"x2"
,
-
innerTickSize
).
attr
(
"y1"
,
tickY
).
attr
(
"y2"
,
tickY
);
textUpdate
.
attr
(
"x"
,
-
(
Math
.
max
(
innerTickSize
,
0
)
+
tickPadding
)).
attr
(
"y"
,
tickOffset
);
text
.
attr
(
"dy"
,
".32em"
).
style
(
"text-anchor"
,
"end"
);
textUpdate
.
attr
(
"x"
,
-
tickLength
).
attr
(
"y"
,
tickOffset
);
text
.
style
(
"text-anchor"
,
"end"
);
tspan
.
attr
(
'x'
,
-
tickLength
).
attr
(
"dy"
,
tspanDy
);
pathUpdate
.
attr
(
"d"
,
"M"
+
-
outerTickSize
+
","
+
range
[
0
]
+
"H0V"
+
range
[
1
]
+
"H"
+
-
outerTickSize
);
break
;
}
...
...
@@ -6419,10 +6499,11 @@
{
tickTransform
=
axisY
;
lineEnter
.
attr
(
"x2"
,
innerTickSize
);
textEnter
.
attr
(
"x"
,
Math
.
max
(
innerTickSize
,
0
)
+
tickPadding
);
textEnter
.
attr
(
"x"
,
tickLength
);
lineUpdate
.
attr
(
"x2"
,
innerTickSize
).
attr
(
"y2"
,
0
);
textUpdate
.
attr
(
"x"
,
Math
.
max
(
innerTickSize
,
0
)
+
tickPadding
).
attr
(
"y"
,
0
);
text
.
attr
(
"dy"
,
".32em"
).
style
(
"text-anchor"
,
"start"
);
textUpdate
.
attr
(
"x"
,
tickLength
).
attr
(
"y"
,
0
);
text
.
style
(
"text-anchor"
,
"start"
);
tspan
.
attr
(
'x'
,
tickLength
).
attr
(
"dy"
,
tspanDy
);
pathUpdate
.
attr
(
"d"
,
"M"
+
outerTickSize
+
","
+
range
[
0
]
+
"H0V"
+
range
[
1
]
+
"H"
+
outerTickSize
);
break
;
}
...
...
c3.min.js
View file @
e1e3ddcf
This source diff could not be displayed because it is too large. You can
view the blob
instead.
spec/axis-spec.js
View file @
e1e3ddcf
...
...
@@ -32,10 +32,19 @@ describe('c3 chart axis', function () {
}
};
beforeEach
(
function
()
{
window
.
initDom
();
beforeEach
(
function
(
done
)
{
if
(
typeof
chart
===
'undefined'
)
{
window
.
initDom
();
}
chart
=
window
.
c3
.
generate
(
args
);
d3
=
chart
.
internal
.
d3
;
chart
.
internal
.
d3
.
select
(
'.jasmine_html-reporter'
)
.
style
(
'position'
,
'absolute'
)
.
style
(
'right'
,
0
);
window
.
setTimeout
(
function
()
{
done
();
},
10
);
});
describe
(
'axis.y.tick.count'
,
function
()
{
...
...
@@ -87,4 +96,337 @@ describe('c3 chart axis', function () {
});
describe
(
'axis.x.tick.width'
,
function
()
{
describe
(
'indexed x axis and y/y2 axis'
,
function
()
{
describe
(
'not rotated'
,
function
()
{
it
(
'should update args successfully'
,
function
()
{
args
=
{
data
:
{
columns
:
[
[
'data1'
,
30
,
200
,
100
,
400
,
150
,
250
],
[
'data2'
,
50
,
20
,
10
,
40
,
15
,
25
]
],
axes
:
{
data2
:
'y2'
}
},
axis
:
{
y2
:
{
show
:
true
}
}
};
expect
(
true
).
toBeTruthy
();
});
it
(
'should construct indexed x axis properly'
,
function
()
{
var
ticks
=
chart
.
internal
.
main
.
select
(
'.c3-axis-x'
).
selectAll
(
'g.tick'
),
expectedX
=
'0'
,
expectedDy
=
'.71em'
;
expect
(
ticks
.
size
()).
toBe
(
6
);
ticks
.
each
(
function
(
d
,
i
)
{
var
tspans
=
d3
.
select
(
this
).
selectAll
(
'tspan'
);
expect
(
tspans
.
size
()).
toBe
(
1
);
tspans
.
each
(
function
()
{
var
tspan
=
d3
.
select
(
this
);
expect
(
tspan
.
text
()).
toBe
(
i
+
''
);
expect
(
tspan
.
attr
(
'x'
)).
toBe
(
expectedX
);
expect
(
tspan
.
attr
(
'dy'
)).
toBe
(
expectedDy
);
});
});
});
it
(
'should set axis.x.tick.format'
,
function
()
{
args
.
axis
.
x
=
{
tick
:
{
format
:
function
()
{
return
'very long tick text on x axis'
;
}
}
};
expect
(
true
).
toBeTruthy
();
});
it
(
'should not split x axis tick text to multiple lines'
,
function
()
{
var
ticks
=
chart
.
internal
.
main
.
select
(
'.c3-axis-x'
).
selectAll
(
'g.tick'
),
expectedX
=
'0'
,
expectedDy
=
'.71em'
;
expect
(
ticks
.
size
()).
toBe
(
6
);
ticks
.
each
(
function
()
{
var
tspans
=
d3
.
select
(
this
).
selectAll
(
'tspan'
);
expect
(
tspans
.
size
()).
toBe
(
1
);
tspans
.
each
(
function
()
{
var
tspan
=
d3
.
select
(
this
);
expect
(
tspan
.
text
()).
toBe
(
'very long tick text on x axis'
);
expect
(
tspan
.
attr
(
'x'
)).
toBe
(
expectedX
);
expect
(
tspan
.
attr
(
'dy'
)).
toBe
(
expectedDy
);
});
});
});
it
(
'should construct y axis properly'
,
function
()
{
var
ticks
=
chart
.
internal
.
main
.
select
(
'.c3-axis-y'
).
selectAll
(
'g.tick'
),
expectedX
=
'-9'
,
expectedDy
=
'3'
;
expect
(
ticks
.
size
()).
toBe
(
9
);
ticks
.
each
(
function
(
d
)
{
var
tspans
=
d3
.
select
(
this
).
selectAll
(
'tspan'
);
expect
(
tspans
.
size
()).
toBe
(
1
);
tspans
.
each
(
function
()
{
var
tspan
=
d3
.
select
(
this
);
expect
(
tspan
.
text
()).
toBe
(
d
+
''
);
expect
(
tspan
.
attr
(
'x'
)).
toBe
(
expectedX
);
expect
(
tspan
.
attr
(
'dy'
)).
toBe
(
expectedDy
);
});
});
});
it
(
'should construct y2 axis properly'
,
function
()
{
var
ticks
=
chart
.
internal
.
main
.
select
(
'.c3-axis-y2'
).
selectAll
(
'g.tick'
),
expectedX
=
'9'
,
expectedDy
=
'3'
;
expect
(
ticks
.
size
()).
toBe
(
9
);
ticks
.
each
(
function
(
d
)
{
var
tspans
=
d3
.
select
(
this
).
selectAll
(
'tspan'
);
expect
(
tspans
.
size
()).
toBe
(
1
);
tspans
.
each
(
function
()
{
var
tspan
=
d3
.
select
(
this
);
expect
(
tspan
.
text
()).
toBe
(
d
+
''
);
expect
(
tspan
.
attr
(
'x'
)).
toBe
(
expectedX
);
expect
(
tspan
.
attr
(
'dy'
)).
toBe
(
expectedDy
);
});
});
});
it
(
'should set big values in y'
,
function
()
{
args
.
data
.
columns
=
[
[
'data1'
,
3000000000000000
,
200
,
100
,
400
,
150
,
250
],
[
'data2'
,
50
,
20
,
10
,
40
,
15
,
25
]
];
expect
(
true
).
toBeTruthy
();
});
it
(
'should not split y axis tick text to multiple lines'
,
function
()
{
var
ticks
=
chart
.
internal
.
main
.
select
(
'.c3-axis-y2'
).
selectAll
(
'g.tick'
);
ticks
.
each
(
function
()
{
var
tspans
=
d3
.
select
(
this
).
selectAll
(
'tspan'
);
expect
(
tspans
.
size
()).
toBe
(
1
);
});
});
});
describe
(
'rotated'
,
function
()
{
it
(
'should update args to rotate axis'
,
function
()
{
args
.
axis
.
rotated
=
true
;
expect
(
true
).
toBeTruthy
();
});
it
(
'should not split x axis tick text to multiple lines'
,
function
()
{
var
ticks
=
chart
.
internal
.
main
.
select
(
'.c3-axis-x'
).
selectAll
(
'g.tick'
),
expectedX
=
'-9'
,
expectedDy
=
'3'
;
expect
(
ticks
.
size
()).
toBe
(
6
);
ticks
.
each
(
function
()
{
var
tspans
=
d3
.
select
(
this
).
selectAll
(
'tspan'
);
expect
(
tspans
.
size
()).
toBe
(
1
);
tspans
.
each
(
function
()
{
var
tspan
=
d3
.
select
(
this
);
expect
(
tspan
.
text
()).
toBe
(
'very long tick text on x axis'
);
expect
(
tspan
.
attr
(
'x'
)).
toBe
(
expectedX
);
expect
(
tspan
.
attr
(
'dy'
)).
toBe
(
expectedDy
);
});
});
});
it
(
'should not split y axis tick text to multiple lines'
,
function
()
{
var
ticks
=
chart
.
internal
.
main
.
select
(
'.c3-axis-y'
).
selectAll
(
'g.tick'
),
expectedTexts
=
[
'0'
,
'500000000000000'
,
'1000000000000000'
,
'1500000000000000'
,
'2000000000000000'
,
'2500000000000000'
,
'3000000000000000'
],
expectedX
=
'0'
,
expectedDy
=
'.71em'
;
expect
(
ticks
.
size
()).
toBe
(
7
);
ticks
.
each
(
function
(
d
,
i
)
{
var
tspans
=
d3
.
select
(
this
).
selectAll
(
'tspan'
);
expect
(
tspans
.
size
()).
toBe
(
1
);
tspans
.
each
(
function
()
{
var
tspan
=
d3
.
select
(
this
);
expect
(
tspan
.
text
()).
toBe
(
expectedTexts
[
i
]);
expect
(
tspan
.
attr
(
'x'
)).
toBe
(
expectedX
);
expect
(
tspan
.
attr
(
'dy'
)).
toBe
(
expectedDy
);
});
});
});
});
});
describe
(
'category axis'
,
function
()
{
describe
(
'not rotated'
,
function
()
{
it
(
'should update args successfully'
,
function
()
{
args
=
{
data
:
{
x
:
'x'
,
columns
:
[
[
'x'
,
'this is a very long tick text on category axis'
,
'cat1'
,
'cat2'
,
'cat3'
,
'cat4'
,
'cat5'
],
[
'data1'
,
30
,
200
,
100
,
400
,
150
,
250
],
[
'data2'
,
50
,
20
,
10
,
40
,
15
,
25
]
]
},
axis
:
{
x
:
{
type
:
'category'
}
}
};
expect
(
true
).
toBeTruthy
();
});
it
(
'should locate ticks properly'
,
function
()
{
var
ticks
=
chart
.
internal
.
main
.
select
(
'.c3-axis-x'
).
selectAll
(
'g.tick'
);
ticks
.
each
(
function
(
d
,
i
)
{
var
tspans
=
d3
.
select
(
this
).
selectAll
(
'tspan'
),
expectedX
=
'0'
,
expectedDy
=
'.40em'
;
if
(
i
>
0
)
{
// i === 0 should be checked in next test
expect
(
tspans
.
size
()).
toBe
(
1
);
tspans
.
each
(
function
()
{
var
tspan
=
d3
.
select
(
this
);
expect
(
tspan
.
attr
(
'x'
)).
toBe
(
expectedX
);
expect
(
tspan
.
attr
(
'dy'
)).
toBe
(
expectedDy
);
});
}
});
});
it
(
'should split tick text properly'
,
function
()
{
var
tick
=
chart
.
internal
.
main
.
select
(
'.c3-axis-x'
).
select
(
'g.tick'
),
tspans
=
tick
.
selectAll
(
'tspan'
),
expectedTickTexts
=
[
'this is a very'
,
'long tick text on'
,
'category axis'
],
expectedX
=
'0'
,
expectedDys
=
[
'.40em'
,
'10'
,
'10'
];
expect
(
tspans
.
size
()).
toBe
(
3
);
tspans
.
each
(
function
(
d
,
i
)
{
var
tspan
=
d3
.
select
(
this
);
expect
(
tspan
.
text
()).
toBe
(
expectedTickTexts
[
i
]);
expect
(
tspan
.
attr
(
'x'
)).
toBe
(
expectedX
);
expect
(
tspan
.
attr
(
'dy'
)).
toBe
(
expectedDys
[
i
]);
});
});
});
describe
(
'rotated'
,
function
()
{
it
(
'should update args to rotate axis'
,
function
()
{
args
.
axis
.
rotated
=
true
;
expect
(
true
).
toBeTruthy
();
});
it
(
'should locate ticks on rotated axis properly'
,
function
()
{
var
ticks
=
chart
.
internal
.
main
.
select
(
'.c3-axis-x'
).
selectAll
(
'g.tick'
);
ticks
.
each
(
function
(
d
,
i
)
{
var
tspans
=
d3
.
select
(
this
).
selectAll
(
'tspan'
),
expectedX
=
'-9'
,
expectedDy
=
'2'
;
if
(
i
>
0
)
{
// i === 0 should be checked in next test
expect
(
tspans
.
size
()).
toBe
(
1
);
tspans
.
each
(
function
()
{
var
tspan
=
d3
.
select
(
this
);
expect
(
tspan
.
attr
(
'x'
)).
toBe
(
expectedX
);
expect
(
tspan
.
attr
(
'dy'
)).
toBe
(
expectedDy
);
});
}
});
});
it
(
'should split tick text on rotated axis properly'
,
function
()
{
var
tick
=
chart
.
internal
.
main
.
select
(
'.c3-axis-x'
).
select
(
'g.tick'
),
tspans
=
tick
.
selectAll
(
'tspan'
),
expectedTickTexts
=
[
'this is a very'
,
'long tick text'
,
'on category axis'
],
expectedX
=
'-9'
,
expectedDys
=
[
'-8'
,
'10'
,
'10'
];
expect
(
tspans
.
size
()).
toBe
(
3
);
tspans
.
each
(
function
(
d
,
i
)
{
var
tspan
=
d3
.
select
(
this
);
expect
(
tspan
.
text
()).
toBe
(
expectedTickTexts
[
i
]);
expect
(
tspan
.
attr
(
'x'
)).
toBe
(
expectedX
);
expect
(
tspan
.
attr
(
'dy'
)).
toBe
(
expectedDys
[
i
]);
});
});
});
describe
(
'option used'
,
function
()
{
describe
(
'as null'
,
function
()
{
it
(
'should update args not to split ticks'
,
function
()
{
args
.
axis
.
x
.
tick
=
{
width
:
null
};
expect
(
true
).
toBeTruthy
();
});
it
(
'should not split x tick'
,
function
()
{
var
tick
=
chart
.
internal
.
main
.
select
(
'.c3-axis-x'
).
select
(
'g.tick'
),
tspans
=
tick
.
selectAll
(
'tspan'
);
expect
(
tspans
.
size
()).
toBe
(
1
);
});
});
describe
(
'as value'
,
function
()
{
it
(
'should update args not to split ticks'
,
function
()
{
args
.
axis
.
x
.
tick
=
{
width
:
150
};
expect
(
true
).
toBeTruthy
();
});
it
(
'should split x tick to 2 lines properly'
,
function
()
{
var
tick
=
chart
.
internal
.
main
.
select
(
'.c3-axis-x'
).
select
(
'g.tick'
),
tspans
=
tick
.
selectAll
(
'tspan'
),
expectedTickTexts
=
[
'this is a very long tick text'
,
'on category axis'
],
expectedX
=
'-9'
,
expectedDys
=
[
'-3'
,
'10'
];
expect
(
tspans
.
size
()).
toBe
(
2
);
tspans
.
each
(
function
(
d
,
i
)
{
var
tspan
=
d3
.
select
(
this
);
expect
(
tspan
.
text
()).
toBe
(
expectedTickTexts
[
i
]);
expect
(
tspan
.
attr
(
'x'
)).
toBe
(
expectedX
);
expect
(
tspan
.
attr
(
'dy'
)).
toBe
(
expectedDys
[
i
]);
});
});
});
});
});
});
});
spec/legend-spec.js
View file @
e1e3ddcf
...
...
@@ -34,7 +34,7 @@ describe('c3 chart legend', function () {
it
(
'should be located on the center of chart'
,
function
()
{
var
box
=
chart
.
internal
.
legend
.
node
().
getBoundingClientRect
();
expect
(
box
.
left
+
box
.
right
).
toBe
(
64
0
);
expect
(
box
.
left
+
box
.
right
).
toBe
(
64
5
);
});
});
...
...
src/axis.js
View file @
e1e3ddcf
...
...
@@ -32,7 +32,11 @@ c3_chart_internal_fn.initAxis = function () {
};
c3_chart_internal_fn
.
getXAxis
=
function
(
scale
,
orient
,
tickFormat
,
tickValues
,
withOuterTick
)
{
var
$$
=
this
,
config
=
$$
.
config
,
axisParams
=
{
isCategory
:
$$
.
isCategorized
(),
withOuterTick
:
withOuterTick
},
axisParams
=
{
isCategory
:
$$
.
isCategorized
(),
withOuterTick
:
withOuterTick
,
tickWidth
:
$$
.
isCategorized
()
?
config
.
axis_x_tick_width
:
undefined
},
axis
=
c3_axis
(
$$
.
d3
,
axisParams
).
scale
(
scale
).
orient
(
orient
);
if
(
$$
.
isTimeSeries
()
&&
tickValues
)
{
...
...
@@ -268,7 +272,7 @@ c3_chart_internal_fn.getMaxTickWidth = function (id) {
axis
=
$$
.
getXAxis
(
scale
,
$$
.
xOrient
,
$$
.
getXAxisTickFormat
(),
$$
.
getXAxisTickValues
());
}
$$
.
d3
.
select
(
'body'
).
append
(
"g"
).
style
(
'visibility'
,
'hidden'
).
call
(
axis
).
each
(
function
()
{
$$
.
d3
.
select
(
this
).
selectAll
(
'text'
).
each
(
function
()
{
$$
.
d3
.
select
(
this
).
selectAll
(
'text
tspan
'
).
each
(
function
()
{
var
box
=
this
.
getBoundingClientRect
();
if
(
box
.
left
>
0
&&
maxWidth
<
box
.
width
)
{
maxWidth
=
box
.
width
;
}
});
...
...
src/c3.axis.js
View file @
e1e3ddcf
...
...
@@ -48,6 +48,23 @@ function c3_axis(d3, params) {
function
textFormatted
(
v
)
{
return
tickFormat
?
tickFormat
(
v
)
:
v
;
}
function
getSizeFor1Char
(
tick
)
{
var
size
=
{
h
:
11.5
,
w
:
5.5
};
tick
.
select
(
'text'
).
text
(
textFormatted
).
each
(
function
(
d
)
{
var
box
=
this
.
getBoundingClientRect
(),
text
=
textFormatted
(
d
),
h
=
box
.
height
,
w
=
text
?
(
box
.
width
/
text
.
length
)
:
undefined
;
if
(
h
&&
w
)
{
size
.
h
=
h
;
size
.
w
=
w
;
}
}).
text
(
''
);
return
size
;
}
function
axis
(
g
)
{
g
.
each
(
function
()
{
var
g
=
d3
.
select
(
this
);
...
...
@@ -69,7 +86,6 @@ function c3_axis(d3, params) {
var
lineEnter
=
tickEnter
.
select
(
"line"
),
lineUpdate
=
tickUpdate
.
select
(
"line"
),
text
=
tick
.
select
(
"text"
).
text
(
textFormatted
),
textEnter
=
tickEnter
.
select
(
"text"
),
textUpdate
=
tickUpdate
.
select
(
"text"
);
...
...
@@ -81,20 +97,77 @@ function c3_axis(d3, params) {
tickOffset
=
tickX
=
0
;
}
var
text
,
tspan
,
sizeFor1Char
=
getSizeFor1Char
(
tick
),
counts
=
[];
var
tickLength
=
Math
.
max
(
innerTickSize
,
0
)
+
tickPadding
,
isVertical
=
orient
===
'left'
||
orient
===
'right'
;
// this should be called only when category axis
function
splitTickText
(
d
)
{
var
tickText
=
textFormatted
(
d
)
+
""
,
maxWidth
=
isVertical
?
params
.
tickWidth
:
tickOffset
*
2
-
10
,
subtext
,
spaceIndex
,
textWidth
,
splitted
=
[];
function
split
(
splitted
,
text
)
{
spaceIndex
=
undefined
;
for
(
var
i
=
0
;
i
<
text
.
length
;
i
++
)
{
if
(
text
.
charAt
(
i
)
===
' '
)
{
spaceIndex
=
i
;
}
subtext
=
text
.
substr
(
0
,
i
+
1
);
textWidth
=
sizeFor1Char
.
w
*
subtext
.
length
;
// if text width gets over tick width, split by space index or crrent index
if
(
maxWidth
<
textWidth
)
{
return
split
(
splitted
.
concat
(
text
.
substr
(
0
,
spaceIndex
?
spaceIndex
:
i
)),
text
.
slice
(
spaceIndex
?
spaceIndex
+
1
:
i
)
);
}
}
return
splitted
.
concat
(
text
);
}
return
split
(
splitted
,
tickText
);
}
function
tspanDy
(
d
,
i
)
{
var
dy
=
sizeFor1Char
.
h
;
if
(
i
===
0
)
{
if
(
orient
===
'left'
||
orient
===
'right'
)
{
dy
=
-
((
counts
[
d
.
index
]
-
1
)
*
(
sizeFor1Char
.
h
/
2
)
-
(
params
.
isCategory
?
2
:
3
));
}
else
{
dy
=
params
.
isCategory
?
".40em"
:
".71em"
;
}
}
return
dy
;
}
function
tickSize
(
d
)
{
var
tickPosition
=
scale
(
d
)
+
tickOffset
;
return
range
[
0
]
<
tickPosition
&&
tickPosition
<
range
[
1
]
?
innerTickSize
:
0
;
}
text
=
tick
.
select
(
"text"
);
tspan
=
text
.
selectAll
(
'tspan'
)
.
data
(
function
(
d
,
i
)
{
var
splitted
=
params
.
tickWidth
?
splitTickText
(
d
)
:
[
textFormatted
(
d
)];
counts
[
i
]
=
splitted
.
length
;
return
splitted
.
map
(
function
(
s
)
{
return
{
index
:
i
,
splitted
:
s
};
});
})
.
enter
().
append
(
'tspan'
)
.
text
(
function
(
d
)
{
return
d
.
splitted
;
});
switch
(
orient
)
{
case
"bottom"
:
{
tickTransform
=
axisX
;
lineEnter
.
attr
(
"y2"
,
innerTickSize
);
textEnter
.
attr
(
"y"
,
Math
.
max
(
innerTickSize
,
0
)
+
tickPadding
);
textEnter
.
attr
(
"y"
,
tickLength
);
lineUpdate
.
attr
(
"x1"
,
tickX
).
attr
(
"x2"
,
tickX
).
attr
(
"y2"
,
tickSize
);
textUpdate
.
attr
(
"x"
,
0
).
attr
(
"y"
,
Math
.
max
(
innerTickSize
,
0
)
+
tickPadding
);
text
.
attr
(
"dy"
,
".71em"
).
style
(
"text-anchor"
,
"middle"
);
textUpdate
.
attr
(
"x"
,
0
).
attr
(
"y"
,
tickLength
);
text
.
style
(
"text-anchor"
,
"middle"
);
tspan
.
attr
(
'x'
,
0
).
attr
(
"dy"
,
tspanDy
);
pathUpdate
.
attr
(
"d"
,
"M"
+
range
[
0
]
+
","
+
outerTickSize
+
"V0H"
+
range
[
1
]
+
"V"
+
outerTickSize
);
break
;
}
...
...
@@ -102,10 +175,11 @@ function c3_axis(d3, params) {
{
tickTransform
=
axisX
;
lineEnter
.
attr
(
"y2"
,
-
innerTickSize
);
textEnter
.
attr
(
"y"
,
-
(
Math
.
max
(
innerTickSize
,
0
)
+
tickPadding
)
);
textEnter
.
attr
(
"y"
,
-
tickLength
);
lineUpdate
.
attr
(
"x2"
,
0
).
attr
(
"y2"
,
-
innerTickSize
);
textUpdate
.
attr
(
"x"
,
0
).
attr
(
"y"
,
-
(
Math
.
max
(
innerTickSize
,
0
)
+
tickPadding
));
text
.
attr
(
"dy"
,
"0em"
).
style
(
"text-anchor"
,
"middle"
);
textUpdate
.
attr
(
"x"
,
0
).
attr
(
"y"
,
-
tickLength
);
text
.
style
(
"text-anchor"
,
"middle"
);
tspan
.
attr
(
'x'
,
0
).
attr
(
"dy"
,
"0em"
);
pathUpdate
.
attr
(
"d"
,
"M"
+
range
[
0
]
+
","
+
-
outerTickSize
+
"V0H"
+
range
[
1
]
+
"V"
+
-
outerTickSize
);
break
;
}
...
...
@@ -113,10 +187,11 @@ function c3_axis(d3, params) {
{
tickTransform
=
axisY
;
lineEnter
.
attr
(
"x2"
,
-
innerTickSize
);
textEnter
.
attr
(
"x"
,
-
(
Math
.
max
(
innerTickSize
,
0
)
+
tickPadding
)
);
textEnter
.
attr
(
"x"
,
-
tickLength
);
lineUpdate
.
attr
(
"x2"
,
-
innerTickSize
).
attr
(
"y1"
,
tickY
).
attr
(
"y2"
,
tickY
);
textUpdate
.
attr
(
"x"
,
-
(
Math
.
max
(
innerTickSize
,
0
)
+
tickPadding
)).
attr
(
"y"
,
tickOffset
);
text
.
attr
(
"dy"
,
".32em"
).
style
(
"text-anchor"
,
"end"
);
textUpdate
.
attr
(
"x"
,
-
tickLength
).
attr
(
"y"
,
tickOffset
);
text
.
style
(
"text-anchor"
,
"end"
);
tspan
.
attr
(
'x'
,
-
tickLength
).
attr
(
"dy"
,
tspanDy
);
pathUpdate
.
attr
(
"d"
,
"M"
+
-
outerTickSize
+
","
+
range
[
0
]
+
"H0V"
+
range
[
1
]
+
"H"
+
-
outerTickSize
);
break
;
}
...
...
@@ -124,10 +199,11 @@ function c3_axis(d3, params) {
{
tickTransform
=
axisY
;
lineEnter
.
attr
(
"x2"
,
innerTickSize
);
textEnter
.
attr
(
"x"
,
Math
.
max
(
innerTickSize
,
0
)
+
tickPadding
);
textEnter
.
attr
(
"x"
,
tickLength
);
lineUpdate
.
attr
(
"x2"
,
innerTickSize
).
attr
(
"y2"
,
0
);
textUpdate
.
attr
(
"x"
,
Math
.
max
(
innerTickSize
,
0
)
+
tickPadding
).
attr
(
"y"
,
0
);
text
.
attr
(
"dy"
,
".32em"
).
style
(
"text-anchor"
,
"start"
);
textUpdate
.
attr
(
"x"
,
tickLength
).
attr
(
"y"
,
0
);
text
.
style
(
"text-anchor"
,
"start"
);
tspan
.
attr
(
'x'
,
tickLength
).
attr
(
"dy"
,
tspanDy
);
pathUpdate
.
attr
(
"d"
,
"M"
+
outerTickSize
+
","
+
range
[
0
]
+
"H0V"
+
range
[
1
]
+
"H"
+
outerTickSize
);
break
;
}
...
...
src/config.js
View file @
e1e3ddcf
...
...
@@ -92,6 +92,7 @@ c3_chart_internal_fn.getDefaultConfig = function () {
axis_x_tick_values
:
null
,
axis_x_tick_rotate
:
undefined
,
axis_x_tick_outer
:
true
,
axis_x_tick_width
:
80
,
axis_x_max
:
undefined
,
axis_x_min
:
undefined
,
axis_x_padding
:
{},
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment