Graph won't start at zero - node.js

I'm working on a Dashboard, and I'm trying to display daily sales on a graph using mongodb. The issue that I'm having is that my graph does not start at 0, instead it starts at a number closer to the lowest number of daily sales that I entered. Also, the graph only displays the two dates that had sales, and I was wondering if there was a way to include all dates in between and following those dates? I would really appreciate any help or advice on how to solve this problem. Thank you!
OrderRouter.js
import express from 'express';
import expressAsyncHandler from 'express-async-handler';
import Order from '../models/orderModel.js';
import User from '../models/userModel.js';
import Product from '../models/productModel.js';
import {isAdmin, isAuth, isSellerOrAdmin, mailer, payOrderEmailTemplate} from '../utils.js';
orderRouter.get(
'/summary',
isAuth,
isAdmin,
expressAsyncHandler(async (req, res) => {
const dailySales = await Order.aggregate([
{
$group: {
_id: { $dateToString: { format: '%m-%d-%Y', date: '$createdAt' } },
orders: { $sum: 1 },
sales: { $sum: '$totalPrice' },
},
},
{ $sort: { _id: 1 } },
]);
res.send({ dailySales });
})
);
export default orderRouter;
DashboardScreen.js
import { useDispatch, useSelector } from 'react-redux';
import Chart from 'react-google-charts';
import { summaryOrder } from '../actions/orderActions';
import LoadingBox from '../components/LoadingBox';
import MessageBox from '../components/MessageBox';
export default function DashboardScreen() {
const orderSummary = useSelector((state) => state.orderSummary);
const { loading, summary, error } = orderSummary;
const dispatch = useDispatch();
useEffect(() => {
dispatch(summaryOrder());
}, [dispatch]);
return (
<div>
<div className="line">
</div>
<div className="background">
<div>
<h1>Dashboard</h1>
</div>
{loading ? (
<LoadingBox />
) : error ? (
<MessageBox variant="danger">{error}</MessageBox>
) : (
<>
<div className="graphs">
<div>
<h2 className="graphname">Daily Sales</h2>
{summary.dailySales.length === 0 ? (
<MessageBox>No Sale</MessageBox>
) : (
<Chart
width="100%"
height="400px"
chartType="AreaChart"
loader={<div>Loading Chart</div>}
data={[
['Date', 'Sales'],
...summary.dailySales.map((x) => [x._id, x.sales]),
]}
></Chart>
)}
</div>
</div>
<div>
</div>
</>
)}
</div>
</div>
);
}

In answer to your first question: in the Documentation for react-google-charts, there is a configuration option called: vAxis.minValue, described as:
Moves the min value of the vertical axis to the specified value; this will be downward in most charts. Ignored if this is set to a value greater than the minimum y-value of the data.
I'm betting this will help you out. In the docs, there's also an example of implementation:
vAxis: {minValue: 0}

Related

How to find and print array of objects in mongoDB document

I have this document in mongoDB:
{
"_id": {
"$oid": "628f739398580cae9c21b44f"
},
"events": [
{
"eventName": "Dans",
"eventText": "Danse",
"eventDate": "010101"
},
{
"eventName": "Spill",
"eventText": "Spille",
"eventDate": "020202"
}
],
"school": "Høyskolen Kristiania"
}
I am trying to get each event (name, text and date) in their own div, but can't seem to access each "block" by their own. They are supposed to be printed as one, and only where school matches, and my intention was to make different documents for each school and filter by query from there. That though, is not an issue. I am able to get all of them as one array of objects or like
{
[dev:server] _id: new ObjectId("628f739398580cae9c21b44f"),
[dev:server] events: [ [Object], [Object] ],
[dev:server] school: 'Høyskolen Kristiania'
[dev:server] }
My API currently looks like this:
Name of course is going to be sent in by userinfo, hardcoded for testing purposes.
router.get("/", async (req, res) => {
const name = "Høyskolen Kristiania";
const schools = await mongoDatabase
.collection("tempschool")
.find()
.toArray();
console.log(schools);
res.json(schools);
});
And my client:
function EventCard({ event }) {
const { eventName, eventDate, eventText } = event;
return (
<div>
<h1>{eventName}</h1>
<h3>{eventDate}</h3>
<div>{eventText}</div>
</div>
);
}
export function SchoolPage() {
const {loading, error, data} = useLoader(
async () => await fetchJSON("/api/schools")
);
const school = data;
if (loading) {
return <div>Loading...</div>;
}
if (error) {
return (
<div>Error</div>
);
}
return (
<div>
{school.map((event) => (
<div key={event.name}>
<EventCard event={event}/>
</div>
))}
</div>
);
}
I don't know if you've created tempschool as a MongooseSchema or not. You should though, you will then query it as
const school = await TempSchool.findOne({school: "Høyskolen Kristiania"});
school.events will then give you an array of objects. You will use it on front-end as
return(
<div>
school.events.map((event) => (
<div>
<h1>{event.eventName}</h1>
<h3>{event.eventDate}</h3>
<div>{event.eventText}</div>
</div>
)
)
</div>
);

