Get data from MongoDB for dc.js charts - node.js

How to modify following index.html and dc.js code to pull data from MongoDB database using Node.js rather than csv?
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
<link rel="stylesheet" type="text/css" href="http://cdnjs.cloudflare.com/ajax/libs/dc/1.7.5/dc.css"/>
</head>
<body>
<div class="container-fluid">
<div class="row">
<h3>
<div class="dc-data-count">
<span class="filter-count"></span> selected out of <span class="total-count"></span> transitions | Reset All
</div>
</h3>
<br>
<br>
<br>
<br>
</div>
<div class="row">
<div class="col-md-6">
<div id="pie-chart"></div>
</div>
<div class="col-md-6">
<div id="bar-chart"></div>
</div>
</div>
</div>
<script src="https://code.jquery.com/jquery-3.2.1.slim.min.js" integrity="sha384-KJ3o2DKtIkvYIK3UENzmM7KCkRr/rE9/Qpg6aAZGJwFDMVNA/GpGFF93hXpG5KkN" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.12.3/umd/popper.min.js" integrity="sha384-vFJXuSJphROIrBnz7yo7oB41mKfc8JzQZiCq4NCceLEaO4IHwicKwpJf9c9IpFgh" crossorigin="anonymous"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/crossfilter/1.3.9/crossfilter.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.8/d3.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/dc/2.0.0-beta.29/dc.js"></script>
<script type="text/javascript">
d3.csv("https://raw.githubusercontent.com/dc-js/dc.js/master/web/examples/morley.csv", function (err, experiments) {
if (err) throw err;
var pieChart = dc.pieChart("#pie-chart");
var barChart = dc.barChart("#bar-chart");
var visCount = dc.dataCount(".dc-data-count");
experiments.forEach(function(x) {
x.Speed = +x.Speed;
});
var ndx = crossfilter(experiments);
var all = ndx.groupAll();
runDimension_pie = ndx.dimension(function(d) {return "run-"+d.Run;})
speedSumGroup_pie = runDimension_pie.group().reduceSum(function(d) {return d.Speed * d.Run;});
runDimension_bar = ndx.dimension(function(d) {return +d.Run;}),
speedSumGroup_bar = runDimension_bar.group().reduceSum(function(d) {return d.Speed * d.Run / 1000;});
visCount
.dimension(ndx)
.group(all);
pieChart
.width(768)
.height(480)
.slicesCap(4)
.innerRadius(100)
.dimension(runDimension_pie)
.group(speedSumGroup_pie)
.legend(dc.legend())
.on('pretransition', function(chart) {
chart.selectAll('text.pie-slice').text(function(d) {
return d.data.key + ' ' + dc.utils.printSingleValue((d.endAngle - d.startAngle) / (2*Math.PI) * 100) + '%';
})
});
barChart
.width(768)
.height(480)
.x(d3.scale.linear().domain([6,20]))
.brushOn(false)
.yAxisLabel("This is the Y Axis!")
.dimension(runDimension_bar)
.group(speedSumGroup_bar)
.on('renderlet', function(chart) {
chart.selectAll('rect').on("click", function(d) {
console.log("click!", d);
});
});;
dc.renderAll();
})
</script>
</body>
</html>
I tried creating and using the following index.js. I get JSON at http://localhost:3000/api/data but I'm not sure how to set Node up properly to pass data to current index.html and update charts accordingly.
var express = require('express');
var app = express();
var mongoose = require('mongoose');
const connection_URI = "mongodb://localhost:27017";
const connection_DB = "myDatabase";
mongoose.connect(connection_URI, {dbName: connection_DB});
var Schema = mongoose.Schema;
var connection = mongoose.connection;
var Runs = mongoose.model('Run', new Schema({
}), 'morley');
app.get('/api/data', function(req, res) {
Runs.find({}, {}, function(err, runDetails) {
if (err)
res.send(err);
res.json(runDetails);
});
});
app.listen(3000, () => {
console.log('Listening on port 3000');
});
I looked at this example as a reference, but it's a bit too complicated.

Related

Page needs to be refreshed to load the data from an API in Node

