Pie Chart not rendering React Chart.js - javascript

I'm trying to render a simple pie chart in a react component, using the Chart.js library.
I've managed to render a Line chart, but for some reason my Pie chart is just rendering an empty canvas. Is it a problem with the chartData not being valid? I'm not getting any kind of error.
import React, { Component, PropTypes } from 'react';
import * as axios from 'axios';
import s from './Test.css';
import withStyles from 'isomorphic-style-loader/lib/withStyles';
import cx from 'classnames';
var PieChart = require("react-chartjs").Pie;
class Test extends Component {
constructor(props) {
super(props);
this.chartData = {
datasets: [{
data: [100, 200, 300],
backgroundColor: ["#FF6384", "#36A2EB", "FFCE56"]
}]
};
this.chartOptions = {
scale: {
reverse: true,
ticks: {
beginAtZero: true
}
}
};
};
render() {
return(<div className={s.graphic}><PieChart data={this.chartData} options={this.chartOptions} width="600" height="250" /></div>);
}
}
export default withStyles(s)(Test);

Apologies for the first (non) answer. I've actually got somewhere:
The problem was my CSS.
canvas {
width: 100% !important;
height: auto !important;
}
For some reason still not known to me forcing the pie chart sizes causes it not to render. Removing the css solved the rendering problem.

Related

Vue-Chartjs not rendering graph

I am buiding a website with laravel and using the vuejs to manage the front-end. I want to display several charts through vue-chartjs but the vue-chartjs is not showing the graph even though the data is successfully passed. I have been following their website guide but the graph never displays.
My Vue Component
<teplate>
<div>
...
<line-chart :chart-data="datacollection"></line-chart>
<button #click="fillData()">Randomize</button>
</div>
</template>
<script>
import Table from '../equipments/table.vue'
import LineChart from '../equipments/LineChart.js'
import DropDownList from '../equipments/dropdownlist.vue'
export default {
data () {
return {
datacollection: null
}
},
components: {
LineChart,
Table,
DropDownList
},
mounted () {
this.fillData()
},
methods: {
fillData () {
this.datacollection = {
labels: ['weqw','wewq'],
datasets: [
{
label: 'Data One',
backgroundColor: '#f87979',
data: [this.getRandomInt(), this.getRandomInt()]
},
{
label: 'Data One',
backgroundColor: '#f87979',
data: [this.getRandomInt(), this.getRandomInt()]
}
]
}
},
getRandomInt () {
return Math.floor(Math.random() * (50 - 5 + 1)) + 5
}
}
}
</script>
<style>
.small {
max-width: 600px;
margin: 150px auto;
}
</style>
my Chart.js
import { Line, mixins } from 'vue-chartjs'
const { reactiveProp } = mixins
export default {
extends: Line,
mixins: [reactiveProp],
props: ['options'],
mounted () {
// this.chartData is created in the mixin.
// If you want to pass options please create a local options object
this.renderChart(this.chartData, this.options)
}
}
Hope could receive some hints here, thanks in advance
Vue-chartjs only works with v2 of chart.js. So you will need to downgrade chart.js to version 2.9.4 if you want to use it.
npm i chart.js#2.9.4

JSX element type 'Line' is not a constructor function for JSX elements

I am trying to use chart.js with Typescript to build an application in React, however when attempting to render a Line chart I get the error described above on this line:
<Line data={data}/>.
Along with this I also get the message "Type 'ChartComponent' is missing the following properties from type 'ElementClass': render, context, setState, forceUpdate, and 3 more."
Furthermore, when I use yarn start to run the application, the graph will render, but only for a split second before crashing with the error message.
I am fairly new to Typescript so I am confused as to what this error means. Any help would be appreciated.
import React, {Component} from 'react';
import Line from "react-chartjs-2"
class LineTest extends React.Component{
render() {
const data = {
labels: [
'10/04/2018', '10/05/2018',
'10/06/2018', '10/07/2018',
'10/08/2018', '10/09/2018',
'10/10/2018', '10/11/2018',
'10/12/2018', '10/13/2018',
'10/14/2018', '10/15/2018'
],
datasets: [
{
label: 'Temperature',
data: [22,19,27,23,22,24,17,25,23,24,20,19],
fill: false,
borderColor: 'green'
}
]
}
return (
<div className="App">
<div>
<Line data={data}/>
</div>
</div>
);
}
}
export default LineTest
The Line component is exported by react-chartjs-2 as a named export. You need to import it by its name:
import {Line} from 'react-chartjs-2';
Live Example:

React Component with shared mouseOver handler

I have a simple react component that wraps the SVG 1.1 specifications recttag and adds in some defaults and looks like this:
import React, { Component } from 'react';
const defaults = {
x: 100,
y: 100,
width: 200,
height: 100,
rx: 0,
ry: 0,
};
export default class Rectangle extends Component {
constructor(props) {
super(props);
this.state = {
...defaults,
...props,
};
}
render() {
return (
<rect
{...this.state}>
{this.props.children}
</rect>
);
}
}
I am trying to find a good way to add on a mouseOver function, but would like to do it in a way that can be reused with other components similar to this.
I have looked into Higher Order Components, but am having trouble when I try to set the state, because the state is not part of the above component's state.

Using Dygraph in React with redux?

