Published
Edited
Sep 25, 2020
Importers
Insert cell
md`# NetV.js v1 Test Document
- Interfaces and Utils
- Initialization
- [Container](https://observablehq.com/@jackieanxis/netv-1-testdoc-initialization?collection=@jackieanxis/netv-js-v1-test-documents)
- [Width & Height](https://observablehq.com/@jackieanxis/netv-1-testdoc-initialization-width-height?collection=@jackieanxis/netv-js-v1-test-documents)
- [BackgroundColor](https://observablehq.com/@jackieanxis/netv-1-testdoc-initialization-backgroundcolor?collection=@jackieanxis/netv-js-v1-test-documents)
- [Default Node Style](https://observablehq.com/@jackieanxis/netv-1-testdoc-initialization-node?collection=@jackieanxis/netv-js-v1-test-documents)
- [Default Link Style](https://observablehq.com/@jackieanxis/netv-1-testdoc-initialization-link?collection=@jackieanxis/netv-js-v1-test-documents)`
Insert cell
NNetV = require("netv@1") // require from npm
Insert cell
NetV = NNetV.NetV
Insert cell
function refresh (div) {
const canvas = div.querySelector('canvas')
if(canvas) canvas.getContext('webgl2').getExtension('WEBGL_lose_context').loseContext()
Array.from(div.children).forEach((child) => div.removeChild.bind(div)(child))
}
Insert cell
function getPixelColor (canvas, x, y) {
var context = canvas.getContext('webgl2')
var pixels = new Uint8Array(
4 * context.drawingBufferWidth * context.drawingBufferHeight
)
context.readPixels(
0,
0,
context.drawingBufferWidth,
context.drawingBufferHeight,
context.RGBA,
context.UNSIGNED_BYTE,
pixels
)
return {
r: pixels[4 * (y * context.drawingBufferWidth + x)] / 255,
g: pixels[4 * (y * context.drawingBufferWidth + x) + 1] / 255,
b: pixels[4 * (y * context.drawingBufferWidth + x) + 2] / 255,
a: pixels[4 * (y * context.drawingBufferWidth + x) + 3] / 255
}
}
Insert cell
function rgba2hex(rgba) {
function num2hex (n) {
let hex = Math.round(n * 255).toString(16)
if (hex.length < 2) return '0' + hex
else return hex
}
return '#' + num2hex(rgba.r) + num2hex(rgba.g) + num2hex(rgba.b) + ('a' in rgba ? num2hex(rgba.a) : '')
}
Insert cell
function hex2rgba(hex) { // r, g, b, a: 0-1
function isFormatted(hex) {
if (hex[0] != '#') {
return Array.from(hex).every(char => !isNaN(parseInt(char, 16)))
} else {
return Array.from(hex.slice(1)).every(char => !isNaN(parseInt(char, 16)))
}
}
function hex2num (h) {
return parseInt(h, 16) / (h.length > 1 ? 255 : 15)
}
if (!isFormatted (hex)) {
throw TypeError(`${hex} is not a hex color`)
}
if (hex.length == 3) {
return {
r: hex2num(hex.slice(0 ,1)),
g: hex2num(hex.slice(1, 2)),
b: hex2num(hex.slice(2, 3)),
a: 1
}
} else if (hex.length == 4) {
if (hex[0] == '#') {
return {
r: hex2num(hex.slice(1, 2)),
g: hex2num(hex.slice(2, 3)),
b: hex2num(hex.slice(3, 4)),
a: 1
}
} else {
return {
r: hex2num(hex.slice(0 ,1)),
g: hex2num(hex.slice(1, 2)),
b: hex2num(hex.slice(2, 3)),
a: hex2num(hex.slice(3, 4))
}
}
} else if (hex.length == 5) {
return {
r: hex2num(hex.slice(1, 2)),
g: hex2num(hex.slice(2, 3)),
b: hex2num(hex.slice(3, 4)),
a: hex2num(hex.slice(4, 5))
}
} else if (hex.length == 6) {
return {
r: hex2num(hex.slice(0, 2)),
g: hex2num(hex.slice(2, 4)),
b: hex2num(hex.slice(4, 6)),
a: 1
}
} else if (hex.length == 7) {
return {
r: hex2num(hex.slice(1, 3)),
g: hex2num(hex.slice(3, 5)),
b: hex2num(hex.slice(5, 7)),
a: 1
}
} else if (hex.length == 8) {
return {
r: hex2num(hex.slice(0, 2)),
g: hex2num(hex.slice(2, 4)),
b: hex2num(hex.slice(4, 6)),
a: hex2num(hex.slice(6, 8))
}
} else if (hex.length == 9) {
return {
r: hex2num(hex.slice(1, 3)),
g: hex2num(hex.slice(3, 5)),
b: hex2num(hex.slice(5, 7)),
a: hex2num(hex.slice(7, 9))
}
} else {
throw TypeError(`${hex} is not a hex color`)
}
}
Insert cell
error_color = "rgb(240, 58, 23)"
Insert cell
success_color = "rgb(20, 185, 11)"
Insert cell
warning_color = "rgb(250, 141, 50)"
Insert cell
function generateAutoTestCaseDescription(caseObj) {
return `### ${caseObj.isPassed ? "✔️" : "❌"} ${caseObj.title}
- Expected Result: <code style="background: ${caseObj.expected.includes('Error') ? error_color : success_color}; color: white;">"${caseObj.expected}"</code>
- Actual Result: <code style="background: ${caseObj.log.includes('Error') ? error_color : success_color}; color: white;">"${caseObj.log}"</code>`
}
Insert cell
function generateE2ETestCaseDescription(caseObj) {
return `### ${caseObj.isPassed ? "🌝" : "🌚"} ${caseObj.title}
- Expected Result: <code style="background: ${caseObj.expected.includes('Error') ? error_color : success_color}; color: white;">"${caseObj.expected}"</code>
- E2E Test Result: <code style="background: ${warning_color}; color: white;">"${caseObj.testerReport}"</code>`
}
Insert cell
function isHexColorSame (hexColorA, hexColorB, THRESHOLD_RANGE_0_TO_1 = 0.01) {
const rgbaColorA = hex2rgba(hexColorA)
const rgbaColorB = hex2rgba(hexColorB)
const isChannelRSame = Math.abs(rgbaColorA.r - rgbaColorB.r) < THRESHOLD_RANGE_0_TO_1
const isChannelGSame = Math.abs(rgbaColorA.g - rgbaColorB.g) < THRESHOLD_RANGE_0_TO_1
const isChannelBSame = Math.abs(rgbaColorA.b - rgbaColorB.b) < THRESHOLD_RANGE_0_TO_1
const isChannelASame = Math.abs(rgbaColorA.a - rgbaColorB.a) < THRESHOLD_RANGE_0_TO_1
return isChannelRSame && isChannelGSame && isChannelBSame && isChannelASame
}
Insert cell
function detectZoom() {
var ratio = 0,
screen = window.screen,
ua = navigator.userAgent.toLowerCase();

if (window.devicePixelRatio !== undefined) {
ratio = window.devicePixelRatio;
}
else if (~ua.indexOf('msie')) {
if (screen.deviceXDPI && screen.logicalXDPI) {
ratio = screen.deviceXDPI / screen.logicalXDPI;
}
}
else if (window.outerWidth !== undefined && window.innerWidth !== undefined) {
ratio = window.outerWidth / window.innerWidth;
}
return ratio;
}
Insert cell
function isNumberSame (lengthA, lengthB, threshold = 2) {
return lengthA - lengthB < threshold
}
Insert cell
function isStringSameIgnoreQuotesCase (stringA, stringB) {
return stringA.replace(/\"/g, "'").replace(/\'/g, '"') == stringB.replace(/\"/g, "'").replace(/\'/g, '"')
}
Insert cell
function isSameForColorCompare (a, b) {
try {
return isHexColorSame(a, b)
} catch (e) {
return isStringSameIgnoreQuotesCase(a, b) // compare error log information
}
}
Insert cell

Purpose-built for displays of data

Observable is your go-to platform for exploring data and creating expressive data visualizations. Use reactive JavaScript notebooks for prototyping and a collaborative canvas for visual data exploration and dashboard creation.
Learn more