import React from 'react' import { Line, Bar } from 'react-chartjs-2' import debounceRender from 'react-debounce-render' import platform from 'platform' import { downloadAsJson } from '../../../lib/json-download/index.js' import { datasetNames } from '../data/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 } addLegendEntry(data, `High quality mode: ${formState.highQual}`) addLegendEntry(data, `Platform: ${platform.description}`) 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.id !== 'numberOfNodes')) { dataset.data = dataset.data.map(mean => 1000 / mean) } } render() { let data = JSON.parse(JSON.stringify(this.props.data)) // deep copy let options = genOptions( 'Simplify.wasm vs. Simplify.js', false, this.state.scaleY, this.state.values ) 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, id) { return data.datasets.filter(d => d.id === id)[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, newDatasetLabel) { if (getDataset(data, exec) && getDataset(data, pre)) { data.datasets.splice(1, 0, { id: 'execution', backgroundColor: 'red', borderColor: 'red', label: newDatasetLabel, data: calculateTimeDelta( getDataset(data, exec).data, getDataset(data, pre).data, getDataset(data, after).data ), stack: 'a' }) for (let dataset of data.datasets) { if (dataset.id === exec) { dataset.label = 'Total execution time' dataset.stack = 'b' dataset.backgroundColor = '#ff7a6b' dataset.borderColor = '#ff7a6b' } } } } class WasmStackChart extends React.Component { render() { const data = this.props.data modifyDataArrays( data, 'simplifyWASM', 'storeCoords', 'loadResult', 'Simplification' ) const options = genOptions('Simplify.wasm runtime insights', 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( 'Simplify.js with coordinates transformation', true ) modifyDataArrays( data, 'origSimplifyWithTransformCase', 'transformToObjectFormCase', 'transformToArrayFormCase', 'Simplification' ) 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') } /** * Adds an empty dataset to attach info to legend * @param {} data * @param {*} label */ function addLegendEntry(data, label) { data.datasets.push({ label, data: [] }) }