vue-d3-network
Version:
Vue component to graph networks using d3-force
144 lines (130 loc) • 3.75 kB
JavaScript
export default {
NS: 'http://www.w3.org/2000/svg',
// svgOrg: svg element
// allCss : true includes all svg css styles, false includes only matched styles
export (svgOrg, allCss) {
let svg = null
if (this.isSvgData(svgOrg)) {
svg = svgOrg.cloneNode(true)
let childs = svgOrg.parentNode.querySelectorAll('*')
let cssStyle = {}
let rules = this.getcssRules()
for (let child of childs) {
let elRules = rules
if (!allCss) {
elRules = rules.filter((rule) => {
return child.matches(rule.selectorText)
})
}
for (let rule of elRules) {
cssStyle[rule.selectorText] = rule.cssText
}
}
let css = Object.values(cssStyle).join('\n')
if (css) {
let style = document.createElementNS(this.NS, 'style')
style.type = 'text/css'
svg.insertBefore(style, svg.childNodes[0])
style.innerHTML = css
svg.appendChild(style)
}
}
return svg
},
makeCanvas (width, height, background) {
let canvas = document.createElement('canvas')
canvas.width = width
canvas.height = height
let ctx = canvas.getContext('2d')
ctx.fillStyle = background || 'white'
ctx.fillRect(0, 0, canvas.width, canvas.height)
return canvas
},
serialize (svg) {
return (new XMLSerializer()).serializeToString(svg)
},
svgToImg (svg, canvas, cb) {
let xml = this.serialize(svg)
let img = new Image()
let ctx = canvas.getContext('2d')
img.onload = function () {
ctx.drawImage(this, 0, 0)
let png = canvas.toDataURL('image/png')
cb(null, png, ctx)
}
img.onerror = function (err) {
cb(err)
}
img.src = 'data:image/svg+xml;base64,' + btoa(unescape(encodeURIComponent(xml)))
},
save (svg) {
return 'data:image/svg+xml;charset=utf-8,' + encodeURIComponent(this.serialize(svg))
},
getcssRules () {
let rules = []
for (let styles of document.styleSheets) {
let styleRules = this.readRules(styles)
for (let rule of styleRules) {
if (rule && rule.cssText) {
rules.push(rule)
}
}
}
return rules
},
readRules (styles) {
try {
if (!styles.cssRules) return styles.rules || []
} catch (e) {
// Firefox returns Security Error if stylesheet originates from different domain
if (e.name !== 'SecurityError') throw e
return []
}
return styles.cssRules
},
toDom (svgData) {
let div = document.createElement('div')
div.innerHTML = svgData
return div.firstChild || null
},
toObject (svg) {
if (svg) {
let attrs = {}
if (svg.attributes) {
for (let i = svg.attributes.length; i >= 0; i--) {
let a = svg.attributes[i]
if (a) attrs[a.name] = a.value
}
}
let data = svg.innerHTML
if (data) return { attrs, data }
}
return null
},
svgElFromString (svgData) {
let svgEl = this.toDom(svgData)
if (!this.isSvgData(svgEl)) return
svgEl.setAttribute('xmlns', 'http://www.w3.org/2000/svg')
return svgEl
},
svgDataToUrl (svgData, attrs) {
if (typeof (attrs) === 'object') {
for (let a in attrs) {
let attribute = (attrs[a]) ? (attrs[a]) : ''
svgData.setAttribute(a, attribute)
}
}
let svg = this.export(svgData)
if (svg) return this.svgToUrl(this.serialize(svg))
return null
},
isSvgData (svgData) {
if (!svgData.firstChild) return false
return (svgData.firstChild.parentNode.nodeName === 'svg')
},
svgToUrl (svg) {
let xml = new Blob([svg], { type: 'image/svg+xml' })
let url = URL.createObjectURL(xml)
return url
}
}