So I'm building a simple web app that gets data from an API that needs to be displayed on the screen.
However after the Post request is made, the data from the API gets logged through the console.log() however it does not get displayed on the screen though I've got the correct code, it gets displayed after a manual refresh.
I'm using EJS to display the API data on the screen.
The app.js has the following:
var cityName='';
var temperature='';
var pressure='';
app.get('/',function(req,res){
res.render('home');
});
app.get('/results',function(req,res){
res.render('results',{
cityName: cityName,
pressure:pressure,
temperature:temperature,
}
);
});
app.post('/',function(req,res){
cityName=req.body.cityName;
const api_url= 'https://api.openweathermap.org/data/2.5/weather?q='+ cityName +'&appid=8bb235e1990db4b5ae16f92e920bad25';
https.get(api_url,function(output){
//console.log(output);
output.on('data', function(data){
const weatherData= JSON.parse(data);
// WEATHER
temperature=Number(weatherData.main.temp)-273.15;
pressure= Number(weatherData.main.pressure);
console.log('Temparature:'+temperature+' °C');
console.log('Pressure:'+pressure + ' hPa');
});
});
res.redirect('/results');
});
let port = process.env.PORT;
if (port == null || port == "") {
port = 3000;
}
app.listen(port, function(){
console.log("Server ativated at port successfully");
});
The results.ejs file simply has the following:
<div class="container">
<div class="card-deck">
<div class="card bg-light mb-3" >
<div class="card-header">City</div>
<div class="card-body">
<ul>
<li><p class="card-text" name="cityName">City Name: <%= cityName %>.</p></li>
<li><p class="card-text" name="temperature">Temperature: <%= temperature %> °C.</p></li>
<li><p class="card-text" name="pressure">Pressure: <%= pressure %> hPa.</p></li>
</ul>
</div>
</div>
</div>
</div>
The home.ejs file has:
<div class="container1 container">
<form method="post" action="/">
<div class="brand-logo"></div>
<div class="brand-title">WEATHER MONITORING</div>
<div class="inputs">
<label>CITY NAME</label>
<input autocomplete="off" name="cityName" type="text" placeholder="Mumbai" />
<button type="submit">CHECK</button>
</form>
</div>
You redirect the user before the data loads
Move your redirect inside the callback
app.post("/", function (req, res) {
cityName = req.body.cityName;
const api_url =
"https://api.openweathermap.org/data/2.5/weather?q=" +
cityName +
"&appid=8bb235e1990db4b5ae16f92e920bad25";
https.get(api_url, function (output) {
//console.log(output);
output.on("data", function (data) {
const weatherData = JSON.parse(data);
// WEATHER
temperature = Number(weatherData.main.temp) - 273.15;
pressure = Number(weatherData.main.pressure);
console.log("Temparature:" + temperature + " °C");
console.log("Pressure:" + pressure + " hPa");
res.redirect("/results");
});
});
});

Modifying chrome.storage.sync from popup script

I have a chrome extension with options.js and popup.js.
I have a setting that I want the user to control both from options and popup alternatively.
In options it's straight forward:
options.html
<!DOCTYPE html>
<html>
<head><title>Random options placeholder</title></head>
<body>
<label>
<input type="checkbox" id="activate">
Active
</label>
<div id="status"></div>
<button id="save">Save</button>
<script src="options.js"></script>
</body>
</html>
options.js
function save_options() {
var isActive = document.getElementById('activate').checked;
chrome.storage.sync.set({
isActive: true
}, function() {
// Update status to let user know options were saved.
var status = document.getElementById('status');
status.textContent = 'Options saved.';
setTimeout(function() {
status.textContent = '';
}, 750);
});
}
but in popup.js I don't understand how to use the chrome.storage.sync.set
to update the same shared value (isActive).
popup.js (fail)
var isActive = document.getElementById('activate').checked;
chrome.storage.sync.set({
isActive: true
});
Any suggestions?

How to add img src attribute with VueJs

