Skip to content

Commit

Permalink
fixes #2963, fixes #3452; safari bugs fixed by removing legend from s…
Browse files Browse the repository at this point in the history
…vg foreignObject
  • Loading branch information
junedchhipa committed Feb 5, 2025
1 parent c5109b3 commit beb688b
Show file tree
Hide file tree
Showing 3 changed files with 38 additions and 41 deletions.
4 changes: 1 addition & 3 deletions src/modules/Core.js
Original file line number Diff line number Diff line change
Expand Up @@ -107,9 +107,7 @@ export default class Core {
gl.dom.elLegendWrap = document.createElement('div')
gl.dom.elLegendWrap.classList.add('apexcharts-legend')

gl.dom.elLegendWrap.setAttribute('xmlns', 'http://www.w3.org/1999/xhtml')
gl.dom.elLegendForeign.appendChild(gl.dom.elLegendWrap)

gl.dom.elWrap.appendChild(gl.dom.elLegendWrap)
gl.dom.Paper.node.appendChild(gl.dom.elLegendForeign)

gl.dom.elGraphical = gl.dom.Paper.group().attr({
Expand Down
73 changes: 37 additions & 36 deletions src/modules/Exports.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,12 @@ class Exports {
this.w = ctx.w
}

svgStringToNode(svgString) {
const parser = new DOMParser()
const svgDoc = parser.parseFromString(svgString, 'image/svg+xml')
return svgDoc.documentElement
}

scaleSvgNode(svg, scale) {
// get current both width and height of the svg
let svgWidth = parseFloat(svg.getAttributeNS(null, 'width'))
Expand All @@ -30,18 +36,43 @@ class Exports {
if (!scale) {
scale = 1 // if no scale is specified, don't scale...
}
let svgString = this.w.globals.dom.Paper.svg()

// clone the svg node so it remains intact in the UI
const svgNode = this.w.globals.dom.Paper.node.cloneNode(true)

// in case the scale is different than 1, the svg needs to be rescaled
const width = w.globals.svgWidth * scale
const height = w.globals.svgHeight * scale

const clonedNode = w.globals.dom.elWrap.cloneNode(true)
clonedNode.style.width = width + 'px'
clonedNode.style.height = height + 'px'
const serializedNode = new XMLSerializer().serializeToString(clonedNode)

let svgString = `
<svg xmlns="http://www.w3.org/2000/svg"
version="1.1"
xmlns:xlink="http://www.w3.org/1999/xlink"
class="apexcharts-svg"
xmlns:data="ApexChartsNS"
transform="translate(0, 0)"
width="${w.globals.svgWidth}px" height="${w.globals.svgHeight}px">
<foreignObject width="100%" height="100%">
<div xmlns="http://www.w3.org/1999/xhtml" style="width:${width}px; height:${height}px;">
<style type="text/css">
.apexcharts-tooltip, .apexcharts-toolbar, .apexcharts-xaxistooltip, .apexcharts-yaxistooltip, .apexcharts-xcrosshairs, .apexcharts-ycrosshairs, .apexcharts-zoom-rect, .apexcharts-selection-rect {
display: none;
}
</style>
${serializedNode}
</div>
</foreignObject>
</svg>
`

const svgNode = this.svgStringToNode(svgString)

if (scale !== 1) {
// scale the image
this.scaleSvgNode(svgNode, scale)
}
// Convert image URLs to base64

this.convertImagesToBase64(svgNode).then(() => {
svgString = new XMLSerializer().serializeToString(svgNode)
resolve(svgString.replace(/&nbsp;/g, '&#160;'))
Expand Down Expand Up @@ -84,37 +115,8 @@ class Exports {
})
}

cleanup() {
const w = this.w

// hide some elements to avoid printing them on exported svg
const xcrosshairs = w.globals.dom.baseEl.getElementsByClassName(
'apexcharts-xcrosshairs'
)
const ycrosshairs = w.globals.dom.baseEl.getElementsByClassName(
'apexcharts-ycrosshairs'
)
const zoomSelectionRects = w.globals.dom.baseEl.querySelectorAll(
'.apexcharts-zoom-rect, .apexcharts-selection-rect'
)
Array.prototype.forEach.call(zoomSelectionRects, (z) => {
z.setAttribute('width', 0)
})
if (xcrosshairs && xcrosshairs[0]) {
xcrosshairs[0].setAttribute('x', -500)
xcrosshairs[0].setAttribute('x1', -500)
xcrosshairs[0].setAttribute('x2', -500)
}
if (ycrosshairs && ycrosshairs[0]) {
ycrosshairs[0].setAttribute('y', -100)
ycrosshairs[0].setAttribute('y1', -100)
ycrosshairs[0].setAttribute('y2', -100)
}
}

svgUrl() {
return new Promise((resolve) => {
this.cleanup()
this.getSvgString().then((svgData) => {
const svgBlob = new Blob([svgData], {
type: 'image/svg+xml;charset=utf-8',
Expand All @@ -132,7 +134,6 @@ class Exports {
? options.scale || options.width / w.globals.svgWidth
: 1

this.cleanup()
const canvas = document.createElement('canvas')
canvas.width = w.globals.svgWidth * scale
canvas.height = parseInt(w.globals.dom.elWrap.style.height, 10) * scale // because of resizeNonAxisCharts
Expand Down
2 changes: 0 additions & 2 deletions src/modules/legend/Legend.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
import { SVG } from '@svgdotjs/svg.js'

import CoreUtils from '../CoreUtils'
import Dimensions from '../dimensions/Dimensions'
import Graphics from '../Graphics'
Expand Down

0 comments on commit beb688b

Please sign in to comment.