Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in
Toggle navigation
Menu
Open sidebar
Sascha Herzinger
AdaCharts
Commits
e6f8245e
Commit
e6f8245e
authored
Mar 21, 2019
by
Sascha Herzinger
Browse files
refactored textwrapper utils across charts
parent
fc18555d
Changes
4
Hide whitespace changes
Inline
Side-by-side
src/charts/impl/Barplot.js
View file @
e6f8245e
import
*
as
d3
from
'
d3
'
;
import
Chart
from
'
../Chart
'
;
import
'
../../assets/css/barplot.css
'
;
import
textUtils
from
'
../../utils/textwrappers
'
;
export
default
class
extends
Chart
{
constructor
({
container
})
{
...
...
@@ -96,7 +97,9 @@ export default class extends Chart {
this
.
axisLeft
.
attr
(
'
transform
'
,
`translate(
${
0
}
,
${
0
}
)`
)
.
call
(
d3
.
axisLeft
(
y
));
.
call
(
d3
.
axisLeft
(
y
))
.
selectAll
(
'
text
'
)
.
call
(
textUtils
.
axisShrinkFitText
,
margin
.
left
);
this
.
axisRight
.
attr
(
'
transform
'
,
`translate(
${
width
}
,
${
0
}
)`
)
...
...
@@ -125,7 +128,7 @@ export default class extends Chart {
.
attr
(
'
x
'
,
d
=>
xSub
(
d
.
group
))
.
attr
(
'
y
'
,
height
)
.
transition
()
.
duration
(
5
00
)
.
duration
(
10
00
)
.
attr
(
'
x
'
,
d
=>
xSub
(
d
.
group
))
.
attr
(
'
y
'
,
d
=>
y
(
d
.
y
)
-
2
)
.
attr
(
'
width
'
,
xSub
.
bandwidth
())
...
...
@@ -133,20 +136,19 @@ export default class extends Chart {
.
attr
(
'
fill
'
,
d
=>
color
(
d
.
group
));
parent
.
append
(
'
text
'
)
.
attr
(
'
text-anchor
'
,
'
middle
'
)
.
attr
(
'
x
'
,
d
=>
xSub
(
d
.
group
)
+
xSub
.
bandwidth
()
/
2
)
.
attr
(
'
y
'
,
height
)
.
attr
(
'
text-anchor
'
,
'
end
'
)
.
style
(
'
dominant-baseline
'
,
'
central
'
)
.
attr
(
'
transform
'
,
d
=>
`translate(
${
xSub
(
d
.
group
)
+
xSub
.
bandwidth
()
/
2
}
,
${
y
(
d
.
y
)
-
4
}
)rotate(90)`
)
.
style
(
'
visibility
'
,
'
hidden
'
)
.
text
(
d
=>
d
.
y
)
.
transition
(
d3
.
easePoly
)
.
duration
(
500
)
.
attr
(
'
y
'
,
d
=>
y
(
d
.
y
)
-
4
);
.
text
(
d
=>
d
.
y
);
})
.
merge
(
barGroup
)
.
on
(
'
click
'
,
d
=>
barClickCallback
(
d
))
.
on
(
'
mouseenter
'
,
(
d
)
=>
{
this
.
svg
.
selectAll
(
'
.ac-bar-group
'
)
.
filter
(
e
=>
d
.
group
!==
e
.
group
)
.
transition
()
.
duration
(
1000
)
.
style
(
'
opacity
'
,
0.2
);
this
.
svg
.
selectAll
(
'
.ac-bar-group
'
)
.
filter
(
e
=>
d
.
group
===
e
.
group
)
...
...
@@ -157,6 +159,8 @@ export default class extends Chart {
})
.
on
(
'
mouseleave
'
,
()
=>
{
this
.
svg
.
selectAll
(
'
.ac-bar-group
'
)
.
transition
()
.
duration
(
1000
)
.
style
(
'
opacity
'
,
1
)
.
call
((
parent
)
=>
{
parent
.
select
(
'
text
'
)
...
...
@@ -168,7 +172,7 @@ export default class extends Chart {
.
call
((
parent
)
=>
{
parent
.
select
(
'
rect
'
)
.
transition
()
.
duration
(
5
00
)
.
duration
(
10
00
)
.
attr
(
'
x
'
,
d
=>
xSub
(
d
.
group
))
.
attr
(
'
y
'
,
d
=>
y
(
d
.
y
)
-
2
)
.
attr
(
'
width
'
,
xSub
.
bandwidth
())
...
...
@@ -176,27 +180,21 @@ export default class extends Chart {
.
attr
(
'
fill
'
,
d
=>
color
(
d
.
group
));
parent
.
select
(
'
text
'
)
.
attr
(
'
transform
'
,
d
=>
`translate(
${
xSub
(
d
.
group
)
+
xSub
.
bandwidth
()
/
2
}
,
${
y
(
d
.
y
)
-
4
}
)rotate(90)`
)
.
style
(
'
visibility
'
,
'
hidden
'
)
.
text
(
d
=>
d
.
y
)
.
transition
(
d3
.
easePoly
)
.
duration
(
500
)
.
attr
(
'
x
'
,
d
=>
xSub
(
d
.
group
)
+
xSub
.
bandwidth
()
/
2
)
.
attr
(
'
y
'
,
d
=>
y
(
d
.
y
)
-
4
);
.
text
(
d
=>
d
.
y
);
});
barGroup
.
exit
()
.
call
((
parent
)
=>
{
parent
.
select
(
'
rect
'
)
.
transition
()
.
duration
(
500
)
.
attr
(
'
width
'
,
0
)
.
remove
();
parent
.
select
(
'
text
'
)
.
remove
();
})
.
transition
()
.
delay
(
5
00
)
.
delay
(
10
00
)
.
remove
();
const
legendElementSize
=
height
/
30
;
...
...
@@ -235,14 +233,14 @@ export default class extends Chart {
.
each
((
d
,
i
,
arr
)
=>
{
d3
.
select
(
arr
[
i
])
.
transition
()
.
duration
(
5
00
)
.
duration
(
10
00
)
.
style
(
'
opacity
'
,
selectedGroups
.
length
===
0
||
selectedGroups
.
includes
(
d
.
group
)
?
1
:
0.2
);
});
this
.
svg
.
selectAll
(
'
.ac-bar-legend-element
'
)
.
each
((
d
,
i
,
arr
)
=>
{
d3
.
select
(
arr
[
i
])
.
transition
()
.
duration
(
5
00
)
.
duration
(
10
00
)
.
style
(
'
opacity
'
,
selectedGroups
.
length
===
0
||
selectedGroups
.
includes
(
d
)
?
1
:
0.2
);
});
});
...
...
src/charts/impl/Heatmap.js
View file @
e6f8245e
import
*
as
d3
from
'
d3
'
;
import
Chart
from
'
../Chart
'
;
import
'
../../assets/css/heatmap.css
'
;
import
textUtils
from
'
../../utils/textwrappers
'
;
const
ANIMATION_DURATION
=
1000
;
const
MAX_FONT_SIZE
=
20
;
...
...
@@ -209,17 +210,6 @@ export default class extends Chart {
rect
.
exit
()
.
remove
();
function
wrap
(
selection
,
maxWidth
)
{
const
node
=
d3
.
select
(
selection
);
let
textLength
=
node
.
node
().
getComputedTextLength
();
let
text
=
node
.
text
();
while
(
textLength
>
maxWidth
&&
text
.
length
>
0
)
{
text
=
text
.
slice
(
0
,
-
1
);
node
.
text
(
`
${
text
}
..`
);
textLength
=
node
.
node
().
getComputedTextLength
();
}
}
const
rowLabels
=
this
.
svg
.
selectAll
(
'
text.ac-heatmap-row-label
'
)
.
data
(
this
.
rows
,
d
=>
d
);
...
...
@@ -246,7 +236,7 @@ export default class extends Chart {
})
.
merge
(
rowLabels
)
.
style
(
'
font-size
'
,
`
${
this
.
yScale
.
bandwidth
()
>
MAX_FONT_SIZE
?
MAX_FONT_SIZE
:
this
.
yScale
.
bandwidth
()}
px`
)
.
each
((
_
,
i
,
arr
)
=>
wrap
(
arr
[
i
],
(
this
.
rowLabelPos
===
'
left
'
?
this
.
margin
.
left
:
this
.
margin
.
right
)
-
AXIS_LABEL_FONT_SIZE
-
ROW_COL_LABELS_OFFSET
));
.
each
((
_
,
i
,
arr
)
=>
textUtils
.
sliceFitText
(
arr
[
i
],
(
this
.
rowLabelPos
===
'
left
'
?
this
.
margin
.
left
:
this
.
margin
.
right
)
-
AXIS_LABEL_FONT_SIZE
-
ROW_COL_LABELS_OFFSET
));
rowLabels
.
transition
()
...
...
@@ -285,7 +275,7 @@ export default class extends Chart {
})
.
merge
(
colLabels
)
.
style
(
'
font-size
'
,
`
${(
this
.
xScale
.
bandwidth
()
>
MAX_FONT_SIZE
?
MAX_FONT_SIZE
:
this
.
xScale
.
bandwidth
())
-
1
}
px`
)
.
each
((
_
,
i
,
arr
)
=>
wrap
(
arr
[
i
],
(
this
.
colLabelPos
===
'
top
'
?
this
.
margin
.
top
:
this
.
margin
.
bottom
)
-
AXIS_LABEL_FONT_SIZE
-
ROW_COL_LABELS_OFFSET
));
.
each
((
_
,
i
,
arr
)
=>
textUtils
.
sliceFitText
(
arr
[
i
],
(
this
.
colLabelPos
===
'
top
'
?
this
.
margin
.
top
:
this
.
margin
.
bottom
)
-
AXIS_LABEL_FONT_SIZE
-
ROW_COL_LABELS_OFFSET
));
colLabels
.
transition
()
...
...
src/charts/impl/Scatterplot.js
View file @
e6f8245e
import
*
as
d3
from
'
d3
'
;
import
Chart
from
'
../Chart
'
;
import
'
../../assets/css/scatterplot.css
'
;
import
textUtils
from
'
../../utils/textwrappers
'
;
const
ANIMATION_DURATION
=
500
;
const
MAX_FONT_SIZE
=
20
;
const
D3_AXIS_TEXT_OFFSET
=
9
;
export
default
class
extends
Chart
{
constructor
({
container
})
{
...
...
@@ -197,21 +198,11 @@ export default class extends Chart {
.
tickSizeInner
(
width
)
.
tickFormat
(
''
);
function
axisWrap
(
nodes
,
maxWidth
)
{
nodes
.
each
(
function
()
{
const
text
=
d3
.
select
(
this
);
while
(
text
.
node
().
getComputedTextLength
()
>
maxWidth
-
D3_AXIS_TEXT_OFFSET
)
{
const
fontSize
=
parseInt
(
text
.
style
(
'
font-size
'
).
split
(
'
px
'
)[
0
],
10
);
text
.
style
(
'
font-size
'
,
`
${(
fontSize
)
-
1
}
px`
);
}
});
}
this
.
axisBottom
.
attr
(
'
transform
'
,
`translate(0,
${
height
}
)`
)
.
call
(
xAxisBottom
)
.
selectAll
(
'
text
'
)
.
call
(
axisWrap
,
width
/
(
x
.
ticks
().
length
));
.
call
(
textUtils
.
axisShrinkFitText
,
width
/
(
x
.
ticks
().
length
));
this
.
axisTop
.
call
(
xAxisTop
);
...
...
@@ -219,7 +210,7 @@ export default class extends Chart {
this
.
axisLeft
.
call
(
yAxisLeft
)
.
selectAll
(
'
text
'
)
.
call
(
axisWrap
,
margin
.
left
-
yLabelSize
);
.
call
(
textUtils
.
axisShrinkFitText
,
margin
.
left
-
yLabelSize
);
this
.
axisRight
.
attr
(
'
transform
'
,
`translate(
${
width
}
, 0)`
)
...
...
@@ -307,39 +298,6 @@ ${!categoryKeys ? d[2] : this.categories[d[2]]}</br>
.
attr
(
'
r
'
,
0
)
.
remove
();
function
legendWrap
(
nodes
,
maxWidth
)
{
nodes
.
each
(
function
()
{
const
text
=
d3
.
select
(
this
);
const
words
=
text
.
text
().
split
(
/
\s
+/
);
let
line
=
[];
let
lineNumber
=
0
;
const
lineHeight
=
1.1
;
// ems
let
tspan
=
text
.
text
(
null
)
.
append
(
'
tspan
'
)
.
attr
(
'
x
'
,
text
.
attr
(
'
x
'
))
.
attr
(
'
y
'
,
text
.
attr
(
'
y
'
));
words
.
forEach
((
word
,
i
)
=>
{
line
.
push
(
word
);
tspan
.
text
(
line
.
join
(
'
'
));
if
(
tspan
.
node
().
getComputedTextLength
()
>
maxWidth
)
{
if
(
i
>
0
)
{
line
.
pop
();
tspan
.
text
(
lineNumber
===
1
?
`
${
line
.
join
(
'
'
)}
...`
:
line
.
join
(
'
'
));
if
(
lineNumber
<
1
)
{
lineNumber
+=
1
;
line
=
[
word
];
tspan
=
text
.
append
(
'
tspan
'
)
.
attr
(
'
x
'
,
text
.
attr
(
'
x
'
))
.
attr
(
'
y
'
,
text
.
attr
(
'
y
'
))
.
attr
(
'
dy
'
,
`
${
lineNumber
*
lineHeight
}
em`
)
.
text
(
word
);
}
}
}
});
});
}
const
legendRectHeight
=
height
/
30
;
const
legendRectWidth
=
width
/
30
;
const
legendPadding
=
legendRectHeight
/
2
;
...
...
@@ -382,7 +340,7 @@ ${!categoryKeys ? d[2] : this.categories[d[2]]}</br>
.
attr
(
'
y
'
,
(
_
,
i
)
=>
((
legendRectHeight
+
legendPadding
)
*
i
+
legendRectHeight
/
2
))
.
style
(
'
dominant-baseline
'
,
'
central
'
)
.
text
(
d
=>
this
.
categories
[
d
])
.
call
(
legendWrap
,
legendTextMaxWidth
);
.
call
(
textUtils
.
wrapFitText
,
legendTextMaxWidth
);
legendElement
.
exit
()
.
remove
();
...
...
src/utils/textwrappers.js
0 → 100644
View file @
e6f8245e
import
*
as
d3
from
'
d3
'
;
const
D3_AXIS_TEXT_OFFSET
=
9
;
export
default
{
sliceFitText
(
selection
,
maxWidth
)
{
const
node
=
d3
.
select
(
selection
);
let
textLength
=
node
.
node
().
getComputedTextLength
();
let
text
=
node
.
text
();
while
(
textLength
>
maxWidth
&&
text
.
length
>
0
)
{
text
=
text
.
slice
(
0
,
-
1
);
node
.
text
(
`
${
text
}
..`
);
textLength
=
node
.
node
().
getComputedTextLength
();
}
},
axisShrinkFitText
(
nodes
,
maxWidth
)
{
nodes
.
each
(
function
()
{
const
text
=
d3
.
select
(
this
);
while
(
text
.
node
().
getComputedTextLength
()
>
maxWidth
-
D3_AXIS_TEXT_OFFSET
)
{
const
fontSize
=
parseInt
(
text
.
style
(
'
font-size
'
).
split
(
'
px
'
)[
0
],
10
);
text
.
style
(
'
font-size
'
,
`
${(
fontSize
)
-
1
}
px`
);
}
});
},
wrapFitText
(
nodes
,
maxWidth
)
{
nodes
.
each
(
function
()
{
const
text
=
d3
.
select
(
this
);
const
words
=
text
.
text
().
split
(
/
\s
+/
);
let
line
=
[];
let
lineNumber
=
0
;
const
lineHeight
=
1.1
;
// ems
let
tspan
=
text
.
text
(
null
)
.
append
(
'
tspan
'
)
.
attr
(
'
x
'
,
text
.
attr
(
'
x
'
))
.
attr
(
'
y
'
,
text
.
attr
(
'
y
'
));
words
.
forEach
((
word
,
i
)
=>
{
line
.
push
(
word
);
tspan
.
text
(
line
.
join
(
'
'
));
if
(
tspan
.
node
().
getComputedTextLength
()
>
maxWidth
)
{
if
(
i
>
0
)
{
line
.
pop
();
tspan
.
text
(
lineNumber
===
1
?
`
${
line
.
join
(
'
'
)}
...`
:
line
.
join
(
'
'
));
if
(
lineNumber
<
1
)
{
lineNumber
+=
1
;
line
=
[
word
];
tspan
=
text
.
append
(
'
tspan
'
)
.
attr
(
'
x
'
,
text
.
attr
(
'
x
'
))
.
attr
(
'
y
'
,
text
.
attr
(
'
y
'
))
.
attr
(
'
dy
'
,
`
${
lineNumber
*
lineHeight
}
em`
)
.
text
(
word
);
}
}
}
});
});
}
};
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new 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