feat: added two axis charts
scatter chart
This commit is contained in:
parent
bdf05d0250
commit
0b5a0466b7
@ -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' */
|
||||||
}
|
}
|
||||||
|
@ -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)
|
||||||
}
|
}
|
||||||
|
@ -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
|
||||||
|
@ -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()
|
||||||
|
40
src/Models/Chart/TwoAxisChart.js
Normal file
40
src/Models/Chart/TwoAxisChart.js
Normal 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
|
@ -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
|
||||||
|
@ -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>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -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
Loading…
x
Reference in New Issue
Block a user