modern_charts 0.1.17

  • README.md
  • CHANGELOG.md
  • Example
  • Installing
  • Versions
  • 90

A package for creating simple yet modern looking charts.

Five chart types #

  • Bar

  • Gauge

  • Line

  • Pie

  • Radar

Canvas + DOM #

modern_charts combines Canvas and DOM to achieve the best performance and experience.

  • Canvas is used to render chart contents (axes, grids, and series)
  • DOM is used to create legends and tooltips

DataTable #

Data are passed to a chart via a DataTable object. By using DataTable, you can flexibly modify the data even after the chart has been rendered.

Animations #

Animations are supported for different types of data modifications:

  • New data table
  • Changes to data table values
  • Insertion and removal of rows (categories)
  • Insertion and removal of columns (series)
  • Series visibility toggle

Responsive #

Charts automatically resize when the browser is resized.

Interactive #

  • Shows tooltips on hover/tap
  • The visibility of a series is toggled when you click the corresponding legend item

Modular #

Each chart type has its own class, so your final production code only contains the code of the chart types you use.

Usage #

Please read the wiki for instructions on how to use these beautiful charts.

0.1.17 #

  • Fix #18
  • Chart: add isInteractive
  • Chart: add method dispose
  • Chart: deprecate animating, use isAnimating instead
  • Chart: listen for mousemove on the container rather than window
  • Chart: allow updating the drawing options via method update
  • PieChart: fix a bug where pies' inner and outer radii are not updated
  • utils: optimize mergeMaps

0.1.16 #

  • pubspec: fix the documentation link
  • example: move files from example/web to example

0.1.15 #

  • Chart: fix a bug that happens when options is not provided to draw
  • Chart: fix an animation bug when clicking a legend item
  • test: use package test

0.1.14 #

  • BREAKING CHANGE: This version requires Dart 2.0.0 or later

0.1.13 #

  • base: charts no longer resize automatically on window resize
  • base: fixed a bug that happens when Chart.resize and Chart.update is called while the width or height of the chart is zero
  • RadarChart: fixed a bug where the tooltip is still shown when all series are hidden

0.1.12 #

  • LineChart: fix a bug causing data labels not to be displayed even when enabled

0.1.11 #

  • LineChart: add series:markers:enabled option
  • RadarChart: add series:markers:enabled option

0.1.10 #

  • All: change the default background color of legend to transparent
  • BarChart: change bar group hover effect
  • BarChart: change tooltip offset
  • BarChart: change the positions of x-axis tick marks based on whether x-axis labels are skipped or not
  • BarChart, LineChart: hide x-axis tick marks whose corresponding labels are hidden
  • BarChart, LineChart: axis label baselines are adjusted with respect to font size
  • BarChart, LineChart: fix a bug in the calculation of hovered entity group

0.1.9 #

  • GaugeChart: fix a bug that causes the tooltip not to show when hovering the top left quadrant
  • LineChart: adjust the position of x-axis labels so they span the whole x-axis

0.1.8 #

  • BarChart: add xAxis:labels:maxRotation and xAxis:labels:minRotation
  • LineChart: add xAxis:labels:maxRotation and xAxis:labels:minRotation

0.1.7 #

  • Fix tooltip label formatter and value formatter
  • Update README.md

0.1.6 #

  • Fix #10
  • Fix broken links in CHANGELOG.md
  • Enable strong mode
  • Perform code cleanup
  • Improve performance
  • animation:easing now accepts a function
  • Add DataRow.toList
  • Rename degree to rad2deg and radian to deg2rad in utils.dart
  • PieChart: Add series:counterclockwise and series:startAngle options
  • PieChart: Pie labels, if enabled, are now displayed during animations
  • PieChart: Fix tooltip position when pieHole > 0

0.1.5 #

  • Change the semantics of yAxis:minValue and yAxis:maxValue
  • Add tooltip:labelFormatter and legend:labelFormatter

