/// import { BasicElement, Time, IDCompound, DynamicGraph, NodePair, Node, Link, LinkType, copyPropsShallow } from './dynamicgraph' import * as moment from 'moment' /* moved from utils to queries */ export function getType(elements: any[]): string | undefined { // before was only string var type: string = ''; // before only string, without init if (elements.length == 0) return; if (elements[0] instanceof Node) type = 'node'; else if (elements[0] instanceof Link) { type = 'link'; } else if (elements[0] instanceof Time) { type = 'time'; } else if (elements[0] instanceof NodePair) { type = 'nodePair'; } else if (elements[0] instanceof LinkType) { type = 'linkType'; } else if (typeof elements[0] == 'number') { type = 'number'; } return type; } /* moved from utils to queries */ export function makeElementCompound(elements: IDCompound, g: DynamicGraph): ElementCompound { var result: ElementCompound = new ElementCompound; if (elements != undefined) { if (elements.nodeIds) { result.nodes = elements.nodeIds.map((id, i) => g.node(id)); // ?? WITH OR WITHOUT ?? .filter((element) => { return (element != undefined) }); } if (elements.linkIds) { result.links = elements.linkIds.map((id, i) => g.link(id)); } if (elements.timeIds) { result.times = elements.timeIds.map((id, i) => g.time(id)); } if (elements.nodePairIds) { result.nodePairs = elements.nodePairIds.map((id, i) => g.nodePair(id)); } } return result; } /* moved from utils to queries */ export class ElementCompound { nodes: Node[] = []; links: Link[] = []; times: Time[] = []; nodePairs: NodePair[] = []; locations: Location[] = []; } export function getPriorityColor(element: BasicElement): string | undefined { // before: return string var j = 0 var selections = element.getSelections(); while (!selections[j].showColor) { j++; if (j == selections.length) { j = -1; return; } } return element.getSelections()[j].color; } export function sortByPriority(s1: any, s2: any) { return s1.priority - s2.priority; } export function getUrlVars(): Object { var vars: Object = {}; var params = window.location.search.replace("?", "").split('&'); var tmp: any; var value: any; params.forEach(function (item) { tmp = item.split("="); value = decodeURIComponent(tmp[1]); (vars as any)[tmp[0]] = value; }); return vars; } export function capitalizeFirstLetter(string: string): string { return string.charAt(0).toUpperCase() + string.slice(1); } export function isBefore(t1: Time, t2: Time): boolean { return t1.time < t2.time; } export function isAfter(t1: Time, t2: Time): boolean { return t1.time > t2.time; } export function hex2Rgb(hex: string): number[] { return [hexToR(hex), hexToG(hex), hexToB(hex)] } function hexToR(h: any) { return parseInt((cutHex(h)).substring(0, 2), 16); } function hexToG(h: any) { return parseInt((cutHex(h)).substring(2, 4), 16); } function hexToB(h: any) { return parseInt((cutHex(h)).substring(4, 6), 16); } function cutHex(h: any) { return (h.charAt(0) == "#") ? h.substring(1, 7) : h; } export function hex2web(v: string) { v = v + ''; return v.replace('0x', '#'); } export function hex2RgbNormalized(hex: string): number[] { return [hexToR(hex) / 255, hexToG(hex) / 255, hexToB(hex) / 255] } export function areEqualShallow(a: any, b: any): boolean { for (var key in a) { if (!(key in b) || a[key] !== b[key]) { return false; } } for (var key in b) { if (!(key in a) || a[key] !== b[key]) { return false; } } return true; } export function compareTypesShallow(a: any, b: any): boolean { if (a == null || b == null) return a == b; if (typeof a != typeof b) return false; else if (typeof a != 'object') return true; else if (a.constructor !== b.constructor) return false; else { return true; } } export function copyArray(arr: any[], ctorFunc: () => TElement): TElement[] { var arrayClone: TElement[] = []; for (var elem in arr) { arrayClone.push(copyPropsShallow(arr[elem], ctorFunc())); } return arrayClone; } export class Box { x1: number; x2: number; y1: number; y2: number; constructor(x1: number, y1: number, x2: number, y2: number) { this.x1 = Math.min(x1, x2); this.x2 = Math.max(x1, x2); this.y1 = Math.min(y1, y2); this.y2 = Math.max(y1, y2); } get width(): number { return this.x2 - this.x1; } get height(): number { return this.y2 - this.y1; } isPoint(): boolean { return (this.width == 0) && (this.height == 0); } } export function inBox(x: any, y: any, box: Box): boolean { return (x > box.x1 && x < box.x2 && y > box.y1 && y < box.y2) } export function isSame(a: any[], b: any[]): boolean { if (a.length != b.length) return false; var found = true; for (var i = 0; i < a.length; i++) { found = false; for (var j = 0; j < b.length; j++) { if (a[i] == b[j]) found = true; } if (!found) return false; } return true; } export function cloneCompound(compound: IDCompound): IDCompound { var result: IDCompound = new IDCompound(); if (compound.nodeIds) { result.nodeIds = []; for (var i = 0; i < compound.nodeIds.length; i++) { result.nodeIds.push(compound.nodeIds[i]) } } if (compound.linkIds) { result.linkIds = []; for (var i = 0; i < compound.linkIds.length; i++) { result.linkIds.push(compound.linkIds[i]) } } if (compound.nodePairIds) { result.nodePairIds = []; for (var i = 0; i < compound.nodePairIds.length; i++) { result.nodePairIds.push(compound.nodePairIds[i]) } } if (compound.timeIds) { result.timeIds = []; for (var i = 0; i < compound.timeIds.length; i++) { result.timeIds.push(compound.timeIds[i]) } } return result; } export function makeIdCompound(elements: ElementCompound | undefined): IDCompound { var result: IDCompound = new IDCompound; if (elements != undefined) { if (elements.nodes) { result.nodeIds = elements.nodes.map((n: any, i: any) => n.id()); } if (elements.links) { result.linkIds = elements.links.map((n: any, i: any) => n.id()); } if (elements.times) { result.timeIds = elements.times.map((n: any, i: any) => n.id()); } if (elements.nodePairs) { result.nodePairIds = elements.nodePairs.map((n: any, i: any) => n.id()); } } return result; } export function formatAtGranularity(time: any, granualarity: number) { switch (granualarity) { case 0: return time.millisecond(); case 1: return time.second(); case 2: return time.minute(); case 3: return time.hour(); case 4: return time.day(); case 5: return time.week(); case 6: return time.month() + 1; case 7: return time.year(); } } export function arraysEqual(a: any, b: any) { if (a === b) return true; if (a == null || b == null) return false; if (a.length != b.length) return false; // If you don't care about the order of the elements inside // the array, you should sort both arrays here. for (var i = 0; i < a.length; ++i) { if (a[i] !== b[i]) return false; } return true; } export function encapsulate(array: any[], attrName?: string): Object[] { if (attrName == undefined) { attrName = 'element'; } var a = [] var o: Object; for (var i = 0; i < array.length; i++) { o = { index: i, }; (o as any)[attrName] = array[i]; a.push(o); } return a; } export function isPointInPolyArray(poly: number[][], pt: number[]) { for (var c = false, i = -1, l = poly.length, j = l - 1; ++i < l; j = i) ((poly[i][1] <= pt[1] && pt[1] < poly[j][1]) || (poly[j][1] <= pt[1] && pt[1] < poly[i][1])) && (pt[0] < (poly[j][0] - poly[i][0]) * (pt[1] - poly[i][1]) / (poly[j][1] - poly[i][1]) + poly[i][0]) && (c = !c); return c; } export function formatTimeAtGranularity(time: Time, granualarity: number) { var momentTime = moment.utc(time.unixTime()) switch (granualarity) { case 0: return momentTime.millisecond(); case 1: return momentTime.second(); case 2: return momentTime.minute(); case 3: return momentTime.hour(); case 4: return momentTime.day(); case 5: return momentTime.week(); case 6: return momentTime.month() + 1; default: return momentTime.year(); } } //////////////////////////// /// SCREENSHOT FUNCTIONS /// //////////////////////////// /////////// /// PNG /// /////////// // Downloads the content of the openGL canvas to the // desktop. export function downloadPNGFromCanvas(name: string) { var blob = getBlobFromCanvas(document.getElementsByTagName('canvas')[0]); var fileNameToSaveAs = name + '_' + new Date().toUTCString() + '.png'; var downloadLink = document.createElement("a") downloadLink.download = fileNameToSaveAs; downloadLink.href = window.URL.createObjectURL(blob); downloadLink.click(); } // Returns a blob from the passed canvas. function getBlobFromCanvas(canvas: any): Blob { var dataURL = canvas.toDataURL("image/png") return dataURItoBlob(dataURL); } /////////// /// SVG /// /////////// // downloads a screenshot on the desktop from the passed svg export function downloadPNGfromSVG(name: string, svgId: string) { var blob = getBlobFromSVG(name, svgId); } // creates an image blob from the passed svg and calls the // callback function with the blob as parameter export function getBlobFromSVG(name: string, svgId: string, callback?: Function) { var width = $('#' + svgId).width(); var height = $('#' + svgId).height(); if (callback != undefined) // UNDEFINED ?? getBlobFromSVGString(name, getSVGString(d3.select('#' + svgId).node()), width, height, callback) // what happend if callback undefinied (example above) } export function getBlobFromSVGNode(name: string, svgNode: any, callback: Function, backgroundColor?: string) { var string = getSVGString(svgNode); var width = svgNode.getAttribute('width') var height = svgNode.getAttribute('height') if (width == null) { width = window.innerWidth + 1000; } if (height == null) { height = window.innerHeight + 1000; } getBlobFromSVGString(name, string, width, height, callback, backgroundColor) } export function getBlobFromSVGString(name: string, svgString: string, width: number, height: number, callback: Function, backgroundColor?: string) { // get SVG string // CREATE PNG var format: any = format ? format : 'png'; // turn SVG in to PNG var imgsrc: string = 'data:image/svg+xml;base64,' + btoa(unescape(encodeURIComponent(svgString))); // Convert SVG string to data URL // Prepare canvas var canvas: any = document.createElement("canvas"); canvas.width = width; canvas.height = height; var context: any = canvas.getContext("2d"); var image: any = new Image(); image.src = imgsrc; image.onload = function () { context.clearRect(0, 0, width, height); if (backgroundColor) { context.fillStyle = backgroundColor; context.fillRect(0, 0, canvas.width, canvas.height); } context.drawImage(image, 0, 0, width, height); canvas.toBlob(function (blob: any) { callback(blob, name) }); }; } export function getSVGString(svgNode: any) { svgNode.setAttribute('xlink', 'http://www.w3.org/1999/xlink'); var cssStyleText = getCSSStyles(svgNode); appendCSS(cssStyleText, svgNode); var serializer = new XMLSerializer(); var svgString = serializer.serializeToString(svgNode); svgString = svgString.replace(/(\w+)?:?xlink=/g, 'xmlns:xlink='); // Fix root xlink without namespace svgString = svgString.replace(/NS\d+:href/g, 'xlink:href'); // Safari NS namespace fix return svgString; function getCSSStyles(parentElement: any) { var selectorTextArr = []; // Add Parent element Id and Classes to the list selectorTextArr.push('#' + parentElement.id); for (var c = 0; c < parentElement.classList.length; c++) if (!contains('.' + parentElement.classList[c], selectorTextArr)) selectorTextArr.push('.' + parentElement.classList[c]); // Add Children element Ids and Classes to the list var nodes = parentElement.getElementsByTagName("*"); for (var i = 0; i < nodes.length; i++) { var id = nodes[i].id; if (!contains('#' + id, selectorTextArr)) selectorTextArr.push('#' + id); var classes = nodes[i].classList; for (var c = 0; c < classes.length; c++) if (!contains('.' + classes[c], selectorTextArr)) selectorTextArr.push('.' + classes[c]); } // Extract CSS Rules var extractedCSSText = ""; for (var i = 0; i < document.styleSheets.length; i++) { var s = document.styleSheets[i]; try { if (!s.cssRules) continue; } catch (e) { if (e.name !== 'SecurityError') throw e; // for Firefox continue; } var cssRules = s.cssRules; for (var r = 0; r < cssRules.length; r++) { var rule = cssRules[r]; if (contains(rule.selectorText, selectorTextArr)) extractedCSSText += rule.cssText; } } return extractedCSSText; function contains(str: string, arr: any) { return arr.indexOf(str) === -1 ? false : true; } } function appendCSS(cssText: string, element: any) { var styleElement = document.createElement("style"); styleElement.setAttribute("type", "text/css"); styleElement.innerHTML = cssText; var refNode = element.hasChildNodes() ? element.children[0] : null; element.insertBefore(styleElement, refNode); } } export function exportPNG(canvas: any, name: string) { var dataURL: any = canvas.toDataURL('image/jpg', 1); var blob: any = dataURItoBlob(dataURL); // window.open(dataURL); var fileNameToSaveAs: any = name + '_' + new Date().toUTCString() + '.png'; var downloadLink: any = document.createElement("a") downloadLink.download = fileNameToSaveAs; downloadLink.href = (window as any).webkitURL.createObjectURL(blob); downloadLink.click(); } // returns a blob from a URL/URI function dataURItoBlob(dataURI: string): Blob { // convert base64/URLEncoded data component to raw binary data held in a string var byteString; if (dataURI.split(',')[0].indexOf('base64') >= 0) byteString = atob(dataURI.split(',')[1]); else byteString = unescape(dataURI.split(',')[1]); // separate out the mime component var mimeString = dataURI.split(',')[0].split(':')[1].split(';')[0]; console.log('mimeString', mimeString) // write the bytes of the string to a typed array var ia = new Uint8Array(byteString.length); for (var i = 0; i < byteString.length; i++) { ia[i] = byteString.charCodeAt(i); } return new Blob([ia], { type: mimeString }); } var msgBox; export function showMessage(message: string, timeout: any) { if ($('.messageBox')) $('.messageBox').remove(); msgBox = $('
'); msgBox.append('
\

' + message + '

'); $('body').append(msgBox); msgBox.click(function () { $('.messageBox').remove(); }) if (timeout) { // Automatically disappear window.setTimeout(function () { $('.messageBox').fadeOut(1000); }, timeout); } }