feat: added two axis charts

scatter chart
This commit is contained in:
ysandler 2020-08-09 04:27:33 -05:00 committed by Joshua Shoemaker
parent bdf05d0250
commit 0b5a0466b7
9 changed files with 1411 additions and 1807 deletions

View File

@ -1,3 +1,4 @@
export default { export default {
oneAxisCharts: ['line', 'bar', 'radar', 'doughnut', 'pie', 'polar'] /*'bubble', 'scatter', 'area', 'mixed' */ oneAxisCharts: ['line', 'bar', 'radar', 'doughnut', 'pie', 'polar'],
twoAxisCharts: ['scatter'] /*'bubble', 'scatter', 'area', 'mixed' */
} }

View File

@ -12,6 +12,8 @@ class CreateTableController {
type: chart.type, type: chart.type,
table: chart.table, table: chart.table,
reportValue: chart.reportValue, reportValue: chart.reportValue,
xAxis: chart.xAxis,
yAxis: chart.yAxis
}) })
document.dispatchEvent(this.updatedChartsEvent) document.dispatchEvent(this.updatedChartsEvent)
} }

View File

@ -1,5 +1,6 @@
import { uuid } from 'uuidv4' import { uuid } from 'uuidv4'
import OneAxisChart from '../../Models/Chart/OneAxisChart' import OneAxisChart from '../../Models/Chart/OneAxisChart'
import TwoAxisChart from '../../Models/Chart/TwoAxisChart'
import chartTypes from '../../Constants/chartTypes' import chartTypes from '../../Constants/chartTypes'
let instance = null let instance = null
@ -14,6 +15,7 @@ class Charts {
addNewChart = chart => { addNewChart = chart => {
let newChart = null let newChart = null
if (chartTypes.oneAxisCharts.includes(chart.type)) newChart = this._generateOneAxisChart(chart) if (chartTypes.oneAxisCharts.includes(chart.type)) newChart = this._generateOneAxisChart(chart)
if (chartTypes.twoAxisCharts.includes(chart.type)) newChart = this._generateTwoAxisChart(chart)
if (newChart) this.collection.push(newChart) if (newChart) this.collection.push(newChart)
} }
@ -51,6 +53,19 @@ class Charts {
}) })
return newChart return newChart
} }
_generateTwoAxisChart = chart => {
const newChart = new TwoAxisChart({
id: chart.id || uuid(),
label: chart.label,
type: chart.type,
table: chart.table,
xAxis: chart.xAxis,
yAxis: chart.yAxis
// reportValue: chart.reportValue
})
return newChart
}
} }
export default Charts export default Charts

View File