In my NodeJs route, I have the following:
router.get('/list/:id', function(req, res, next) {
request("http://localhost:3000/api/journal/" + req.params.id, function(error, response, body) {
var json = JSON.parse(body);
res.render('listdetail', { title: 'Journal', data: json });
});
});
The data is a json object containing all my screen fields. One of the fields is a base64 presentation of an image.
Then, in my List Detail html I have the following:
<div id="app">
<img class="materialboxed" src="{{data.base64Image}}" width="200">
</div>
This is surely not working... How can I add to the src attribute the base64 information that was sent by NodeJS?
I tried also the following:
<img class="materialboxed" :src=imagebase64Source width="200">
<script type="text/javascript">
var app = new Vue({
el: '#app',
data: {
imagebase64Source: {{data.base64Image}}
}
})
</script>
But it obviously does not work
Thanks
EDIT:
Strange, it's working now!
Here's what I've done:
<img class="materialboxed" src="{{ data.base64Image }}" width="200">
The only difference I can see is the spacing between the mustache.
Thanks to all who helped.
You can do it simply like this:
<template>
<div>
<img :src="image"/>
</div>
</template>
<script>
module.exports = {
data: function() {
return {
image: //your b64 string there
};
}
};
</script>
Pay attention by the way, depending on what you have on your string, you may have to add a header to the raw string.
<template>
<div>
<img :src="imgWithHeader"/>
</div>
</template>
<script>
module.exports = {
data: function() {
return {
image: //your b64 string there
};
},
computed: {
imgWithHeader() {
return 'data:' + MIMETypeOfTheImage + ';base64,' + this.image;
}
}
};
</script>
Of course you should figure out what is the type of the image, in this case.
I think the method you tried should work if the syntax is corrected
So this:
<img class="materialboxed" :src=imagebase64Source width="200">
<script type="text/javascript">
var app = new Vue({
el: '#app',
data: {
imagebase64Source: {{data.base64Image}}
}
})
</script>
should be changed to this:
<img class="materialboxed" :src="imagebase64Source" width="200">
<script type="text/javascript">
var app = new Vue({
el: '#app',
data () {
return {
imagebase64Source: data.base64Image,
}
}
})
</script>

Can't find all the users connected in room in socket.io

It's giving me cannot read property of undefined error in server.js file at this line
io.nsps['/'].adapter.rooms[roomName].length;
I want to display all the names of users those are connected in the chat room..
I take user name and room name by prompt when first time loads the page...
I am using socket.io v1.5.1
I have tried almost all the codes that are available for >v1.0 but i failed.
Here is my code..
server.js
var app = require('express')();
var http = require('http').Server(app);
var io = require('socket.io')(http);
var express = require('express');
app.use(express.static('public'));
io.on('connection', function(socket){
var userName = null;
var roomName = null;
//creating chat room
socket.on('createRoom',function(data){
userName = data.userName;
//creating or joining room
socket.join(data.roomName);
roomName = data.roomName;
//broadcasting new user joined to all other sockets in room
socket.broadcast.in(data.roomName).emit('user joined','<span style="color:#10c469 !important;"><strong>'+userName+'</strong> has joined chatroom.</span><br>');
});
var userLength = io.nsps['/'].adapter.rooms[roomName].length;
//Server receives message from client
socket.on('messageForServer',function(data){
//will alert all users
socket.emit('all users',userLength);
io.sockets.in(data.roomName).emit('messageToBeDisplayed','<strong>'+data.userName+'</strong> : '+data.message+'<br>');
});
//when user is typing
socket.on('userIsTyping',function(data){
socket.broadcast.in(roomName).emit('userIsStillTyping','<span style="color:#ff4242 !important;"<strong>'+userName+'</strong></span> is typing...</br>');
});
//when user stops typing
socket.on('noLongerTyping',function(data){
socket.broadcast.in(roomName).emit('userIsNotTyping');
});
//when user gets bored
socket.on('disconnect',function(){
socket.broadcast.in(roomName).emit('disconnected','<span style="color:#ff4242 !important;"<strong>'+userName+'</strong> has left the chat room.</span><br>');
});
});
http.listen(3000, function(){
console.log('listening on localhost:3000');
});
index.html
<!DOCTYPE html>
<html>
<head>
<title>ChatterBox</title>
<link rel="stylesheet" type="text/css" href="bootstrap/css/bootstrap.css">
<link rel="stylesheet" type="text/css" href="bootstrap/css/main.css">
<link rel="stylesheet" type="text/css" href="css/core.css">
<link rel="stylesheet" type="text/css" href="css/components.css">
</head>
<style>
.bottom{
position: fixed;
text-align: center;
bottom: 10px;
width: 100%;
}
.wrapper{
padding-top: 4%;
}
</style>
<body>
<div class="container">
<div class="row">
<nav class="navbar navbar-default navbar-fixed-top">
ChatterBox
</nav>
<div class="wrapper">
<div class="col-md-7 col-md-offset-2">
<div id="message-container"></div>
</div>
<div class="col-md-3">
<div id="typer-container"></div>
</div>
<div class="form-group bottom">
<div class="col-md-7 col-md-offset-2">
<input type="text" id="message" class="form-control" placeholder="Enter message here">
</div>
<div class="col-md-1">
<button type="button" onclick="sendMessage()" class="btn btn-trans btn-inverse waves-effect w-md waves-light m-b-5">Send</button>
</div>
</div>
</div>
</div>
</div>
</body>
<script type="text/javascript" src="js/jquery.min.js"></script>
<script type="text/javascript" src="js/app.js"></script>
<script src="/socket.io/socket.io.js"></script>
<script>
//initialize socket library and its object
var socket = io();
//taking input from user
var roomName = prompt("Enter name of chat room that you want to create or join");
var userName = prompt("Enter your username");
//create chat room
socket.emit('createRoom',{roomName:roomName,userName:userName});
//when user joins the chat room
socket.on('user joined',function(data){
document.getElementById('message-container').innerHTML += data;
});
//to display when user leave chat room
socket.on('disconnected',function(data){
document.getElementById('message-container').innerHTML += data;
});
//Press enter to send message code
$('#message').keypress(function(event){
if(event.which == 13){
sendMessage();
}
});
//Send message to server
function sendMessage()
{
var msg = document.getElementById('message').value;
document.getElementById('message').value = '';
if(msg){
socket.emit('messageForServer', {message: msg, roomName:roomName,userName: userName});
}
}
var typing = false;
var timeout = undefined;
//when user is no longer typing
function timeoutFunction(){
typing = false;
socket.emit('noLongerTyping');
}
function onKeyDownNotEnter(){
if(typing == false) {
typing = true;
socket.emit('userIsTyping',userName+' is typing...');
timeout = setTimeout(timeoutFunction, 5000);
} else {
clearTimeout(timeout);
timeout = setTimeout(timeoutFunction, 5000);
}
}
//User is typing functionality
$('#message').keyup(function(event){
if(event.which != 13 && userName != ''){
onKeyDownNotEnter();
}
});
socket.on('all users',function(data){
alert(data);
});
//users will see who is typing from this code
socket.on('userIsStillTyping',function(data){
document.getElementById('typer-container').innerHTML += data;
});
//remove user is typing
socket.on('userIsNotTyping',function(){
document.getElementById('typer-container').innerHTML = '';
});
//Display broadcasted message
socket.on('messageToBeDisplayed',function(data){
document.getElementById('message-container').innerHTML += data;
});
</script>
</html>
You can try this:
//Server receives message from client
socket.on('messageForServer',function(data){
//will alert all users
var userLength = io.nsps['/'].adapter.rooms[roomName].length;
socket.emit('all users',userLength);
io.sockets.in(data.roomName).emit('messageToBeDisplayed','<strong>'+data.userName+'</strong> : '+data.message+'<br>');
});
But it does not display the names of the connected users but only their number.