0.1.4 #

  • Add a 500ms delay before resizing all charts
  • Correct gauge center and outer radius

0.1.3 #

  • Fix #7
  • Fix #8
  • Add yAxis:minInterval setting to BarChart, LineChart, and RadarChart
  • Perform code cleanup

0.1.2 #

  • Fix #5
  • Fix #6
  • Format code using dartfmt

0.1.1 #

  • Fixed the legend-position-none bug

0.1.0 #

  • Initial version

example/example.dart

library example;

import 'dart:html';
import 'package:modern_charts/modern_charts.dart';
import 'dart:math';

final random = Random();

int rand(int min, int max) => random.nextInt(max - min) + min;

void main() {
  createBarChart();
  createLineChart();
  createPieChart();
  createRadarChart();
  createGaugeChart();
}

Element createContainer() {
  var e = DivElement()
    ..style.height = '400px'
//    ..style.width = '800px'
    ..style.maxWidth = '100%'
    ..style.marginBottom = '50px';
  document.body.append(e);
  return e;
}

// February
void createBarChart() {
  var table = DataTable([
    ['Categories', 'Long series name', 'Series 2', 'Series 3'],
    ['January', 1, 3, 5],
    ['February', 3, 4, 6],
    ['March', 4, 3, 1],
    ['April', null, 5, 1],
    ['May', 3, 4, 2],
    ['June', 5, 10, 4],
    ['July', 4, 12, 8],
    ['August', 1, 3, 5],
    ['September', 3, 4, 6],
    ['October', 4, 3, 1],
    ['November', null, 5, 1],
    ['December', 3, 4, 2],
  ]);

  var changeDataButton = ButtonElement()..text = 'Change data';
  document.body.append(changeDataButton);

  var insertRemoveColumnButton = ButtonElement()
    ..text = 'Insert/remove data column';
  document.body.append(insertRemoveColumnButton);

  var insertRemoveRowButton = ButtonElement()..text = 'Insert/remove data row';
  document.body.append(insertRemoveRowButton);

  var container = createContainer();

  var options = {
    'animation': {
      'onEnd': () {
        changeDataButton.disabled = false;
        insertRemoveColumnButton.disabled = false;
        insertRemoveRowButton.disabled = false;
      }
    },
    'series': {
      'labels': {'enabled': true}
    },
    'xAxis': {
      'crosshair': {'enabled': true},
      'labels': {'maxRotation': 90, 'minRotation': 0}
    },
    'yAxis': {'maxValue': 30, 'minInterval': 5},
    'title': {'text': 'Bar Chart Demo'},
    'tooltip': {'valueFormatter': (value) => '$value units'}
  };

  var chart = BarChart(container);
  chart.draw(table, options);

  void disableAllButtons() {
    changeDataButton.disabled = true;
    insertRemoveColumnButton.disabled = true;
    insertRemoveRowButton.disabled = true;
  }

  changeDataButton.onClick.listen((_) {
    disableAllButtons();
    for (var row in table.rows) {
      for (var i = 1; i < table.columns.length; i++) {
        row[i] = rand(2, 20);
      }
    }
    chart.update();
  });

  var insertColumn = true;
  insertRemoveColumnButton.onClick.listen((_) {
    disableAllButtons();
    if (insertColumn) {
      table.columns.insert(2, DataColumn('New series', num));
      for (var row in table.rows) {
        row[2] = rand(2, 20);
      }
    } else {
      table.columns.removeAt(2);
    }
    insertColumn = !insertColumn;
    chart.update();
  });

  var insertRow = true;
  insertRemoveRowButton.onClick.listen((_) {
    disableAllButtons();
    if (insertRow) {
      var values = <dynamic>['New'];
      for (var i = 1; i < table.columns.length; i++) {
        values.add(rand(2, 20));
      }
      table.rows.insert(2, values);
    } else {
      table.rows.removeAt(2);
    }
    insertRow = !insertRow;
    chart.update();
  });
}