I've been having a lot of trouble implementing Dygraph in React (I'm using redux): http://dygraphs.com/. The Dygraph wrapper packages on NPM don't seem to work.
Also I can't simply use:
<div id="graph"></div>.
I believe this is because in react your working in a state instead of an actual index.html file.
So the method I'm currently trying to use is to create the graph component:
import React, { Component } from 'react';
import Dygraph from 'dygraphs';
import myData from '../../mockdata/sample-data.json';
import 'dygraphs/dist/dygraph.min.css'
import './graphComponent.css';
class DyGraph extends Component {
constructor(props) {
super(props);
// mock json data for graph
const messages = myData;
var data = "";
messages.forEach((response) => {
data += response[0] + ',' + response[1] + "\n";
});
new Dygraph('graphContainer', data, {
title: 'Pressure Transient(s)',
titleHeight: 32,
ylabel: 'Pressure (meters)',
xlabel: 'Time',
gridLineWidth: '0.1',
width: 700,
height: 300,
connectSeparatedPoints: true,
axes: { "x": { "axisLabelFontSize": 9 }, "y": { "axisLabelFontSize": 9 } },
labels: ['Date', 'Tampines Ave10 (Stn 40)'],
});
}
render() {
return <div></div>
}
}
export default DyGraph;
and then import it into:
import React, { Component } from 'react';
import DyGraph from './components/graph/graphComponent';
import './App.css';
class DeviceDetails extends Component {
render() {
return (
<div >
<DyGraph />
</div>
);
}
}
export default DeviceDetails;
And there is a Display state that if you click something it will go to:
import React, { PropTypes } from 'react'
import { connect } from 'react-redux'
import WarningView from '../warning/warningView'
import DirectoryView from '../directory/directoryView'
import DeviceDetailView from '../devicedetails/devicedetails'
export const Display = ({ currentPage }) => {
switch(currentPage) {
case 'WARNING_PAGE':
return <WarningView/>;
case 'DIRECTORY_PAGE':
return <DirectoryView/>;
case 'SENSOR_PAGE':
return <DeviceDetailView/>;
default:
return <WarningView/>;
}
};
Display.propTypes = {
currentPage: PropTypes.string.isRequired,
};
export default connect(
(state) => ({ currentPage: state.currentPage }),
(dispatch) => ({ })
)(Display)
When I build and run this locally I get an error in the console (when I try to see the graph):
Uncaught (in promise) Error: Constructing dygraph with a non-existent div!
at Dygraph.__init__ (dygraph.js:217)
at new Dygraph (dygraph.js:162)
at new DyGraph (graphComponent.js:19)
at ReactCompositeComponent.js:295
at measureLifeCyclePerf (ReactCompositeComponent.js:75)
at ReactCompositeComponentWrapper._constructComponentWithoutOwner (ReactCompositeComponent.js:294)
at ReactCompositeComponentWrapper._constructComponent (ReactCompositeComponent.js:280)
at ReactCompositeComponentWrapper.mountComponent (ReactCompositeComponent.js:188)
at Object.mountComponent (ReactReconciler.js:46)
at ReactDOMComponent.mountChildren (ReactMultiChild.js:238)
If anyone can figure out what's going on or even give me a hint that'd be SOOO APPRECIATED. I specifically want to use dygraph instead of google charts or other react charts (which I've gotten working very easily), however, there is little information about dygraph implementation in React and I don't really understand why it won't work.
The problem is that this line:
new Dygraph('graphContainer', data, { ... })
Tries to create a Dygraph in the element with ID graphContainer. But there is no element with that ID, hence the failure.
You need to wait until React creates a div in the DOM to create the dygraph. You'll want to instantiate the Dygraph in componentDidMount:
class Dygraph extends Component {
render() {
return <div ref="chart"></div>;
}
componentDidMount() {
const messages = myData;
var data = "";
messages.forEach((response) => {
data += response[0] + ',' + response[1] + "\n";
});
new Dygraph(this.refs.chart, data, {
/* options */
});
}
}

Javascript react-jss hover not changing color

I am trying out React-Jss from cssinjs.org/react.jss and this is what I've done upto now:
Installation:
npm install --save react-jss
I then tested this file where I added a Hover to the footer just to give this a test:
import React from 'react';
import injectSheet from 'react-jss';
const style = {
Footer: {
backgroundColor: '#000000',
},
'&:hover': {
backgroundColor: '#ff0000',
}
};
export class Footer extends React.Component {
render() {
return (
<Footer>This is the footer</Footer>
);
}
}
export default injectSheet(style);
When I hover over the Footer component I would expect the footer to turn red but nothing is happening.
I'm I missing something or is something wrong in the syntax?
There's a handful of reasons the code above isn't working. There's issues with your React code beyond the JSS syntax.
In regards to the JSS style declaration specifically, let's first make sure you understand what you're declaring in the style object. The properties of the style object (in your case Footer, are the class names that you want to define and as such should probably be all lowercase. The value of each of those properties is an object containing the CSS styles that you want applied by that class. If you want to define a hover styles for a given class then you would declare those styles inside of the class's style object like so:
const style = {
footer: {
backgroundColor: '#000000',
'&:hover': {
backgroundColor: '#ff0000',
}
}
};
I suspect you're attempting to follow the first code example under 'Usage' in the package's readme. Here's a working example that follows that approach.
import React from 'react'
import injectSheet from 'react-jss'
const style = {
footer: {
backgroundColor: '#000000',
'&:hover': {
backgroundColor: '#ff0000'
}
}
}
const Footer = ({sheet}) => (
<div className={sheet.classes.footer}>This is the footer</div>
)
export default injectSheet(style)(Footer)
Below is a working example that utilizes the advantages of ES6 in case you're interested.
import React, {PropTypes} from 'react';
import injectSheet from 'react-jss';
const style = {
footer: {
backgroundColor: '#000000',
'&:hover': {
backgroundColor: '#ff0000'
}
}
};
#injectSheet(style)
export default class Footer extends React.Component {
static propTypes = {
sheet: PropTypes.object.isRequired
}
render() {
const {sheet} = this.props
return (
<div className={sheet.classes.footer}>This is the footer</div>
);
}
}

Categories

Resources