I'm fairly new to React.
I am trying to import this following test json data file into my React graph.
{
"data": [
{"datetime": "", "data": [1,2,3,4]},
{"datetime": "", "data": [1,2,3,4]}
]
}
The x-axis is the time so it should not matter very much.
But I don't know how to read the data into the y-axis.
This is my Graph.js:
import React, { Component } from 'react';
import Highcharts from 'highcharts';
import socketIOClient from "socket.io-client";
import {
HighchartsChart, Chart, withHighcharts, XAxis, YAxis, Title, Legend, LineSeries
} from 'react-jsx-highcharts';
import './Graph.css'
var jsonData = import '../jsonData.json' //pass the json file location
class Graph extends Component {
constructor (props) {
super(props);
this.addDataPoint = this.addDataPoint.bind(this);
const now = Date.now();
this.state = {
data: []
}
}
componentDidMount() {
//THIS is to add points from json
//Please don't mind the stuff here--------
//This is for another graph
var sensorSerial = this.props.match.params.sensorId
const socket = socketIOClient("http://localhost:5001/test");
socket.on("newnumber", data => this.addDataPoint(data));
//----------------------------------------
}
addDataPoint(data){
//This is for another graph------------
if(data.sensorSerial == this.props.match.params.sensorId){
var newData = this.state.data.slice(0)
console.log(new Date(data.dateTime.split(' ').join('T')))
newData.push([new Date(data.dateTime.split(' ').join('T')), data.number])
this.setState({
data: newData
})
}
//-------------------------------------
}
render() {
// const {data} = this.state;
const plotOptions = {
series: {
pointStart: new Date("2019-04-04T10:55:08.841287Z")
}
}
return (
<div className="graph">
<HighchartsChart plotOptions={plotOptions}>
<Chart />
//Title
<Title>Sensor Data</Title>
//Legend
<Legend layout="vertical" align="right" verticalAlign="middle" >
<Legend.Title>Legend</Legend.Title>
</Legend>
<XAxis type="datetime">
<XAxis.Title>Time</XAxis.Title>
</XAxis>
<YAxis>
<YAxis.Title>Y-axis</YAxis.Title>
<LineSeries name="Channel 1" data={this.state.data}/>
</YAxis>
</HighchartsChart>
</div>
);
}
}
export default withHighcharts(Graph, Highcharts);
If this is a duplicate question, please let met know!
I'm not a frequent on Stakoverflow, so if there's anything I can do to improve my post, please let me know.
Thank you for your time!
Related
Short story: I am making my own GIS (geographic information system) and want to be able to upload JSON files with geographical data. I do not however want to save files in a database, just in a list. Furthermore I'm using Context to parse data to the <MAP/> (leaflet) component.
My problem is that when pushing the JSON to the list it is not recogniezed as a JSON but as string. How can I solve this problem.
I am quite new to react so I am open for suggestions to solve it differently.
Here is my code
import React, {createContext, useState} from 'react';
import "../../App.css";
import data from '../../Layers/layer1.json'
import data1 from '../../Layers/layer2.json'
export const FileContext = createContext()
const layerList = []
function updateList(layer){
layerList.push(layer)
}
export const FileProvider = (props) => {
const [layer, setLayer] = useState(
layerList
)
return(
<FileContext.Provider value = {[layer, setLayer]}>
{props.children}
</FileContext.Provider>
);
}
// Create an object of formData
const onFileChange = e => {
const fileReader = new FileReader();
fileReader.readAsText(e.target.files[0], "UTF-8");
fileReader.onload = e => {
console.log(e.target.result);
updateList(e.target.result);
console.log(layerList)
};
//console.log(layerList)
}
function FileUpload() {
return (
<div>
<div id='fileupload'>
<input type="file" onChange={onFileChange} />
</div>
</div>
);
}
export default FileUpload;
And this is the Map component
import { Map, TileLayer, GeoJSON} from 'react-leaflet'
import "../App.css";
import data from '../Layers/layer1.json'
import { FileContext } from '../LandingPage/ToolbarComponents/FileUpload';
function MapOslo() {
const [layer, setLayer] = useContext(FileContext)
return (
<Map center={[59.93, 10.75]} zoom={4}>
<TileLayer
url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
attribution='© OpenStreetMap contributors'
/>
<GeoJSON data={layer} style={['color','#006400']} />
</Map>
);
}
export default MapOslo;
To convert a String to JSON you can use JSON.parse(str)
var jsonStr = "{test: 'hi'}";
var json = JSON.parse(jsonStr);
So I think you have to implement parse here: updateList(JSON.parse(e.target.result));
I'm very new in React and JS. I'm trying to create a graph from JSON, but I can't pass value to graph with MAP function and PUSH, my result is just numbers that I put manually (2, 3, 5 - Line 45)
dataGraf.push(hit.minutos) //Works well
this.state.items.map((hit) => (dataGraf.push(hit.minutos))) //No erros, but no data add
My JSON:
[
{"indice":1,"minutos":569,"programa":"seg"},
{"indice":2,"minutos":421,"programa":"ter"},
{"indice":3,"minutos":258,"programa":"quar"}
]
import React,{Component} from 'react';
import Chart from "chart.js";
import Config from '../components/config.js';
let dataGraf = []
class GraphChart extends Component {
constructor(props) {
super(props);
this.myRef = React.createRef();
this.state = {
items: [],
error: null
};
}
componentDidMount() {
let url1 = `${Config.FullURL}/progativo`
const ctx = this.ctx;
fetch(url1)
.then(items => items.json())
.then((items) => {
this.setState({ items });
});
this.funDadosGrafico()
new Chart(ctx, {
type: "pie",
data: {
labels: ['blue', 'green','red'],
datasets: [
{
label: "# of Likes",
data: dataGraf
}
]
}
});
} //End of componentDidMount
funDadosGrafico(){
dataGraf.push(2, 5, 3) //Just for test
this.state.items.map((hit) => (
dataGraf.push(hit.minutos)))
}
render() {
return (
<div>
<canvas width='800' height='300' ref={ctx => (this.ctx = ctx)}/>
</div>
)
}
}
export default GraphChart;
try moving the execution this.funDadosGrafico() and Canvas creation to componentDidUpdate.
once you call fetch, fetch wont block the thread, hence this.funDadosGrafico() is executed right aftwards. then blocks are executed only after fetch is resolved.
plus, setState method is also async. it is not going to work as expected even if you remove setState from fetch call like:
this.setState(updateMyState)
this.funDadosGrafico() // not going to work also, setState is async
I am working on kepler.gl .... wright now i am reading data from an api and plot that data in keplr.gl and that's working fine here is the code ...
import keplerGlReducer from "kepler.gl/reducers";
import { createStore, combineReducers, applyMiddleware } from "redux";
import { taskMiddleware } from "react-palm/tasks";
import { Provider, useDispatch } from "react-redux";
import KeplerGl from "kepler.gl";
import { addDataToMap } from "kepler.gl/actions";
import useSwr from "swr";
const reducers = combineReducers({
keplerGl: keplerGlReducer
});
const store = createStore(reducers, {}, applyMiddleware(taskMiddleware));
export default function App() {
return (
<Provider store={store}>
<Map />
<csv/>
</Provider>
);
}
function Map() {
const dispatch = useDispatch();
const { data } = useSwr("covid", async () => {
const response = await fetch(
"https://gist.githubusercontent.com/leighhalliday/a994915d8050e90d413515e97babd3b3/raw/a3eaaadcc784168e3845a98931780bd60afb362f/covid19.json"
);
const data = await response.json();
return data;
});
React.useEffect(() => {
if (data) {
dispatch(
addDataToMap({
datasets: {
info: {
label: "COVID-19",
id: "covid19"
},
data
},
option: {
centerMap: true,
readOnly: false
},
config: {}
})
);
}
}, [dispatch, data]);
return (
<KeplerGl
id="covid"
mapboxApiAccessToken="pk.eyJ1IjoiYWxpcmF6YTcwNSIsImEiOiJjazh5d2hjb3AwOHBqM2VsY21wOHo5eXprIn0.9G5CE4KqfbvU9HQ6WBuo3w"
width={window.innerWidth}
height={window.innerHeight}
/>
);
}
now i want to read data from jason or csv file and plot that data into kepler.gl map .. how can i do this can anyone help me ?..... thanks
In React do it like this
import datajson from './yourdata.json';
const data=datajson;
easiest way would be to place your json or csv file beside your code and
import your json file:
const dataJson = require('./data.json');
change your data source to your json:
const data = dataJson
// or dataJson.data depending on your json structure
or if your data is in csv format the fastest way that comes to mind is installing the csv-parse and then:
const data = parse(csvData, {
//config based on your csv format
columns: true,
skip_empty_lines: true
});
hope this is what you are looking for
I have a json file named autofill.json and it's created to autofill a search bar when pressed on.
the autofill.json is a test file that's why it looks like this.
[
{
"a": {
"apple": {
"name": "apple",
"href": "https://www.apple.com/"
},
"armadillo": {
"name": "armadillo",
"href": "https://www.armadillo.com/"
}
},
"b": {
"box": {
"name": "apple",
"href": "https://www.berserk.com/"
},
"berserk": {
"name": "berserk",
"href": "https://www.berserk.com/"
}
}
}
]
The .json file is then fetched in the file named FetchAndParseResults.js
import fetch from 'isomorphic-fetch'
const FetchAndParseResults = (url) => {
return fetch(url).then(response => {
const parsedJson = response.json()
return parsedJson
})
}
export default FetchAndParseResults
The data that gets fetched is used in searchcontainer.js where everything gets placed in, the search etc.
import React from 'react'
import Searchbar from './index.js'
import FetchAndParseResults from './FetchAndParseResults.js'
class SearchContainer extends React.Component {
state = {
results: []
}
performSearch = event => {
return FetchAndParseResults('static/autofill.json').then(data => {
this.setState({ results: data })
})
}
render () {
console.log('performSearch event', this.performSearch)
console.log('data inside performSearch', this.state.results)
return (
<Searchbar
performSearch={this.performSearch}
results={this.state.results}
/>
)
}
}
export default SearchContainer
Then to map through the data that is in autofill.json there is a file named autofill.js
import React from 'react'
import PropTypes from 'prop-types'
import Styles from './searchbar.scss'
const AutoFill = (props) => {
console.log('proppppppsss', props)
const results = props.results || []
return (
<ul className={Styles.searchUl}>
{results.map(({ name, href }) => (
<li className={Styles.searchLi} key={href}>
<a className={Styles.searchA} href={href} target='_blank' rel='noopener noreferrer' key={href}>
{name}
</a>
</li>
))}
</ul>
)
}
AutoFill.propTypes = {
results: PropTypes.array
}
export default AutoFill
the Searchbar component in (index.js) that is being used in searchcontainer.js
import React from 'react'
import Styles from './searchbar.scss'
import Icon from '../../components/icon/icon'
import Search from '../../components/form-input/search'
import AutoFill from './autofill'
import PropTypes from 'prop-types'
export default class Searchbar extends React.Component {
constructor (props) {
super(props)
this.state = {
className: Styles.input,
icon: Styles.icon__wrapper,
value: []
}
this.input = React.createRef()
}
openInput = () => {
this.setState({
className: Styles.input__active,
icon: Styles.iconWidth
}, () => {
this.input.focus()
})
this.props.onOpen && this.props.onOpen()
}
closeInput = () => {
this.setState({
className: Styles.input,
icon: Styles.icon__wrapper
})
this.props.onClose && this.props.onClose()
}
handleChange = event => {
let value = event.target.value
this.setState({ value })
this.props.performSearch(value)
}
handleSubmit = event => {
event.preventDefault()
}
render () {
console.log('results', this.props.results)
console.log('state.value', this.state.value)
return (
<div>
<form onSubmit={this.handleSubmit} className={Styles.search}>
<div className={this.state.icon}>
<Icon className={Styles.icon__wrapper} iconName='faSearch' onClick={this.openInput} />
</div>
<Search autoComplete='off' value={this.state.value} onChange={this.handleChange} id='search' tabIndex='0' myref={input => { this.input = input }} className={this.state.className} onBlur={this.closeInput} placeholder='Search' />
</form>
<div>
<AutoFill results={this.props.results} />
</div>
</div>
)
}
}
Search.propTypes = {
performSearch: PropTypes.func,
results: PropTypes.array
}
When i try to refer to a what is in the json file from the search i receive the error,
GET http://localhost:3000/[object%20Object] 404 (Not Found)
And
about:1 Uncaught (in promise) SyntaxError: Unexpected token < in JSON
at position 0
The second error is fixed by doing
const parsedJson = response.text(
instead of
const parsedJson = response.json()
to get more information where/what the error takes place. But by doing this i receive the error,
searchcontainer.js:12 Uncaught (in promise) TypeError: Cannot read property 'results' of undefined
I've tried to run it from npm build instead of running it in a dev environment which didn't fix it.
I read that a mock url should work but then again i want to acces it from a file and not from a url?
Any help would be highly appreciated and looked into.
The problem is most likely in the fetch call. If you look at the error message GET http://localhost:3000/[object%20Object] 404 (Not Found)
You can see that it is trying to append an object to the URL localhost:3000/.
You are getting the Unexpected token < in JSON at position 0 error because the response of your fetch request is probably a 404 page. The < is most likely the first char of <html>
To access the JSON object in your React files, you can simply do an importation like so;
import * as autofillData from 'autofill.json';
It will be returned as a JSON object.
I believe you are using the isomorphic-fetch package wrongly, if you look at their source code, https://github.com/matthew-andrews/isomorphic-fetch/blob/master/fetch-npm-node.js#L5 , they are accepting a URL to make a call to the API URL which will return a promise or a JSON object depending on the implementation of the API that you are calling.
If you were to dive deeper into the open-source code here (https://github.com/matthew-andrews/isomorphic-fetch/blob/master/fetch-npm-node.js#L8) , you will notice that isomorphic-fetch package is using another package node-fetch to do their fetch call, which accepts the API URL and the method request options to call the API with. (As stated here; https://github.com/bitinn/node-fetch/blob/master/src/index.js#L34)
To continue with your test, perhaps this might be the solution you'd prefer?
import fetch from 'isomorphic-fetch';
import * as autofillData from 'autofill.json'; //test data
const FetchResults = event => {
return fetch('/https://jsonplaceholder.typicode.com/todos/1'') //mockURL, to be replaced with real API
.then(response => {
// const parsedJson = response.json(); // TODO: un-comment this line when the real API url is usable
const parsedJson = autofillData; // TODO: remove this line when mocking is done and the real API URL is ready
return parsedJson;
})
}
export default FetchResults;
To have a mock URL placeholder, I would suggest https://jsonplaceholder.typicode.com/ to prevent your fetch result to return an unexpected error during test mocking.
Hope this is helpful.
The question has been solved, The main issue was with defining const names such as const results = [] which should've been const results = props.results || [].
The code has been updated incase you have problems aswell.
I need to output data from the json file that the user loads at the front.
I download the json file, but I get a strange store in Redux and can not figure out how to further display the data to the screen from the store.
What should I need to do?
import React from 'react'
import { connect } from 'react-redux'
import * as actions from './actions'
class File extends React.Component {
constructor (props) {
super(props)
}
handleChange (e) {
e.preventDefault();
let reader = new FileReader();
let file = e.target.files[0];
reader.onloadend = () => {
let text = reader.result;
this.props.jsonLoad(JSON.parse(text))
}
reader.readAsText(file)
}
render () {
return (
<div>
<h3> Add your file: </h3>
<input type="file" multiple onChange={this.handleChange.bind(this)}/>
<button >
add text from file
</button>
</div>
)
}
}
const mapStateToProps = (state) => {
return {
json: state.json
}
}
function mapDispatchToProps (dispatch) {
return {
jsonLoad: (json) => dispatch(actions.jsonLoad(json)),
}
}
export default connect(mapStateToProps, mapDispatchToProps)(File)
action.js
const USER_JSON = 'USER_JSON';
export function jsonLoad(json) {
console.log( json)
return function (dispatch) {
let file = json
dispatch(addFile(file))
}
}
export function addFile (json) {
return{
type: 'USER_JSON',
payload: json
}
};