Created
January 29, 2020 13:23
-
-
Save akhoury/dbb19ead63defb2f75bf9755bdbc58a8 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(function () { | |
// By joseph khoury | |
let context = new AudioContext(); | |
let sound = context.createOscillator(); | |
sound.type = "sine"; | |
sound.connect(context.destination); | |
sound.frequency.value = 200; | |
sound.start(); | |
let ison = true; | |
let values = []; | |
let sdiv = document.createElement('div'); | |
sdiv.style = "color:white; padding: 10px;top: 10px;right: 10px;position: fixed;width: auto;height: auto;background-color: #002030;" | |
sdiv.innerHTML = `<p>Sound monitor</p> | |
<button id="sound_btn" style="margin-top: 10px;padding: 5px 10px;">Sound On/Off</button> | |
<p id="sound_sinr_p"><span id="sound_sinr" style="margin-top:10px;font-size:3em;">0</span>dB</p> | |
<style> | |
.chart { | |
width: 600px; | |
padding-left: 50px; | |
height: 300px; | |
margin: auto; | |
position: relative; | |
display: flex; | |
justify-content: space-between; | |
border-bottom: 1px solid #d4e3f6; | |
} | |
.chart .chartMeasurements { | |
position: absolute; | |
top: 0; | |
left: 0px; | |
width: 100%; | |
height: 100%; | |
display: flex; | |
justify-content: space-between; | |
flex-direction: column; | |
text-align: left; | |
z-index: 1; | |
} | |
.chart .chartMeasurements .chartMeasurement { | |
width: 100%; | |
flex-grow: 1; | |
border-top: 1px solid #d4e3f6; | |
} | |
.chart svg { | |
position: relative; | |
z-index: 2; | |
} | |
.chart svg polygon { | |
box-shadow: inset 2px 0 red; | |
fill: rgba(65, 131, 215, 0.6); | |
} | |
</style> | |
<div class="chart"></div> | |
`; | |
document.body.appendChild(sdiv); | |
let sound_sinr = document.getElementById('sound_sinr'); | |
let sound_sinr_p = document.getElementById('sound_sinr_p'); | |
document.getElementById('sound_btn').addEventListener('click',togglesound); | |
function togglesound(){ | |
ison = !ison; | |
if (!ison){ | |
sound.disconnect(context.destination); | |
}else{ | |
sound.connect(context.destination); | |
getsinr(); | |
} | |
} | |
//setInterval(getsinr, 1000); | |
getsinr(); | |
function getsinr() { | |
fetch('/../api/device/signal').then((response)=> response.text()).then(processsinr); | |
} | |
function processsinr(resp) { | |
let sinr = parseInt(getxml(resp, 'sinr'), 10); | |
if (isNaN(sinr)){ | |
sound_sinr.innerText = 'Error Need to Login'; | |
ison = false; | |
return; | |
} | |
values.push(sinr); | |
if (values.length >20){ | |
values = values.slice(-20); | |
} | |
//console.log('sinr',sinr); | |
adjustsound(sinr); | |
sound_sinr.innerText = sinr.toString(); | |
chart.createChart('.chart',values); | |
if (ison) { | |
setTimeout(getsinr, 500) | |
} | |
} | |
function getxml(txt, elm) { | |
let len = elm.length; | |
let a = txt.indexOf('<' + elm + '>'); | |
if (a == -1) return null | |
a = a + len + 2; | |
let b = txt.indexOf('</' + elm + '>', a); | |
if (b == -1) return null | |
return txt.substring(a, b); | |
} | |
function adjustsound(sinr) { | |
let min = 300; | |
let max = 2016; | |
if (sinr < 2) { | |
sinr = 2; | |
} else if (sinr > 24) { | |
sinr = 24; | |
} | |
sound.frequency.value = 78 * sinr + 144; | |
} | |
//TODO | |
function adjustcolor(sinr){ | |
let red = 0; | |
let green = 0; | |
//7, 10 , 12.5 | |
sound_sinr_p.style.background = "radial-gradient(rgba(100, 100, 3, 1), transparent)"; | |
} | |
console.clear(); | |
var chart = { | |
element : "", | |
chart : "", | |
polygon : "", | |
width : 100, | |
height : 50, | |
maxValue : 0, | |
values : [], | |
points : [], | |
vSteps : 5, | |
measurements : [], | |
calcMeasure : function(){ | |
this.measurements = []; | |
for(x=0; x < this.vSteps; x++){ | |
var measurement = Math.ceil((this.maxValue / this.vSteps) * (x +1)); | |
this.measurements.push(measurement); | |
} | |
this.measurements.reverse(); | |
}, | |
/** | |
* Get Element | |
* Take the selector being passed, determine if | |
* the selector is a class (".") or an id ("#"), and get the element | |
* @param {String} element - the element selector | |
*/ | |
getElement : function(element){ | |
if(element.indexOf(".") == 0){ | |
this.element = document.getElementsByClassName("chart")[0] | |
} | |
else if(element.indexOf("#") == 0){ | |
this.element = document.getElementById("chart"); | |
} | |
else { | |
console.error("Please select a valid element"); | |
} | |
}, | |
/** | |
* Create Chart | |
* - calc the max value | |
* - calc the points for the polygon | |
* - create a chart <svg> | |
* - set width, height, and viewbox attributes on <svg> | |
* - create a <polygon> | |
* - set points on <polygon> | |
* - calc the vertical measurements | |
* @param {array} values - the values to plot on the chart | |
*/ | |
createChart : function(element, values){ | |
this.getElement(element); | |
this.values = values; | |
// Do some calculations | |
this.calcMaxValue(); | |
this.calcPoints(); | |
this.calcMeasure(); | |
// Clear any existing | |
this.element.innerHTML = ""; | |
// Create the <svg> | |
this.chart = document.createElementNS("http://www.w3.org/2000/svg", "svg"); | |
this.chart.setAttribute("width", "100%"); | |
this.chart.setAttribute("height", "100%"); | |
this.chart.setAttribute("viewBox", "0 0 " + chart.width + " " + chart.height); | |
// Create the <polygon> | |
this.polygon = document.createElementNS('http://www.w3.org/2000/svg','polygon'); | |
this.polygon.setAttribute("points", this.points); | |
this.polygon.setAttribute("class", "line"); | |
if(this.values.length > 1){ | |
var measurements = document.createElement("div"); | |
measurements.setAttribute("class", "chartMeasurements"); | |
for(x=0; x < this.measurements.length; x++){ | |
var measurement = document.createElement("div"); | |
measurement.setAttribute("class", "chartMeasurement"); | |
measurement.innerHTML = this.measurements[x]; | |
measurements.appendChild(measurement); | |
} | |
this.element.appendChild(measurements); | |
// Append the <svg> to the target <div> | |
this.element.appendChild(this.chart); | |
// Append the polygon to the target <svg> | |
this.chart.appendChild(this.polygon); | |
} | |
}, | |
/** | |
* Calc Points | |
* Calculate all the points for the polygon | |
*/ | |
calcPoints : function(){ | |
this.points = []; | |
if(this.values.length > 1){ | |
// First point is bottom left hand side (max value is the bottom of graph) | |
var points = "0," + chart.height + " "; | |
// Loop through each value | |
for(x=0; x < this.values.length; x++){ | |
// Calculate the perecentage of this value/the max value | |
var perc = this.values[x] / this.maxValue; | |
// Steps is a percentage (100) / the total amount of values | |
var steps = 100 / ( this.values.length - 1 ); | |
// Create the point, limit points to 2 decimal points, | |
// Y co-ord is calculated by the taking the chart height, | |
// then subtracting (chart height * the percentage of this point) | |
// Remember the & co-ord is measured from the top not the bottom like a traditional graph | |
var point = (steps * (x )).toFixed(2) + "," + (this.height - (this.height * perc)).toFixed(2) + " "; | |
// Add this point | |
points += point; | |
} | |
// Add the final point (bottom right) | |
points += "100," + this.height; | |
this.points = points; | |
} | |
}, | |
/** | |
* Calculate Max Value | |
* Find the highest value in the array, and then | |
* add 10% to it so the graph doesn't touch the top of the chart | |
*/ | |
calcMaxValue : function(){ | |
this.maxValue = 0; | |
for(x=0; x < this.values.length; x++){ | |
if(this.values[x] > this.maxValue){ | |
this.maxValue = this.values[x]; | |
} | |
} | |
// Round up to next integer | |
this.maxValue = Math.ceil(this.maxValue); | |
} | |
} | |
function clearChart(){ | |
values = []; | |
chart.createChart('.chart',values); | |
} | |
chart.createChart('.chart',[0,0,1,0]); | |
})(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment