A Flutter data visualization library based on Grammar of Graphics.

Overview

Graphic is now under a total refactoring. The prior available version code is here: v0.3.0 .

examples

A Flutter data visualization library based on Grammar of Graphics.

Usage

Installing

pub.dev

Basic example

graphic.Chart(
  data: [
    { 'genre': 'Sports', 'sold': 275 },
    { 'genre': 'Strategy', 'sold': 115 },
    { 'genre': 'Action', 'sold': 120 },
    { 'genre': 'Shooter', 'sold': 350 },
    { 'genre': 'Other', 'sold': 150 },
  ],
  scales: {
    'genre': graphic.CatScale(
      accessor: (map) => map['genre'] as String,
    ),
    'sold': graphic.LinearScale(
      accessor: (map) => map['sold'] as num,
      nice: true,
    )
  },
  geoms: [graphic.IntervalGeom(
    position: graphic.PositionAttr(field: 'genre*sold'),
  )],
  axes: {
    'genre': graphic.Defaults.horizontalAxis,
    'sold': graphic.Defaults.verticalAxis,
  },
)

Document

If you have ever used data visualization libs based on Grammar of Graphics, such as AntV , ggplot2, you can be quite familiar with these concepts.

The document has not been written yet, but by referring to the Example App , I believe you can be smart enough to build your charts :)

