blob: 0ddacba066f3b6c6156e2cc6aa4e60f477911682 [file] [log] [blame]
//
// 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;
///
/// Model that maintains state of each visualization item. Each entry in the
/// legend is considered one visualization item.
/// - In [CartesianArea] it is always a column.
/// - In [LayoutArea] renders choose either columns or rows.
///
class DefaultChartStateImpl extends Observable implements ChartState {
final bool isMultiSelect;
final bool isMultiHighlight;
final bool isSelectOrHighlight;
final bool supportColumnSelection;
final bool supportColumnPreview;
final bool supportValueHighlight;
final bool supportValueHover;
LinkedHashSet<int> hidden = new LinkedHashSet<int>();
LinkedHashSet<int> selection = new LinkedHashSet<int>();
LinkedHashSet<Pair<int, int>> highlights =
new LinkedHashSet<Pair<int, int>>();
Pair<int, int> _hovered;
int _preview;
DefaultChartStateImpl(
{this.supportColumnSelection: true,
this.supportColumnPreview: true,
this.supportValueHighlight: true,
this.supportValueHover: true,
this.isMultiSelect: false,
this.isMultiHighlight: false,
this.isSelectOrHighlight: true});
set hovered(Pair<int, int> value) {
if (!this.supportValueHover) return null;
if (value != _hovered) {
_hovered = value;
notifyChange(new ChartHoverChangeRecord(_hovered));
}
}
Pair<int, int> get hovered => _hovered;
set preview(int value) {
if (!this.supportColumnPreview) return null;
if (value != _preview) {
_preview = value;
notifyChange(new ChartPreviewChangeRecord(_preview));
}
}
int get preview => _preview;
bool unhide(int id) {
if (hidden.contains(id)) {
hidden.remove(id);
notifyChange(new ChartVisibilityChangeRecord(unhide: id));
}
return true;
}
bool hide(int id) {
if (!hidden.contains(id)) {
hidden.add(id);
notifyChange(new ChartVisibilityChangeRecord(hide: id));
}
return false;
}
bool isVisible(int id) => !hidden.contains(id);
bool select(int id) {
if (!this.supportColumnSelection) return false;
if (!selection.contains(id)) {
if (!isMultiSelect) {
selection.clear();
}
if (isSelectOrHighlight) {
highlights.clear();
}
selection.add(id);
notifyChange(new ChartSelectionChangeRecord(add: id));
}
return true;
}
bool unselect(int id) {
if (selection.contains(id)) {
selection.remove(id);
notifyChange(new ChartSelectionChangeRecord(remove: id));
}
return false;
}
bool isSelected(int id) => selection.contains(id);
bool highlight(int column, int row) {
if (!this.supportValueHighlight) return false;
if (!isHighlighted(column, row)) {
if (!isMultiHighlight) {
highlights.clear();
}
if (isSelectOrHighlight) {
selection.clear();
}
var item = new Pair<int, int>(column, row);
highlights.add(item);
notifyChange(new ChartHighlightChangeRecord(add: item));
}
return true;
}
bool unhighlight(int column, int row) {
if (isHighlighted(column, row)) {
var item = new Pair<int, int>(column, row);
highlights.remove(item);
notifyChange(new ChartHighlightChangeRecord(remove: item));
}
return false;
}
bool isHighlighted(int column, int row) =>
highlights.any((x) => x.first == column && x.last == row);
}