| Index: charted/lib/charts/data_transformers/aggregation_transformer.dart
|
| diff --git a/charted/lib/charts/data_transformers/aggregation_transformer.dart b/charted/lib/charts/data_transformers/aggregation_transformer.dart
|
| deleted file mode 100644
|
| index 37db0b1a670f7eef3ebd0576a8c72c0a514db71b..0000000000000000000000000000000000000000
|
| --- a/charted/lib/charts/data_transformers/aggregation_transformer.dart
|
| +++ /dev/null
|
| @@ -1,223 +0,0 @@
|
| -/*
|
| - * Copyright 2014 Google Inc. All rights reserved.
|
| - *
|
| - * Use of this source code is governed by a BSD-style
|
| - * license that can be found in the LICENSE file or at
|
| - * https://developers.google.com/open-source/licenses/bsd
|
| - */
|
| -
|
| -part of charted.charts;
|
| -
|
| -/**
|
| - * Transforms the ChartData base on the specified dimension columns and facts
|
| - * columns indices. The values in the facts columns will be aggregated by the
|
| - * tree hierarchy generated by the dimension columns. Expand and Collapse
|
| - * methods may be called to display different levels of aggregation.
|
| - *
|
| - * The output ChartData produced by transform() will contain only columns in the
|
| - * original ChartData that were specified in dimensions or facts column indices.
|
| - * The output column will be re-ordered first by the indices specified in the
|
| - * dimension column indices then by the facts column indices. The data in the
|
| - * cells of each row will also follow this rule.
|
| - */
|
| -class AggregationTransformer extends ChangeNotifier
|
| - implements ChartDataTransform, ChartData {
|
| -
|
| - static const String AGGREGATION_TYPE_SUM = 'sum';
|
| - static const String AGGREGATION_TYPE_MIN = 'min';
|
| - static const String AGGREGATION_TYPE_MAX = 'max';
|
| - static const String AGGREGATION_TYPE_VALID = 'valid';
|
| - final SubscriptionsDisposer _dataSubscriptions = new SubscriptionsDisposer();
|
| - final Set<List> _expandedSet = new Set();
|
| - Iterable<ChartColumnSpec> columns;
|
| - ObservableList<Iterable> rows = new ObservableList();
|
| - List<int> _dimensionColumnIndices;
|
| - List<int> _factsColumnIndices;
|
| - String _aggregationType;
|
| - AggregationModel _model;
|
| - bool _expandAllDimension = false;
|
| - List _selectedColumns = [];
|
| - FieldAccessor _indexFieldAccessor = (List row, int index) => row[index];
|
| - ChartData _data;
|
| -
|
| - AggregationTransformer(this._dimensionColumnIndices,
|
| - this._factsColumnIndices,
|
| - [String aggregationType = AGGREGATION_TYPE_SUM]) {
|
| - _aggregationType = aggregationType;
|
| - }
|
| -
|
| - /**
|
| - * Transforms the ChartData base on the specified dimension columns and facts
|
| - * columns, aggregation type and currently expanded dimensions.
|
| - */
|
| - ChartData transform(ChartData data) {
|
| - assert(data.columns.length > max(_dimensionColumnIndices));
|
| - assert(data.columns.length > max(_factsColumnIndices));
|
| - _data = data;
|
| - _registerListeners();
|
| - _transform();
|
| - return this;
|
| - }
|
| -
|
| - /** Registers listeners if data.rows or data.columns are Observable. */
|
| - _registerListeners() {
|
| - _dataSubscriptions.dispose();
|
| -
|
| - if(_data is Observable) {
|
| - var observable = (_data as Observable);
|
| - _dataSubscriptions.add(observable.changes.listen((records) {
|
| - _transform();
|
| -
|
| - // NOTE: Currently we're only passing the first change because the chart
|
| - // area just draw with the updated data. When we add partial update
|
| - // to chart area, we'll need to handle this better.
|
| - notifyChange(records.first);
|
| - }));
|
| - }
|
| - }
|
| -
|
| - /**
|
| - * Performs the filter transform with _data. This is called on transform and
|
| - * onChange if the input ChartData is Observable.
|
| - */
|
| - _transform() {
|
| - _model = new AggregationModel(_data.rows, _dimensionColumnIndices,
|
| - _factsColumnIndices, aggregationTypes: [_aggregationType],
|
| - dimensionAccessor: _indexFieldAccessor,
|
| - factsAccessor: _indexFieldAccessor);
|
| - _model.compute();
|
| -
|
| - // If user called expandAll prior to model initiation, do it now.
|
| - if (_expandAllDimension) {
|
| - expandAll();
|
| - }
|
| -
|
| - _selectedColumns.clear();
|
| - _selectedColumns.addAll(_dimensionColumnIndices);
|
| - _selectedColumns.addAll(_factsColumnIndices);
|
| -
|
| - // Process rows.
|
| - rows.clear();
|
| - var transformedRows = <Iterable>[];
|
| - for (var value in _model.valuesForDimension(_dimensionColumnIndices[0])) {
|
| - _generateAggregatedRow(transformedRows, [value]);
|
| - }
|
| - rows.addAll(transformedRows);
|
| -
|
| - // Process columns.
|
| - columns = new List<ChartColumnSpec>.generate(_selectedColumns.length, (index) =>
|
| - _data.columns.elementAt(_selectedColumns[index]));
|
| - }
|
| -
|
| - /**
|
| - * Fills the aggregatedRows List with data base on the set of expanded values
|
| - * recursively. Currently when a dimension is expanded, rows are
|
| - * generated for its children but not for itself. If we want to change the
|
| - * logic to include itself, just move the expand check around the else clause
|
| - * and always write a row of data whether it's expanded or not.
|
| - */
|
| - _generateAggregatedRow(List<Iterable> aggregatedRows, List dimensionValues) {
|
| - var entity = _model.facts(dimensionValues);
|
| - var dimensionLevel = dimensionValues.length - 1;
|
| -
|
| - // Dimension is not expanded at this level. Generate data rows and fill int
|
| - // value base on whether the column is dimension column or facts column.
|
| - if (!_isExpanded(dimensionValues) ||
|
| - dimensionValues.length == _dimensionColumnIndices.length) {
|
| - aggregatedRows.add(new List.generate(_selectedColumns.length, (index) {
|
| -
|
| - // Dimension column.
|
| - if (index < _dimensionColumnIndices.length) {
|
| - if (index < dimensionLevel) {
|
| - // If column index is in a higher level, write parent value.
|
| - return dimensionValues[0];
|
| - } else if (index == dimensionLevel) {
|
| - // If column index is at current level, write value.
|
| - return dimensionValues.last;
|
| - } else {
|
| - // If column Index is in a lower level, write empty string.
|
| - return '';
|
| - }
|
| - } else {
|
| - // Write aggregated value for facts column.
|
| - return entity['${_aggregationType}(${_selectedColumns[index]})'];
|
| - }
|
| - }));
|
| - } else {
|
| - // Dimension is expanded, process each child dimension in the expanded
|
| - // dimension.
|
| - for (AggregationItem childAggregation in entity['aggregations']) {
|
| - _generateAggregatedRow(aggregatedRows, childAggregation.dimensions);
|
| - }
|
| - }
|
| - }
|
| -
|
| - /**
|
| - * Expands a specific dimension and optionally expands all of its parent
|
| - * dimensions.
|
| - */
|
| - void expand(List dimension, [bool expandParent = true]) {
|
| - _expandAllDimension = false;
|
| - _expandedSet.add(dimension);
|
| - if (expandParent && dimension.length > 1) {
|
| - Function eq = const ListEquality().equals;
|
| - var dim = dimension.take(dimension.length - 1).toList();
|
| - if (!_expandedSet.any((e) => eq(e, dim))) {
|
| - expand(dim);
|
| - }
|
| - }
|
| - }
|
| -
|
| - /**
|
| - * Collapses a specific dimension and optionally collapse all of its
|
| - * Children dimensions.
|
| - */
|
| - void collapse(List dimension, [bool collapseChildren = true]) {
|
| - _expandAllDimension = false;
|
| - if (collapseChildren) {
|
| - Function eq = const ListEquality().equals;
|
| - // Doing this because _expandedSet.where doesn't work.
|
| - var collapseList = [];
|
| - for (List dim in _expandedSet) {
|
| - if (eq(dim.take(dimension.length).toList(), dimension)) {
|
| - collapseList.add(dim);
|
| - }
|
| - }
|
| - _expandedSet.removeAll(collapseList);
|
| - } else {
|
| - _expandedSet.remove(dimension);
|
| - }
|
| - }
|
| -
|
| - /** Expands all dimensions. */
|
| - void expandAll() {
|
| - if (_model != null) {
|
| - for (var value in _model.valuesForDimension(_dimensionColumnIndices[0])) {
|
| - _expandAll([value]);
|
| - }
|
| - _expandAllDimension = false;
|
| - } else {
|
| - _expandAllDimension = true;
|
| - }
|
| - }
|
| -
|
| - void _expandAll(value) {
|
| - var entity = _model.facts(value);
|
| - _expandedSet.add(value);
|
| - for (AggregationItem childAggregation in entity['aggregations']) {
|
| - _expandAll(childAggregation.dimensions);
|
| - }
|
| - }
|
| -
|
| - /** Collapses all dimensions. */
|
| - void collapseAll() {
|
| - _expandAllDimension = false;
|
| - _expandedSet.clear();
|
| - }
|
| -
|
| - /** Tests if specific dimension is expanded. */
|
| - bool _isExpanded(List dimension) {
|
| - Function eq = const ListEquality().equals;
|
| - return _expandedSet.any((e) => eq(e, dimension));
|
| - }
|
| -}
|
|
|