Skip to content

Commit

Permalink
implements precalculation for charts during dataset loading
Browse files Browse the repository at this point in the history
closes #309
  • Loading branch information
frabarz committed Dec 3, 2018
1 parent e4ead97 commit 546101f
Show file tree
Hide file tree
Showing 14 changed files with 548 additions and 580 deletions.
19 changes: 10 additions & 9 deletions packages/vizbuilder/src/components/ChartArea/ChartCard.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,15 +18,16 @@ class ChartCard extends React.PureComponent {
<div className="chart-card">
<div className="wrapper">
{this.props.children}

<footer>
<Button
className="pt-minimal"
iconName={active ? "cross" : "zoom-in"}
text={active ? "CLOSE" : "ENLARGE"}
onClick={this.handleToggleSelect}
/>
</footer>
{!this.props.hideFooter && (
<footer>
<Button
className="pt-minimal"
iconName={active ? "cross" : "zoom-in"}
text={active ? "CLOSE" : "ENLARGE"}
onClick={this.handleToggleSelect}
/>
</footer>
)}
</div>
</div>
);
Expand Down
81 changes: 32 additions & 49 deletions packages/vizbuilder/src/components/ChartArea/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import ChartCard from "./ChartCard";

import "./style.css";

const EMPTY_DATASETS = (
const NO_CHARTS = (
<div className="area-chart empty">
<NonIdealState visual="error" title="Empty dataset" />
</div>
Expand Down Expand Up @@ -106,46 +106,29 @@ class ChartArea extends React.Component {
}

render() {
const {generalConfig} = this.context;
const {
activeChart,
datasets,
members,
queries,
selectedTime,
toolbar
} = this.props;
const {heightArea, heightToolbar} = this.state;
const {activeChart, charts, selectedTime, toolbar} = this.props;
const state = this.state;

if (!datasets.length) {
return EMPTY_DATASETS;
const n = charts.length;
if (n === 0) {
return NO_CHARTS;
}

const chartElements = [];

let n = queries.length;
while (n--) {
const configs = createChartConfig(
queries[n],
datasets[n],
members[n],
{activeChart, selectedTime, onTimeChange: this.handleTimeChange},
generalConfig
);
chartElements.unshift.apply(chartElements, configs);
}
const isUniqueChart = n === 1;
const isSingleChart = activeChart || n === 1;

if (!chartElements.length) {
return EMPTY_DATASETS;
}
const chartsToRender = activeChart
? charts.filter(chart => chart.key === activeChart)
: charts;

const uniqueChart = !activeChart && chartElements.length === 1;
const singleChart = activeChart || chartElements.length === 1;
const chartHeight = uniqueChart
? heightArea - heightToolbar
: singleChart
? heightArea - heightToolbar - 50
: 400;
const uiparams = {
activeChart,
isSingle: isSingleChart,
isUnique: isUniqueChart || chartsToRender.length === 1,
onTimeChange: this.handleTimeChange,
selectedTime,
uiheight: state.heightArea - state.heightToolbar,
};

return (
<div
Expand All @@ -161,21 +144,23 @@ class ChartArea extends React.Component {
<div
className={classNames(
"wrapper chart-wrapper",
{unique: uniqueChart, single: singleChart, multi: !singleChart},
isSingleChart ? "single" : "multi",
isUniqueChart && "unique",
activeChart
)}
>
{chartElements.map(chartConfig => {
const {config, key} = chartConfig;
config.height = Math.max(400, chartHeight);
{chartsToRender.map(chart => {
const {key} = chart;
const config = createChartConfig(chart, uiparams);
return (
<ChartCard
active={key === activeChart}
active={key === activeChart || isSingleChart}
hideFooter={charts.length === 1}
key={key}
name={key}
onSelect={this.handleChartSelect}
>
<chartConfig.component config={config} />
<chart.component config={config} />
</ChartCard>
);
})}
Expand All @@ -186,23 +171,21 @@ class ChartArea extends React.Component {
}

ChartArea.contextTypes = {
generalConfig: PropTypes.object,
stateUpdate: PropTypes.func
};

ChartArea.propTypes = {
activeChart: PropTypes.string,
datasets: PropTypes.arrayOf(PropTypes.array),
datagroups: PropTypes.arrayOf(PropTypes.object),
lastUpdate: PropTypes.number,
members: PropTypes.arrayOf(PropTypes.objectOf(PropTypes.array)),
queries: PropTypes.arrayOf(PropTypes.object)
selectedTime: PropTypes.any,
toolbar: PropTypes.any
};

ChartArea.defaultProps = {
activeChart: null,
datasets: [],
members: [],
queries: []
charts: [],
datagroups: []
};

export default ChartArea;
12 changes: 4 additions & 8 deletions packages/vizbuilder/src/components/ChartArea/style.css
Original file line number Diff line number Diff line change
Expand Up @@ -24,14 +24,6 @@
justify-content: flex-start;
align-items: flex-start;
}

&.single .chart-card {
height: 100%;
}

&.unique .chart-card footer {
display: none;
}
}

& .chart-card {
Expand All @@ -47,6 +39,10 @@
height: 100%;
}

&:only-child > .wrapper {
margin: 0;
}

& .viz {
flex: 1 0;

Expand Down
37 changes: 15 additions & 22 deletions packages/vizbuilder/src/components/Sidebar/Ranking.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,53 +3,46 @@ import PropTypes from "prop-types";

class Ranking extends React.PureComponent {
render() {
const {formatting} = this.context.generalConfig;
const props = this.props;
const dataset = props.datasets[0];
const members = props.members[0];
const query = props.queries[0];
const {datagroup, selectedTime} = this.props;
const {dataset, formatter} = datagroup || {};

if (!dataset || !members || !query) return null;
if (!dataset || !dataset.length) return null;

const measureName = query.measure.name;
const levelName = query.level.name;
const timeLevelName = query.timeLevel.name;
const {measureName, levelName, timeLevelName, xlevelName} = datagroup.names;

const measureFormatter =
formatting[query.measure.annotations.units_of_measurement] ||
formatting["default"];
const getLevelNames = query.xlevel
? a => `${a[levelName]} - ${a[query.xlevel.name]}`
const getLevelNames = xlevelName
? a => `${a[levelName]} - ${a[xlevelName]}`
: a => a[levelName];

const renderListItem = datapoint => (
<li className="ranking-item">
<div className="row">
<span className="item-label">{getLevelNames(datapoint)}</span>
<span className="item-value">
{measureFormatter(datapoint[measureName])}
{formatter(datapoint[measureName])}
</span>
</div>
</li>
);

const selectedTime = props.selectedTime;
const maxTimeDataset = dataset.filter(
const selectedTimeDataset = dataset.filter(
d => d[timeLevelName] == selectedTime
);

if (maxTimeDataset.length < 20) {
if (selectedTimeDataset.length < 20) {
return (
<div className="control ranking">
<p className="label">{`Ranking (${selectedTime})`}</p>
<ol className="ranking-list">{maxTimeDataset.map(renderListItem)}</ol>
<ol className="ranking-list">
{selectedTimeDataset.map(renderListItem)}
</ol>
</div>
);
}

const upperDataset = maxTimeDataset.slice(0, 10);
const lowerIndex = maxTimeDataset.length - 10;
const lowerDataset = maxTimeDataset.slice(lowerIndex);
const upperDataset = selectedTimeDataset.slice(0, 10);
const lowerIndex = selectedTimeDataset.length - 10;
const lowerDataset = selectedTimeDataset.slice(lowerIndex);

return (
<div className="control ranking">
Expand Down
Loading

0 comments on commit 546101f

Please sign in to comment.