@ -7,7 +7,7 @@ class OneAxisChart extends Chart {
this.groupByNodule = new GroupByNodule({ this.groupByNodule = new GroupByNodule({
id: this.id, id: this.id,
label: `${this.label} groupedBy ${this.reportValue}`, label: `${this.label} Grouped By ${this.reportValue}`,
tables: [this.table], tables: [this.table],
groupByValue: this.reportValue groupByValue: this.reportValue
}).export() }).export()

View File

@ -0,0 +1,40 @@
import Chart from './Chart'
class TwoAxisChart extends Chart {
constructor (props) {
super(props)
this.xAxis = props.xAxis
this.yAxis = props.yAxis
this.rows = props.table.export()
}
get scatter () {
const rows = this.table.export()
const data = rows.map(r => {
return { x: r[this.xAxis], y: r[this.yAxis] }
})
const pointColor = { r: this._generateRandomRGBNumber(), g: this._generateRandomRGBNumber(), b: this._generateRandomRGBNumber(), a: 0.2 }
return {
labels: [this.label],
datasets: [
{
data: data,
label: this.label,
pointBorderColor: `rgba(${pointColor.r}, ${pointColor.g}, ${pointColor.b}, 0.2)`,
pointBackgroundColor: `rgba(${pointColor.r}, ${pointColor.g}, ${pointColor.b}, 1)`,
backgroundColor: `rgba(${pointColor.r}, ${pointColor.g}, ${pointColor.b}, 1)`,
}
]
}
}
_generateRandomRGBNumber () {
const max = 255
const min = 0
return Math.round(Math.random() * (max - min) - min)
}
}
export default TwoAxisChart

View File

@ -1,6 +1,5 @@
import React, { Component } from 'react' import React, { Component } from 'react'
import { Card, Icon } from 'semantic-ui-react' import { Card, Icon } from 'semantic-ui-react'
// import './TableList.css'
import ChartListController from '../../Controllers/ChartListController' import ChartListController from '../../Controllers/ChartListController'
@ -16,7 +15,7 @@ class ChartListItem extends Component {
<Card key={chart.id} id={chart.id} style={{ width: '380px' }}> <Card key={chart.id} id={chart.id} style={{ width: '380px' }}>
<Card.Content> <Card.Content>
<Card.Header>{ chart.label }</Card.Header> <Card.Header>{ chart.label }</Card.Header>
<Card.Meta>{`${chart.table} grouped by ${chart.reportValue}`}</Card.Meta> {/* <Card.Meta>{`${chart.table} grouped by ${chart.reportValue}`}</Card.Meta> */}
</Card.Content> </Card.Content>
<Card.Content extra> <Card.Content extra>
<span <span

View File

@ -1,6 +1,6 @@
import React, { Component } from 'react' import React, { Component } from 'react'
import FocusChart from '../../Models/Chart/FocusChart' import FocusChart from '../../Models/Chart/FocusChart'
import { Doughnut, Bar, Line, Pie, Polar, Radar } from 'react-chartjs-2' import { Doughnut, Bar, Line, Pie, Polar, Radar, Scatter } from 'react-chartjs-2'
import { Button } from 'semantic-ui-react' import { Button } from 'semantic-ui-react'
import download from 'downloadjs' import download from 'downloadjs'
@ -48,13 +48,15 @@ class ChartViewer extends Component {
if (chart.type === 'pie') return <Pie data={chart[chart.type]} width={600} height={600} ref={this.chart} /> if (chart.type === 'pie') return <Pie data={chart[chart.type]} width={600} height={600} ref={this.chart} />
if (chart.type === 'polar') return <Polar data={chart[chart.type]} width={600} height={600} ref={this.chart} /> if (chart.type === 'polar') return <Polar data={chart[chart.type]} width={600} height={600} ref={this.chart} />
if (chart.type === 'radar') return <Radar data={chart[chart.type]} width={600} height={600} ref={this.chart} /> if (chart.type === 'radar') return <Radar data={chart[chart.type]} width={600} height={600} ref={this.chart} />
if (chart.type === 'scatter') return <Scatter data={chart[chart.type]} width={600} height={600} ref={this.chart} />
} }
render = () => { render = () => {
return ( return (
<div className='ChartViewer'> <div className='ChartViewer'>
{this.renderChart()} {this.renderChart()}
{ this.state.chart ? <Button onClick={this.saveChart}>Save As Image</Button> : '' } <br />
{ this.state.chart ? <Button fluid onClick={this.saveChart}>Save As Image</Button> : '' }
</div> </div>
) )
} }

View File

@ -17,7 +17,9 @@ class CreateChartForm extends Component {
selectedTableId: '', selectedTableId: '',
tables: this.tables.getCollectionProps(), tables: this.tables.getCollectionProps(),
reportValue: '', reportValue: '',
headers : [] headers : [],
xAxisValue: '',
yAxisValue: ''
} }
this.tables = new Tables() this.tables = new Tables()
@ -45,10 +47,18 @@ class CreateChartForm extends Component {
this.setState({ chartType: value.value }) this.setState({ chartType: value.value })
} }
handleGroupByChange = (e, value) => { handleReportValueChange = (e, value) => {
this.setState({ reportValue: value.value }) this.setState({ reportValue: value.value })
} }
handleXAxisChange = (e, value) => {
this.setState({ xAxisValue: value.value })
}
handleYAxisChange = (e, value) => {
this.setState({ yAxisValue: value.value })
}
handleSelectedTableChange = (e, value) => { handleSelectedTableChange = (e, value) => {
const selectedTable = this.tables.getById(value.value) const selectedTable = this.tables.getById(value.value)
this.setState({ this.setState({
@ -69,7 +79,7 @@ class CreateChartForm extends Component {
return tableDropdownOptions return tableDropdownOptions
} }
getGroupByDropDownOptions = () => { getHeaderDropDownOptions = () => {
const { headers } = this.state const { headers } = this.state
const tableDropdownOptions = headers.map(h => { const tableDropdownOptions = headers.map(h => {
return { return {
@ -82,21 +92,65 @@ class CreateChartForm extends Component {
} }
handleSubmit = () => { handleSubmit = () => {
const { chartType, selectedTableId, reportValue } = this.state const { chartType, selectedTableId, reportValue, xAxisValue, yAxisValue } = this.state
const chartLabel = this.chartLabelInput.current.inputRef.current.value const chartLabel = this.chartLabelInput.current.inputRef.current.value
// const reportValue = this.reportValueInput.current.inputRef.current.value
const table = this.tables.getById(selectedTableId) const table = this.tables.getById(selectedTableId)
this.controller.addNewChart({ this.controller.addNewChart({
label: chartLabel, label: chartLabel,
type: chartType, type: chartType,
table: table, table: table,
reportValue: reportValue reportValue: reportValue,
xAxis: xAxisValue,
yAxis: yAxisValue
}) })
this.clearInput() this.clearInput()
} }
renderConfigOptions = () => {
const { oneAxisCharts, twoAxisCharts } = chartTypes
const { chartType } = this.state
let configElements = []
if (oneAxisCharts.includes(chartType)) configElements.push(
<Dropdown
value ={this.state.reportValue}
placeholder='Report By'
options={this.getHeaderDropDownOptions()}
fluid
selection
style={{ width: '300px' }}
onChange={this.handleReportValueChange}
/>
)
else if (twoAxisCharts.includes(chartType)) {
configElements.push(
<Dropdown
value ={this.state.xAxisValue}
placeholder='X-Axis'
options={this.getHeaderDropDownOptions()}
fluid
selection
style={{ width: '300px' }}
onChange={this.handleXAxisChange}
/>
)
configElements.push(
<Dropdown
value ={this.state.yAxisValue}
placeholder='Y-Axis'
options={this.getHeaderDropDownOptions()}
fluid
selection
style={{ width: '300px' }}
onChange={this.handleYAxisChange}
/>
)
}
return configElements
}
updateTableList = () => { updateTableList = () => {
this.setState({tables: this.tables.getCollectionProps()}) this.setState({tables: this.tables.getCollectionProps()})
} }
@ -107,21 +161,10 @@ class CreateChartForm extends Component {
<Header as='h3'>Create Graph</Header> <Header as='h3'>Create Graph</Header>
<Input <Input
placeholder='Chart Label' placeholder='Chart Label'
ref={this.chartLabelInput} ref={this.chartLabelInput}
icon='tags' icon='tags'
style={{ width: '300px' }}
/>
<br />
<Dropdown
value ={this.state.chartType}
placeholder='Select a Chart Type'
options={this.getChartTypeDropdownOptions()}
fluid
selection
style={{ width: '300px' }} style={{ width: '300px' }}
onChange={this.handleChartTypeChange}
/> />
<Dropdown <Dropdown
@ -133,17 +176,19 @@ class CreateChartForm extends Component {
style={{ width: '300px' }} style={{ width: '300px' }}
onChange={this.handleSelectedTableChange} onChange={this.handleSelectedTableChange}
/> />
<Dropdown <Dropdown
value ={this.state.selectedTable} value ={this.state.chartType}
placeholder='Group By' placeholder='Select a Chart Type'
options={this.getGroupByDropDownOptions()} options={this.getChartTypeDropdownOptions()}
fluid fluid
selection selection
style={{ width: '300px' }} style={{ width: '300px' }}
onChange={this.handleGroupByChange} onChange={this.handleChartTypeChange}
/> />
{ this.renderConfigOptions() }
<div className='creatTableFormSubmitButtons'> <div className='creatTableFormSubmitButtons'>
<Button content='Cancel' secondary /> <Button content='Cancel' secondary />
<Button content='Confirm' primary onClick={this.handleSubmit} /> <Button content='Confirm' primary onClick={this.handleSubmit} />

File diff suppressed because it is too large Load Diff