knockout textbox validation error

i am facing problem with knockout basic textbox validation
Here is my html
<input type="text" data-bind="value:text" />
<br />
<br />
<input type="button" data-bind="click:save" value="save" />
Here is my script
$(document).ready(function () {
ko.validation.registerExtenders();
ko.validation.configure({
registerExtenders: true,
decorateElement: true
});
var vm = ko.validatedObservable({
text: ko.observable().extend({
required: true
}),
save: function () {
debugger;
if (this.isValid()) {
alert('success');
}
else {
this.errors.showAllMessages();
alert('error');
}
}
});
ko.applyBindings(vm);
});
I have included below scripts
<script src="/Scripts/jquery-2.1.1.min.js" type="text/javascript"></script>
<script src="/Scripts/knockout-2.1.0.js" type="text/javascript"></script>
<script src="/Scripts/knockout.mapping-latest.js" type="text/javascript"></script>
<script src="/Scripts/knockout.validation.min.js" type="text/javascript"></script>
when i run this i am getting 'Undefined is not a function' at "this.isValid()"
Please help me.
I prefer this pattern to use validatedObservable - http://codepen.io/dmoojunk/pen/PwNbEL
ko.validation.registerExtenders();
ko.validation.configure({
registerExtenders: true,
decorateElement: true
});
var vm = function(){
var self = this;
self.text= ko.observable().extend({
required: true
}),
self.save= function () {
if (this.isValid()) {
alert('success');
}
else {
this.errors.showAllMessages();
alert('error');
}
}
};
var viewmodel = ko.validatedObservable(new vm())();
ko.applyBindings(viewmodel);

Resources