Searching in mongodb atlas on express

hi everyone i have data on mongodB atlas this is my mongoose Schema
mongoose Schema
and this is client
client
import React, { useState, useEffect } from 'react';
import { Container, AppBar, Typography, Grow, Grid } from '#material-ui/core';
import { useDispatch } from 'react-redux';
import SearchBar from "material-ui-search-bar";
import Posts from './components/Posts/Posts';
import Form from './components/Form/Form';
import { getPosts } from './actions/posts';
import useStyles from './styles';
import memories from './images/memories.png';
const App = () => {
const [currentId, setCurrentId] = useState(0);
const dispatch = useDispatch();
const classes = useStyles();
useEffect(() => {
dispatch(getPosts());
}, [currentId, dispatch]);
return (
<Container maxWidth="lg" >
<AppBar className={classes.appBar} position="static" color="inherit">
<Typography className={classes.heading} variant="h2" align="center">Search Bar</Typography>
<SearchBar />
</AppBar>
<Grow in>
<Container>
<Grid container justify="space-between" alignItems="stretch" spacing={3}>
<Grid item xs={12} sm={7}>
<Posts setCurrentId={setCurrentId} />
</Grid>
<Grid item xs={12} sm={4} >
<Form currentId={currentId} setCurrentId={setCurrentId} />
</Grid>
</Grid>
</Container>
</Grow>
</Container>
);
};
export default App;
use this https://github.com/TeamWertarbyte/material-ui-search-bar
to Search i try to use "Mongoose Fuzzy Searching Plugin"
i do this Mongoose Fuzzy Searching
import mongoose from 'mongoose';
import mongoose_fuzzy_searching from 'mongoose-fuzzy-searching';
const postSchema = mongoose.Schema({
title: String,
message: String,
creator: String,
tags: [String],
selectedFile: String,
link:String,
createdAt: {
type: Date,
default: new Date(),
},
})
postSchema.plugin(mongoose_fuzzy_searching, { fields: ['message', 'title'] });
var PostMessage = mongoose.model('PostMessage', postSchema);
export default PostMessage;
what i need to write in router? i don't understand...
and how i displays the results in react?
In addition, how i can URL validation?
You have to use the fuzzy search with your backend API just like that
await Product.fuzzySearch(search).find()
export const SearchPost = async (req, res) => {
const search = req.body.search;
try {
const search = await PostMessage.fuzzySearch(search).find();
res.status(200).json(search);
} catch (error) {
res.status(404).json({ message: error.message });
}
}

How do we load the selected Item values from MongoDB for <Select /> in react

