Commit e6f8245e authored by Sascha Herzinger's avatar Sascha Herzinger
Browse files

refactored textwrapper utils across charts

parent fc18555d
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(500)
.duration(1000)
.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(500)
.duration(1000)
.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(500)
.delay(1000)
.remove();
const legendElementSize = height / 30;
......@@ -235,14 +233,14 @@ export default class extends Chart {
.each((d, i, arr) => {
d3.select(arr[i])
.transition()
.duration(500)
.duration(1000)
.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(500)
.duration(1000)
.style('opacity', selectedGroups.length === 0 || selectedGroups.includes(d) ? 1 : 0.2);
});
});
......
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()
......
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();
......
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);
}
}
}
});
});
}
};
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