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.82k stars 1.77k forks source link

Horizontal Bar Charts: Can I overlay labels on top of the bars? #1434

Open SteveBraich opened 1 year ago

SteveBraich commented 1 year ago

This is a great tool!! Thank you so much for the hard work.

I am creating a dashboard in Flutter web app with multiple fl_chart widgets. I don't have a lot of real estate to spare. Currently I have four LineCharts and I'm trying to fit in a horizontal BarChart.

So, each bar contains a label that indicates what the data point is. The problem is that the bar is most often not long enough to contain the label. This causes a right overflow error. Is there any way to have the labels overlay the bars themselves and display without an overflow?

I have attached a screenshot of my BarChart. I like how it looks except for the overflow and I would like the values (not the labels) to be right justified.

LL Translate - Dashboard - LanguagePairs

I have provided the code below. I am just using static data to flesh this out.

DashboardScreen Widget:

import 'package:project/widgets/usage_chart_language_pair.dart';
import 'package:project/models/language_pair_model.dart';

class DashboardPage extends StatefulWidget 
{
    const DashboardPage({ Key? key, required this.title }) : super(key: key);

    final String title;

    @override
    State<DashboardPage> createState() => _DashboardPageState();
}

class _DashboardPageState extends State<DashboardPage> with AutomaticKeepAliveClientMixin<DashboardPage>
{  
    //  All the other widgets 

    // fl_chart: Horizontal BarChart for Language Pairs
    Row
    (
        children: const 
        [
            Text( 'Language Pairs', style: TextStyle ( color: Colors.white, fontSize: 24.0 ), ),
            Spacer(),
        ],
    ),

    const SizedBox( height: kDefaultPadding, ),

    ...languagePairs.map
    (
        (e) => UsageCharLanguagePairs
        (
            percent: e.percent,
            percentHighest: e.percentHighest,
            languagePair: e.languagePair,
        ),
    ),

    ...
}

UsageChartLanguagePair Widget

import 'package:flutter/material.dart';
import 'package:project/config/constants.dart';

class UsageChartLanguagePair extends StatelessWidget 
{
    final double percent;
    final double percentHighest;
    final String languagePair;

    const UsageChartLanguagePair
    (
        {
            Key? key,
            required this.percent,
            required this.percentHighest,
            required this.languagePair,
        }
    ) : super(key: key);

    @override
    Widget build(BuildContext context) 
    {
        return LayoutBuilder
        (
            builder: (context, constraints) 
            {
                return Container
                (
                    width: (percent / percentHighest) * constraints.maxWidth,
                    height: 30.0,
                    padding: const EdgeInsets.symmetric( horizontal: kDefaultPadding, ),
                    margin: const EdgeInsets.only(bottom: kDefaultPadding),
                    decoration: BoxDecoration
                    (
                        color: percent == percentHighest
                            ? yellowColor.withOpacity(0.5)
                            : yellowColor.withOpacity(0.2),
                        borderRadius: BorderRadius.circular(30.0),
                    ),
                    child: Row
                    (
                        mainAxisAlignment: MainAxisAlignment.spaceBetween,
                        children: 
                        [
                            Text( languagePair, style: const TextStyle( color: Colors.white, ), ),
                            Text( '$percent',   style: const TextStyle( color: yellowColor,  ), ),
                        ],
                    ),
                );
            }
        );
    }
}

LanguagePair Model Data:

class LanguagePairModel 
{
    final String languagePair;
    final double percent;
    final double percentHighest;

    LanguagePairModel
    ({
        required this.languagePair,
        required this.percent,
        required this.percentHighest,
    });
}

List<LanguagePairModel> languagePairs = 
[
    LanguagePairModel( languagePair: 'English > Spanish',      percent: 22.52, percentHighest: 22.52, ),
    LanguagePairModel( languagePair: 'Portuguese > English',   percent: 11.87, percentHighest: 22.52, ),
    LanguagePairModel( languagePair: 'Spanish (US) > English', percent: 05.59, percentHighest: 22.52, ),
    LanguagePairModel( languagePair: 'English > French',       percent: 04.77, percentHighest: 22.52, ),
    LanguagePairModel( languagePair: 'English > German',       percent: 04.34, percentHighest: 22.52, ),
    LanguagePairModel( languagePair: 'English > Korean',       percent: 3.79,  percentHighest: 22.52, ),
    LanguagePairModel( languagePair: 'English > Serbian',      percent: 2.80,  percentHighest: 22.52, ),
    LanguagePairModel( languagePair: 'Other',                  percent: 22.18, percentHighest: 22.52, ),
];

Thanks!

Steve

imaNNeo commented 11 months ago

Please provide me a reproducible code (a main.dart file content that I can run it without any other dependency. a simplified version)