I am new to learning React. I have build a small application which includes React,Node and MongoDB. I have two modules here, the Create data and the Edit data. My question is regarding the Select component from Reacts's built in library. When I create a user, I enter his availability time slots(isMulti in Select) from a component. On Submit, this data along with the the slots is getting inserted in the Mongo Db.This is all fine. I am having problem when loading the page for edit. How to make the previously selected items from dropdown show up on page load. The other fields show up fine with componentDidMount().
Here is what my update module looks like-
// eslint-disable-next-line
import React, { Component } from 'react';
import { Link } from 'react-router-dom';
import Select from 'react-select';
import DatePicker from 'react-datepicker';
import "react-datepicker/dist/react-datepicker.css";
// Connecting from front end to backend with Axios
import axios from "axios";
export default class EditPanel extends Component {
constructor(props) {
super(props);
//defining this
this.onChangefield1 = this.onChangefield1.bind(this);
this.onChangefield2 = this.onChangefield2.bind(this);
this.onSubmit = this.onSubmit.bind(this);
this.handleChange=this.handleChange.bind(this);
this.state = {
field1: "",
field2: "",
timeSlots:[],
filterOptions:[
{ label:"9:00am to 10:00am", value: "9:00am to 10:00am" },
{ label: "10:00am to 11:00am", value: "10:00am to 11:00am" },
{ label: "11:00am to 12:00pm", value: "11:00am to 12:00pm" },
{ label: "12:00pm to 01:00pm", value: "12:00pm to 01:00pm" },
{ label: "01:00pm to 02:00pm", value: "01:00pm to 02:00pm" },
],
selectedOption:[]
}
}
componentDidMount() {
console.log("inside componentmount");
axios.get('http://localhost:5000/someEndpoint/' + this.props.match.params.id)
.then(response => {
this.setState({
field1: response.data.field1,
field2: response.data.field2,
mailId: response.data.mailId,
timeSlots:response.data.timeSlots,
selectedOption: response.data.timeSlots,
})
console.log("Meow"+response.data.timeSlots);
})
.catch(function (error) {
console.log(error);
})
}
onChangefield1(e) {
this.setState({ field1: e.target.value });
}
onChangefield2(e) {
this.setState({ field2: e.target.value });
}
// This is for insertion of any new selected list items
handleChange = selectedOption => {
console.log(selectedOption.value);
this.setState({ selectedOption: selectedOption.value }); // selected option value
console.log(selectedOption);
var dataArray = [];
for(var o in selectedOption) {
dataArray.push(selectedOption[o].value);
this.setState({ timeSlots: dataArray });
console.log(this.timeSlots);
}
};
onSubmit(e) {
e.preventDefault();
const panel =
{
field1: this.state.field1,
field2: this.state.field2,
timeSlots:this.state.timeSlots
}
axios.post('http://localhost:5000/someEndpoint/update/' + this.props.match.params.id, panel)
.then(res => console.log(res.data));
console.log("calling from edit");
window.location = '/';
}
render() {
return (
<div>
<h3>Edit Panel Info</h3>
<form onSubmit={this.onSubmit}>
<div className="form-group">
<label>Field 1: </label>
<input type="text"
required
className="form-control"
value={this.state.field1}
onChange={this.onChangefield1}
/>
</div>
<div className="form-group">
<label>field2: </label>
<input
type="text"
className="form-control"
value={this.state.field1}
onChange={this.onChangefield2}
/>
</div>
<div className="form-group">
<label>Time Slots</label>
<div>
<Select
options={this.state.filterOptions} // Options to display in the dropdown
isMulti
value={this.state.selectedOption} // would like to see the values we have in DB
onChange={this.handleChange}
closeIcon="close"
/>
</div>
</div>
<div className="form-group">
<input type="submit" value="Edit Panel" className="btn btn-primary" />
</div>
</form>
</div>
)
enter code here
}
}`enter image description here`
[enter image description here][1]
[1]: https://i.stack.imgur.com/NliEH.png
The mongo db data looks like
timeSlots
:
Array
0
:
"10:00am to 11:00am"
1
:
"12:00pm to 01:00pm"

fetching data from API in react poll

I want to fetch data from API and show frontend using react but I am getting error from frontend side which is (TypeError: answers.map is not a function ) so how can I solve this error --
MY CODE IS -
import React, { useState, useEffect } from "react";
import Poll from "react-polls";
import { getPolls } from "../helper/coreapicalls";
const MainPoll = () => {
const [polls, setPoll] = useState([]);
const [error, seterror] = useState(false);
// Setting answers to state to reload the component with each vote
const [pollAnswers, setPollAnswers] = useState([]);
useEffect(() => {
loadPoll();
}, []);
const loadPoll = () => {
getPolls().then((data) => {
if (data.error) {
seterror(data.error);
} else {
setPoll(data);
console.log(data);
}
});
};
// Handling user vote
// Increments the votes count of answer when the user votes
const handalchange = () => {
console.log("hello");
};
return (
<div className="">
<div className="container">
<h1 className="blog_heading">Poll's of the Day</h1>
<div className="row">
{polls.map((poll, index) => (
<div className="col-lg-4 col-12" key={index}>
<Poll
question={poll.question}
answers={poll.options.none}
onVote={handalchange}
/>
</div>
))}
</div>
</div>
</div>
);
};
export default MainPoll;
Data which I am getting from API is-
Here I have Question , 3 options how can I show to frontend
Error -
There is two little mistakes in the code that you show us:
the first One you imported import Polls from "./polls"; and you call <Poll noStorage question={poll.question} answers={poll.options} onVote={handleVote}/> just change Poll by Polls.
const [pollAnswers, setPollAnswers] = useState([...answers]); this didn't work because you need to pass a initial value for your state and answer is not yet initialize and accessible. just change useState([...answers]); by useState([]);
UPDATE:
you need to pass an array to answers props .
We can see in your console screenshot that the array of options has "none" as key so
try this : <Poll noStorage question={poll.question} answers={poll.options.none} onVote={handleVote}/> ("none" is a strange key...)
UPDATE
Your data object is not well formated to fit react-polls answers props.
in the npmjs doc of react-polls we can see an example of options and it's an array of object like this:
[
{ option: 'Yes', votes: 8 },
{ option: 'No', votes: 2 }
]
so based on the data console log that you add in your question it should looks like this:
[
{
createdAt: "2020-12-01T21:43:23:21.061Z",
options: {
none: [ { option: 'Yes', votes: 8 },
{ option: 'No', votes: 2 }],
student: ["12345678978945"],
teacher: ["7894567894231"]
},
question: "Are you student ot teacher",
updatedAt: "2020-12-01T21:43:23:21.061Z"
}
]
see a sandBox here working with your code (except getPolls()).
I think the issue come from the API.