void createLineChart() {
  var table = DataTable([
    ['Categories', 'Series 1', 'Series 2', 'Series 3'],
    ['Monday', 1, 3, 5],
    ['Tuesday', 3, 4, 6],
    ['Wednesday', 4, 3, 1],
    ['Thursday', null, 5, 1],
    ['Friday', 3, 4, 2],
    ['Saturday', 5, 10, 4],
    ['Sunday', 4, 12, 8]
  ]);

  var changeDataButton = ButtonElement()..text = 'Change data';
  document.body.append(changeDataButton);

  var insertRemoveColumnButton = ButtonElement()
    ..text = 'Insert/remove data column';
  document.body.append(insertRemoveColumnButton);

  var insertRemoveRowButton = ButtonElement()..text = 'Insert/remove data row';
  document.body.append(insertRemoveRowButton);

  var container = createContainer();

  var options = {
    'animation': {
      'onEnd': () {
        changeDataButton.disabled = false;
        insertRemoveColumnButton.disabled = false;
        insertRemoveRowButton.disabled = false;
      }
    },
    'series': {
      'fillOpacity': 0.25,
      'labels': {'enabled': true},
    },
    'yAxis': {'minInterval': 5},
    'title': {'text': 'Line Chart Demo'}
  };

  var chart = LineChart(container);
  chart.draw(table, options);

  void disableAllButtons() {
    changeDataButton.disabled = true;
    insertRemoveColumnButton.disabled = true;
    insertRemoveRowButton.disabled = true;
  }

  changeDataButton.onClick.listen((_) {
    disableAllButtons();
    for (var row in table.rows) {
      for (var i = 1; i < table.columns.length; i++) {
        row[i] = rand(2, 20);
      }
    }
    chart.update();
  });

  var insertColumn = true;
  insertRemoveColumnButton.onClick.listen((_) {
    disableAllButtons();
    if (insertColumn) {
      table.columns.insert(2, DataColumn('New series', num));
      for (var row in table.rows) {
        row[2] = rand(2, 20);
      }
    } else {
      table.columns.removeAt(2);
    }
    insertColumn = !insertColumn;
    chart.update();
  });

  var insertRow = true;
  insertRemoveRowButton.onClick.listen((_) {
    disableAllButtons();
    if (insertRow) {
      var values = <Object>['New'];
      for (var i = 1; i < table.columns.length; i++) {
        values.add(rand(2, 20));
      }
      table.rows.insert(2, values);
    } else {
      table.rows.removeAt(2);
    }
    insertRow = !insertRow;
    chart.update();
  });
}

void createPieChart() {
  var changeDataButton = ButtonElement()..text = 'Change data';
  document.body.append(changeDataButton);

  var insertRemoveRowButton = ButtonElement()..text = 'Insert/remove data row';
  document.body.append(insertRemoveRowButton);

  var container = createContainer();
  var table = DataTable([
    ['Browser', 'Share'],
    ['Chrome', 35],
    ['Firefox', 20],
    ['IE', 30],
    ['Opera', 5],
    ['Safari', 8],
    ['Other', 2]
  ]);
  var chart = PieChart(container);
  chart.draw(table, {
    'animation': {
      'onEnd': () {
        changeDataButton.disabled = false;
        insertRemoveRowButton.disabled = false;
      }
    },
    'pieHole': .5,
    'series': {
      'counterclockwise': true,
      'labels': {'enabled': true},
      'startAngle': 90 + 10 * 360,
    },
    'title': {'text': 'Pie Chart Demo'},
  });

  void disableAllButtons() {
    changeDataButton.disabled = true;
    insertRemoveRowButton.disabled = true;
  }

  changeDataButton.onClick.listen((_) {
    disableAllButtons();
    for (var row in table.rows) {
      for (var i = 1; i < table.columns.length; i++) {
        row[i] = rand(2, 25);
      }
    }
    chart.update();
  });

  var insertRow = true;
  insertRemoveRowButton.onClick.listen((_) {
    insertRemoveRowButton.disabled = true;
    if (insertRow) {
      var values = ['New', 6];
      table.rows.insert(2, values);
    } else {
      table.rows.removeAt(2);
    }
    insertRow = !insertRow;
    chart.update();
  });
}

