Couple of small fixes for vizzes. (#10963)

- Improve logic for white space rendering (render leading/trailing in partial, change the tab rendering).
- Escape HTML characters.
- Fix for the geo viz starting zoom and center.

![image](https://github.com/user-attachments/assets/ac8c8893-14b5-4242-ba82-b821797546a1)

![image](https://github.com/user-attachments/assets/a179b4ad-d295-4783-97d9-803b6958cb95)

![image](https://github.com/user-attachments/assets/e4be7a81-28ff-4e79-b6e0-9aadae059270)

(cherry picked from commit 26678f3e71)
This commit is contained in:
James Dunkerley 2024-09-03 22:17:08 +02:00
parent 5befcd6110
commit babddd768d
2 changed files with 36 additions and 10 deletions

View File

@ -119,6 +119,7 @@ const LABEL_COLOR = `rgba(0, 0, 0, 0.8)`
const DEFAULT_MAP_STYLE = 'mapbox://styles/mapbox/light-v9'
const DEFAULT_MAP_ZOOM = 11
const DEFAULT_MAX_MAP_ZOOM = 18
const ACCENT_COLOR: Color = [78, 165, 253]
const dataPoints = ref<LocationWithPosition[]>([])
@ -166,9 +167,24 @@ function updateState(data: Data) {
}
const center = centerPoint()
const viewPort = new deck.WebMercatorViewport({
width: mapNode.value?.clientWidth ?? 600,
height: mapNode.value?.clientHeight ?? 400,
longitude: center.longitude,
latitude: center.latitude,
zoom: DEFAULT_MAP_ZOOM,
pitch: 0,
}).fitBounds(
[
[center.minX, center.minY],
[center.maxX, center.maxY],
],
{ padding: 10, maxZoom: DEFAULT_MAX_MAP_ZOOM },
)
latitude.value = center.latitude
longitude.value = center.longitude
zoom.value = DEFAULT_MAP_ZOOM
zoom.value = viewPort.zoom
mapStyle.value = DEFAULT_MAP_STYLE
pitch.value = 0
controller.value = true
@ -303,16 +319,16 @@ function centerPoint() {
{
const xs = dataPoints.value.map((p) => p.position[0])
minX = Math.min(...xs)
maxX = Math.min(...xs)
maxX = Math.max(...xs)
}
{
const ys = dataPoints.value.map((p) => p.position[1])
minY = Math.min(...ys)
maxY = Math.min(...ys)
maxY = Math.max(...ys)
}
let longitude = (minX + maxX) / 2
let latitude = (minY + maxY) / 2
return { latitude, longitude }
return { latitude, longitude, minX, maxX, minY, maxY }
}
/**

View File

@ -210,25 +210,35 @@ function formatNumber(params: ICellRendererParams) {
}
function formatText(params: ICellRendererParams) {
const htmlEscaped = params.value
.replaceAll('&', '&amp;')
.replaceAll('<', '&lt;')
.replaceAll('>', '&gt;')
.replace(
/https?:\/\/([-()_.!~*';/?:@&=+$,A-Za-z0-9])+/g,
(url: string) => `<a href="${url}" target="_blank" class="link">${url}</a>`,
)
if (textFormatterSelected.value === TextFormatOptions.Off) {
return params.value
return htmlEscaped.replace(/^\s+|\s+$/g, '&nbsp;')
}
const partialMappings = {
'\r': '<span style="color: #df8800">␍</span> <br>',
'\n': '<span style="color: #df8800;">␊</span> <br>',
'\t': '<span style="white-space: break-spaces;"> </span>',
'\t': '<span style="color: #df8800; white-space: break-spaces;">&#8594; |</span>',
}
const fullMappings = {
'\r': '<span style="color: #df8800">␍</span> <br>',
'\n': '<span style="color: #df8800">␊</span> <br>',
'\t': '<span style="color: #df8800; white-space: break-spaces;">&#8594; </span>',
'\t': '<span style="color: #df8800; white-space: break-spaces;">&#8594; |</span>',
}
const replaceSpaces =
textFormatterSelected.value === TextFormatOptions.On ?
params.value.replaceAll(' ', '<span style="color: #df8800">&#183;</span>')
: params.value.replace(/ {2,}/g, function (match: string) {
return `<span style="color: #df8800">${'&#183;'.repeat(match.length)}</span>`
htmlEscaped.replaceAll(' ', '<span style="color: #df8800">&#183;</span>')
: htmlEscaped.replace(/ \s+|^ +| +$/g, function (match: string) {
return `<span style="color: #df8800">${match.replaceAll(' ', '&#183;')}</span>`
})
const replaceReturns = replaceSpaces.replace(