Skip to content

Commit

Permalink
fix line break in image export (#227)
Browse files Browse the repository at this point in the history
  • Loading branch information
JannikStreek authored Jan 16, 2024
1 parent e9376d7 commit 5503142
Show file tree
Hide file tree
Showing 5 changed files with 274 additions and 140 deletions.
2 changes: 1 addition & 1 deletion docker-compose-prod.yml
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ services:
- postgres_prod

postgres_prod:
image: postgres:12-alpine
image: postgres:15-alpine
# Pass config parameters to the postgres server.
# Find more information below when you need to generate the ssl-relevant file your self
# command: -c ssl=on -c ssl_cert_file=/var/lib/postgresql/server.crt -c ssl_key_file=/var/lib/postgresql/server.key
Expand Down
2 changes: 1 addition & 1 deletion docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ services:
- postgres

postgres:
image: postgres:12-alpine
image: postgres:15-alpine
environment:
PGDATA: /var/lib/postgresql/data/pgdata
POSTGRES_DB: ${POSTGRES_DB:-teammapper-backend-dev}
Expand Down
25 changes: 15 additions & 10 deletions teammapper-frontend/mmp/src/map/handlers/export.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import {MapSnapshot} from './history'
import Utils from '../../utils/utils'
import {Event} from './events'
import * as d3 from 'd3'
import DOMPurify from 'dompurify'

/**
* Manage map image exports.
Expand Down Expand Up @@ -129,18 +130,22 @@ export default class Export {
svg.appendChild(clone)

// convert all foreignObjects to native svg text to ensure better compatibility with svg readers
d3.select(clone).selectAll("foreignObject").nodes().forEach((fo: HTMLElement) => {
d3.select(clone).selectAll('foreignObject').nodes().forEach((fo: HTMLElement) => {
const parent = fo.parentElement
const x = parseInt(fo.getAttribute('x'), 10) + Math.floor(parseInt(fo.getAttribute('width'), 10) / 2)
const splittedText = fo.firstChild.textContent.split('\n')
// line breaks are created via tspan elements that are relatively positioned using dy property
const svgTextWithLineBreaks = splittedText.map((text, i) => `<tspan dy="${(i === 0 || i === splittedText.length - 1) ? '0' : '1.2em'}" x="${x}">${text}</tspan>`)
d3.select(parent)
.attr("width", fo.getAttribute("width"))
.append("text")
.text(fo.firstChild.textContent)
.attr("y", parseInt(fo.getAttribute('y'), 10) + parseInt((fo.firstElementChild as HTMLElement).style.fontSize, 10))
.attr("x", parseInt(fo.getAttribute('x'), 10) + Math.floor(parseInt(fo.getAttribute('width'), 10) / 2))
.attr("text-anchor", "middle")
.attr("font-family", (fo.firstElementChild as HTMLElement).style.fontFamily)
.attr("font-size", (fo.firstElementChild as HTMLElement).style.fontSize)
.attr("fill", (fo.firstElementChild as HTMLElement).style.color);
.attr('width', fo.getAttribute('width'))
.append('text')
.attr('y', parseInt(fo.getAttribute('y'), 10) + parseInt((fo.firstElementChild as HTMLElement).style.fontSize, 10))
.attr('x', x)
.attr('text-anchor', 'middle')
.attr('font-family', (fo.firstElementChild as HTMLElement).style.fontFamily)
.attr('font-size', (fo.firstElementChild as HTMLElement).style.fontSize)
.attr('fill', (fo.firstElementChild as HTMLElement).style.color)
.html(DOMPurify.sanitize(svgTextWithLineBreaks.join('')))
fo.remove()
})

Expand Down
Loading

0 comments on commit 5503142

Please sign in to comment.