# GPS Skyplot on dashboard with node template and json

**URL:** <https://discourse.nodered.org/t/gps-skyplot-on-dashboard-with-node-template-and-json/29451>\
**Category:** Dashboard\
**Created:** [3 July 2020 16:11 UTC](https://discourse.nodered.org/t/gps-skyplot-on-dashboard-with-node-template-and-json/29451 "2020-07-03T16:11:40Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![Martin](https://avatars.discourse-cdn.com/v4/letter/m/73ab20/32.png) [@Martin](https://discourse.nodered.org/u/Martin)\
**Post date:** [3 July 2020 16:11 UTC](https://discourse.nodered.org/t/gps-skyplot-on-dashboard-with-node-template-and-json/29451/1 "2020-07-03T16:11:40Z")

</div>

Hello guys!!,

First of all i'm new with html and javascript, i have some experience with c++.  
As i said i'm trying to build a gps skyplot on Node-red dashboard for that purpose i took and edit this  
[html code](https://stackoverflow.com/questions/49562122/adding-text-values-into-a-circle-in-html-page-using-js) to get cover about circle's color wich was needed to be by gps constellation. With my edition i got this:

![skyplot](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/3X/1/a/1af3148aeec04c407402e661dcdd9ce3d0327eb1.png)

`

```auto
<!DOCTYPE html>
<html>
	<head>
		<meta charset='ISO-8859-1'>
		<script src="https://d3js.org/d3.v3.min.js"></script>
	</head>

	<body style='background-color:lightgray'>
		<div id="chart" style='width: 400px; height: 400px; padding-left: 5px; padding-bottom: 5px;'></div>

		<script>
			var deg2rad = Math.PI/180;
            var width = 400, height = 350, radius = Math.min(width, height) / 2 - 30;

            var svg = d3.select("#chart").append("svg")
			    .attr("width", width)
			    .attr("height", height)
			    .append("g")
			    .attr("transform", "translate(" + width / 2 + "," + height / 2 + ")");
				  
            var r = d3.scale.linear()
			    .domain([90, 0])
			    .range([0, radius]);
  
           var line = d3.svg.line.radial()
			    .radius(function(d) {return r(d[1]);})
			    .angle(function(d) {return -d[0] + Math.PI / 2;});

            var gr = null;

            createSkyplot();

			var json = {"type" : "GSV",
                        "inView" : [{"data" : [1, 45, 90,"#EEE41D"]},
                                    {"data" : [2, 70, 180,"#EEE41D"]},
                                    {"data" : [3, 70, 225,"#EC1C0B"]},
                                    {"data" : [4, 70, 270,"#EC1C0B"]},
                                    {"data" : [5, 70, 315,"#0BA1EC"]},
                                    {"data" : [6, 70, 0,"#0BA1EC"]}]
                       };
                       
            updateSkyPlot(json);

            function createSkyplot(){	
	            //////////////////////			  
	            gr = svg.append("g")
				    .attr("class", "r axis")
				    .selectAll("g")
				    .data(r.ticks(5))
				    .enter().append("g");

                gr.append("circle").attr("r", r).style('fill', 'white');

	            gr.append("text")
		            .attr("y", function(d) { return -r(d) - 4; })
		            .attr("transform", "rotate(20)")
		            .style("text-anchor", "middle")
		            .style('fill', 'blue')
    	            .text(function(d) { return d;});
	            /////////////////////

	            /////////////////////
	            var ga = svg.append("g")
				    .attr("class", "a axis")
				    .selectAll("g")
				    .data(d3.range(0, 360, 45))
				    .enter().append("g")
      			    .attr("transform", function(d) {return "rotate(" + (d - 90) + ")";});

                ga.append("line").attr("x2", radius).style('stroke', 'black').style('stroke-dasharray', '1,8');
	  
	            ga.append("text")
    	            .attr("x", radius + 6)
    	            .attr("dy", ".35em")
    	            .style("text-anchor", function(d) { return d < 360 && d > 90 ? "end" : null; })
		            .attr("transform", function(d) { return d < 360 && d > 90 ? "rotate(180 " + (radius + 3) + ",0)" : null; })
    	            .text(function(d) { return d + "°"; });
	            /////////////////////
            }

function updateSkyPlot(d){
	var pos = [];
	var inview = d.inView;

	for (var elem in inview){
		if (inview.hasOwnProperty(elem)) {
			// the azimuth should be in radians and substracted from (Math.PI/2)	"data" : [1, 45, 90]
			var d = [(Math.PI/2) - inview[elem].data[2]*deg2rad, inview[elem].data[1]]; 
			pos.push({ "angle": d, "label": inview[elem].data[0] , "col": inview[elem].data[3] });
		}
	}

	var r = d3.scale.linear()
		.domain([90, 0])
		.range([0, radius]);

	var line = d3.svg.line.radial()
		.radius(function(d) {return r(d[1]);})
		.angle(function(d) {return -d[0] + Math.PI / 2;});

	var color = d3.scale.category20();

	svg.selectAll('circle').remove();

	gr.append("circle").attr("r", r).style('fill', 'white');

    var points = svg.selectAll("point")
    	.data(pos)
    	.enter()
    	.append("a")
    	.attr("transform", function(d) {
    		var coors = line([d.angle]).slice(1).slice(0, -1);
    		return "translate(" + coors + ")"
    	});

    points.append("circle")
    	.attr("class", "point")
      	.attr("r", 8)
        .attr("fill",function(d,i){return color(d.col);});

	points.append("text")
		.text( function(d) { return d.label })
		.attr("transform", "translate(-4,5)")
		
}

		</script>

	</body>
</html>

```

At the above code there are two main functions with are CreateSkyplot() and updateSkyPlot(). These two functions needed to work a json data.

So there is my ask for help, how could i push json data into this code ?, i'been spending a couple days and still didn't make it work.

this is what i actually have on Node-Red.

```auto
[{"id":"cd495777.95bf48","type":"ui_template","z":"671b9ab9.9caff4","group":"c90580c4.94fb","name":"","order":1,"width":"0","height":"0","format":"<!DOCTYPE html>\n<html>\n\t<head>\n\t\t<meta charset='ISO-8859-1'>\n\t\t<script src=\"https://d3js.org/d3.v3.min.js\"></script>\n\t</head>\n\n\t<body style='background-color:lightgray'>\n\t\t<div id=\"chart\" style='width: 400px; height: 400px; padding-left: 5px; padding-bottom: 5px;'></div>\n\n\t\t<script>\n\t\t(function(scope) {\n // watch msg object from Node-RED\n scope.$watch('msg',function(msg) {\n // new message received\n var Data=msg.payload;\n //window.alert(strlink2);\n //document.getElementById(\"refee\").setAttribute(\"href\",strlink2);\n \t\t\tvar deg2rad = Math.PI/180;\n var width = 400, height = 350, radius = Math.min(width, height) / 2 - 30;\n \n var svg = d3.select(\"#chart\").append(\"svg\")\n \t\t\t .attr(\"width\", width)\n \t\t\t .attr(\"height\", height)\n \t\t\t .append(\"g\")\n \t\t\t .attr(\"transform\", \"translate(\" + width / 2 + \",\" + height / 2 + \")\");\n \t\t\t\t \n var r = d3.scale.linear()\n \t\t\t .domain([90, 0])\n \t\t\t .range([0, radius]);\n \n var line = d3.svg.line.radial()\n \t\t\t .radius(function(d) {return r(d[1]);})\n \t\t\t .angle(function(d) {return -d[0] + Math.PI / 2;});\n \n var gr = null;\n \n createSkyplot();\n \n \t\t\tvar json = {\"type\" : \"GSV\",\n \"inView\" : [{\"data\" : [1, 45, 90,\"#69b3a2\"]},\n {\"data\" : [3, 70, 180,\"#69b3a2\"]},\n {\"data\" : [5, 70, 225,\"#A82051\"]},\n {\"data\" : [3, 70, 270,\"#69b3a2\"]},\n {\"data\" : [3, 70, 315,\"#69b3a2\"]},\n {\"data\" : [3, 70, 0,\"#69b3a2\"]}]\n };\n \n //updateSkyPlot(json);\n updateSkyPlot(Data);\n \n function createSkyplot(){\t\n \t //////////////////////\t\t\t \n \t gr = svg.append(\"g\")\n \t\t\t\t .attr(\"class\", \"r axis\")\n \t\t\t\t .selectAll(\"g\")\n \t\t\t\t .data(r.ticks(5))\n \t\t\t\t .enter().append(\"g\");\n \n gr.append(\"circle\").attr(\"r\", r).style('fill', 'white');\n \n \t gr.append(\"text\")\n \t\t .attr(\"y\", function(d) { return -r(d) - 4; })\n \t\t .attr(\"transform\", \"rotate(20)\")\n \t\t .style(\"text-anchor\", \"middle\")\n \t\t .style('fill', 'blue')\n \t .text(function(d) { return d;});\n \t /////////////////////\n \n \t /////////////////////\n \t var ga = svg.append(\"g\")\n \t\t\t\t .attr(\"class\", \"a axis\")\n \t\t\t\t .selectAll(\"g\")\n \t\t\t\t .data(d3.range(0, 360, 45))\n \t\t\t\t .enter().append(\"g\")\n \t\t\t .attr(\"transform\", function(d) {return \"rotate(\" + (d - 90) + \")\";});\n \n ga.append(\"line\").attr(\"x2\", radius).style('stroke', 'black').style('stroke-dasharray', '1,8');\n \t \n \t ga.append(\"text\")\n \t .attr(\"x\", radius + 6)\n \t .attr(\"dy\", \".35em\")\n \t .style(\"text-anchor\", function(d) { return d < 360 && d > 90 ? \"end\" : null; })\n \t\t .attr(\"transform\", function(d) { return d < 360 && d > 90 ? \"rotate(180 \" + (radius + 3) + \",0)\" : null; })\n \t .text(function(d) { return d + \"°\"; });\n \t /////////////////////\n }\n \n function updateSkyPlot(d){\n \tvar pos = [];\n \tvar inview = d.inView;\n \n \tfor (var elem in inview){\n \t\tif (inview.hasOwnProperty(elem)) {\n \t\t\t// the azimuth should be in radians and substracted from (Math.PI/2)\t\"data\" : [1, 45, 90]\n \t\t\tvar d = [(Math.PI/2) - inview[elem].data[2]*deg2rad, inview[elem].data[1]]; \n \t\t\tpos.push({ \"angle\": d, \"label\": inview[elem].data[0] , \"col\": inview[elem].data[3] });\n \t\t}\n \t}\n \n \tvar r = d3.scale.linear()\n \t\t.domain([90, 0])\n \t\t.range([0, radius]);\n \n \tvar line = d3.svg.line.radial()\n \t\t.radius(function(d) {return r(d[1]);})\n \t\t.angle(function(d) {return -d[0] + Math.PI / 2;});\n \n \tvar color = d3.scale.category20();\n \n \tsvg.selectAll('circle').remove();\n \n \tgr.append(\"circle\").attr(\"r\", r).style('fill', 'white');\n \n var points = svg.selectAll(\"point\")\n \t.data(pos)\n \t.enter()\n \t.append(\"a\")\n \t.attr(\"transform\", function(d) {\n \t\tvar coors = line([d.angle]).slice(1).slice(0, -1);\n \t\treturn \"translate(\" + coors + \")\"\n \t});\n \n points.append(\"circle\")\n \t.attr(\"class\", \"point\")\n \t.attr(\"r\", 8)\n .attr(\"fill\",function(d,i){return color(d.col);});\n \n \tpoints.append(\"text\")\n \t\t.text( function(d) { return d.label })\n \t\t.attr(\"transform\", \"translate(-4,5)\")\n });\t\n }\n })(scope);\n\t\t</script>\n\n\t</body>\n</html>","storeOutMessages":true,"fwdInMessages":true,"templateScope":"local","x":400,"y":1880,"wires":[["ea5302c.44631"]]},{"id":"9d15c900.429ef8","type":"inject","z":"671b9ab9.9caff4","name":"JSON2","topic":"","payload":"{\"type\":\"GSV\",\"inView\":[{\"data\":[1,25,90,\"#69b3a2\"]},{\"data\":[2,25,180,\"#69b3a2\"]},{\"data\":[3,25,225,\"#A82051\"]},{\"data\":[4,25,270,\"#69b3a2\"]},{\"data\":[5,25,315,\"#69b3a2\"]},{\"data\":[6,25,0,\"#69b3a2\"]}]}","payloadType":"json","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":210,"y":1880,"wires":[["cd495777.95bf48"]]},{"id":"ea5302c.44631","type":"debug","z":"671b9ab9.9caff4","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","x":560,"y":1880,"wires":[]},{"id":"c90580c4.94fb","type":"ui_group","z":"","name":"Skyplot","tab":"a624fbe6.d612b8","order":1,"disp":true,"width":"6","collapse":false},{"id":"a624fbe6.d612b8","type":"ui_tab","z":"","name":"GPS","icon":"gps_fixed","order":1,"disabled":false,"hidden":false}]

```

Thanks for reading and any advice. Regards!!

---

<div class="post-metadata">

**Author:** ![Andrei](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/andrei/32/10446_2.png) [@Andrei](https://discourse.nodered.org/u/Andrei)\
**Post date:** [4 July 2020 01:03 UTC](https://discourse.nodered.org/t/gps-skyplot-on-dashboard-with-node-template-and-json/29451/2 "2020-07-04T01:03:23Z")

</div>

I got an error (in the browser console) when trying to run your flow. There is a syntax error (unbalanced closing brackets) near the end of the code. After fixing I could get the drawing in the dashboard for both the hard coded json variable as well as for the data injected via msg.payload.

```auto
updateSkyPlot(json);
//updateSkyPlot(Data);

```

Modified flow:

```auto
[{"id":"8caf3d00.56893","type":"tab","label":"Flow 1","disabled":false,"info":""},{"id":"cb6392a.179c97","type":"ui_template","z":"8caf3d00.56893","group":"e7d5b9e4.972fe8","name":"","order":1,"width":"10","height":"12","format":"<!DOCTYPE html>\n<html>\n\n<head>\n <meta charset='ISO-8859-1'>\n <script src=\"https://d3js.org/d3.v3.min.js\"></script>\n</head>\n\n<body style='background-color:lightgray'>\n <div id=\"chart\" style='width: 400px; height: 400px; padding-left: 5px; padding-bottom: 5px;'></div>\n\n <script>\n (function (scope) {\n // watch msg object from Node-RED\n scope.$watch('msg', function (msg) {\n // new message received\n var Data = msg.payload;\n //window.alert(strlink2);\n //document.getElementById(\"refee\").setAttribute(\"href\",strlink2);\n var deg2rad = Math.PI / 180;\n var width = 400, height = 350, radius = Math.min(width, height) / 2 - 30;\n\n var svg = d3.select(\"#chart\").append(\"svg\")\n .attr(\"width\", width)\n .attr(\"height\", height)\n .append(\"g\")\n .attr(\"transform\", \"translate(\" + width / 2 + \",\" + height / 2 + \")\");\n\n var r = d3.scale.linear()\n .domain([90, 0])\n .range([0, radius]);\n\n var line = d3.svg.line.radial()\n .radius(function (d) { return r(d[1]); })\n .angle(function (d) { return -d[0] + Math.PI / 2; });\n\n var gr = null;\n\n createSkyplot();\n\n var json = {\n \"type\": \"GSV\",\n \"inView\": [{ \"data\": [1, 45, 90, \"#69b3a2\"] },\n { \"data\": [3, 70, 180, \"#69b3a2\"] },\n { \"data\": [5, 70, 225, \"#A82051\"] },\n { \"data\": [3, 70, 270, \"#69b3a2\"] },\n { \"data\": [3, 70, 315, \"#69b3a2\"] },\n { \"data\": [3, 70, 0, \"#69b3a2\"] }]\n };\n\n //updateSkyPlot(json);\n updateSkyPlot(Data);\n\n function createSkyplot() {\n //////////////////////\t\t\t \n gr = svg.append(\"g\")\n .attr(\"class\", \"r axis\")\n .selectAll(\"g\")\n .data(r.ticks(5))\n .enter().append(\"g\");\n\n gr.append(\"circle\").attr(\"r\", r).style('fill', 'white');\n\n gr.append(\"text\")\n .attr(\"y\", function (d) { return -r(d) - 4; })\n .attr(\"transform\", \"rotate(20)\")\n .style(\"text-anchor\", \"middle\")\n .style('fill', 'blue')\n .text(function (d) { return d; });\n /////////////////////\n\n /////////////////////\n var ga = svg.append(\"g\")\n .attr(\"class\", \"a axis\")\n .selectAll(\"g\")\n .data(d3.range(0, 360, 45))\n .enter().append(\"g\")\n .attr(\"transform\", function (d) { return \"rotate(\" + (d - 90) + \")\"; });\n\n ga.append(\"line\").attr(\"x2\", radius).style('stroke', 'black').style('stroke-dasharray', '1,8');\n\n ga.append(\"text\")\n .attr(\"x\", radius + 6)\n .attr(\"dy\", \".35em\")\n .style(\"text-anchor\", function (d) { return d < 360 && d > 90 ? \"end\" : null; })\n .attr(\"transform\", function (d) { return d < 360 && d > 90 ? \"rotate(180 \" + (radius + 3) + \",0)\" : null; })\n .text(function (d) { return d + \"°\"; });\n /////////////////////\n }\n\n function updateSkyPlot(d) {\n var pos = [];\n var inview = d.inView;\n\n for (var elem in inview) {\n if (inview.hasOwnProperty(elem)) {\n // the azimuth should be in radians and substracted from (Math.PI/2)\t\"data\" : [1, 45, 90]\n var d = [(Math.PI / 2) - inview[elem].data[2] * deg2rad, inview[elem].data[1]];\n pos.push({ \"angle\": d, \"label\": inview[elem].data[0], \"col\": inview[elem].data[3] });\n }\n }\n\n var r = d3.scale.linear()\n .domain([90, 0])\n .range([0, radius]);\n\n var line = d3.svg.line.radial()\n .radius(function (d) { return r(d[1]); })\n .angle(function (d) { return -d[0] + Math.PI / 2; });\n\n var color = d3.scale.category20();\n\n svg.selectAll('circle').remove();\n\n gr.append(\"circle\").attr(\"r\", r).style('fill', 'white');\n\n var points = svg.selectAll(\"point\")\n .data(pos)\n .enter()\n .append(\"a\")\n .attr(\"transform\", function (d) {\n var coors = line([d.angle]).slice(1).slice(0, -1);\n return \"translate(\" + coors + \")\"\n });\n\n points.append(\"circle\")\n .attr(\"class\", \"point\")\n .attr(\"r\", 8)\n .attr(\"fill\", function (d, i) { return color(d.col); });\n\n points.append(\"text\")\n .text(function (d) { return d.label })\n .attr(\"transform\", \"translate(-4,5)\")\n }\n })\n }) (scope);\n </script>\n\n</body>\n\n</html>","storeOutMessages":true,"fwdInMessages":true,"resendOnRefresh":false,"templateScope":"local","x":400,"y":180,"wires":[["91242dc3.e1365"]]},{"id":"7c2b01f8.e85d4","type":"inject","z":"8caf3d00.56893","name":"JSON2","props":[{"p":"payload","v":"{\"type\":\"GSV\",\"inView\":[{\"data\":[1,25,90,\"#69b3a2\"]},{\"data\":[2,25,180,\"#69b3a2\"]},{\"data\":[3,25,225,\"#A82051\"]},{\"data\":[4,25,270,\"#69b3a2\"]},{\"data\":[5,25,315,\"#69b3a2\"]},{\"data\":[6,25,0,\"#69b3a2\"]}]}","vt":"json"},{"p":"topic","v":"","vt":"string"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"{\"type\":\"GSV\",\"inView\":[{\"data\":[1,25,90,\"#69b3a2\"]},{\"data\":[2,25,180,\"#69b3a2\"]},{\"data\":[3,25,225,\"#A82051\"]},{\"data\":[4,25,270,\"#69b3a2\"]},{\"data\":[5,25,315,\"#69b3a2\"]},{\"data\":[6,25,0,\"#69b3a2\"]}]}","payloadType":"json","x":210,"y":180,"wires":[["cb6392a.179c97"]]},{"id":"91242dc3.e1365","type":"debug","z":"8caf3d00.56893","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","x":560,"y":180,"wires":[]},{"id":"e7d5b9e4.972fe8","type":"ui_group","z":"","name":"Skyplot","tab":"148b6089.d57b1f","order":1,"disp":true,"width":"10","collapse":false},{"id":"148b6089.d57b1f","type":"ui_tab","z":"","name":"GPS","icon":"gps_fixed","order":1,"disabled":false,"hidden":false}]

```

 ![gps](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/3X/2/d/2d20ef80b2873fadf4d0644f764afe0bce42b6d0.png)

---

<div class="post-metadata">

**Author:** ![Martin](https://avatars.discourse-cdn.com/v4/letter/m/73ab20/32.png) [@Martin](https://discourse.nodered.org/u/Martin)\
**Post date:** [6 July 2020 12:17 UTC](https://discourse.nodered.org/t/gps-skyplot-on-dashboard-with-node-template-and-json/29451/3 "2020-07-06T12:17:42Z")

</div>

Andrei, Thanks for you reply and fixing my brackets, i didn't notice about it. After run this code there is a little trouble, this nodes inject a skyplot on every msg.paylaoad, what could i change to just update the one already shown?, as far as i understand with this code it's already updating any skyplot.

 ![Captura](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/3X/2/3/236365db4aa9fa9bd3ae6aac328ddeff8f3a6822.png)

---

<div class="post-metadata">

**Author:** ![Martin](https://avatars.discourse-cdn.com/v4/letter/m/73ab20/32.png) [@Martin](https://discourse.nodered.org/u/Martin)\
**Post date:** [6 July 2020 13:44 UTC](https://discourse.nodered.org/t/gps-skyplot-on-dashboard-with-node-template-and-json/29451/4 "2020-07-06T13:44:32Z")

</div>

I've just made the final solution. Here's the flow. Andrei, Thanks again for your help. Regards!

```auto
[{"id":"24a9e9b4.730fe6","type":"ui_template","z":"97fc7bbb.f970d8","group":"d02c68f8.1ad438","name":"","order":1,"width":"10","height":"12","format":"<!DOCTYPE html>\n<html>\n\n<head>\n <meta charset='ISO-8859-1'>\n <script src=\"https://d3js.org/d3.v3.min.js\"></script>\n</head>\n\n<body style='background-color:lightgray'>\n <div id=\"chart\" style='width: 400px; height: 400px; padding-left: 5px; padding-bottom: 5px;'></div>\n\n <script>\n var deg2rad = Math.PI / 180;\n var width = 400, height = 350, radius = Math.min(width, height) / 2 - 30;\n\n var svg = d3.select(\"#chart\").append(\"svg\")\n .attr(\"width\", width)\n .attr(\"height\", height)\n .append(\"g\")\n .attr(\"transform\", \"translate(\" + width / 2 + \",\" + height / 2 + \")\");\n\n var r = d3.scale.linear()\n .domain([90, 0])\n .range([0, radius]);\n\n var line = d3.svg.line.radial()\n .radius(function (d) { return r(d[1]); })\n .angle(function (d) { return -d[0] + Math.PI / 2; });\n\n var gr = null;\n \n createSkyplot();\n \n function createSkyplot() {\n //////////////////////\t\t\t \n gr = svg.append(\"g\")\n .attr(\"class\", \"r axis\")\n .selectAll(\"g\")\n .data(r.ticks(5))\n .enter().append(\"g\");\n\n gr.append(\"circle\").attr(\"r\", r).style('fill', 'white');\n\n gr.append(\"text\")\n .attr(\"y\", function (d) { return -r(d) - 4; })\n .attr(\"transform\", \"rotate(20)\")\n .style(\"text-anchor\", \"middle\")\n .style('fill', 'blue')\n .text(function (d) { return d; });\n /////////////////////\n\n /////////////////////\n var ga = svg.append(\"g\")\n .attr(\"class\", \"a axis\")\n .selectAll(\"g\")\n .data(d3.range(0, 360, 45))\n .enter().append(\"g\")\n .attr(\"transform\", function (d) { return \"rotate(\" + (d - 90) + \")\"; });\n\n ga.append(\"line\").attr(\"x2\", radius).style('stroke', 'black').style('stroke-dasharray', '1,8');\n\n ga.append(\"text\")\n .attr(\"x\", radius + 6)\n .attr(\"dy\", \".35em\")\n .style(\"text-anchor\", function (d) { return d < 360 && d > 90 ? \"end\" : null; })\n .attr(\"transform\", function (d) { return d < 360 && d > 90 ? \"rotate(180 \" + (radius + 3) + \",0)\" : null; })\n .text(function (d) { return d + \"°\"; });\n /////////////////////\n }\n \n \n (function ($scope) {\n // watch msg object from Node-RED\n scope.$watch('msg', function (msg) {\n \n svg.selectAll('circle').remove();\n svg.selectAll('text').remove();\n \n createSkyplot();\n \n function createSkyplot() {\n //////////////////////\t\t\t \n gr = svg.append(\"g\")\n .attr(\"class\", \"r axis\")\n .selectAll(\"g\")\n .data(r.ticks(5))\n .enter().append(\"g\");\n \n gr.append(\"circle\").attr(\"r\", r).style('fill', 'white');\n \n gr.append(\"text\")\n .attr(\"y\", function (d) { return -r(d) - 4; })\n .attr(\"transform\", \"rotate(20)\")\n .style(\"text-anchor\", \"middle\")\n .style('fill', 'blue')\n .text(function (d) { return d; });\n /////////////////////\n \n /////////////////////\n var ga = svg.append(\"g\")\n .attr(\"class\", \"a axis\")\n .selectAll(\"g\")\n .data(d3.range(0, 360, 45))\n .enter().append(\"g\")\n .attr(\"transform\", function (d) { return \"rotate(\" + (d - 90) + \")\"; });\n \n ga.append(\"line\").attr(\"x2\", radius).style('stroke', 'black').style('stroke-dasharray', '1,8');\n \n ga.append(\"text\")\n .attr(\"x\", radius + 6)\n .attr(\"dy\", \".35em\")\n .style(\"text-anchor\", function (d) { return d < 360 && d > 90 ? \"end\" : null; })\n .attr(\"transform\", function (d) { return d < 360 && d > 90 ? \"rotate(180 \" + (radius + 3) + \",0)\" : null; })\n .text(function (d) { return d + \"°\"; });\n /////////////////////\n }\n \n \n \n // new message received\n var Data = msg.payload;\n //window.alert(strlink2);\n //document.getElementById(\"refee\").setAttribute(\"href\",strlink2);\n var json = {\n \"type\": \"GSV\",\n \"inView\": [{ \"data\": [1, 45, 90, \"#69b3a2\"] },\n { \"data\": [3, 70, 180, \"#69b3a2\"] },\n { \"data\": [5, 70, 225, \"#A82051\"] },\n { \"data\": [3, 70, 270, \"#69b3a2\"] },\n { \"data\": [3, 70, 315, \"#69b3a2\"] },\n { \"data\": [3, 70, 0, \"#69b3a2\"] }]\n };\n\n //updateSkyPlot(json);\n updateSkyPlot(Data);\n \n \n \n \n \n function updateSkyPlot(d) {\n \n \n \n \n var pos = [];\n var inview = d.inView;\n\n for (var elem in inview) {\n if (inview.hasOwnProperty(elem)) {\n // the azimuth should be in radians and substracted from (Math.PI/2)\t\"data\" : [1, 45, 90]\n var d = [(Math.PI / 2) - inview[elem].data[2] * deg2rad, inview[elem].data[1]];\n pos.push({ \"angle\": d, \"label\": inview[elem].data[0], \"col\": inview[elem].data[3] });\n }\n }\n\n var r = d3.scale.linear()\n .domain([90, 0])\n .range([0, radius]);\n\n var line = d3.svg.line.radial()\n .radius(function (d) { return r(d[1]); })\n .angle(function (d) { return -d[0] + Math.PI / 2; });\n\n var color = d3.scale.category20();\n\n svg.selectAll('circle').remove();\n \n\n gr.append(\"circle\").attr(\"r\", r).style('fill', 'white');\n\n var points = svg.selectAll(\"point\")\n .data(pos)\n .enter()\n .append(\"a\")\n .attr(\"transform\", function (d) {\n var coors = line([d.angle]).slice(1).slice(0, -1);\n return \"translate(\" + coors + \")\"\n });\n\n points.append(\"circle\")\n .attr(\"class\", \"point\")\n .attr(\"r\", 8)\n .attr(\"fill\", function (d, i) { return color(d.col); });\n\n points.append(\"text\")\n .text(function (d) { return d.label })\n .attr(\"transform\", \"translate(-4,5)\")\n }\n })\n }) (scope);\n </script>\n</body>\n</html>","storeOutMessages":true,"fwdInMessages":true,"templateScope":"local","x":420,"y":220,"wires":[["e1b9877f.1c3e38"]]},{"id":"7a6eba55.43bec4","type":"inject","z":"97fc7bbb.f970d8","name":"JSON2","topic":"","payload":"{\"type\":\"GSV\",\"inView\":[{\"data\":[5,25,90,\"#00FF00\"]},{\"data\":[5,25,180,\"#0000FF\"]},{\"data\":[5,25,225,\"#FF0000\"]},{\"data\":[5,25,270,\"#FFFF00\"]},{\"data\":[5,25,315,\"#00FFFF\"]},{\"data\":[5,25,0,\"#FF00FF\"]}]}","payloadType":"json","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":210,"y":220,"wires":[["24a9e9b4.730fe6"]]},{"id":"e1b9877f.1c3e38","type":"debug","z":"97fc7bbb.f970d8","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","x":630,"y":220,"wires":[]},{"id":"e2f9fd7e.c4e17","type":"inject","z":"97fc7bbb.f970d8","name":"JSON2","topic":"","payload":"{\"type\":\"GSV\",\"inView\":[{\"data\":[5,70,90,\"#69b3a2\"]},{\"data\":[5,70,180,\"#69b3a2\"]},{\"data\":[5,70,225,\"#A82051\"]},{\"data\":[5,70,270,\"#69b3a2\"]},{\"data\":[5,70,315,\"#69b3a2\"]},{\"data\":[5,70,0,\"#69b3a2\"]}]}","payloadType":"json","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":210,"y":260,"wires":[["24a9e9b4.730fe6"]]},{"id":"5f3a5195.eb244","type":"inject","z":"97fc7bbb.f970d8","name":"JSON2","topic":"","payload":"{\"type\":\"GSV\",\"inView\":[{\"data\":[0,50,90,\"#69b3a2\"]},{\"data\":[0,50,180,\"#69b3a2\"]},{\"data\":[0,50,225,\"#A82051\"]},{\"data\":[0,50,270,\"#69b3a2\"]},{\"data\":[0,50,315,\"#69b3a2\"]},{\"data\":[0,50,0,\"#69b3a2\"]}]}","payloadType":"json","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":210,"y":300,"wires":[["24a9e9b4.730fe6"]]},{"id":"d02c68f8.1ad438","type":"ui_group","z":"","name":"Skyplot 2","tab":"f1e6af6c.7b594","order":1,"disp":true,"width":"10","collapse":false},{"id":"f1e6af6c.7b594","type":"ui_tab","z":"","name":"GPS","icon":"gps_fixed","order":1,"disabled":false,"hidden":false}]

```

---

<div class="post-metadata">

**Author:** ![system](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/1X/d073cd938eafa2e558d7c2cd59003b3ef4963033.png) [@system](https://discourse.nodered.org/u/system)\
**Post date:** [20 July 2020 13:44 UTC](https://discourse.nodered.org/t/gps-skyplot-on-dashboard-with-node-template-and-json/29451/5 "2020-07-20T13:44:38Z")

</div>

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.
