Add other charts

This commit is contained in:
Alfred Melch 2019-08-05 13:05:21 +02:00
parent c039da9d05
commit 397587b537
5 changed files with 93 additions and 29 deletions

View File

@ -7,7 +7,7 @@
"lib": "lib" "lib": "lib"
}, },
"scripts": { "scripts": {
"build": "webpack --mode development", "build": "webpack --mode production",
"serve": "webpack serve", "serve": "webpack serve",
"test": "echo \"Error: no test specified\" && exit 1", "test": "echo \"Error: no test specified\" && exit 1",
"lint": "prettier --check '**/*.js'", "lint": "prettier --check '**/*.js'",

View File

@ -11,13 +11,13 @@ import {
} from './simplifyWasm.js' } from './simplifyWasm.js'
export const chartDependencies = { export const chartDependencies = {
wasmStack: [StoreCoordsCase, LoadResultCase, SimplifyWASMCase], wasmStack: [StoreCoordsCase, SimplifyWASMCase, LoadResultCase],
simplifyJSStack: [ simplifyJSStack: [
TransformToObjectFormCase,
OrigSimplifyWithTransformCase, OrigSimplifyWithTransformCase,
TransformToArrayFormCase, TransformToArrayFormCase
TransformToObjectFormCase
], ],
wasmVsJs: [SimplifyJSCase, SimplifyWASMCase, SimplifyJSAltCase] wasmVsJs: [SimplifyWASMCase, SimplifyJSCase, SimplifyJSAltCase]
} }
const uniqueFilter = (val, idx, self) => self.indexOf(val) === idx const uniqueFilter = (val, idx, self) => self.indexOf(val) === idx

View File

@ -1,22 +1,14 @@
import React, { Component } from 'react' import React from 'react'
import { Line } from 'react-chartjs-2' import { Line, Bar } from 'react-chartjs-2'
import debounceRender from 'react-debounce-render' import debounceRender from 'react-debounce-render'
import { datasetTemplates, genOptions } from './chartOptions.js' import { datasetTemplates, genOptions } from './chartOptions.js'
export class Chart extends Component { export class Chart extends React.Component {
constructor(props) {
super(props)
this.state = {
scaleY: 'linear',
values: 'mean'
}
}
render() { render() {
let { formState, stats, nodeData } = this.props let { formState, stats, nodeData } = this.props
let { tolRange, chart } = formState let { tolRange, chart } = formState
tolRange = tolRange || [] tolRange = tolRange || []
let { scaleY, values } = this.state
let labels = tolRange let labels = tolRange
// let labels = tolRange.map(x => Math.round(x * 1000) / 1000) // let labels = tolRange.map(x => Math.round(x * 1000) / 1000)
@ -24,20 +16,40 @@ export class Chart extends Component {
...datasetTemplates[name], ...datasetTemplates[name],
data: stats[name] data: stats[name]
})) }))
if (values === 'hz') {
for (let dataset of datasets) {
dataset.data = dataset.data.map(mean => 1000 / mean)
}
}
datasets.push({ ...datasetTemplates.numberOfNodes, data: nodeData }) datasets.push({ ...datasetTemplates.numberOfNodes, data: nodeData })
let data = { datasets, labels } let data = { datasets, labels }
let options = genOptions(chart, false, scaleY)
// console.log(JSON.stringify(data, null, 2))
return ( return (
<div className="component"> <div className="component">
<h2>Chart</h2> <h2>Chart</h2>
<Line height={400} width={600} data={data} options={options} /> {chart === 'wasmVsJs' && <WasmVsJsChart data={data} />}
{chart === 'wasmStack' && <WasmStackChart data={data} />}
{chart === 'simplifyJSStack' && <JsStackChart data={data} />}
</div>
)
}
}
class WasmVsJsChart extends React.Component {
constructor(props) {
super(props)
this.state = {
scaleY: 'linear',
values: 'mean'
}
}
convertDataToHz() {
let datasets = this.props.data.datasets
for (let dataset of datasets.filter(d => d.label !== 'numberOfNodes')) {
dataset.data = dataset.data.map(mean => 1000 / mean)
}
}
render() {
let data = this.props.data
let options = genOptions('Wasm vs. JavaScript', false, this.state.scaleY)
if (this.state.values === 'hz') this.convertDataToHz()
return (
<>
<Line height={400} width={400} data={data} options={options} />
<label>Scale Y-Axis</label> <label>Scale Y-Axis</label>
<select <select
name="scaleY" name="scaleY"
@ -57,9 +69,54 @@ export class Chart extends Component {
<option value="mean">ms per operation (mean)</option> <option value="mean">ms per operation (mean)</option>
<option value="hz">Operations per second (hz)</option> <option value="hz">Operations per second (hz)</option>
</select> </select>
</div> </>
) )
} }
} }
/**
* Returns the dataset specified by label
*/
function getDataset(data, label) {
return data.datasets.filter(d => d.label === label)[0]
}
/**
* Takes three data arrays. Subtracts the values of arr1 and arr2 from whole.
* This is used for calculating the time of execution in cases where the data
* transformation is part of the whole operation.
* Example: subtract storeCoords and loadResult from the whole simplifyWASM
* operation to get execution time of wasm code.
*/
function calculateTimeDelta(whole, arr1, arr2) {
const safeGet = (arr, idx) => (idx < arr.length ? arr[idx] : 0)
return whole.map((val, i) => val - (safeGet(arr1, i) + safeGet(arr2, i)))
}
function modifyDataArrays(data, exec, pre, after) {
if (getDataset(data, exec)) {
getDataset(data, exec).data = calculateTimeDelta(
getDataset(data, exec).data,
getDataset(data, pre).data,
getDataset(data, after).data
)
}
}
const WasmStackChart = ({ data }) => {
modifyDataArrays(data, 'simplifyWASM', 'storeCoords', 'loadResult')
const options = genOptions('Wasm execution', true)
return <Bar height={400} width={400} data={data} options={options} />
}
const JsStackChart = ({ data }) => {
const options = genOptions('SimplifyJS execution', true)
modifyDataArrays(
data,
'origSimplifyWithTransformCase',
'transformToObjectFormCase',
'transformToArrayFormCase'
)
return <Bar height={400} width={400} data={data} options={options} />
}
export const DebouncedChart = debounceRender(Chart, 300) export const DebouncedChart = debounceRender(Chart, 300)

