| Index: charted/lib/charts/cartesian_renderers/line_chart_renderer.dart
|
| diff --git a/charted/lib/charts/cartesian_renderers/line_chart_renderer.dart b/charted/lib/charts/cartesian_renderers/line_chart_renderer.dart
|
| deleted file mode 100644
|
| index 058402465d34a56133e643a327d2a86c06e7bd72..0000000000000000000000000000000000000000
|
| --- a/charted/lib/charts/cartesian_renderers/line_chart_renderer.dart
|
| +++ /dev/null
|
| @@ -1,275 +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;
|
| -
|
| -class LineChartRenderer extends CartesianRendererBase {
|
| - final Iterable<int> dimensionsUsingBand = const[];
|
| - final SubscriptionsDisposer _disposer = new SubscriptionsDisposer();
|
| -
|
| - final bool alwaysAnimate;
|
| - final bool trackDataPoints;
|
| - final bool trackOnDimensionAxis;
|
| - final int quantitativeScaleProximity;
|
| -
|
| - bool _trackingPointsCreated = false;
|
| - List _xPositions = [];
|
| -
|
| - // Currently hovered row/column
|
| - int _savedOverRow = 0;
|
| - int _savedOverColumn = 0;
|
| -
|
| - int currentDataIndex = -1;
|
| -
|
| - @override
|
| - final String name = "line-rdr";
|
| -
|
| - LineChartRenderer({
|
| - this.alwaysAnimate: false,
|
| - this.trackDataPoints: true,
|
| - this.trackOnDimensionAxis: false,
|
| - this.quantitativeScaleProximity: 5 });
|
| -
|
| - /*
|
| - * Returns false if the number of dimension axes on the area is 0.
|
| - * Otherwise, the first dimension scale is used to render the chart.
|
| - */
|
| - @override
|
| - bool prepare(ChartArea area, ChartSeries series) {
|
| - _ensureAreaAndSeries(area, series);
|
| - if (trackDataPoints != false) {
|
| - _trackPointerInArea();
|
| - }
|
| - return area is CartesianArea;
|
| - }
|
| -
|
| - @override
|
| - void draw(Element element, {Future schedulePostRender}) {
|
| - _ensureReadyToDraw(element);
|
| -
|
| - var measureScale = area.measureScales(series).first,
|
| - dimensionScale = area.dimensionScales.first;
|
| -
|
| - // Create lists of values in measure columns.
|
| - var lines = series.measures.map((column) {
|
| - return area.data.rows.map((values) => values[column]).toList();
|
| - }).toList();
|
| -
|
| - // We only support one dimension axes, so we always use the
|
| - // first dimension.
|
| - var x = area.data.rows.map(
|
| - (row) => row.elementAt(area.config.dimensions.first)).toList();
|
| -
|
| - var rangeBandOffset =
|
| - dimensionScale is OrdinalScale ? dimensionScale.rangeBand / 2 : 0;
|
| -
|
| - // If tracking data points is enabled, cache location of points that
|
| - // represent data.
|
| - if (trackDataPoints) {
|
| - _xPositions =
|
| - x.map((val) => dimensionScale.scale(val) + rangeBandOffset).toList();
|
| - }
|
| -
|
| - var line = new SvgLine(
|
| - xValueAccessor: (d, i) => dimensionScale.scale(x[i]) + rangeBandOffset,
|
| - yValueAccessor: (d, i) => measureScale.scale(d));
|
| -
|
| - // Add lines and hook up hover and selection events.
|
| - var svgLines = root.selectAll('.line-rdr-line').data(lines);
|
| - svgLines.enter.append('path').each((d, i, e) {
|
| - e.attributes['fill'] = 'none';
|
| - });
|
| -
|
| - svgLines.each((d, i, e) {
|
| - var column = series.measures.elementAt(i),
|
| - color = colorForColumn(column),
|
| - filter = filterForColumn(column),
|
| - styles = stylesForColumn(column);
|
| - e.attributes
|
| - ..['d'] = line.path(d, i, e)
|
| - ..['stroke'] = color
|
| - ..['class'] = styles.isEmpty
|
| - ? 'line-rdr-line'
|
| - : 'line-rdr-line ${styles.join(' ')}'
|
| - ..['data-column'] = '$column';
|
| - if (isNullOrEmpty(filter)) {
|
| - e.attributes.remove('filter');
|
| - } else {
|
| - e.attributes['filter'] = filter;
|
| - }
|
| - });
|
| -
|
| - if (area.state != null) {
|
| - svgLines
|
| - ..on('click', (d, i, e) => _mouseClickHandler(d, i, e))
|
| - ..on('mouseover', (d, i, e) => _mouseOverHandler(d, i, e))
|
| - ..on('mouseout', (d, i, e) => _mouseOutHandler(d, i, e));
|
| - }
|
| -
|
| - svgLines.exit.remove();
|
| - }
|
| -
|
| - @override
|
| - void dispose() {
|
| - if (root == null) return;
|
| - root.selectAll('.line-rdr-line').remove();
|
| - root.selectAll('.line-rdr-point').remove();
|
| - _disposer.dispose();
|
| - }
|
| -
|
| - @override
|
| - void handleStateChanges(List<ChangeRecord> changes) {
|
| - var lines = host.querySelectorAll('.line-rdr-line');
|
| - if (lines == null || lines.isEmpty) return;
|
| -
|
| - for (int i = 0, len = lines.length; i < len; ++i) {
|
| - var line = lines.elementAt(i),
|
| - column = int.parse(line.dataset['column']),
|
| - filter = filterForColumn(column);
|
| - line.classes.removeAll(ChartState.COLUMN_CLASS_NAMES);
|
| - line.classes.addAll(stylesForColumn(column));
|
| - line.attributes['stroke'] = colorForColumn(column);
|
| -
|
| - if (isNullOrEmpty(filter)) {
|
| - line.attributes.remove('filter');
|
| - } else {
|
| - line.attributes['filter'] = filter;
|
| - }
|
| - }
|
| - }
|
| -
|
| - void _createTrackingCircles() {
|
| - var linePoints = root.selectAll('.line-rdr-point').data(series.measures);
|
| - linePoints.enter.append('circle').each((d, i, e) {
|
| - e.classes.add('line-rdr-point');
|
| - e.attributes['r'] = '4';
|
| - });
|
| -
|
| - linePoints
|
| - ..each((d, i, e) {
|
| - var color = colorForColumn(d);
|
| - e.attributes
|
| - ..['r'] = '4'
|
| - ..['stroke'] = color
|
| - ..['fill'] = color
|
| - ..['data-column'] = '$d';
|
| - })
|
| - ..on('click', _mouseClickHandler)
|
| - ..on('mousemove', _mouseOverHandler) // Ensure that we update values
|
| - ..on('mouseover', _mouseOverHandler)
|
| - ..on('mouseout', _mouseOutHandler);
|
| -
|
| - linePoints.exit.remove();
|
| - _trackingPointsCreated = true;
|
| - }
|
| -
|
| - void _showTrackingCircles(int row) {
|
| - if (_trackingPointsCreated == false) {
|
| - _createTrackingCircles();
|
| - }
|
| -
|
| - var yScale = area.measureScales(series).first;
|
| - root.selectAll('.line-rdr-point').each((d, i, e) {
|
| - var x = _xPositions[row],
|
| - measureVal = area.data.rows.elementAt(row).elementAt(d);
|
| - if (measureVal != null && measureVal.isFinite) {
|
| - var color = colorForColumn(d),
|
| - filter = filterForColumn(d);
|
| - e.attributes
|
| - ..['cx'] = '$x'
|
| - ..['cy'] = '${yScale.scale(measureVal)}'
|
| - ..['fill'] = color
|
| - ..['stroke'] = color
|
| - ..['data-row'] = '$row';
|
| - e.style
|
| - ..setProperty('opacity', '1')
|
| - ..setProperty('visibility', 'visible');
|
| - if (isNullOrEmpty(filter)) {
|
| - e.attributes.remove('filter');
|
| - } else {
|
| - e.attributes['filter'] = filter;
|
| - }
|
| - } else {
|
| - e.style
|
| - ..setProperty('opacity', '$EPSILON')
|
| - ..setProperty('visibility', 'hidden');
|
| - }
|
| - });
|
| - }
|
| -
|
| - void _hideTrackingCircles() {
|
| - root.selectAll('.line-rdr-point')
|
| - ..style('opacity', '0.0')
|
| - ..style('visibility', 'hidden');
|
| - }
|
| -
|
| - int _getNearestRowIndex(double x) {
|
| - var lastSmallerValue = 0;
|
| - var chartX = x - area.layout.renderArea.x;
|
| - for (var i = 0; i < _xPositions.length; i++) {
|
| - var pos = _xPositions[i];
|
| - if (pos < chartX) {
|
| - lastSmallerValue = pos;
|
| - } else {
|
| - return i == 0 ? 0 :
|
| - (chartX - lastSmallerValue <= pos - chartX) ? i - 1 : i;
|
| - }
|
| - }
|
| - return _xPositions.length - 1;
|
| - }
|
| -
|
| - void _trackPointerInArea() {
|
| - _trackingPointsCreated = false;
|
| - _disposer.add(area.onMouseMove.listen((ChartEvent event) {
|
| - if (area.layout.renderArea.contains(event.chartX, event.chartY)) {
|
| - var row = _getNearestRowIndex(event.chartX);
|
| - window.animationFrame.then((_) => _showTrackingCircles(row));
|
| - } else {
|
| - _hideTrackingCircles();
|
| - }
|
| - }));
|
| - _disposer.add(area.onMouseOut.listen((ChartEvent event) {
|
| - _hideTrackingCircles();
|
| - }));
|
| - }
|
| -
|
| - void _mouseClickHandler(d, int i, Element e) {
|
| - if (area.state != null) {
|
| - area.state.select(int.parse(e.dataset['column']));
|
| - }
|
| - if (mouseClickController != null && e.tagName == 'circle') {
|
| - var row = int.parse(e.dataset['row']),
|
| - column = int.parse(e.dataset['column']);
|
| - mouseClickController.add(
|
| - new DefaultChartEventImpl(scope.event, area, series, row, column, d));
|
| - }
|
| - }
|
| -
|
| - void _mouseOverHandler(d, i, e) {
|
| - if (area.state != null) {
|
| - area.state.preview = int.parse(e.dataset['column']);
|
| - }
|
| - if (mouseOverController != null && e.tagName == 'circle') {
|
| - _savedOverRow = int.parse(e.dataset['row']);
|
| - _savedOverColumn = int.parse(e.dataset['column']);
|
| - mouseOverController.add(new DefaultChartEventImpl(
|
| - scope.event, area, series, _savedOverRow, _savedOverColumn, d));
|
| - }
|
| - }
|
| -
|
| - void _mouseOutHandler(d, i, e) {
|
| - if (area.state != null &&
|
| - area.state.preview == int.parse(e.dataset['column'])) {
|
| - area.state.preview = null;
|
| - }
|
| - if (mouseOutController != null && e.tagName == 'circle') {
|
| - mouseOutController.add(new DefaultChartEventImpl(
|
| - scope.event, area, series, _savedOverRow, _savedOverColumn, d));
|
| - }
|
| - }
|
| -}
|
|
|