modern_charts 0.1.16

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

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.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.16

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.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
0.1.7 Jun 9, 2017 Go to the documentation of modern_charts 0.1.7 Download modern_charts 0.1.7 archive

All 17 versions...

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

We analyzed this package on Dec 5, 2018, and provided a score, details, and suggestions below. Analysis was completed with status completed using:

  • Dart: 2.1.0
  • pana: 0.12.7

Platforms

Detected platforms: web

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

Health suggestions

Format lib/src/pie.dart.

Run dartfmt to format lib/src/pie.dart.

Format lib/src/utils.dart.

Run dartfmt to format lib/src/utils.dart.

Maintenance suggestions

The description is too short. (-20 points)

Add more detail about the package, what it does and what is its target use case. Try to write at least 60 characters.

Dependencies

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