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 { render() { let { formState, stats, nodeData } = this.props let { tolRange, chart } = formState tolRange = tolRange || [] let labels = beautifyLabels(tolRange) // let labels = tolRange.map(x => Math.round(x * 1000) / 1000) let datasets = Object.keys(stats).map(name => ({ ...datasetTemplates[name], data: stats[name] })) datasets.push({ ...datasetTemplates.numberOfNodes, data: nodeData }) let data = { datasets, labels } return (

Chart

{chart === 'wasmVsJs' && } {chart === 'wasmStack' && } {chart === 'simplifyJSStack' && }
) } } class WasmVsJsChart extends React.Component { constructor(props) { super(props) this.state = { scaleY: 'linear', values: 'mean' } } convertDataToHz(data) { let datasets = data.datasets for (let dataset of datasets.filter(d => d.label !== 'numberOfNodes')) { 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 ( <> (this.ref = ref)} height={400} width={400} data={data} options={options} /> ) } } /** * 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 ) } } class WasmStackChart extends React.Component { render() { const data = this.props.data modifyDataArrays(data, 'simplifyWASM', 'storeCoords', 'loadResult') const options = genOptions('Wasm execution', true) return ( <> (this.ref = ref)} height={400} width={400} data={data} options={options} /> ) } } class JsStackChart extends React.Component { render() { const data = this.props.data const options = genOptions('SimplifyJS execution', true) modifyDataArrays( data, 'origSimplifyWithTransformCase', 'transformToObjectFormCase', 'transformToArrayFormCase' ) return ( <> (this.ref = ref)} height={400} width={400} data={data} options={options} /> ) } } 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') }