Comments
  • performance problem with a lot of data

    performance problem with a lot of data

    Hi, it is great library, but I have problem with performance. I have classic line chart with a lot of data. But chart is too slow, i cant zoom because it is not possible. I'm trying it on the web.

    Config:

    
    selections: {
                  'tooltipMouse': PointSelection(
                    on: {
                      GestureType.hover,
                    },
                    devices: {PointerDeviceKind.mouse},
                    variable: 'Datum',
                    dim: Dim.x,
                  ),
                  'tooltipTouch': PointSelection(
                    on: {
                      GestureType.scaleUpdate,
                      GestureType.tapDown,
                      GestureType.longPressMoveUpdate
                    },
                    devices: {PointerDeviceKind.touch},
                    variable: 'Datum',
                    dim: Dim.x,
                  ),
                },
    coord: RectCoord(
                  horizontalRangeUpdater: Defaults.horizontalRangeSignal,
                ),
    data: _data,
                variables: {
                  'Datum': Variable(
                    accessor: (Map datum) => datum['Datum'] as String,
                    scale: OrdinalScale(),
                  ),
                  'Hodnota': Variable(
                    accessor: (Map datum) => datum['Hodnota'] as num,
                    scale: LinearScale(),
                  ),
                  'Skupina': Variable(
                    accessor: (Map datum) => datum['Skupina'] as String,
                    scale: OrdinalScale(),
                  ),
                },
                elements: [
                  LineElement(
                    position:
                        Varset('Datum') * Varset('Hodnota') / Varset('Skupina'),
                    color: ColorAttr(
                      variable: 'Skupina',
                      values: [
                        const Color.fromARGB(255, 0, 236, 0),
                        const Color.fromARGB(255, 0, 128, 255),
                        const Color.fromARGB(255, 192, 192, 192),
                      ],
                    ),
                  ),
                ],
                axes: [
                  Defaults.horizontalAxis,
                  Defaults.verticalAxis,
                ],
    
    opened by ZdenekKrcal 19
  • How to show two line data's

    How to show two line data's

    In Example i could find only a single line plotting in all charts. How to show two line charts with datetime in x-axis and different sets of value in y-axis.

    opened by srishalu 16
  • improv: add custom modifier example

    improv: add custom modifier example

    This PR adds an example of a custom Modifier. It creates a DodgeSizeModifier that changes an element's position and width depending on the number of elements in a band.

    Custom Legend Example Custom Modifier Example
    image image
    opened by bernardobelchior 14
  • memory leak in gesture controller with rebuilding

    memory leak in gesture controller with rebuilding

    Hi @entronad , We have tried to implement issue #83, but we ran into a big problem. Updating ticks requires rebuilding the chart, but this causes a memory leak. To investigate what the issue is, we have modified one of your examples (See the code below).
    If we profile this example, we can see a memory leak happening. We believe this is due to the fact that the chart keeps listening to the gesture controller.


    Our code

    modified from line_area_point.dart

    import 'dart:async';
    
    import 'package:flutter/material.dart';
    import 'package:graphic/graphic.dart';
    
    import 'package:intl/intl.dart';
    
    final _monthDayFormat = DateFormat('MM-dd');
    
    ///DATA FOR CHART
    
    class TimeSeriesSales {
      final DateTime time;
      final int sales;
    
      TimeSeriesSales(this.time, this.sales);
    }
    
    final timeSeriesSales = getData();
    
    List<TimeSeriesSales> getData() {
      final List<TimeSeriesSales> result = [];
      for (int i = 0; i < 4000; i++) {
        result.add(TimeSeriesSales(DateTime.fromMicrosecondsSinceEpoch(i), i));
      }
      return result;
    }
    ///DATA FOR CHART END
    
    
    
    class LineAreaPointPage extends StatefulWidget {
      const LineAreaPointPage({Key? key}) : super(key: key);
    
      @override
      State<LineAreaPointPage> createState() => _LineAreaPointPageState();
    }
    
    class _LineAreaPointPageState extends State<LineAreaPointPage> {
      final GlobalKey<ScaffoldState> _scaffoldKey = GlobalKey<ScaffoldState>();
      late final StreamController<GestureSignal> gestureChannel;
    
      int tickCount = 50;
    
      @override
      void initState() {
        gestureChannel = StreamController<GestureSignal>.broadcast();
        debugPrint("Init");
        super.initState();
      }
    
      void incTickCount() {
        setState(() {
          tickCount += 1;
        });
      }
    
      @override
      Widget build(BuildContext context) {
        debugPrint("REBUILDING");
    
        if (!gestureChannel.hasListener) {
          gestureChannel.stream.listen((event) => debugPrint("EVENT"));
        }
        return Scaffold(
          appBar: AppBar(
            title: const Text('Line and Area Element'),
          ),
          floatingActionButton: FloatingActionButton(
              onPressed: () {
                for (int i = 0; i < 40; i++) {
                  incTickCount();
                }
              },
              child: const Text("Rebuild Button")),
          backgroundColor: Colors.white,
          body: Chart(
            key: _scaffoldKey,
            data: timeSeriesSales,
           //when the line below is removed, the issue disappears 
            gestureChannel: gestureChannel,
            variables: {
              'time': Variable(
                  accessor: (TimeSeriesSales datum) => datum.time,
                  scale: TimeScale(
                    formatter: (time) => _monthDayFormat.format(time),
                    tickCount: tickCount,
                  )),
              'sales': Variable(
                accessor: (TimeSeriesSales datum) => datum.sales,
              ),
            },
            elements: [
              LineElement(
                shape: ShapeAttr(value: BasicLineShape(dash: [5, 2])),
                selected: {
                  'touchMove': {1}
                },
              )
            ],
            coord: RectCoord(color: const Color(0xffdddddd)),
            axes: [
              Defaults.horizontalAxis,
              Defaults.verticalAxis,
            ],
            selections: {
              'touchMove': PointSelection(
                on: {
                  GestureType.scaleUpdate,
                  GestureType.tapDown,
                  GestureType.longPressMoveUpdate
                },
                dim: Dim.x,
              )
            },
            tooltip: TooltipGuide(
              followPointer: [false, true],
              align: Alignment.topLeft,
              offset: const Offset(-20, -20),
            ),
            crosshair: CrosshairGuide(followPointer: [false, true]),
          ),
        );
      }
    }
    
    opened by BentEngbers 10
  • fix: remove tooltip on exit chart area

    fix: remove tooltip on exit chart area

    Just opening this as a show-case of my failed attempt to fix #62.

    It fixes the case where the user moves the mouse outside the area of the chart, but if the user alt-tabs to another window and then back to the flutter window the tooltip is left open forever.

    Maybe this is ok, and two other things could be added:

    1. a TTL for tooltips
    2. a way of allowing the consumer of the chart to indicate if hover is enabled, it would to the consumer to control if the window is focused or not.

    Maybe n.2 is possible, I'm still pretty new with this lib.

    Let me know your thoughts about this.

    opened by canastro 10
  • How to skip a value while keeping its tick on X axis?

    How to skip a value while keeping its tick on X axis?

    In a line chart I need to skip the drawing of a line while keeping its corresponding tick in the x axis. This is my code:

    data: [
            LineChartVM(date: '2022-06-09', value: 3),
            LineChartVM(date: '2022-06-10', value: 5),
            LineChartVM(date: '2022-06-12', value: 10),
            LineChartVM(date: '2022-06-13', value: -1),
            LineChartVM(date: '2022-06-14', value: 7),
          ];
    
    Chart<LineChartVM>(
            data: data,
            variables: {
              'label': Variable(accessor: (LineChartVM map) => map.date),
              'value': Variable(accessor: (LineChartVM map) => map.value),
              'name': Variable(accessor: (LineChartVM map) => 'test'),
            },
            elements: [
              if (Varset('value') != -1) ...[
                LineElement(
                  position: Varset('label') * Varset('value') / Varset('name'),
                  size: SizeAttr(value: 2),
                  color: ColorAttr(
                    variable: 'name',
                    values: [
                      Colors.blue,
                      Colors.blue
                    ],
                  ),
                ),
                PointElement(
                  size: SizeAttr(value: 10),
                  color: ColorAttr(
                    variable: 'name',
                    values: [Colors.red, Colors.green],
                  ),
                ),
              ]
            ],
            axes: [
              Defaults.horizontalAxis
                ..line = null
                ..grid = null,
              Defaults.verticalAxis
                ..line = null
                ..grid = Defaults.strokeStyle
            ],
     );
    

    In the attribute "elements" I'm trying to draw only lines for values other than -1 and I want to keep the date tick in X axis.

    The if statement is not working. Varset('value') returns an object instance of Varset and I don't know how to access its internal value.

    It's possible to do that?

    opened by gabrirulli 9
  • Error while building app with graphic package

    Error while building app with graphic package

    Hi, @entronad I am getting this error while running the app after installing the graphic package can you please help me with this.

    /E:/software/flutter/.pub-cache/hosted/pub.dartlang.org/graphic-0.4.1/lib/src/in
    teraction/selection/selection.dart:182:36: Error: The getter 'delta' isn't      
    defined for the class 'ScaleUpdateDetails'.
     - 'ScaleUpdateDetails' is from 'package:flutter/src/gestures/scale.dart'       
     ('/E:/software/flutter/packages/flutter/lib/src/gestures/scale.dart').
    Try correcting the name to the name of an existing getter, or defining a getter 
    or field named 'delta'.
                  final delta = detail.delta - gesture.preScaleDetail!.delta;       
                                       ^^^^^
    /E:/software/flutter/.pub-cache/hosted/pub.dartlang.org/graphic-0.4.1/lib/src/in
    teraction/selection/selection.dart:182:68: Error: The getter 'delta' isn't      
    defined for the class 'ScaleUpdateDetails'.
     - 'ScaleUpdateDetails' is from 'package:flutter/src/gestures/scale.dart'       
     ('/E:/software/flutter/packages/flutter/lib/src/gestures/scale.dart').
    Try correcting the name to the name of an existing getter, or defining a getter 
    or field named 'delta'.
                  final delta = detail.delta - gesture.preScaleDetail!.delta;
                                                                       ^^^^^        
    /E:/software/flutter/.pub-cache/hosted/pub.dartlang.org/graphic-0.4.1/lib/src/ch
    art/chart.dart:255:11: Error: No named parameter with the name
    'onLongPressCancel'.
              onLongPressCancel: () {
              ^^^^^^^^^^^^^^^^^
    /E:/software/flutter/packages/flutter/lib/src/widgets/gesture_detector.dart:216:
    3: Context: Found this candidate, but the arguments don't match.
      GestureDetector({
      ^^^^^^^^^^^^^^^
    /E:/software/flutter/.pub-cache/hosted/pub.dartlang.org/graphic-0.4.1/lib/src/co
    mmon/defaults.dart:162:28: Error: The getter 'delta' isn't defined for the class
    'ScaleUpdateDetails'.
     - 'ScaleUpdateDetails' is from 'package:flutter/src/gestures/scale.dart'       
     ('/E:/software/flutter/packages/flutter/lib/src/gestures/scale.dart').
    Try correcting the name to the name of an existing getter, or defining a getter
    or field named 'delta'.
            (detail) => detail.delta.dx,
                               ^^^^^
    /E:/software/flutter/.pub-cache/hosted/pub.dartlang.org/graphic-0.4.1/lib/src/co
    mmon/defaults.dart:169:29: Error: The getter 'delta' isn't defined for the class
    'ScaleUpdateDetails'.
     - 'ScaleUpdateDetails' is from 'package:flutter/src/gestures/scale.dart'
     ('/E:/software/flutter/packages/flutter/lib/src/gestures/scale.dart').
    Try correcting the name to the name of an existing getter, or defining a getter 
    or field named 'delta'.
            (detail) => -detail.delta.dy,
    
    opened by adarsh-technocrat 9
  • fix(#84): fix DodgeModifier with symmetric flag not centering symmetrically

    fix(#84): fix DodgeModifier with symmetric flag not centering symmetrically

    Fixes #84.

    The DodgeModifier wasn't correctly centering the values around the original position. This pull request fixes that issue. I've also added tests to ensure that it works now and it doesn't break in the future.

    Used ggplot's dodging documentation as a comparison for this modifier.

    Before (main):

    image

    Note how the 0 label wasn't properly centered with relation to the vertical bars.

    Now (fix/dodge-modifier-symmetric):

    image

    Note how the 0 label is now properly centered with relation to the vertical bars.

    opened by bernardobelchior 8
  • 请问如何正确构造数据 Expected a value of type '(dynamic) => dynamic', but got one of type '(Map<dynamic, dynamic>) => String'

    请问如何正确构造数据 Expected a value of type '(dynamic) => dynamic', but got one of type '(Map) => String'

    image 我这边会出现这种情况 Expected a value of type '(dynamic) => dynamic', but got one of type '(Map<dynamic, dynamic>) => String' json数据没有问题 image 大概是这样 [{ time: 2021 - 11 - 29 15: 00, name: 空气温度(℃), value: 20.1 }, { time: 2021 - 11 - 29 15: 20, name: 空气温度(℃), value: 20.1 }]

    opened by zjyhll 8
  • Problem using more than 12 elements in line_area graph

    Problem using more than 12 elements in line_area graph

    Hello guys,

    When i add more than 12 elements to a line_area graphic, the grid lines are not being displayed.

    Only 8 are being shown, and the other ones are blank.

    i'll attach a simple code, so you can replicate the error:

    import 'package:flutter/gestures.dart';
    import 'package:flutter/material.dart';
    import 'package:graphic/graphic.dart';
    import 'package:intl/intl.dart';
    
    import '../data.dart';
    
    final _monthDayFormat = DateFormat('MM-dd');
    
    class LineAreaPage extends StatelessWidget {
      LineAreaPage({Key? key}) : super(key: key);
    
      final GlobalKey<ScaffoldState> _scaffoldKey = GlobalKey<ScaffoldState>();
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          key: _scaffoldKey,
          appBar: AppBar(
            title: const Text('Line and Area Element'),
          ),
          backgroundColor: Colors.white,
          body: SingleChildScrollView(
            child: Center(
              child: Column(
                children: <Widget>[ 
                  Container(
                    child: const Text(
                      'Spider Net Chart',
                      style: TextStyle(fontSize: 20),
                    ),
                    padding: const EdgeInsets.fromLTRB(20, 40, 20, 5),
                  ),
                  Container(
                    child: const Text(
                      '- A loop connects the first and last point.',
                    ),
                    padding: const EdgeInsets.fromLTRB(10, 5, 10, 0),
                    alignment: Alignment.centerLeft,
                  ),
                  Container(
                    margin: const EdgeInsets.only(top: 10),
                    width: 350,
                    height: 300,
                    child: Chart(
                      data: adjustData,
                      variables: {
                        'index': Variable(
                          accessor: (Map map) => map['index'].toString(),
                        ),
                        'type': Variable(
                          accessor: (Map map) => map['type'] as String,
                        ),
                        'value': Variable(
                          accessor: (Map map) => map['value'] as num,
                        ),
                      },
                      elements: [
                        LineElement(
                          position:
                              Varset('index') * Varset('value') / Varset('type'),
                          shape: ShapeAttr(value: BasicLineShape(loop: true)),
                          color: ColorAttr(
                              variable: 'type', values: Defaults.colors10),
                        )
                      ],
                      coord: PolarCoord(),
                      axes: [
                        Defaults.circularAxis,
                        Defaults.radialAxis,
                      ],
                      selections: {
                        'touchMove': PointSelection(
                          on: {
                            GestureType.scaleUpdate,
                            GestureType.tapDown,
                            GestureType.longPressMoveUpdate
                          },
                          dim: 1,
                          variable: 'index',
                        )
                      },
                      tooltip: TooltipGuide(
                        anchor: (_) => Offset.zero,
                        align: Alignment.bottomRight,
                        multiTuples: true,
                        variables: ['type', 'value'],
                      ),
                      crosshair: CrosshairGuide(followPointer: [false, true]),
                    ),
                  ),
                ],
              ),
            ),
          ),
        );
      }
    }
    

    For this example we are using static data:

    const adjustData = [
      {"type": "Email", "index": 1, "value": 120},
      {"type": "Email", "index": 2, "value": 220},
      {"type": "Email", "index": 3, "value": 150},
      {"type": "Email", "index": 4, "value": 320},
      {"type": "Email", "index": 5, "value": 320},
      {"type": "Email", "index": 6, "value": 420},
      {"type": "Email", "index": 7, "value": 520},
      {"type": "Email", "index": 8, "value": 620},
      {"type": "Email", "index": 9, "value": 720},
      {"type": "Email", "index": 10, "value": 820},
      {"type": "Email", "index": 11, "value": 120},
      {"type": "Email", "index": 12, "value": 220},
      {"type": "Email", "index": 13, "value": 320},
    ];
    

    error llokalla

    Thank you so much in advance,

    Yosue

    opened by Kashorako 8
  • Understanding gradients 'stops'

    Understanding gradients 'stops'

    from the library, it says:

      /// A list of values from 0.0 to 1.0 that denote fractions along the gradient.
      ///
      /// If non-null, this list must have the same length as [colors].
      ///
      /// If the first value is not 0.0, then a stop with position 0.0 and a color
      /// equal to the first color in [colors] is implied.
      ///
      /// If the last value is not 1.0, then a stop with position 1.0 and a color
      /// equal to the last color in [colors] is implied.
      ///
      /// The values in the [stops] list must be in ascending order. If a value in
      /// the [stops] list is less than an earlier value in the list, then its value
      /// is assumed to equal the previous value.
      ///
      /// If stops is null, then a set of uniformly distributed stops is implied,
      /// with the first stop at 0.0 and the last stop at 1.0.
    

    so, stops:[0,1] (default) is just like normal gradient, right?

    the problem is, when the data has fewer spike, the gradient is wrong

    Screenshot_1644552473 Screenshot_1644552487

    any solution?

    opened by anggaaryas 7
  • Rebuilding chart, removes the selection & crosshair

    Rebuilding chart, removes the selection & crosshair

    When rebuilding the chart, the current selection is removed and the crosshair removed. We have tried to add a selection to the selection channel as such: selectionChannel.add({'touchMove': {0}}) as well as putting this code in a postFrameCallback, but no crosshair shows up...

    our elements look as follows (subscribing to the selection channel):

    LineElement(
      color: ColorAttr(value: Colors.red),
      shape: ShapeAttr(value: BasicLineShape(smooth: true)),
      position: Varset('time') * Varset('c1'),
      selectionChannel: selectionChannel,
    ),
    LineElement(
      color: ColorAttr(value: Colors.green),
      shape: ShapeAttr(value: BasicLineShape(smooth: true)),
      position: Varset('time') * Varset('ce'),
      selectionChannel: selectionChannel,
    )
    

    and our selections as follows:

    {
      'touchMove': PointSelection(
        on: {
          // GestureType.scaleStart,
          // GestureType.scaleUpdate,
          // GestureType.scaleEnd,
          GestureType.longPress,
          GestureType.longPressMoveUpdate,
          GestureType.longPressEnd,
        },
        dim: Dim.x,
      ),
    }
    
    opened by LucaCras 0
  • PointSelection on transposed stacked bar charts

    PointSelection on transposed stacked bar charts

    Hi, first of all thank you for your work.

    There is an odd behavior with (tap) selection on transposed stacked bar charts. If I don't specify a dimension for the PointSelection, it doesn't work at all.

    If I specify "dim : Dim.y" a different bar will be selected depending on which segment i press. With one segment it is the correct bar, with all other segments an incorrect bar is selected.

    If I turn transposed off, everything works fine.

    opened by janwol 1
  • Boxplot in Graphic

    Boxplot in Graphic

    Good afternoon, I hope you're having a good day.

    Just to say that a box plot would be great in the library. Is it expected to develop in the future?

    Thanks for your time!

    opened by NUR-IA 0
  • Rebuilding chart resets coord ranges / zoom levels

    Rebuilding chart resets coord ranges / zoom levels

    When rebuilding the chart (to update the tick count upon zooming), the zoom levels get reset to the initial values, instead of keeping the zoom state after zooming. In my opinion, the current zoom should be maintained in some way.

    opened by LucaCras 0
  • chart点击事件的相关疑问

    chart点击事件的相关疑问

    1. GestureType 是否会实现MoveUpdate响应?无需长按而移动更新。
    2. CrosshairGuide 中 followPointer 设置为 [false, false] 时,长按点击移动时,十字光标存在延迟。
    3. crosshair 支持在曲线图上标注点击时的数据点吗,可以注明点击时数据的位置。
    opened by liumuchengyun 1
Releases(v1.0.0)
  • v1.0.0(Nov 1, 2022)

    • Graphic has finished initial development and ready for production from this version. The API will be stable while a new major version begins in the design.
    • Add size to tooltip renderer function: https://github.com/entronad/graphic/pull/159
    Source code(tar.gz)
    Source code(zip)
  • v0.10.7(Sep 19, 2022)

  • v0.10.6(Jul 22, 2022)

  • v0.10.5(Jun 7, 2022)

    • Fix the bug that GeomElement.selected dosen't work.
    • Fix: handle big numbers when calculating nice range/numbers: https://github.com/entronad/graphic/pull/107
    Source code(tar.gz)
    Source code(zip)
  • v0.10.4(May 20, 2022)

    • Remove _mouseIsConnected checking from chart widget state.
    • Expose linearNiceRange and linearNiceNumbers algorithms: https://github.com/entronad/graphic/pull/105
    Source code(tar.gz)
    Source code(zip)
  • v0.10.3(May 2, 2022)

  • v0.10.2(May 2, 2022)

  • v0.10.1(Apr 28, 2022)

  • v0.10.0(Apr 28, 2022)

    • Add tuple indexes in tooltip renderer: https://github.com/entronad/graphic/pull/80
    • Make modifier customizable: https://github.com/entronad/graphic/pull/88
    • Remove CustomShape. Custom shapes directly extend Shape.
    Source code(tar.gz)
    Source code(zip)
  • v0.9.4(Apr 20, 2022)

  • v0.9.3(Apr 19, 2022)

    • Fix: add key to Chart StatefulWidget: https://github.com/entronad/graphic/pull/75
    • Fix: add dispose to Chart.dart: https://github.com/entronad/graphic/pull/79
    • Add size argument to custom annotation renderer method for responsiveness: https://github.com/entronad/graphic/pull/82
    • Fix Sector corner radius bug: https://github.com/entronad/graphic/issues/58
    Source code(tar.gz)
    Source code(zip)
  • v0.9.2(Apr 5, 2022)

    • Remove tooltip on exit chart area: https://github.com/entronad/graphic/pull/63
    • Handle NaN in Point shape: https://github.com/entronad/graphic/pull/70
    Source code(tar.gz)
    Source code(zip)
  • v0.9.1(Feb 21, 2022)

    • Allow Label.text and Scale.formatter return type to be null. For better performance, if they are null or empty string, nothing will be rendered: https://github.com/entronad/graphic/issues/51.
    • The element gradient will be constained within the coordinate region except point element: https://github.com/entronad/graphic/issues/53.
    • Fix non-gesture signal bug of signal updaters in Defaults: https://github.com/entronad/graphic/issues/52.
    Source code(tar.gz)
    Source code(zip)
  • v0.9.0(Jan 23, 2022)

    • Add Interaction Channel feature. See details in [Chart.gestureChannel], [Chart.resizeChannel], [Chart.changeDataChannel] and [Element.selectionChannel].
    • Rename updater properties.
    • Add more [LabelStyle] properties. Now it includes all properties for [TextPainter].
    • Add coordinate region background.
    • Fix auto scale bug when all values are 0.
    Source code(tar.gz)
    Source code(zip)
  • v0.8.0(Jan 8, 2022)

    • Upgrade the tick nice numbers algorithm and API.
    • Optimize radical axis label alignment.
    • Forced data operator equalValue method to false so that modifying the data list instance can trigger evaluation: https://github.com/entronad/graphic/issues/43.
    Source code(tar.gz)
    Source code(zip)
  • v0.7.0(Dec 28, 2021)

    • Dimensions now has a enum type Dim instead of int [1, 2], which is always confused with [0, 1]: https://github.com/entronad/graphic/issues/31.
    • layer now replace zIndex, which may confuse with z dimension and has a flavour of HTML.
    • Fix ScaleUpdateDetails.delta problem.
    • Fix resize problem. Now chart will resize properly and will inflate even if parent has no indicated size: https://github.com/entronad/graphic/issues/37.
    • Fix and recover the auto spec diff feature.
    • Add dash line feature.
    Source code(tar.gz)
    Source code(zip)
  • v0.6.2(Dec 19, 2021)

    • Fix the issue of CustomAnnotation: https://github.com/entronad/graphic/issues/33.
    • Fix the auto scale range when all data values are equal: https://github.com/entronad/graphic/issues/30.
    Source code(tar.gz)
    Source code(zip)
  • v0.6.1(Dec 13, 2021)

    • Fix the issue of shouldRelayout: https://github.com/entronad/graphic/issues/29.
    • Temporarily remove the auto spec diff feature. Now the default rebuild is always false.
    Source code(tar.gz)
    Source code(zip)
  • v0.6.0(Dec 11, 2021)

    • Upgrade flutter version to '>=2.6.0' for ScaleUpdate.focalPointDelta: https://github.com/entronad/graphic/issues/21.
    • The default multituples is true if a selection's variable is set.
    • Add OrdinalScale.inflate.
    • Remove the clip of figure annotation.
    • Chart.padding is a function of chart size now.
    Source code(tar.gz)
    Source code(zip)
  • v0.5.1(Dec 1, 2021)

    0.5.1

    2021-12-01

    • Tooltip constraints.
    • Now selections triggerd with same gesture is allowd.
    • Device settings of selection.
    • Now all z indexes are static, thus no need to resort scenes.
    • Some updates above are inspired by https://github.com/entronad/graphic/issues/27.
    Source code(tar.gz)
    Source code(zip)
  • v0.5.0(Nov 18, 2021)

    • Add nest operator: \ of algebra.
    • Remove GeomElement.groupBy, which is replaced by nesting.
    • Force labels always above graphics in an element.
    • Rename All function properties to nouns.
    • Fix a scale fommatter generic bug: https://github.com/entronad/graphic/issues/22.
    • Constrain flutter version to '>=2.4.0 <2.6.0' for ScaleUpdate.delta: https://github.com/entronad/graphic/issues/21.
    Source code(tar.gz)
    Source code(zip)
  • v0.4.1(Oct 27, 2021)

  • v0.4.0(Oct 26, 2021)

Owner
LIN Chen
Data visualization
LIN Chen
Flutter GraphView is used to display data in graph structures. It can display Tree layout, Directed and Layered graph. Useful for Family Tree, Hierarchy View.

GraphView Get it from | Flutter GraphView is used to display data in graph structures. It can display Tree layout, Directed and Layered graph. Useful

Nabil Mosharraf 320 Nov 20, 2022
Android GraphView is used to display data in graph structures.

GraphView Android GraphView is used to display data in graph structures. Overview The library can be used within RecyclerView and currently works with

Block & Block 988 Nov 14, 2022
In this project you will see how to generate charts with the data from the Firestore.

FlutterChartFirestore Flutter Tutorial - Flutter Charts+Firestore Video series can be watched here https://youtu.be/HGkbPrTSndM Getting Started In thi

Whatsupcoders 49 Oct 21, 2022
Stores and manages the data of your week expenses with a chart

personal_expenses_app A new Flutter project. Getting Started This project is a starting point for a Flutter application. A few resources to get you st

null 1 Dec 26, 2021
Flutter Cryptocurrency Charts application based on Clean Architecture.

About the project The purpose of this project is to develop the best Cryptocurrency, markets data and charts experience. This project has been built u

null 23 Nov 20, 2022
Charts Library for Flutter, written in Dart with Flutter.

Table of Contents New in the current release Illustration of the new "iterative auto layout" feature Autolayout step 1 Autolayout step 2 Autolayout st

Milan Zimmermann 221 Sep 13, 2022
A powerful Flutter chart library, currently supporting Line Chart, Bar Chart, Pie Chart, Scatter Chart and Radar Chart.

FL Chart ?? A library to draw fantastic charts in Flutter ?? Chart Types LineChart BarChart PieChart Read More Read More Read More ScatterChart RadarC

Iman khoshabi 5.1k Nov 23, 2022
A library to draw fantastic bar charts race in Flutter

bar_chart_race The first library to draw fantastic bar charts race in Flutter Usage Let's get started add the dependencies to your app: dependencies:

Mimene Younes 6 Jun 24, 2022
Flutter chart library contains depth charts supporting various indicators and zooming

flutter_k_chart 介绍 一个仿火币的flutter图表库包含深度图,支持各种指标及放大缩小、平移等操作 webdemo演示 Demo v0.1.0:下载 APK 演示 简单用例 1.在 pubspec.yaml 中添加依赖 本项目数据来自火币openApi,火币的接口可能需要翻墙,接口

gwh 257 Oct 21, 2022
A powerful 🚀 Android chart view / graph view library, supporting line- bar- pie- radar- bubble- and candlestick charts as well as scaling, panning and animations.

⚡ A powerful & easy to use chart library for Android ⚡ Charts is the iOS version of this library Table of Contents Quick Start Gradle Maven Documentat

Philipp Jahoda 35.8k Nov 26, 2022
kg_charts icon library. At present, there are only radar charts

kg_charts icon library. At present, there are only radar charts. Other types of charts may be added later

zhonghua 10 Oct 25, 2022
Animated radial and pie charts for Flutter

Flutter Circular Chart A library for creating animated circular chart widgets with Flutter, inspired by Zero to One with Flutter. Overview Create easi

Victor Choueiri 382 Oct 17, 2022
Beautiful sparkline charts for Flutter

flutter_sparkline Beautiful sparkline charts for Flutter. Installation Install the latest version from pub. Quick Start Import the package, create a S

Victor Choueiri 252 Sep 20, 2022
Elegant OHLC Candlestick and Trade Volume charts for @Flutter

flutter_candlesticks Elegant OHLC Candlestick and Trade Volume charts for Flutter Usage Install for Flutter with pub. Property Description data Requir

Trent Piercy 399 Nov 15, 2022
A beautiful bezier line chart widget for flutter that is highly interactive and configurable.

Bezier Chart A beautiful bezier line chart widget for flutter that is highly interactive and configurable. Features Multi bezier lines Allow numbers a

Aeyrium 424 Nov 18, 2022
A Flutter widget to use Apache ECharts (incubating) in a reactive way.

中文 [![pub](https://img.shields.io/pub/v/flutter_echarts.svg)](https://pub.dev/packages/flutter_echarts) A Flutter widget to use Apache ECharts in a re

LIN Chen 616 Nov 13, 2022
Flutter cryptocurrency UI dashboard.

?? ?? Crypto Dashboard Flutter UI Kit ?? ?? ?? ⭐️ ⭐️ ??‍?? Free Flutter UI Kits based on designs on UpLabs ?? . Watch Youtube Speed code Tutorial Here

Olayemii Garuba 69 Nov 20, 2022
A scrollable time chart in Flutter.

time_chart An amazing time chart in Flutter. Chart Types TimeChart AmountChart Getting Started 1 - Depend on it Add it to your package's pubspec.yaml

Minseong Kim 26 Oct 28, 2022
[reborned barcode_scan] A flutter plugin for reading 2D barcodes and QR codes.

Reborned ?? Original barcode_scan was discontinued, so barcode_scan2 was borned with sound null safety support ?? barcode_scan2 A flutter plugin for s

Masayuki Ono (mono) 61 Nov 22, 2022