Published
Edited
Mar 3, 2021
Fork of Untitled
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
viewof gamma3 = {
const chart = html`

<svg style="width:100%; height: 100%; overflow: hidden;" viewBox="0 0 ${width} ${width}" id="htmlChart">
<g stroke="#ccc" stroke-width="0.5" fill="none">
<path d="
${d3.ticks( 0.0, 0.2, 20).slice(1).map(R => resistanceArc(R, -0.2, 0.2))}
${d3.ticks( 0.0, 0.5, 20).slice(1).map(R => resistanceArc(R, -0.5, 0.5))}
${d3.ticks( 0.0, 0.5, 10).slice(1).map(R => resistanceArc(R, 0.5, 1.0))}
${d3.ticks( 0.5, 1.0, 10).map(R => resistanceArc(R, -1.0, 1.0))}
${d3.ticks( 0.0, 2.0, 20).slice(1).map(R => resistanceArc(R, -2.0, 2.0))}
${d3.ticks( 0.0, 5.0, 20).slice(1).map(R => resistanceArc(R, -5.0, 5.0))}
${d3.ticks( 0.0, 10.0, 10).slice(1).map(R => resistanceArc(R, -10.0, 10.0))}
${d3.ticks( 0.0, 20.0, 10).slice(1).map(R => resistanceArc(R, -20.0, 20.0))}
${d3.ticks( 0.0, 50.0, 5).slice(1).map(R => resistanceArc(R, -50.0, 50.0))}
${d3.ticks( -0.2, 0.2, 40).map(X => reactanceArc(X, 0.0, 0.2))}
${d3.ticks( -0.5, 0.5, 40).map(X => reactanceArc(X, 0.0, 0.5))}
${d3.ticks( -1.0, 1.0, 30).map(X => reactanceArc(X, 0.5, 1.0))}
${d3.ticks( -1.0, -0.5, 10).map(X => reactanceArc(X, 0.0, 0.5))}
${d3.ticks( 0.5, 1.0, 10).map(X => reactanceArc(X, 0.0, 0.5))}
${d3.ticks( -2.0, 2.0, 40).map(X => reactanceArc(X, 0.0, 2.0))}
${d3.ticks( -5.0, 5.0, 40).map(X => reactanceArc(X, 0.0, 5.0))}
${d3.ticks(-10.0, 10.0, 20).map(X => reactanceArc(X, 0.0, 10.0))}
${d3.ticks(-20.0, 20.0, 20).map(X => reactanceArc(X, 0.0, 20.0))}
${d3.ticks(-50.0, 50.0, 10).map(X => reactanceArc(X, 0.0, 50.0))}
${d3.ticks(-50.0, 50.0, 5).map(X => reactanceArc(X, 0.0, Infinity))}
" />
</g>
<g stroke="#999" stroke-width="1" fill="none">
<path d="
${d3.ticks( 0.0, 0.2, 5).slice(1).map(R => resistanceArc(R, -0.2, 0.2))}
${d3.ticks( 0.0, 1.0, 10).slice(1).map(R => resistanceArc(R, -1.0, 1.0))}
${d3.ticks( 0.0, 2.0, 10).slice(1).map(R => resistanceArc(R, -2.0, 2.0))}
${d3.ticks( 0.0, 5.0, 5).slice(1).map(R => resistanceArc(R, -5.0, 5.0))}
${d3.ticks( 0.0, 10.0, 2).slice(1).map(R => resistanceArc(R, -10.0, 10.0))}
${d3.ticks( 0.0, 20.0, 2).slice(1).map(R => resistanceArc(R, -20.0, 20.0))}
${d3.ticks( 0.0, 50.0, 2).slice(1).map(R => resistanceArc(R, -Infinity, Infinity))}
${d3.ticks( -0.2, 0.2, 10).map(X => reactanceArc(X, 0.0, 0.2))}
${d3.ticks( -1.0, 1.0, 20).map(X => reactanceArc(X, 0.0, 1.0))}
${d3.ticks( -2.0, 2.0, 20).map(X => reactanceArc(X, 0.0, 2.0))}
${d3.ticks( -5.0, 5.0, 10).map(X => reactanceArc(X, 0.0, 5.0))}
${d3.ticks(-10.0, 10.0, 5).map(X => reactanceArc(X, 0.0, 10.0))}
${d3.ticks(-20.0, 20.0, 5).map(X => reactanceArc(X, 0.0, 20.0))}
${d3.ticks(-50.0, 50.0, 2).map(X => reactanceArc(X, 0.0, Infinity))}
" />
</g>
<g stroke="#000" stroke-width="1" fill="none">
<path d="
${resistanceArc(0, -Infinity, Infinity)}
${reactanceArc(0, 0, Infinity)}
" />
</g>
<g stroke-width="1.5" fill="none" id="objects">
</g>
<circle cx="${width / 2}" cy="${width / 2}" r="3" />
<g font-family="sans-serif" font-size="12" text-anchor="middle">
${[...d3.ticks(0.1, 1, 10), ...d3.ticks(1.2, 2, 4), ...d3.ticks(3, 5, 2), 10, 20, 50].map(R => svg`
<text dy="-6" transform="translate(${transform(smith([R, 0])) + ""})" fill="none" stroke="white" stroke-width="4" stroke-linejoin="round">${R.toFixed(R < 10)}</text>
<text dy="-6" transform="translate(${transform(smith([R, 0])) + ""})">${R.toFixed(R < 10)}</text>`)}
</g>
<g font-family="sans-serif" font-size="12" text-anchor="middle">
${[...d3.ticks(0.1, 1, 10), ...d3.ticks(1.2, 2, 4), ...d3.ticks(3, 5, 2), 10, 20, 50].map(X => svg`
<text dy="0.32em" transform="translate(${label(smith([0, -X])) + ""})">-${X.toFixed(X < 10)}</text>
<text dy="0.32em" transform="translate(${label(smith([0, X])) + ""})">+${X.toFixed(X < 10)}</text>`)}
<text dy="0.32em" transform="translate(${label(smith([0, 0])) + ""})">0.0</text>
</g>
</svg>`;
//get reference to html buttons
const sizeButton = document.getElementById("calcSize");
const zButton = document.getElementById("calcImp");
var reflCart = {real : 0,
imaginary : 0
};
function calculateParam ()
{
//show paragraphs containing calculated Z values
document.getElementById("chartZ").style.visibility = "visible";
document.getElementById("chartZpolar").style.visibility = "visible";
//characteristic impedance
const z0 = 50;
const cy = this.cy.baseVal.value;
const cx = this.cx.baseVal.value;
//reverse the value from G
const Rvalue = Number((width - (2*cx))/((2*margin) - width));
const Xvalue = Number(-(width - (2*cy))/((2*margin)- width));
const point = [Rvalue, Xvalue];
//convert into actual normalised impedance value
const actualVal = smithInvert(point);
//convert to unnormalised values
const Ractual = (actualVal[0]*z0).toFixed(2);
const Xactual = (actualVal[1]*z0).toFixed(2);
const Zid = "chartZ";
const ZpolarId = "chartZpolar";
//display value in html elements and return the magnitude of the plotted load
const Zpolar = impedanceVal (Ractual, Xactual, z0, Zid, ZpolarId);
//obtain html values to calculate length and width
const substrateH = document.getElementById("substrateH").value;
const metalH = document.getElementById("metalH").value;
const relativeP = document.getElementById("relativeP").value;
const frequency = document.getElementById("freq").value;
const degrees = document.getElementById("degrees").value;
//calculate the width of the line in mm
const lineWidth = ((calculateWidth (Zpolar, substrateH, metalH, relativeP))*(10**3)).toFixed(3);
const htmlWidth = "calculatedFirst";
displayWidth (htmlWidth, lineWidth);
//calculate the length of the line
const lineLength = ((calculateLength (relativeP, substrateH, lineWidth, frequency, degrees))*(10**3)).toFixed(3);
const htmlLength = "calculatedSecond";
displayLength (htmlLength, lineLength);
//briefly flash text
const para1 = "calculatedFirst";
makeFlash (para1);
const para2 = "calculatedSecond";
makeFlash (para2);
const para3 = "chartZpolar";
makeFlash(para3);
makeFlash (Zid);
}
//plot a permanent point on click
chart.onclick = event => {
let point = chart.createSVGPoint();
point.x = event.clientX; //x coordinate of mouse position (in pixels)
point.y = event.clientY; //y coordinate of mouse position

//Learn current transformation matrix (CTM) of the SVG element and get screen position
//i.e. convert the SVG coordinates to coordinates in terms of the entire screen
const matrix = chart.getScreenCTM().inverse();
point = point.matrixTransform(matrix);
//get namespace and create a new svg element
const svgns = "http://www.w3.org/2000/svg";
let newPoint = document.createElementNS(svgns, "circle");

//set position of point and attributes
newPoint.setAttribute("cx", point.x);
newPoint.setAttribute("cy", point.y);
newPoint.setAttribute("r", 5);
newPoint.setAttribute('fill','black');
newPoint.classList.add("loadPoint");
newPoint.addEventListener('mouseover', calculateParam, false);

//append point to group containing points
document.getElementById('objects').appendChild(newPoint);
}
//function that calculates impedance after clicking the relevant button
zButton.onclick = event => {
//get values from html elements
const substrateH = document.getElementById("substrateH").value;
const metalH = document.getElementById("metalH").value;
const relativeP = document.getElementById("relativeP").value;
const frequency = document.getElementById("freq").value;
const lineWidth = document.getElementById("htmlWidth").value;
const lineLength = document.getElementById("htmlLength").value;
//calculate z0
const calculatedZ0 = (calculateZ0 (relativeP, substrateH, lineWidth, metalH)).toFixed(2);
const z0id = "calculatedFirst";
displayZ0 (z0id, calculatedZ0);
//calculate length in degrees
const calculatedDeg = (calculateDegrees(relativeP, substrateH, lineWidth, frequency, lineLength)).toFixed(2);
const degId = "calculatedSecond";
displayDegrees (degId, calculatedDeg);
//briefly flash text
const para1 = "calculatedFirst";
makeFlash (para1);
const para2 = "calculatedSecond";
makeFlash (para2);
//hide paragraphs displaying impedance of other calculation
document.getElementById("chartZ").style.visibility = "hidden";
document.getElementById("chartZpolar").style.visibility = "hidden";
}
//function that calculates width and length after clicking on relevant button
sizeButton.onclick = event => {
//hide paragraphs displaying impedance of other calculation
document.getElementById("chartZ").style.visibility = "hidden";
document.getElementById("chartZpolar").style.visibility = "hidden";
//obtain html values to calculate length and width
const substrateH = document.getElementById("substrateH").value;
const metalH = document.getElementById("metalH").value;
const relativeP = document.getElementById("relativeP").value;
const frequency = document.getElementById("freq").value;
const degrees = document.getElementById("degrees").value;
const R0 = document.getElementById("htmlZ0").value;
const x0 = document.getElementById("htmlX0").value;
//convert impedance to magnitude
const Zmag = Math.sqrt((R0**2) + (x0**2));
//calculate the width of the line in mm
const lineWidth = ((calculateWidth (Zmag, substrateH, metalH, relativeP))*(10**3)).toFixed(3);
const htmlWidth = "calculatedFirst";
displayWidth (htmlWidth, lineWidth);
//calculate the length of the line
const lineLength = ((calculateLength (relativeP, substrateH, lineWidth, frequency, degrees))*(10**3)).toFixed(3);
const htmlLength = "calculatedSecond";
displayLength (htmlLength, lineLength);
//briefly flash text
const para1 = "calculatedFirst";
makeFlash (para1);
const para2 = "calculatedSecond";
makeFlash (para2);
}

function label([x, y]) {
return transform([x * 1.025, y * 1.025]);
}
chart.value = [0, 0];
return chart;
};
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
function impedanceVal (Rvalue, Xvalue, z0, Zid, ZpolarId) {
const Rnormalised = Rvalue/z0;
const Xnormalised = Xvalue/z0;
const normTxt = "norm";
const lTxt = "line";
const jsZ = document.getElementById(Zid);
const jsZpolar = document.getElementById(ZpolarId);
//calculate magnitude of impedance
const zPolar = Math.sqrt((Rvalue**2)+(Xvalue**2));
//update value of Z normalised and Z on html page
jsZ.innerHTML = "Z" + lTxt.sub() + " = " + String(Rvalue) + " ";
jsZpolar.innerHTML = "|Z|" + " = " + String((zPolar).toFixed(2));
//check whether reactance is positive or negative
if(Xvalue < 1) {
jsZ.innerHTML = jsZ.innerHTML + "-j" + Math.abs(Xvalue);
}
else {
jsZ.innerHTML = jsZ.innerHTML + "+j" + Math.abs(Xvalue);
}
return zPolar;
}
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
d3 = require("d3-array@2")
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