imaNNeo / fl_chart

FL Chart is a highly customizable Flutter chart library that supports Line Chart, Bar Chart, Pie Chart, Scatter Chart, and Radar Chart.
https://flchart.dev
MIT License
6.85k stars 1.78k forks source link

Add gauge visualization chart to library #199

Open Spiderbezno opened 4 years ago

Spiderbezno commented 4 years ago

Would be very useful a gauge chart, with a range value, to represent a consumption usage of rate mobile or similar

imaNNeo commented 4 years ago

Not yet, but edit the title to more descriptive title, and let it be open, If it gained lot of thumbs up, we will consider it. Thanks!

ghost commented 4 years ago

Adding to the conversation, here we have a couple of designs to consider:

Gauge meter Vector - Dribbble Freebie Smart Home - Dribbble

ghost commented 4 years ago

@Spiderbezno please change the Title to something like: "Add gauge visualization chart to library".

Regards,

imaNNeo commented 4 years ago

Thanks!

imaNNeo commented 4 years ago

It is similar to our PieChart, right?

elhe26 commented 4 years ago

It is similar to our PieChart, right?

Kind of. Checking this example, the gauge viz chart has a circular shape.

Digoun commented 3 years ago

It is similar to our PieChart, right?

To add on this, a simple design could be similar to the actual PieChart but adding a custom angle, for example by passing optional parameters startAngle and endAngle.

Something similar to the way it is done in the ApexChart library in this example: https://apexcharts.com/docs/chart-types/radialbar-gauge/#custom-angle

ClecknerT commented 2 years ago

Gauges would be super useful addition!

FlorianArnould commented 2 years ago

Hi, I started working on this over the weekend, and I already have a first preview to discuss on (my fork branch here).

For the moment a full example would look like this :

GaugeChart(
  GaugeChartData(
    value: 0.7, // double in range [0, 1]
    valueColor: Colors.yellow,
    backgroundColor: Colors.orange,
    strokeWidth: 30,
    startAngle: -90, // degree as you can imagine
    endAngle: 270, // same
    strokeCap: StrokeCap.round, /// can be [StrokeCap.butt] (good looking square), [StrokeCap.round] or [StrokeCap.square] (bad looking square)
  ),
),

strokeCap

StrokeCap.butt StrokeCap.round StrokeCap.square

startAngle / endAngle

This could be simpler with startAngle / sweepAngle.

For example with : startAngle: 135, endAngle: 405, the result is : image

other parameters

It almost work like the circular progress indicator.

Not yet implemented ideas

If you have something else don't hesitate :wink:

ClecknerT commented 2 years ago

This is great. I am trying to use the kdgaugeview package which has some nice features but lacks upkeep and not a lot of customization options. I do like the alertColorArray and the inner tick marks in the stroke. I am having issues with it not updating with new values from a Firestore Stream and it is Android only.

I am not using stroke titles and putting dynamic data in the inner part of the gauge. I really like the multi-gauge idea. I have a use for this but have not found another package that can do it. Screenshot from 2022-06-21 09-00-20

ClecknerT commented 2 years ago

FlorianArnould I'd tip you if accepted them. Thanks for the quick response.

FlorianArnould commented 2 years ago

Here I have some updates : I worked bit more on this and I realized that clockwise / counter clockwise was already supported using something like startAngle: 45, endAngle: -225 (All the images below).
We will have to check if we want to keep it like this for the ticks, I made something like this (value: 0.2, tickCount: 10): image image image

I also took some time to think about the ability to think about the value color changing based on the value with something like this :

abstract class GaugeColor {
  Color getColor(double value);
}

@immutable
class SimpleGaugeColor implements GaugeColor {
  final Color color;
  const SimpleGaugeColor({required this.color});

  @override
  Color getColor(double value) => color;
}

class VariableGaugeColor implements GaugeColor {
  final List<double> limits;
  final List<Color> colors;

  VariableGaugeColor({
    required this.limits,
    required this.colors,
  }) : assert(
    colors.length - 1 == limits.length,
    'length of limits should be equals to colors length minus one'
  ) {
    assert(
      limits.reduce((a, b) => a < b ? 0 : 2) > 0,
      'the limits list should be sorted in ascending order',
    );
    assert(
      limits.first > 0 || limits.last < 1.0,
      'limits values should be in range 0, 1 (exclusive)',
    );
  }

  @override
  Color getColor(double value) {
    for (var i = 0; i < limits.length; i++) {
      if (value < limits[i]) return colors[i];
    }
    return colors.last;
  }
}

// --------------- And -----------
GaugeChart(
  GaugeChartData(
    ...
    valueColor: const SimpleGaugeColor(color: Colors.yellow),
  ),
)

GaugeChart(
  GaugeChartData(
    ...
    valueColor: VariableGaugeColor(limits: [0.5], colors: [Colors.yellow, Colors.red]),
  ),
)

Could also be interesting to have some inputs from @imaNNeoFighT on this :wink:

ClecknerT commented 2 years ago

I think this is great progress. Another possibility would be to have the ticks be the color the stroke color would change to if the value is in the range the tick mark is at the start of. Also I can see the need for tick mark size to be dynamic not sure that it is in this code.

FlorianArnould commented 2 years ago

Yes the idea is to do something similar to the lib you use with special ticks colored with VariableGaugeColor values combined with the limits and also have the ability to customize as most as possible ticks margin, size, color, etc ...

FlorianArnould commented 2 years ago

Some news, I implemented a way to configure all these settings. More than sentences to explain the ideas, there is an example. image

GaugeChartData(
  value: 0.2,
  valueColor: VariableGaugeColor(
    colors: [Colors.yellow, Colors.blue, Colors.red],
    limits: [0.35, 0.5],
  ),
  backgroundColor: Colors.orange,
  strokeWidth: 30,
  startAngle: 45,
  endAngle: -225,
  strokeCap: StrokeCap.round,
  ticks: const GaugeTicks(
    count: 11,
    color: Colors.grey,
    radius: 5,
    position: GaugeTickPosition.inner,
    margin: 5,
    showChangingColorTicks: true,
  ),
)
kyeshmz commented 1 year ago

@FlorianArnould is there really anything thats not allowing you to merge this?

FlorianArnould commented 1 year ago

Sorry it's a long time since I forgot about this. I'm going to try to finish all the bullet points previously listed as "Not yet implemented" :

Maybe for later (after a first working release) :

For now, I rebased all my work on master and restarted to implement stuff (touch support for example). Could we also have your opinion @imaNNeo about this ?

FlorianArnould commented 1 year ago

I added a bunch of tests to keep a high coverage @imaNNeo I will need a new icon for the example app : image

imaNNeo commented 1 year ago

Please use this SVG icon: (It has a white color, that's why you might not see it xD) ic_gauge_chart

Sun3 commented 8 months ago

I was looking for an update. Adding a Gauge chart would be a great addition.

Thanks

ting-dev-coder commented 8 months ago

I am looking forward to this update too!!

imaNNeo commented 7 months ago

I'm doing my best to keep the package updated, but I have a time limit to work here (as I have my full-time job). So, if you want to help, you can become a sponsor of this project here. This way, I can dedicate more time to work here.

LinschotenMelle commented 2 months ago

Any updates related to this topic?