UNPKG

catreact

Version:

Catavolt Core React Components

255 lines (254 loc) 16.1 kB
/** * Created by rburson on 4/27/16. */ "use strict"; var __assign = (this && this.__assign) || Object.assign || function(t) { for (var s, i = 1, n = arguments.length; i < n; i++) { s = arguments[i]; for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p]; } return t; }; ///<reference path="../../../typings/recharts/recharts.d.ts"/> var React = require('react'); var catreact_1 = require('../catreact'); var catavolt_sdk_1 = require('catavolt-sdk'); var recharts_1 = require('recharts'); /* Base mixin for Charts */ exports.CvChart = { colorForDataPointDef: function (dataPointDef, i) { return dataPointDef.seriesColor || this.props.defaultSeriesColors[i % this.props.defaultSeriesColors.length]; }, getMetaValues: function (graphDef) { var minX = graphDef.xAxisRangeFrom ? graphDef.xAxisRangeFrom : 0; var maxX = graphDef.xAxisRangeTo ? graphDef.xAxisRangeTo : 'auto'; var minY = graphDef.yAxisRangeFrom ? graphDef.yAxisRangeFrom : 0; var maxY = graphDef.yAxisRangeTo ? graphDef.yAxisRangeTo : 'auto'; var xAxisLabel = graphDef.xAxisLabel; var yAxisLabel = graphDef.yAxisLabel; return { minX: minX, maxX: maxX, minY: minY, maxY: maxY, xAxisLabel: xAxisLabel, yAxisLabel: yAxisLabel }; }, handleClick: function (id) { if (this.props.clickHandler) { this.props.clickHandler(id); } }, isNumeric: function (graphContext, propName) { var propDef = graphContext.propDefAtName(propName); return propDef && propDef.isNumericType; } }; /* Cartesian style line chart */ exports.CvLineChart = React.createClass({ mixins: [exports.CvChart], render: function () { var _this = this; var graphDef = this.props.graphContext.graphDef; var _a = this.getMetaValues(graphDef), minX = _a.minX, maxX = _a.maxX, minY = _a.minY, maxY = _a.maxY, xAxisLabel = _a.xAxisLabel, yAxisLabel = _a.yAxisLabel; var xType = this.isNumeric(this.props.graphContext, graphDef.identityDataPointDef.name) ? 'numeric' : 'category'; var yType = this.isNumeric(this.props.graphContext, graphDef.dataPointDefs[0].name) ? 'numeric' : 'category'; return (React.createElement("div", {className: "cv-graph-container"}, React.createElement(recharts_1.ResponsiveContainer, {width: "99%", height: "95%"}, React.createElement(recharts_1.LineChart, {data: this.props.data, margin: { top: 20, right: 50, left: 20, bottom: 5 }}, React.createElement(recharts_1.XAxis, {dataKey: this.props.identPropName, domain: [minX, maxX], label: xAxisLabel}), React.createElement(recharts_1.YAxis, {domain: [minY, maxY], label: yAxisLabel}), React.createElement(recharts_1.CartesianGrid, {strokeDasharray: "3 3"}), React.createElement(recharts_1.Tooltip, null), React.createElement(recharts_1.Legend, null), graphDef.dataPointDefs.map(function (dataPointDef, i) { var color = _this.colorForDataPointDef(dataPointDef, i); var legendKey = dataPointDef.legendKey || dataPointDef.name; return React.createElement(recharts_1.Line, {type: "monotone", dataKey: dataPointDef.name, name: legendKey, dot: true, activeDot: true, stroke: color}); }))))); }, }); exports.CvBarChart = React.createClass({ mixins: [exports.CvChart], render: function () { var _this = this; var graphDef = this.props.graphContext.graphDef; var _a = this.getMetaValues(graphDef), minX = _a.minX, maxX = _a.maxX, minY = _a.minY, maxY = _a.maxY, xAxisLabel = _a.xAxisLabel, yAxisLabel = _a.yAxisLabel; var xType = this.isNumeric(this.props.graphContext, graphDef.identityDataPointDef.name) ? 'numeric' : 'category'; var yType = this.isNumeric(this.props.graphContext, graphDef.dataPointDefs[0].name) ? 'numeric' : 'category'; return (React.createElement("div", {className: "cv-graph-container"}, React.createElement(recharts_1.ResponsiveContainer, {width: "99%", height: "95%"}, React.createElement(recharts_1.BarChart, {data: this.props.data, margin: { top: 20, right: 50, left: 20, bottom: 5 }}, React.createElement(recharts_1.XAxis, {dataKey: this.props.identPropName, domain: [minX, maxX], label: xAxisLabel}), React.createElement(recharts_1.YAxis, {domain: [minY, maxY], label: yAxisLabel}), React.createElement(recharts_1.CartesianGrid, {strokeDasharray: "3 3"}), React.createElement(recharts_1.Tooltip, null), React.createElement(recharts_1.Legend, null), graphDef.dataPointDefs.map(function (dataPointDef, i) { var legendKey = dataPointDef.legendKey || dataPointDef.name; var props = { dataKey: dataPointDef.name, name: legendKey, fill: _this.colorForDataPointDef(dataPointDef, i), onClick: function (data) { _this.handleClick(data.id); } }; if (_this.props.stack) props['stackId'] = 'a'; return React.createElement(recharts_1.Bar, __assign({}, props)); }))))); } }); exports.CvScatterChart = React.createClass({ mixins: [exports.CvChart], render: function () { var _this = this; var graphDef = this.props.graphContext.graphDef; var _a = this.getMetaValues(graphDef), minX = _a.minX, maxX = _a.maxX, minY = _a.minY, maxY = _a.maxY, xAxisLabel = _a.xAxisLabel, yAxisLabel = _a.yAxisLabel; //note: to support multiple 'scatter series' the data set has to be broken in corresponding discrete sets //for now, we're taking the first dataPointDef only var dataPointDef = graphDef.dataPointDefs[0]; var xType = this.isNumeric(this.props.graphContext, dataPointDef.xAxisName) ? 'numeric' : 'category'; var yType = this.isNumeric(this.props.graphContext, dataPointDef.name) ? 'numeric' : 'category'; if (dataPointDef) { var legendKey = dataPointDef.legendKey || dataPointDef.name; return (React.createElement("div", {className: "cv-graph-container"}, React.createElement(recharts_1.ResponsiveContainer, {width: "99%", height: "95%"}, React.createElement(recharts_1.ScatterChart, {margin: { top: 20, right: 50, left: 20, bottom: 5 }}, React.createElement(recharts_1.XAxis, {dataKey: dataPointDef.xAxisName, name: dataPointDef.xAxisName, domain: [minX, maxX], label: xAxisLabel}), React.createElement(recharts_1.YAxis, {dataKey: dataPointDef.name, name: legendKey, domain: [minY, maxY], label: yAxisLabel}), (function () { if (_this.props.bubble) { if (dataPointDef.bubbleRadiusName) { return React.createElement(recharts_1.ZAxis, {dataKey: dataPointDef.bubbleRadiusName, name: dataPointDef.bubbleRadiusName, range: [10000, 50000]}); } else { return React.createElement(recharts_1.ZAxis, {dataKey: dataPointDef.bubbleRadiusName, name: dataPointDef.bubbleRadiusName, range: [10000, 10000]}); } } else { return React.createElement(recharts_1.ZAxis, null); } })(), React.createElement(recharts_1.CartesianGrid, null), React.createElement(recharts_1.Tooltip, {cursor: { strokeDasharray: '3 3' }}), React.createElement(recharts_1.Legend, null), React.createElement(recharts_1.Scatter, {data: this.props.data, fill: this.colorForDataPointDef(dataPointDef, 0), onClick: function (data) { }}))))); } else { return null; } } }); exports.CvPieChart = React.createClass({ mixins: [exports.CvChart], render: function () { var _this = this; var graphDef = this.props.graphContext.graphDef; //note: to support multiple 'pie levels' the data set has to be broken in corresponding discrete sets //for now, we're taking the first dataPointDef only var dataPointDef = graphDef.dataPointDefs[0]; if (dataPointDef) { var legendKey = dataPointDef.legendKey || dataPointDef.name; return (React.createElement("div", {className: "cv-graph-container"}, React.createElement(recharts_1.ResponsiveContainer, {width: "99%", height: "95%"}, React.createElement(recharts_1.PieChart, {margin: { top: 20, right: 50, left: 20, bottom: 5 }, onClick: function (data) { _this.handleClick(data.payload.id); }}, React.createElement(recharts_1.Tooltip, {cursor: { strokeDasharray: '3 3' }}), React.createElement(recharts_1.Legend, null), React.createElement(recharts_1.Pie, {data: this.props.data, fill: this.colorForDataPointDef(dataPointDef, 0), nameKey: this.props.identPropName, valueKey: dataPointDef.name, label: true}))))); } else { return null; } } }); /* *************************************************** * Render a Graph *************************************************** */ exports.CvGraphPanel = React.createClass({ mixins: [catreact_1.CvBaseMixin], componentDidMount: function () { }, getDefaultProps: function () { return { paneRef: null, formContext: null, graphContext: null, navigationListeners: [], selectionListener: null, stateChangeListeners: [], actionListeners: [], defaultSeriesColors: ['#1E6FF2', '#F29500', '#15BFA2', '#6F5F5A'], navTarget: null, actionProvider: null }; }, getInitialState: function () { return {}; }, render: function () { var _this = this; var _a = this.state; var graphPaneProps = { paneRef: this.props.paneRef, formContext: this.props.formContext, queryContext: this.props.graphContext, stateChangeListeners: this.props.stateChangeListeners, actionProvider: this.props.actionProvider }; return (React.createElement(catreact_1.CvQueryPane, __assign({}, graphPaneProps, {queryRenderer: function (cvContext, callback) { var graphContext = cvContext.scopeCtx.scopeObj; var selectionAdapter = new catreact_1.CvValueAdapter(); var selectionListener = selectionAdapter.createValueListener(); return React.createElement(catreact_1.CvAction, {actionId: graphContext.graphDef.defaultActionId, paneContext: graphContext, navigationListeners: _this.props.navigationListeners, actionListeners: _this.props.actionListeners, stateChangeListeners: _this.props.stateChangeListeners, selectionProvider: selectionAdapter, renderer: function (cvContext, callback) { var clickHandler = function (id) { selectionListener([id]); callback.fireAction(); }; var graphDef = graphContext.graphDef; var records = catavolt_sdk_1.ArrayUtil.copy(graphContext.scroller.buffer); var points = graphDef.graphType === catavolt_sdk_1.GraphDef.GRAPH_TYPE_PIE ? _this._generateDataForPieChart(graphContext, records) : _this._generateData(graphContext, records); var identPropName = graphDef.identityDataPointDef.name; var plotTypes = graphDef.dataPointDefs.map(function (dataPointDef) { return dataPointDef.plotType; }).filter(function (v) { return !!v; }); if (graphDef.graphType === catavolt_sdk_1.GraphDef.GRAPH_TYPE_CARTESIAN) { if (plotTypes.length === 0 || plotTypes.indexOf(catavolt_sdk_1.GraphDef.PLOT_TYPE_BAR) > -1) { return React.createElement(exports.CvBarChart, {graphContext: graphContext, data: points, identPropName: identPropName, defaultSeriesColors: _this.props.defaultSeriesColors, clickHandler: clickHandler}); } else if (plotTypes.indexOf(catavolt_sdk_1.GraphDef.PLOT_TYPE_LINE) > -1) { return React.createElement(exports.CvLineChart, {graphContext: graphContext, data: points, identPropName: identPropName, defaultSeriesColors: _this.props.defaultSeriesColors, clickHandler: clickHandler}); } else if (plotTypes.indexOf(catavolt_sdk_1.GraphDef.PLOT_TYPE_STACKED) > -1) { return React.createElement(exports.CvBarChart, {graphContext: graphContext, data: points, identPropName: identPropName, defaultSeriesColors: _this.props.defaultSeriesColors, stack: true, clickHandler: clickHandler}); } else if (plotTypes.indexOf(catavolt_sdk_1.GraphDef.PLOT_TYPE_SCATTER) > -1) { return React.createElement(exports.CvScatterChart, {graphContext: graphContext, data: points, identPropName: identPropName, defaultSeriesColors: _this.props.defaultSeriesColors, clickHandler: clickHandler}); } else if (plotTypes.indexOf(catavolt_sdk_1.GraphDef.PLOT_TYPE_BUBBLE) > -1) { return React.createElement(exports.CvScatterChart, {graphContext: graphContext, data: points, identPropName: identPropName, defaultSeriesColors: _this.props.defaultSeriesColors, bubble: true, clickHandler: clickHandler}); } else { return null; } } else if (graphDef.graphType === catavolt_sdk_1.GraphDef.GRAPH_TYPE_PIE) { return React.createElement(exports.CvPieChart, {graphContext: graphContext, data: points, identPropName: identPropName, defaultSeriesColors: _this.props.defaultSeriesColors, clickHandler: clickHandler}); } else { return null; } }}); }}))); }, _formatProp: function (prop, propDef) { return catreact_1.CvProp.formatDataType(prop, propDef); }, _generateData: function (graphContext, records) { var _this = this; var graphDef = graphContext.graphDef; //prop for 1 axis (or dimension) var identPropName = graphDef.identityDataPointDef.name; var points = records.map(function (record) { var item = {}; item['id'] = record.objectId; item[identPropName] = _this._formatProp(record.propAtName(identPropName), graphContext.propDefAtName(identPropName)); //possible props for other axes (or dimensions) graphDef.dataPointDefs.forEach(function (dataPointDef) { var propName = dataPointDef.name; if (propName) item[propName] = _this._formatProp(record.propAtName(propName), graphContext.propDefAtName(propName)); var xAxisName = dataPointDef.xAxisName; if (xAxisName) item[xAxisName] = _this._formatProp(record.propAtName(xAxisName), graphContext.propDefAtName(xAxisName)); var radiusName = dataPointDef.bubbleRadiusName; if (radiusName) item[radiusName] = Number(record.propAtName(radiusName).value); }); return item; }); return points; }, _generateDataForPieChart: function (graphContext, records) { var _this = this; /* The pie chart requires the primary series to be numeric */ var graphDef = graphContext.graphDef; //prop for 1 axis (or dimension) var identPropName = graphDef.identityDataPointDef.name; var points = records.map(function (record) { var item = {}; item['id'] = record.objectId; item[identPropName] = _this._formatProp(record.propAtName(identPropName), graphContext.propDefAtName(identPropName)); graphDef.dataPointDefs.forEach(function (dataPointDef) { var propName = dataPointDef.name; //force numeric typing if (propName) item[propName] = Number(record.propAtName(propName).value); }); return item; }); return points; }, });