Category Archives: JavaScript / Ajax

Multiple Value Axes in amCharts 4

<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
<script src="./amcharts4/core.js"></script>
<script src="./amcharts4/charts.js"></script>
<script src="./amcharts4/maps.js"></script>
<script src="./amcharts4/themes/animated.js"></script>
<div style="width: 100%;max-height: 500px;height: 100vh;" id="chartdiv"></div>
<script>
	am4core.ready(function() {
		// Themes begin
		am4core.useTheme(am4themes_animated);
		// Themes end

		// Create chart instance
		var chart = am4core.create("chartdiv", am4charts.XYChart);

		// Increase contrast by taking evey second color
		chart.colors.step = 2;

		// Add data
		chart.data = generateChartData();

		// Create axes
		var dateAxis = chart.xAxes.push(new am4charts.DateAxis());
		dateAxis.renderer.minGridDistance = 50;
		dateAxis.renderer.labels.template.location = 0.0001;
		dateAxis.baseInterval = {
			 "timeUnit": "second",
			 "count": 1
		}

		// Create series
		function createAxisAndSeries(field, name, opposite, bullet, numberFormat) {
		  var valueAxis = chart.yAxes.push(new am4charts.ValueAxis());
		  if(chart.yAxes.indexOf(valueAxis) != 0){
			valueAxis.syncWithAxis = chart.yAxes.getIndex(0);
		  }
		  
		  var series = chart.series.push(new am4charts.LineSeries());
		  series.dataFields.valueY = field;
		  series.dataFields.dateX = "date";
		  series.strokeWidth = 2;

		  series.yAxis = valueAxis;
		  series.name = name;

		  if(field == "T0"){
			series.tooltipText = " {date.formatDate('YYYY-MM-dd hh:mm')} \n {name}: [red bold]{valueY}°C[/]";
			series.stroke = am4core.color("red");
			
		  }else if(field == "RH"){
			series.tooltipText = " {date.formatDate('YYYY-MM-dd hh:mm')} \n {name}: [blue bold]{valueY}%[/]"; 
			series.stroke = am4core.color("blue");
		  }

		  series.tensionX = 0.8;
		  series.showOnInit = true;
		
		  var interfaceColors = new am4core.InterfaceColorSet();
		  
		  switch(bullet) {
			case "RH":
			 var bullet = series.bullets.push(new am4charts.CircleBullet());
				bullet.circle.strokeWidth = 2;
				bullet.circle.radius = 4;
				bullet.circle.fill = am4core.color("#fff");
				bullet.circle.stroke = am4core.color("blue");
				var bullethover1 = bullet.states.create("hover");
				bullethover1.properties.scale = 1.3;	
				valueAxis.title.text = "相對濕度 (%)";
				break;
			case "T0":
				// Make bullets grow on hover
				var bullet = series.bullets.push(new am4charts.CircleBullet());
				bullet.circle.strokeWidth = 2;
				bullet.circle.radius = 4;
				bullet.circle.fill = am4core.color("#fff");
				bullet.circle.stroke = am4core.color("red");
				var bullethover1 = bullet.states.create("hover");
				bullethover1.properties.scale = 1.3;
				valueAxis.title.text = "氣溫 (°C)";
	
				break;
			default:
				var bullet = series.bullets.push(new am4charts.CircleBullet());
				bullet.circle.stroke = interfaceColors.getFor("background");
				bullet.circle.strokeWidth = 2;
				break;
			} 
			valueAxis.renderer.line.strokeOpacity = 1;
			valueAxis.renderer.line.strokeWidth = 2;
			valueAxis.renderer.line.stroke = series.stroke;
			valueAxis.renderer.labels.template.fill = series.stroke;
			valueAxis.renderer.opposite = opposite;
			valueAxis.numberFormatter = new am4core.NumberFormatter();
			valueAxis.numberFormatter.numberFormat = numberFormat; 
		}
		createAxisAndSeries("T0", "氣溫", true, "T0", "#°C");
		createAxisAndSeries("RH", "相對濕度", false, "RH", "#'%'");
	
		// Add legend
		chart.legend = new am4charts.Legend();

		// Add cursor
		chart.cursor = new am4charts.XYCursor();
		chart.dateFormatter.inputDateFormat = "yyyy-MM-dd H:m";
		
		chart.scrollbarX = new am4core.Scrollbar();
		chart.scrollbarX.parent = chart.bottomAxesContainer;

		// Enable export
		chart.exporting.menu = new am4core.ExportMenu();
    chart.exporting.menu.items[0].icon = "data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIi";
		// chart.exporting.menu.container = document.getElementById("tools");

		// generate some random data, quite different range
		function generateChartData() {
			var chartData = [];
			chartData.push({date: "2020-03-04 00:00",RH: "78.7",T0: "20",});
			chartData.push({date: "2020-03-04 00:01",RH: "78.8",T0: "20",});
			chartData.push({date: "2020-03-04 00:02",RH: "79.1",T0: "20",});
			chartData.push({date: "2020-03-04 00:03",RH: "79.1",T0: "20",});
			chartData.push({date: "2020-03-04 00:04",RH: "78.9",T0: "20",}); 
			return chartData;
		}
	}); // end am4core.ready()

	$(document).ready(function(){
		$("g[aria-labelledby='id-66-title']").hide();
	})
</script>

Ouput:
multiple-value-axes-in-amcharts-4

upload file in JQuery