void createRadarChart() {
  var table = DataTable([
    ['Categories', 'Series 1'],
    ['Monday', 8],
    ['Tuesday', 17],
    ['Wednesday', 7],
    ['Thursday', 16],
    ['Friday', 12],
    ['Saturday', 5],
    ['Sunday', 14]
  ]);

  var changeDataButton = ButtonElement()..text = 'Change data';
  document.body.append(changeDataButton);

  var insertRemoveColumnButton = ButtonElement()
    ..text = 'Insert/remove data column';
  document.body.append(insertRemoveColumnButton);

  var insertRemoveRowButton = ButtonElement()..text = 'Insert/remove data row';
  document.body.append(insertRemoveRowButton);

  var container = createContainer();

  var options = {
    'animation': {
      'onEnd': () {
        changeDataButton.disabled = false;
        insertRemoveColumnButton.disabled = false;
        insertRemoveRowButton.disabled = false;
      }
    },
    'series': {
      'labels': {'enabled': true}
    },
    'title': {'text': 'Radar Chart Demo'},
    'tooltip': {'valueFormatter': (value) => '$value units'}
  };

  var chart = RadarChart(container);
  chart.draw(table, options);

  void disableAllButtons() {
    changeDataButton.disabled = true;
    insertRemoveColumnButton.disabled = true;
    insertRemoveRowButton.disabled = true;
  }

  changeDataButton.onClick.listen((_) {
    disableAllButtons();
    for (var row in table.rows) {
      for (var i = 1; i < table.columns.length; i++) {
        row[i] = rand(5, 20);
      }
    }
    chart.update();
  });

  var insertColumn = true;
  insertRemoveColumnButton.onClick.listen((_) {
    disableAllButtons();
    if (insertColumn) {
      table.columns.insert(2, DataColumn('New series', num));
      for (var row in table.rows) {
        row[2] = rand(5, 20);
      }
    } else {
      table.columns.removeAt(2);
    }
    insertColumn = !insertColumn;
    chart.update();
  });

  var insertRow = true;
  insertRemoveRowButton.onClick.listen((_) {
    disableAllButtons();
    if (insertRow) {
      var values = <Object>['New'];
      for (var i = 1; i < table.columns.length; i++) {
        values.add(rand(5, 20));
      }
      table.rows.insert(2, values);
    } else {
      table.rows.removeAt(2);
    }
    insertRow = !insertRow;
    chart.update();
  });
}

void createGaugeChart() {
  var changeDataButton = ButtonElement()..text = 'Change data';
  document.body.append(changeDataButton);

  var insertRemoveRowButton = ButtonElement()..text = 'Insert/remove data row';
  document.body.append(insertRemoveRowButton);

  var container = createContainer();
  var table = DataTable([
    ['Browser', 'Share'],
    ['Memory', 25],
//    ['CPU', 75],
//    ['Disk', 40]
  ]);
  var chart = GaugeChart(container);
  chart.draw(table, {
    'animation': {
      'easing': (double t) {
        t = 4 * t - 2;
        return (t * t * t - t) / 12 + .5;
      },
      'onEnd': () {
        changeDataButton.disabled = false;
        insertRemoveRowButton.disabled = false;
      }
    },
    'gaugeLabels': {'enabled': false},
    'title': {'text': 'Gauge Chart Demo'},
  });

  void disableAllButtons() {
    changeDataButton.disabled = true;
    insertRemoveRowButton.disabled = true;
  }

  changeDataButton.onClick.listen((_) {
    disableAllButtons();
    for (var row in table.rows) {
      for (var i = 1; i < table.columns.length; i++) {
        row[i] = rand(0, 101);
      }
    }
    chart.update();
  });

  var insertRow = true;
  insertRemoveRowButton.onClick.listen((_) {
    insertRemoveRowButton.disabled = true;
    if (insertRow) {
      var values = ['New', rand(0, 101)];
      table.rows.insert(1, values);
    } else {
      table.rows.removeAt(1);
    }
    insertRow = !insertRow;
    chart.update();
  });
}

