Add chart save/load
This commit is contained in:
parent
2bcd62ebbe
commit
6308b16f34
5
benchmarking/package-lock.json
generated
5
benchmarking/package-lock.json
generated
@ -3924,6 +3924,11 @@
|
||||
"escape-string-regexp": "1.0.5"
|
||||
}
|
||||
},
|
||||
"file-drop-element": {
|
||||
"version": "0.2.0",
|
||||
"resolved": "https://registry.npmjs.org/file-drop-element/-/file-drop-element-0.2.0.tgz",
|
||||
"integrity": "sha512-BGDdaJ4U2Cz0qhv6YGLnuhVtKcN8fp7F/4dS7lGSL1Fbe8m4cbGk+8awwHW0xcFqutMojxGchMVuWYQpEpP/Qg=="
|
||||
},
|
||||
"file-loader": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/file-loader/-/file-loader-4.0.0.tgz",
|
||||
|
@ -22,6 +22,7 @@
|
||||
"dependencies": {
|
||||
"benchmark": "^2.1.4",
|
||||
"chart.js": "^2.8.0",
|
||||
"file-drop-element": "^0.2.0",
|
||||
"lodash": "^4.17.11",
|
||||
"react": "^16.8.6",
|
||||
"react-chartjs-2": "^2.7.6",
|
||||
|
63
benchmarking/public/chart.html
Normal file
63
benchmarking/public/chart.html
Normal file
@ -0,0 +1,63 @@
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
|
||||
<title>Document</title>
|
||||
<style>
|
||||
file-drop {
|
||||
position: relative;
|
||||
box-sizing: border-box;
|
||||
display: block;
|
||||
padding: 10px;
|
||||
background-color: rgba(245, 234, 174, 0.2);
|
||||
overflow: hidden;
|
||||
touch-action: none;
|
||||
}
|
||||
file-drop::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
display: block;
|
||||
left: 2px;
|
||||
top: 2px;
|
||||
right: 2px;
|
||||
bottom: 2px;
|
||||
border: 2px dashed #fff;
|
||||
background-color: rgba(88, 116, 88, 0.2);
|
||||
border-color: rgba(65, 129, 65, 0.5);
|
||||
border-radius: 10px;
|
||||
opacity: 0;
|
||||
transform: scale(0.95);
|
||||
transition: all 200ms ease-in;
|
||||
transition-property: transform, opacity;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.drop-valid::after {
|
||||
opacity: 1;
|
||||
transform: scale(1);
|
||||
transition-timing-function: ease-out;
|
||||
}
|
||||
|
||||
.drop-invalid::after {
|
||||
background-color: rgba(255, 27, 27, 0.2);
|
||||
border-color: rgba(255, 170, 170, 0.5);
|
||||
opacity: 1;
|
||||
transform: scale(1);
|
||||
transition-timing-function: ease-out;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<header>Header <a href="../">Back</a></header>
|
||||
<main>
|
||||
<div>
|
||||
<file-drop id="file-drop" accept="application/json"
|
||||
>Drop config here</file-drop
|
||||
>
|
||||
</div>
|
||||
<div><canvas id="myChart" width="600" height="400"></canvas></div>
|
||||
</main>
|
||||
<script src="./loadChart.js"></script>
|
||||
</body>
|
||||
</html>
|
@ -12,6 +12,10 @@
|
||||
<h1>Benchmarking</h1>
|
||||
</header>
|
||||
<main id="root"></main>
|
||||
<footer>
|
||||
Footer
|
||||
<a href="./chart.html">Load previously saved chart</a>
|
||||
</footer>
|
||||
|
||||
<script src="./bundle.js"></script>
|
||||
</body>
|
||||
|
@ -2,6 +2,7 @@ import React from 'react'
|
||||
import { Line, Bar } from 'react-chartjs-2'
|
||||
import debounceRender from 'react-debounce-render'
|
||||
|
||||
import { downloadAsJson } from '../../../lib/json-download/index.js'
|
||||
import { datasetTemplates, genOptions, beautifyLabels } from './chartOptions.js'
|
||||
|
||||
export class Chart extends React.Component {
|
||||
@ -43,13 +44,20 @@ class WasmVsJsChart extends React.Component {
|
||||
dataset.data = dataset.data.map(mean => 1000 / mean)
|
||||
}
|
||||
}
|
||||
|
||||
render() {
|
||||
let data = JSON.parse(JSON.stringify(this.props.data)) // deep copy
|
||||
let options = genOptions('Wasm vs. JavaScript', false, this.state.scaleY)
|
||||
if (this.state.values === 'hz') this.convertDataToHz(data)
|
||||
return (
|
||||
<>
|
||||
<Line height={400} width={400} data={data} options={options} />
|
||||
<Line
|
||||
ref={ref => (this.ref = ref)}
|
||||
height={400}
|
||||
width={400}
|
||||
data={data}
|
||||
options={options}
|
||||
/>
|
||||
<label>Scale Y-Axis</label>
|
||||
<select
|
||||
name="scaleY"
|
||||
@ -69,6 +77,7 @@ class WasmVsJsChart extends React.Component {
|
||||
<option value="mean">ms per operation (mean)</option>
|
||||
<option value="hz">Operations per second (hz)</option>
|
||||
</select>
|
||||
<button onClick={() => saveChart(this.ref)}>Save chart</button>
|
||||
</>
|
||||
)
|
||||
}
|
||||
@ -103,13 +112,29 @@ function modifyDataArrays(data, exec, pre, after) {
|
||||
}
|
||||
}
|
||||
|
||||
const WasmStackChart = ({ data }) => {
|
||||
class WasmStackChart extends React.Component {
|
||||
render() {
|
||||
const data = this.props.data
|
||||
modifyDataArrays(data, 'simplifyWASM', 'storeCoords', 'loadResult')
|
||||
const options = genOptions('Wasm execution', true)
|
||||
return <Bar height={400} width={400} data={data} options={options} />
|
||||
return (
|
||||
<>
|
||||
<Bar
|
||||
ref={ref => (this.ref = ref)}
|
||||
height={400}
|
||||
width={400}
|
||||
data={data}
|
||||
options={options}
|
||||
/>
|
||||
<button onClick={() => saveChart(this.ref)}>Save chart</button>
|
||||
</>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
const JsStackChart = ({ data }) => {
|
||||
class JsStackChart extends React.Component {
|
||||
render() {
|
||||
const data = this.props.data
|
||||
const options = genOptions('SimplifyJS execution', true)
|
||||
modifyDataArrays(
|
||||
data,
|
||||
@ -117,6 +142,30 @@ const JsStackChart = ({ data }) => {
|
||||
'transformToObjectFormCase',
|
||||
'transformToArrayFormCase'
|
||||
)
|
||||
return <Bar height={400} width={400} data={data} options={options} />
|
||||
return (
|
||||
<>
|
||||
<Bar
|
||||
ref={ref => (this.ref = ref)}
|
||||
height={400}
|
||||
width={400}
|
||||
data={data}
|
||||
options={options}
|
||||
/>
|
||||
<button onClick={() => saveChart(this.ref)}>Save chart</button>
|
||||
</>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
export const DebouncedChart = debounceRender(Chart, 300)
|
||||
|
||||
/**
|
||||
* Downloads the chart config as json
|
||||
*/
|
||||
function saveChart(chartRef) {
|
||||
let myChart = chartRef.chartInstance.config
|
||||
let config = JSON.stringify(myChart, (key, val) =>
|
||||
key === '_meta' ? undefined : val
|
||||
)
|
||||
downloadAsJson(config, 'config.json')
|
||||
}
|
||||
|
23
benchmarking/src/loadChart.js
Normal file
23
benchmarking/src/loadChart.js
Normal file
@ -0,0 +1,23 @@
|
||||
import 'file-drop-element'
|
||||
|
||||
import Chart from 'chart.js'
|
||||
|
||||
const fileDrop = document.getElementById('file-drop')
|
||||
const canvas = document.getElementById('myChart')
|
||||
const ctx = canvas.getContext('2d')
|
||||
|
||||
async function readFile(file) {
|
||||
return new Promise(resolve => {
|
||||
let reader = new FileReader()
|
||||
reader.readAsText(file)
|
||||
reader.onload = function() {
|
||||
resolve(this.result)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
fileDrop.addEventListener('filedrop', e => {
|
||||
readFile(e.files[0])
|
||||
.then(JSON.parse)
|
||||
.then(config => new Chart(ctx, config))
|
||||
})
|
@ -3,10 +3,13 @@ const CopyPlugin = require('copy-webpack-plugin')
|
||||
const path = require('path')
|
||||
|
||||
module.exports = {
|
||||
entry: './src/index.js',
|
||||
entry: {
|
||||
bundle: './src/index.js',
|
||||
loadChart: './src/loadChart.js'
|
||||
},
|
||||
output: {
|
||||
path: path.resolve(__dirname, 'dist'),
|
||||
filename: 'bundle.js'
|
||||
filename: '[name].js'
|
||||
},
|
||||
module: {
|
||||
// Suppress warnings and errors logged by benchmark.js when bundled using webpack.
|
||||
|
15
lib/json-download/index.js
Normal file
15
lib/json-download/index.js
Normal file
@ -0,0 +1,15 @@
|
||||
/*
|
||||
Taken from: https://stackoverflow.com/questions/19721439/download-json-object-as-a-file-from-browser
|
||||
*/
|
||||
|
||||
export function downloadAsJson(exportObj, exportName) {
|
||||
if (typeof exportObj !== 'string') exportObj = JSON.stringify(exportObj)
|
||||
var dataStr =
|
||||
'data:application/json;charset=utf-8,' + encodeURIComponent(exportObj)
|
||||
var downloadAnchorNode = document.createElement('a')
|
||||
downloadAnchorNode.setAttribute('href', dataStr)
|
||||
downloadAnchorNode.setAttribute('download', exportName)
|
||||
document.body.appendChild(downloadAnchorNode) // required for firefox
|
||||
downloadAnchorNode.click()
|
||||
downloadAnchorNode.remove()
|
||||
}
|
Loading…
Reference in New Issue
Block a user