function imageManager(){
	var fd = new FormData(); 
	var files = $('#file')[0].files[0]; 
	fd.append('file', files); 

	$.ajax({
	  type:"POST",
	  url:"http://127.0.0.1/ajax/do-item.ajax.php",
	  data: fd, 
		contentType: false, 
		processData: false, 
	  beforeSend:function(){
		$("#ajax-file").html("Loading...");
	  },
	  success:function(data){
		$("#ajax-file").html(decodeURI(data));
	  }
	});
}

<?php
   var_dump($_FILES);
?>

Get store information in Google Map

<!DOCTYPE html>
<html>
  <head>
    <title>Place Searches</title>
    <meta name="viewport" content="initial-scale=1.0, user-scalable=no">
    <meta charset="utf-8">
    <style>
      /* Always set the map height explicitly to define the size of the div
       * element that contains the map. */
      #map {
        height: 100%;
      }
      /* Optional: Makes the sample page fill the window. */
      html, body {
        height: 100%;
        margin: 0;
        padding: 0;
      }
    </style>
    <script>
      var map;
      var infowindow;

      function initMap() {
        var pyrmont = {lat: -33.867, lng: 151.195};

        map = new google.maps.Map(document.getElementById('map'), {
          center: pyrmont,
          zoom: 15
        });

        infowindow = new google.maps.InfoWindow();
        var service = new google.maps.places.PlacesService(map);
        service.nearbySearch({
          location: pyrmont,
          radius: 500,
          type: ['store']
        }, callback);
      }

      function callback(results, status) {
        if (status === google.maps.places.PlacesServiceStatus.OK) {
          for (var i = 0; i < results.length; i++) {
            createMarker(results[i]);
          }
        }
      }

      function createMarker(place) {
        var placeLoc = place.geometry.location;
        var marker = new google.maps.Marker({
          map: map,
          position: place.geometry.location
        });

        google.maps.event.addListener(marker, 'click', function() {
          infowindow.setContent(place.name);
          infowindow.open(map, this);
        });
      }
    </script>
  </head>
  <body>
    <div id="map"></div>
    <script src="https://maps.googleapis.com/maps/api/js?key=Key&libraries=places&callback=initMap" ></script>
  </body>
</html>

Output :
get-store-information-in-google-map

node.js + mqtt (Docker)

Directory Path : /app

Dockerfile

FROM node:latest
# 
WORKDIR specifies the directory our
# application's code will live within
WORKDIR /app
# We copy our package.json file to our
# app directory

RUN npm install -g nodemon

COPY package.json /app/package.json
# We then run npm install to install
# express for our application
RUN npm install && npm ls
RUN mv /app/node_modules /node_modules

# We then copy the rest of our application
# to the app direcoty
COPY . /app
# We start our application by calling
# npm start.
CMD ["npm", "start"]

mqtt-server.js

var mqtt = require('mqtt');
var fs = require('fs');
var path = require('path');

var clientID = "HKOSub"+Math.random().toString(36).substring(7);

var TRUSTED_CA_LIST = fs.readFileSync(path.join(__dirname, './key.pem'));

var address = '127.0.0.1';
var PORT = 1883;

const options = {
    host: address,
    port: PORT,
    keepalive: 60,
    clientId: clientID,
    // username: "testing_user",
    // password: "password",
    // protocol: 'mqtts',
    // rejectUnauthorized: true,
    // ca: TRUSTED_CA_LIST
};

var client = mqtt.connect(options);
var topic="name/#"
client.subscribe(topic, {  //subscribe to /[SI]/[DI]/raw/json
    qos: 1
});

client.on('message', function (topic, message) {
    console.log("[Received] topic: " + topic.toString());  //Print topic name
    console.log("[Received] message: " + message.toString()); //Print payload
})

function publishdata() {
  client.publish('LEUNG/test/time', 'Current time is: ' + new Date());
}

//setInterval(publishdata, 5000); //publish data every 10 seconds

package.json

{
    "name": "mqtt",
    "version": "1.0.0",
    "main": "mqtt-server.js",
    "dependencies": {
      "express" : "^4.16.3",
      "mqtt" : ""
    },
    "scripts": {
      "start": "node mqtt-server.js"
    }
  }

Docker

Docker build -t mqtt-server .

docker run -it -p 9001:3000 -v $(pwd):/app mqtt-server

Automatically Picking up Changes in node.js (Docker)

Location Dir Path : /app

app.js

const express = require("express");
const app = express();

app.get("/", (req, res) => res.send(`Hello World!`));

app.listen(3000, () => {
  console.log(`Example app listening on port 3000!`);
});

Dockerfile

FROM node:latest
# 
WORKDIR specifies the directory our
# application's code will live within
WORKDIR /app
# We copy our package.json file to our
# app directory
RUN npm install -g nodemon
COPY package.json /app/package.json
# We then run npm install to install
# express for our application
RUN npm install && npm ls
RUN mv /app/node_modules /node_modules
# We then copy the rest of our application
# to the app direcoty
COPY . /app
# We start our application by calling
# npm start.
CMD ["npm", "start"]

package.json

{
    "name": "hello-world",
    "version": "1.0.0",
    "main": "app.js",
    "dependencies": {
      "express" : "^4.16.3"
    },
    "scripts": {
      "start": "node app.js"
    }
}

Docker:

docker build -t node-docker-tutorial .

docker run -it -p 9001:3000 -v $(pwd):/app node-docker-tutorial

Output :
http://127.0.0.1:9001 Hello World

automatically-picking-up-changes-in-node-js-docker