Use this package as a library

1. Depend on it

Add this to your package's pubspec.yaml file:


dependencies:
  modern_charts: ^0.1.17

2. Install it

You can install packages from the command line:

with pub:


$ pub get

Alternatively, your editor might support pub get. Check the docs for your editor to learn more.

3. Import it

Now in your Dart code, you can use:


import 'package:modern_charts/modern_charts.dart';
  
Version Uploaded Documentation Archive
0.1.17 Jan 6, 2019 Go to the documentation of modern_charts 0.1.17 Download modern_charts 0.1.17 archive
0.1.16 Dec 3, 2018 Go to the documentation of modern_charts 0.1.16 Download modern_charts 0.1.16 archive
0.1.15 Nov 29, 2018 Go to the documentation of modern_charts 0.1.15 Download modern_charts 0.1.15 archive
0.1.14 Nov 28, 2018 Go to the documentation of modern_charts 0.1.14 Download modern_charts 0.1.14 archive
0.1.13 Jul 9, 2018 Go to the documentation of modern_charts 0.1.13 Download modern_charts 0.1.13 archive
0.1.12 Sep 11, 2017 Go to the documentation of modern_charts 0.1.12 Download modern_charts 0.1.12 archive
0.1.11 Aug 24, 2017 Go to the documentation of modern_charts 0.1.11 Download modern_charts 0.1.11 archive
0.1.10 Aug 21, 2017 Go to the documentation of modern_charts 0.1.10 Download modern_charts 0.1.10 archive
0.1.9 Aug 20, 2017 Go to the documentation of modern_charts 0.1.9 Download modern_charts 0.1.9 archive
0.1.8 Aug 10, 2017 Go to the documentation of modern_charts 0.1.8 Download modern_charts 0.1.8 archive

All 18 versions...

Popularity:
Describes how popular the package is relative to other packages. [more]
82
Health:
Code health derived from static analysis. [more]
98
Maintenance:
Reflects how tidy and up-to-date the package is. [more]
96
Overall:
Weighted score of the above. [more]
90
Learn more about scoring.

We analyzed this package on Jun 26, 2019, and provided a score, details, and suggestions below. Analysis was completed with status completed using:

  • Dart: 2.3.2
  • pana: 0.12.18

Platforms

Detected platforms: web

Primary library: package:modern_charts/modern_charts.dart with components: html.

Health suggestions

Fix lib/src/datatable.dart. (-1 points)

Analysis of lib/src/datatable.dart reported 2 hints:

line 73 col 29: Use = to separate a named parameter from its default value.

line 157 col 3: Avoid return types on setters.

Fix lib/src/line.dart. (-0.50 points)

Analysis of lib/src/line.dart reported 1 hint:

line 338 col 62: DO use curly braces for all flow control structures.

Fix lib/src/radar.dart. (-0.50 points)

Analysis of lib/src/radar.dart reported 1 hint:

line 424 col 7: DO use curly braces for all flow control structures.

Maintenance suggestions

The package description is too short. (-4 points)

Add more detail to the description field of pubspec.yaml. Use 60 to 180 characters to describe the package, what it does, and its target use case.

Dependencies

Package Constraint Resolved Available
Direct dependencies
Dart SDK >=2.0.0 <3.0.0
intl ^0.15.7 0.15.8
Transitive dependencies
path 1.6.2
Dev dependencies
build_runner ^1.1.2
build_web_compilers ^0.4.4
test ^1.5.1