View File

@ -1,7 +1,8 @@
import ChartJS from 'chart.js' import ChartJS from 'chart.js'
function genDataset(label, color, yAxisID = 'performance', type = 'line') { function genDataset(label, color, yAxisID = 'performance', type) {
return { return {
type,
label, label,
yAxisID, yAxisID,
fill: false, fill: false,
@ -11,12 +12,18 @@ function genDataset(label, color, yAxisID = 'performance', type = 'line') {
} }
export const datasetTemplates = { export const datasetTemplates = {
numberOfNodes: genDataset('numberOfNodes', 'grey', 'nodes'), numberOfNodes: genDataset('numberOfNodes', 'grey', 'nodes', 'line'),
simplifyWASM: genDataset('simplifyWASM', 'red'), simplifyWASM: genDataset('simplifyWASM', 'red'),
simplifyJS: genDataset('simplifyJS', 'blue'), simplifyJS: genDataset('simplifyJS', 'blue'),
simplifyJSAlt: genDataset('simplifyJSAlt', 'green'), simplifyJSAlt: genDataset('simplifyJSAlt', 'green'),
storeCoords: genDataset('storeCoords', 'blue'), storeCoords: genDataset('storeCoords', 'blue'),
loadResult: genDataset('loadResult', 'green') loadResult: genDataset('loadResult', 'green'),
origSimplifyWithTransformCase: genDataset(
'origSimplifyWithTransformCase',
'red'
),
transformToArrayFormCase: genDataset('transformToArrayFormCase', 'blue'),
transformToObjectFormCase: genDataset('transformToObjectFormCase', 'green')
} }
export function genOptions(title, stacked = false, scaleY = 'linear') { export function genOptions(title, stacked = false, scaleY = 'linear') {

View File

@ -110,7 +110,7 @@ export class Form extends Component {
> >
<option value="wasmVsJs">simplifyWasm vs. simplifyJS</option> <option value="wasmVsJs">simplifyWasm vs. simplifyJS</option>
<option value="wasmStack">wasmStack</option> <option value="wasmStack">wasmStack</option>
<option value="simplifyStack">simpslifyStack</option> <option value="simplifyJSStack">simpslifyJSStack</option>
</select> </select>
<label>Benchmarking method: </label> <label>Benchmarking method: </label>