Thank you for your time.
I can't get the Needle on the Gauge to move I used the following and no luck.
In the serial monitor I can see the Value of adc change as I move the Potentiometer.in the Web server address 192.168.4.1 I can see the gauge but no movement of the needle as I move the pot.
In the HTML There are 2 scripts. is that put together wrong?
Is there a better way?
<!doctype html>
<html>
<head>
<title>Testing Gauges</title>
<script src="gauge.min.js"></script>
</head>
<body>
<canvas id="gauge-ps"></canvas>
<script>
setInterval(function() {
// Gets ADC value at every one second
GetADC();
}, 1000);
function GetADC() {
var xhttp = new XMLHttpRequest();
var adc=0;
xhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
adc = Number(this.responseText);
}
};
xhttp.open("GET", "/getADC", false);
xhttp.send();
}
</script>
<script>
var gaugePS = new RadialGauge({
renderTo: 'gauge-ps',
width: 400,
height: 400,
units: 'Temp',
minValue: 0,
maxValue: 100,
majorTicks: [
'0','10','20','30','40','50','60','70','80','90','100'
],
minorTicks: 2,
ticksAngle: 270,
startAngle: 45,
strokeTicks: true,
highlights : [
{ from : 45, to : 80, color : 'rgba(78, 78, 76, 0.5)' },
{ from : 80, to : 100, color : 'rgba(225, 7, 23, 0.75)' }
],
valueInt: 1,
valueDec: 0,
colorPlate: "#fff",
colorMajorTicks: "#686868",
colorMinorTicks: "#686868",
colorTitle: "#000",
colorUnits: "#000",
colorNumbers: "#686868",
valueBox: true,
colorValueText: "#000",
colorValueBoxRect: "#fff",
colorValueBoxRectEnd: "#fff",
colorValueBoxBackground: "#fff",
colorValueBoxShadow: false,
colorValueTextShadow: false,
colorNeedleShadowUp: true,
colorNeedleShadowDown: false,
colorNeedle: "rgba(200, 50, 50, .75)",
colorNeedleEnd: "rgba(200, 50, 50, .75)",
colorNeedleCircleOuter: "rgba(200, 200, 200, 1)",
colorNeedleCircleOuterEnd: "rgba(200, 200, 200, 1)",
borderShadowWidth: 0,
borders: true,
borderInnerWidth: 0,
borderMiddleWidth: 0,
borderOuterWidth: 5,
colorBorderOuter: "#fafafa",
colorBorderOuterEnd: "#cdcdcd",
needleType: "arrow",
needleWidth: 2,
needleCircleSize: 7,
needleCircleOuter: true,
needleCircleInner: false,
animationDuration: 1500,
animationRule: "dequint",
fontNumbers: "Verdana",
fontTitle: "Verdana",
fontUnits: "Verdana",
fontValue: "Led",
fontValueStyle: 'italic',
fontNumbersSize: 20,
fontNumbersStyle: 'italic',
fontNumbersWeight: 'bold',
fontTitleSize: 24,
fontUnitsSize: 22,
fontValueSize: 50,
animatedValue: true
});
gaugePS.draw();
gaugePS.value = "adc" ;
</script>
</body>
</html>
Add an HTTP endpoint for the browser to respond with the latest reading.
First add a handler on the route /getADC:
// declare handleAdcPath before this snippet
server.on("/getADC", handleAdcPath);
Then implement the handler:
void handleAdcPath()
{
auto requestMethod = server.method();
if (requestMethod == HTTP_GET)
{
server.send(200, "text/plain", getAdc());
}
}
Where getAdc has been declared before the snippet above. e.g.
int getAdc()
{
return analogRead(A0);
}
Related
I would like to use JS classes from a cdn within a react component.
This is the cdn: https://cdn.jsdelivr.net/gh/Mikhus/canvas-gauges#gh-pages/download/2.1.7/all/gauge.min.js
I have already written the vanillaJS Code, that works well, however I have not idea how
to implement this with react.
The object that is drawn into a canvas is first instantiated with a set of different values,
then it is drawn on the canvas, then you can access the values from outside. I works well with vanillaJS!!
CDN or local file:
<script src="./lib/canvas-gauges.min.js"></script>
html canvas:
<canvas
id="barometer"
</canvas>
instantiating object and drawing it on the canvas:
const barometer = new RadialGauge({
renderTo: canvas,
title: 'hPa',
width: 400,
height: 400,
units: `${location}`,
minValue: 960,
maxValue: 1060,
majorTicks: [
"",
"970",
"980",
"990",
"1000",
"1010",
"1020",
"1030",
"1040",
"1050",
"",
],
minorTicks: 10,
ticksAngle: 270,
startAngle: 45,
strokeTicks: true,
highlights: [
{
"from": 960,
"to": 1005,
"color": "rgba(0,0,255,0.8)"
},
{
"from": 1005,
"to": 1023,
"color": "rgba(0, 151, 19, 0.3)"
},
{
"from": 1023,
"to": 1060,
"color": "rgba(241, 90, 34, 0.9)"
}
],
valueInt: 1,
valueDec: 0,
colorPlate: "beige",
colorMajorTicks: "#686868",
colorMinorTicks: "#686868",
colorTitle: "#000",
colorUnits: "#000",
colorNumbers: "#686868",
valueBox: true,
colorNeedleShadowUp: true,
colorNeedleShadowDown: true,
colorNeedle: "#f59042",
colorNeedleEnd: "#f59042",
colorNeedleCircleOuter: "rgba(200, 200, 200, 1)",
colorNeedleCircleOuterEnd: "rgba(200, 200, 200, 1)",
borderShadowWidth: 0,
borders: false,
borderInnerWidth: 0,
borderMiddleWidth: 0,
borderOuterWidth: 20,
colorBorderOuter: "silver",
colorBorderOuterEnd: "black",
needleType: "arrow",
needleWidth: 2,
needleCircleSize: 7,
needleCircleOuter: true,
needleCircleInner: false,
animationDuration: 1500,
animationRule: "dequint",
fontNumbers: "Arial",
fontTitle: "Arial",
fontUnits: "Arial",
fontValue: "Arial",
fontValueStyle: "italic",
fontNumbersSize: 16,
// fontNumbersStyle: "italic",
fontNumbersWeight: "bold",
fontTitleSize: 16,
fontUnitsSize: 16,
fontValueSize: 16,
animatedValue: true,
});
barometer.draw();
Then the values of that object can be accessed simply like this:
barometer.value = 1024;
Now, I would like to do the same thing with react!
There is also a node module called react-canvas-gauges, here I can make an import like this: import { RadialGauge, LinearGauge} from "react-canvas-gauges";
I can render then:
render() {
<RadialGauge
title= "hPa"
width = "400"... />
}
The point is, I figured out that I must update the value from "OUTSIDE", instantiating the object, drawing it on the canvas and then updating the value, and that is not possible (or against the philosophy of react) doing this with these JSX Components from "OUTSIDE"
I've isolated my issue but haven't been able to fix it. I'm hoping the brilliant minds of stack overflow can assist!
Problem: The sorting function stops working when the injected tables are present. When I remove the injections, the sorting functions work perfectly. Is there a way for me to isolate the script src so it will work only for the injected charts? Trying to reference them before the highcharts doesn't work.
My page: http://www.wcsddata.net/wearewcsd
At the beginning of my page I reference the following scripts, so, my highcharts will work at the bottom of the page in the tabs:
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<script src="https://code.highcharts.com/highcharts.js"></script>
<script src="https://code.highcharts.com/modules/exporting.js"></script>
<script src="https://code.highcharts.com/modules/data.js"></script>
<script src="https://code.highcharts.com/modules/drilldown.js"></script>
<script src="https://code.highcharts.com/modules/offline-exporting.js"></script>
At the top, I have 4 charts that have been injected into the page via everviz and utilize "script srce":
<div id="highcharts-fvqBbZn4G" style="width: 100%; height: 220px; float: left; padding-bottom: 40px;"><script src="https://app.everviz.com/inject/fvqBbZn4G/" defer="defer"></script></div>
<div id="highcharts-AMGYgGD6V" style="width: 34%; height: 300px; float: left;"><script src="https://app.everviz.com/inject/AMGYgGD6V/" defer="defer"></script></div>
<div id="highcharts-pEyKRkM-l" style="width: 33%; height: 300px; float: left;"><script src="https://app.everviz.com/inject/pEyKRkM-l/" defer="defer"></script></div>
<div id="highcharts-USL8gYv5J" style="width: 33%; height: 300px; float: left;"><script src="https://app.everviz.com/inject/USL8gYv5J/" defer="defer"></script></div>
AT the bottom, I have tab sets that feature 8 different highcharts and many of them have the ability to sort (alphabetically, low-high and high-low). Below is the code for one of them:
<script>
var categories = ['AACT', 'Allen', 'Anderson', 'Beasley', 'Beck', 'Bennett', 'Billinghurst', 'Booth', 'Brown', 'Cannan', 'Caughlin Ranch', 'Clayton', 'Cold Springs', 'Corbett', 'Damonte Ranch', 'Depoali', 'Desert Heights', 'Desert Skies', 'Diedrichsen', 'Dilworth', 'Dodson', 'Donner Springs', 'Double Diamond', 'Drake', 'Duncan', 'Dunn', 'Elmcrest', 'Galena', 'Gerlach K-12', 'Gomes', 'Gomm', 'Greenbrae', 'Hall', 'Hidden Valley', 'Huffaker', 'Hug', 'Hunsberger', 'Hunter Lake', 'Incline ES', 'Incline HS', 'Incline MS', 'Innovations', 'Inspire', 'Juniper', 'Lemelson', 'Lemmon Valley', 'Lenz', 'Lincoln Park', 'Loder', 'Mathews', 'Maxwell', 'McQueen', 'Melton', 'Mendive', 'Mitchell', 'Moss', 'Mount Rose K-8', 'Natchez', 'North Star', 'North Valleys', 'OBrien', 'Palmer', 'Peavine', 'Picollo', 'Pine', 'Pleasant Valley', 'Poulakidas', 'Reed', 'Reno', 'Risley', 'Sepulveda', 'Shaw', 'Silver Lake', 'Sky Ranch', 'Smith Alice', 'Smith Kate', 'Smithridge', 'Spanish Springs ES', 'Spanish Springs HS', 'Sparks HS', 'Sparks MS', 'Stead', 'Sun Valley', 'Swope', 'Taylor', 'TMCC HS', 'Towles', 'Traner', 'Turning Point', 'Van Gorder', 'Vaughn', 'Verdi', 'Veterans', 'Warner', 'Westergard', 'Whitehead', 'Winnemucca', 'Wooster'];
Highcharts.chart('containerfrlschl', {
chart: {
type: 'bar',
events: {
load: function() {
var points = this.series[0].points,
chart = this,
newPoints = [];
Highcharts.each(points, function(point, i) {
point.update({
name: categories[i]
}, false);
newPoints.push({
x: point.x,
y: point.y,
name: point.name
});
});
chart.redraw();
// Sorting A - Z
$('#sort7').on('click', function() {
newPoints.sort(function(a, b) {
if (a.name < b.name)
return -1;
if (a.name > b.name)
return 1;
return 0;
});
Highcharts.each(newPoints, function(frl, i) {
frl.x = i;
});
chart.series[0].setData(newPoints, true, false, false);
});
// Sorting min - max
$('#sort8').on('click', function() {
newPoints.sort(function(a, b) {
return a.y - b.y
});
Highcharts.each(newPoints, function(frl, i) {
frl.x = i;
});
chart.series[0].setData(newPoints, true, false, false);
});
// Sorting max - min
$('#sort9').on('click', function() {
newPoints.sort(function(a, b) {
return b.y - a.y
});
Highcharts.each(newPoints, function(frl, i) {
frl.x = i;
});
chart.series[0].setData(newPoints, true, false, false);
});
}
}
},
exporting: {
enabled: false
},
title:{
text:''
},
xAxis: {
type: 'category'
},
yAxis: {
min: 0,
max: 100,
title: {
text: 'Percentage of Student Population'
}
},
tooltip: {
valueSuffix: '%'
},
credits: {
enabled: false
},
legend: {
enabled: false,
reversed: true,
align: 'center',
verticalAlign: 'top',
itemDistance: 20,
itemStyle: {
"font-family": "'Open Sans', sans-serif",
"color": "#373737",
"fontSize": "16px",
"fontWeight": "normal"
}
},
plotOptions: {
series: {
stacking: 'normal',
dataLabels: {
enabled: true,
filter: {
property: 'percentage',
operator: '>',
value: 1
},
style: {
"font-family": "'Open Sans', sans-serif",
"color": "#ffffff",
"fontSize": "14px",
"fontWeight": "normal",
"textOutline": false
},
format: '{point.y}%'
}
}
},
series: [{
name: 'FRL',
color: '#00619e',
data: [19, 100, 100, 25, 28, 100, 26, 100, 15, 100, 9, 49, 43, 100, 24, 21, 100, 100, 45, 100, 100, 59, 38, 100, 100, 55, 100, 30, 32, 41, 10, 100, 29, 53, 32, 100, 4, 47, 45, 41, 46, 45, 100, 57, 100, 100, 9, 100, 100, 100, 100, 24, 11, 40, 100, 35, 35, 100, 28, 44, 58, 100, 52, 100, 50, 19, 12, 28, 19, 100, 30, 21, 50, 23, 100, 100, 100, 13, 27, 60, 100, 100, 100, 27, 23, 18, 45, 100, 100, 13, 100, 24, 100, 100, 21, 36, 37, 52]
}]
});</script>
Thank you in advance!
Ken
I found that it is a general issue between integration of the everviz charts and the Highcharts charts. The issue occurs because everviz includes all Highcharts modules and doing an update on the main chart makes that this chart "want to get access" to these modules, but assigned arguments are wrong.
Adding missing modules (highcharts-more and accessibility in this case) fixes the issue.
Demo: https://jsfiddle.net/BlackLabel/tqfp79c1/
<div id="highcharts-fvqBbZn4G" style="width: 100%; height: 220px; float: left; padding-bottom: 40px;"><script src="https://app.everviz.com/inject/fvqBbZn4G/" defer="defer"></script></div>
<script src="https://code.highcharts.com/highcharts.js"></script>
<script src="https://code.highcharts.com/highcharts-more.js"></script>
<script src="https://code.highcharts.com/modules/exporting.js"></script>
<script src="https://code.highcharts.com/modules/data.js"></script>
<script src="https://code.highcharts.com/modules/drilldown.js"></script>
<script src="https://code.highcharts.com/modules/offline-exporting.js"></script>
<script src="https://code.highcharts.com/modules/accessibility.js"></script>
I have put a highchart gauge in an html file and am loading it into a webview. I made a function called set_needle() that sets the needle to a certain value. But when I try to load the javascript call to that function in Java, nothing happens. I have looked at several examples and they seem to me to be doing exactly what I am, so I am not sure what the problem is.
Here is the html/js:
<head>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.2/jquery.min.js"></script>
<script src="http://code.highcharts.com/highcharts.js"></script>
<script src="http://code.highcharts.com/highcharts-more.js"></script>
<script src="http://code.highcharts.com/modules/exporting.js"></script>
</head>
<body>
<div id="container" style="min-width: 310px; max-width: 400px; height: 300px; margin: 0 auto"></div>
<script type="text/javascript">
var needle_value = 0;
function set_value(new_val) {
needle_value = new_val;
console.log("setting needle");
}
$(function () {
$('#container').highcharts({
chart: {
type: 'gauge',
plotBackgroundColor: null,
plotBackgroundImage: null,
plotBorderWidth: 0,
plotShadow: false
},
title: {
text: 'Activity Index - Last 24 Hour'
},
pane: {
startAngle: -125,
endAngle: 125,
background: [{
backgroundColor: {
linearGradient: { x1: 0, y1: 0, x2: 0, y2: 1 },
stops: [
[0, '#FFF'],
[1, '#333']
]
},
borderWidth: 0,
outerRadius: '109%'
}, {
backgroundColor: {
linearGradient: { x1: 0, y1: 0, x2: 0, y2: 1 },
stops: [
[0, '#333'],
[1, '#FFF']
]
},
borderWidth: 1,
outerRadius: '107%'
}, {
// default background
}, {
backgroundColor: '#DDD',
borderWidth: 0,
outerRadius: '105%',
innerRadius: '103%'
}]
},
// the value axis
yAxis: {
min: 0,
max: 200,
minorTickInterval: 'auto',
minorTickWidth: 1,
minorTickLength: 0,
minorTickPosition: 'inside',
minorTickColor: '#666',
tickPixelInterval: 40,
tickWidth: 1,
tickPosition: 'inside',
tickLength: 14,
tickColor: '#666',
tickAmount: 11,
labels: {
step: 5,
rotation: 'auto',
format: '{value}%'
},
title: {
text: 'Activity<br />Index',
style: {'fontSize':'11px'},
y: 5
},
plotBands: [{
from: 0,
to: 60,
color: '#DF5353' // red
}, {
from: 60,
to: 80,
color: '#DDDF0D' // yellow
}, {
from: 80,
to: 120,
color: '#55BF3B' // green
},
{
from: 120,
to: 140,
color: '#DDDF0D' // yellow
},
{
from: 140,
to: 200,
color: '#DF5353' // red
}]
},
credits: {
enabled: false
},
exporting: {
enabled: false
},
series: [{
name: 'Activity Index',
data: [20],
tooltip: {
valueSuffix: '% of daily average'
}
}]
},
// Add some life
function (chart) {
if (!chart.renderer.forExport) {
setInterval(function () {
var point = chart.series[0].points[0];
point.update(needle_value);
}, 3000);
}
});
});
</script>
And here is the relevant java code:
WebView myWebView = (WebView) findViewById(R.id.webview);
myWebView.setWebChromeClient(new WebChromeClient());
WebSettings webSettings = myWebView.getSettings();
webSettings.setJavaScriptEnabled(true);
webSettings.setDomStorageEnabled(true);
myWebView.loadUrl("file:///android_asset/SleepActivity.html");
myWebView.loadUrl("javascript:set_value(50)");
Since you are calling the JavaScript function immediately after the html page load url instruction, It could be possible that the page is not completely loaded when trying to execute JavaScript, resulting in an error.
If It is the case I suggest to postpone the myWebView.loadUrl("javascript:set_value(50)"); instruction on the onPageFinished callback of a custom WebViewClient. Something like:
myWebView.setWebViewClient(new WebViewClient(){
#Override
public void onPageFinished(WebView view, String url) {
view.loadUrl("javascript:set_value(50)");
}
});
Here's a sample interface:
public class WebAppInterface {
Context mContext;
/** Instantiate the interface and set the context */
WebAppInterface(Context c) {
mContext = c;
}
/** Show a toast from the web page */
#JavascriptInterface
public void showToast(String toast) {
Toast.makeText(mContext, toast, Toast.LENGTH_SHORT).show();
}
}
Hook it up to WebView like this:
webView.addJavascriptInterface(new WebAppInterface(this), "Android");
Android is the name of the javascript object, so you can call it from javascript like this:
<input type="button" value="Say hello" onClick="showAndroidToast('Hello Android!')" />
<script type="text/javascript">
function showAndroidToast(toast) {
Android.showToast(toast);
}
</script>
The #JavascriptInterface annotation is important; if you don't have it, the method can't be called from javascript.
I'm trying to increment text value everytime I click on the rectangle. What am I doing wrong ?
I don't understand because the call to my var works in drawText but doesn't in setLayer.
I looked at "setLayer" source code, who's working with '+=' syntax, but text is a String var and I don't want to make String concatenation.
value=1
$('canvas').drawText({
name: 'count',
fillStyle: '#0f0',
x: 20, y: 20,
fontSize: 22,
fontFamily: 'Verdana, sans-serif',
text: value
})
.drawRect({
strokeStyle: '#000',
fillStyle: '#ccc',
x: 20, y: 50,
width: 20,
height: 20,
layer: true,
click: function(layer) {
// Spin
$(this).animateLayer(layer, {
rotate: '+=180'
});
v=parseInt(value);
$(this).setLayer('count',{
text: value+1 // TRYING to increment over here
});
}})
Removing and recreating layers will make jCanvas unhappy. A much better solution would be to use setLayer() by parsing the current value to a number, incrementing that value, and passing it to the method:
$('canvas').drawText({
layer: true,
name: 'count',
fillStyle: '#0f0',
x: 20, y: 20,
fontSize: 22,
fontFamily: 'Verdana, sans-serif',
text: '1'
})
.drawRect({
strokeStyle: '#000',
fillStyle: '#ccc',
x: 20, y: 50,
width: 20,
height: 20,
layer: true,
click: function(layer) {
var $canvas = $(this),
countLayer = $canvas.getLayer('count');
// Spin
$canvas.animateLayer(layer, {
rotate: '+=180'
});
$canvas.setLayer(countLayer,{
text: parseFloat(countLayer.text) + 1
});
}
});
I found a workaround removing the layer and creating a new one at the same place.
function updateCount(param) {
$('canvas').removeLayer("count")
.drawText({
name: 'count',
fillStyle: '#0f0',
x: 250, y: 180,
fontSize: 22,
fontFamily: 'Verdana, sans-serif',
text: value,
layer: true,
maxWidth: 200
})
.drawLayers();
}
Having issues with the Knockout-Kendo radial gauge in my application.
I'm trying to initialize it via the data-bind property, but it does not appear to be resizing itself correctly.
<div id="speedGauge" data-bind="kendoRadialGauge: $parent.speedGaugeOptions"></div>
...
self.speedGaugeOptions = {
renderAs: 'svg',
value: 0,
gaugeArea: {
background: 'transparent'
},
pointer: {
color: 'lightgray',
animation: {
speed: 100
}
},
scale: {
minorUnit: 75,
majorUnit: 150,
startAngle: -40,
endAngle: 220,
max: 300,
min: -300,
labels: {
position: 'inside',
font: '10px Arial,Helvetica,sans-serif'
},
ranges: [
{
from: -300,
to: -200,
color: "darkgray"
},
{
from: 300,
to: 200,
color: "darkgray"
}
],
rangeSize: 5,
rangeDistance: -5,
rangePlaceholderColor: '#f2f2f2'
}
Here comes the fun part;
When the page has activated (using durandal), the gauges are drawn like this:
In order for the gauge to scale correctly and fit inside the gray circle, I have to redraw it like this (either from the browser console, or in the .js file):
$("#speedGauge").data("kendoRadialGauge").redraw()
When doing so, my gauge looks the way it's suppose to;
Now, I've tried creating it using the regular Kendo implementation - and that works just fine resulting in the gauge to be drawn correctly like in the image above;
<div id="speedGauge"></div>
...
self.activate = function () {
createGauge();
}
...
function createGauge() {
$("#speedGauge").kendoRadialGauge({
renderAs: 'svg',
value: 0,
gaugeArea: {
background: 'transparent'
},
pointer: {
color: 'lightgray',
animation: {
speed: 100
}
},
scale: {
minorUnit: 75,
majorUnit: 150,
startAngle: -40,
endAngle: 220,
max: 300,
min: -300,
labels: {
position: 'inside',
font: '10px Arial,Helvetica,sans-serif'
},
ranges: [
{
from: -300,
to: -200,
color: "darkgray"
},
{
from: 300,
to: 200,
color: "darkgray"
}
],
rangeSize: 5,
rangeDistance: -5,
rangePlaceholderColor: '#f2f2f2'
}
});
}
Does anyone have an idea of what might be wrong here?
A colleague suggested to do a forced redraw of the gauges on durandals attached event, which solved the problem for now. The actual resizing of the gauge is not visible with this solution.
self.attached = function(element) {
$(element).find("[data-role='radialgauge']").each(function () { $(this).data("kendoRadialGauge").redraw(); });
};
I've reported the issue here.