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"
|
"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": {
|
"file-loader": {
|
||||||
"version": "4.0.0",
|
"version": "4.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/file-loader/-/file-loader-4.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/file-loader/-/file-loader-4.0.0.tgz",
|
||||||
|
@ -22,6 +22,7 @@
|
|||||||
"dependencies": {
|
"dependencies": {
|
||||||
"benchmark": "^2.1.4",
|
"benchmark": "^2.1.4",
|
||||||
"chart.js": "^2.8.0",
|
"chart.js": "^2.8.0",
|
||||||
|
"file-drop-element": "^0.2.0",
|
||||||
"lodash": "^4.17.11",
|
"lodash": "^4.17.11",
|
||||||
"react": "^16.8.6",
|
"react": "^16.8.6",
|
||||||
"react-chartjs-2": "^2.7.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>
|
<h1>Benchmarking</h1>
|
||||||
</header>
|
</header>
|
||||||
<main id="root"></main>
|
<main id="root"></main>
|
||||||
|
<footer>
|
||||||
|
Footer
|
||||||
|
<a href="./chart.html">Load previously saved chart</a>
|
||||||
|
</footer>
|
||||||
|
|
||||||
<script src="./bundle.js"></script>
|
<script src="./bundle.js"></script>
|
||||||
</body>
|
</body>
|
||||||
|
@ -2,6 +2,7 @@ import React from 'react'
|
|||||||
import { Line, Bar } from 'react-chartjs-2'
|
import { Line, Bar } from 'react-chartjs-2'
|
||||||
import debounceRender from 'react-debounce-render'
|
import debounceRender from 'react-debounce-render'
|
||||||
|
|
||||||
|
import { downloadAsJson } from '../../../lib/json-download/index.js'
|
||||||
import { datasetTemplates, genOptions, beautifyLabels } from './chartOptions.js'
|
import { datasetTemplates, genOptions, beautifyLabels } from './chartOptions.js'
|
||||||
|
|
||||||
export class Chart extends React.Component {
|
export class Chart extends React.Component {
|
||||||
@ -43,13 +44,20 @@ class WasmVsJsChart extends React.Component {
|
|||||||
dataset.data = dataset.data.map(mean => 1000 / mean)
|
dataset.data = dataset.data.map(mean => 1000 / mean)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
let data = JSON.parse(JSON.stringify(this.props.data)) // deep copy
|
let data = JSON.parse(JSON.stringify(this.props.data)) // deep copy
|
||||||
let options = genOptions('Wasm vs. JavaScript', false, this.state.scaleY)
|
let options = genOptions('Wasm vs. JavaScript', false, this.state.scaleY)
|
||||||
if (this.state.values === 'hz') this.convertDataToHz(data)
|
if (this.state.values === 'hz') this.convertDataToHz(data)
|
||||||
return (
|
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>
|
<label>Scale Y-Axis</label>
|
||||||
<select
|
<select
|
||||||
name="scaleY"
|
name="scaleY"
|
||||||
@ -69,6 +77,7 @@ class WasmVsJsChart extends React.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>
|
||||||
|
<button onClick={() => saveChart(this.ref)}>Save chart</button>
|
||||||
</>
|
</>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@ -103,20 +112,60 @@ function modifyDataArrays(data, exec, pre, after) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const WasmStackChart = ({ data }) => {
|
class WasmStackChart extends React.Component {
|
||||||
modifyDataArrays(data, 'simplifyWASM', 'storeCoords', 'loadResult')
|
render() {
|
||||||
const options = genOptions('Wasm execution', true)
|
const data = this.props.data
|
||||||
return <Bar height={400} width={400} data={data} options={options} />
|
modifyDataArrays(data, 'simplifyWASM', 'storeCoords', 'loadResult')
|
||||||
|
const options = genOptions('Wasm execution', true)
|
||||||
|
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 {
|
||||||
const options = genOptions('SimplifyJS execution', true)
|
render() {
|
||||||
modifyDataArrays(
|
const data = this.props.data
|
||||||
data,
|
const options = genOptions('SimplifyJS execution', true)
|
||||||
'origSimplifyWithTransformCase',
|
modifyDataArrays(
|
||||||
'transformToObjectFormCase',
|
data,
|
||||||
'transformToArrayFormCase'
|
'origSimplifyWithTransformCase',
|
||||||
)
|
'transformToObjectFormCase',
|
||||||
return <Bar height={400} width={400} data={data} options={options} />
|
'transformToArrayFormCase'
|
||||||
|
)
|
||||||
|
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)
|
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')
|
const path = require('path')
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
entry: './src/index.js',
|
entry: {
|
||||||
|
bundle: './src/index.js',
|
||||||
|
loadChart: './src/loadChart.js'
|
||||||
|
},
|
||||||
output: {
|
output: {
|
||||||
path: path.resolve(__dirname, 'dist'),
|
path: path.resolve(__dirname, 'dist'),
|
||||||
filename: 'bundle.js'
|
filename: '[name].js'
|
||||||
},
|
},
|
||||||
module: {
|
module: {
|
||||||
// Suppress warnings and errors logged by benchmark.js when bundled using webpack.
|
// 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