Return list item with nested ternary in React.js/JSX

I want my react component to return a list item depending on the type of object array that is fed to it (string array element versus non-string array element). Everything works except for the nested ternary part. The conditions are evaluated correctly, when I do <li>{console.log(listValue2)}</li> instead of <li>{listValue2}</li> , the correct value is logged. But the list item does not appear in the DOM or virtual DOM no matter which code I do. My code is also available at https://github.com/neallred/neallred/tree/master/src/components.
Any ideas?
List.jsx
import React from 'react';
export class List extends React.Component {
render(){
return (
<div>
{this.props.list.map(function(listValue, index){
return (
<div key={index}>
<h3>{listValue.title}</h3>
<p>{listValue.description}</p>
<ul>
{(typeof listValue.highlights === 'object' ?
listValue.highlights.map(function(listValue2, index2){
(typeof listValue.highlights[index2] === 'string' ?
<li>{listValue2}</li>
:
<li>{listValue2.title}</li>
)
})
:
<li>no highlights object/outside of nested conditional</li>
)}
</ul>
</div>
);
})}
</div>
);
}
}
This.props.list structure (FixturesEducation.jsx):
import React from 'react';
import { List } from './List.jsx';
...
const researchAssistant = {
title: 'Research Assistant Work',
description: `Working for Professors...`,
highlights: [
'Ensured research replicability',
'more strings here...',
'Used Stata scripts to conduct quantitative analyses'
]
};
const math = {
title: 'Mathematical Foundation',
description: 'Via several math and economics courses...',
highlights: [
'Game Theory (Econ 478)',
'more strings here...',
'Calculus I (Math 112 equivalent)'
]
};
const economics478 = {
title: 'Game Theory',
highlights: [
'several',
'strings...'
]
};
const economics459 = {
...
};
const economics388 = {
...};
const economics382 = {
...
};
const economics = {
title: 'Economics',
description: 'I learned about...,
highlights: [
economics478,
economics459,
economics388,
economics382
]
};
const politicalScience372 = {
...
};
const politicalScience376 = {
...
};
const politicalScience497r = {
...
};
const politicalScience470 = {
...
};
const politicalScience344 = {
...
};
const politicalScience = {
title: 'Political Science',
description: 'I learned a lot...',
highlights: [
politicalScience470,
politicalScience497r,
politicalScience376,
politicalScience372,
politicalScience344
]
};
const spanish = {
title: 'Spanish Language',
description: 'I obtained my Spanish Language certificate...'
};
const businessMinor = {
title: 'Business Minor',
description: 'I this minor, I learned...'
};
const FixturesEducation = {
title: 'Education',
description: 'I attended ...',
highlights: [
researchAssistant,
math,
economics,
politicalScience,
businessMinor,
spanish
]
};
export { FixturesEducation };
Code calling List component (Education.jsx):
import React from 'react';
import { List } from './List.jsx';
...
import { FixturesEducation } from './FixturesEducation.jsx';
...
export class Education extends React.Component {
render(){
return (
<div className='col-md-10 col-md-offset-1 panel' id='education'>
<h1>{FixturesEducation.title}</h1>
<List list ={FixturesEducation.highlights}/>
</div>
);
}
}

Resources