Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

The touch has no response for version 0.5.0 #126

Closed
hsj86715 opened this issue Dec 5, 2019 · 5 comments
Closed

The touch has no response for version 0.5.0 #126

hsj86715 opened this issue Dec 5, 2019 · 5 comments
Labels
bug Something isn't working

Comments

@hsj86715
Copy link

hsj86715 commented Dec 5, 2019

With version 0.5.0, after debug, I found that all type of chart with the function ‘_getChartSize()’ will return a Size(infinity,infinity) in some case, this will trigger the touchCallback return a response with touchedSection null and touchedSectionIndex null. This situation looks like the touch has no response.
The custom widget:

class PieStaticsWidget extends StatefulWidget {
  final List<CountResult> staticsData;
  PieStaticsWidget(this.staticsData);
  @override
  State<StatefulWidget> createState() {
    return _PieStaticsWidgetState();
  }
}
class _PieStaticsWidgetState extends State<PieStaticsWidget> {
  int _touchIdx;
  final List<int> _shadeIdxs = List(); //记录各个色块的颜色深度
  List<MaterialColor> _colorList = List.of(Colors.primaries); //拷贝系统颜色便于打乱顺序
  List<PieChartSectionData> _staticsSections(List<CountResult> results) {
    return List.generate(results.length, (i) {
      final isTouched = i == _touchIdx;
      final double fontSize = isTouched ? 18 : 14;
      final double radius = isTouched ? 100 : 80;
      return PieChartSectionData(
          color: _colorList[i % _colorList.length]
              [colorShades[_shadeIdxs[i % _shadeIdxs.length]]],
          value: results[i].count.toDouble(),
          title: results[i].count.toString(),
          radius: radius,
          titleStyle: TextStyle(
              fontSize: fontSize,
              fontWeight: FontWeight.bold,
              color: Colors.white));
    });
  }

  @override
  void initState() {
    super.initState();
    for (int i = 0; i < widget.staticsData.length; i++) {
      _shadeIdxs.add(random.nextInt(colorShades.length));
    }
    _colorList.shuffle(random);
  }

  @override
  Widget build(BuildContext context) {
    return Row(
      crossAxisAlignment: CrossAxisAlignment.end,
      children: <Widget>[
        PieChart(PieChartData(
            pieTouchData: PieTouchData(touchCallback: (pieTouchResponse) {
              setState(() {
                if (pieTouchResponse.touchInput is FlLongPressEnd ||
                    pieTouchResponse.touchInput is FlPanEnd) {
                  _touchIdx = -1;
                } else {
                  _touchIdx = pieTouchResponse.touchedSectionIndex;
                }
              });
            }),
            borderData: FlBorderData(show: false),
            sectionsSpace: 0,
            centerSpaceRadius: 40,
            sections: _staticsSections(widget.staticsData))),
        SizedBox(width: 2),
        Column(
            crossAxisAlignment: CrossAxisAlignment.start,
            children: List.generate(widget.staticsData.length, (i) {
              final isTouched = i == _touchIdx;
              return Padding(
                  padding: EdgeInsets.symmetric(vertical: 4),
                  child: Indicator(
                      textColor: isTouched
                          ? Theme.of(context).textTheme.title.color
                          : Theme.of(context).textTheme.display1.color,
                      color: _colorList[i % _colorList.length]
                          [colorShades[_shadeIdxs[i]]],
                      text: widget.staticsData[i].name,
                      isSquare: true));
            }))
      ],
    );
  }
}

Using the widget:

class StaticsPage extends StatefulWidget {
  @override
  State<StatefulWidget> createState() {
    return _StaticsPageState();
  }
}

class _StaticsPageState extends State<StaticsPage> {
  Widget _placeHolder(String text) {
    MediaQueryData queryData = MediaQuery.of(context);
    return Container(
        alignment: Alignment.center,
        width: queryData.size.width,
        height: 300,
        child:
            Text(text, style: TextStyle(fontSize: 14, color: Theme.of(context).textTheme.display1.color)));
  }

  @override
  Widget build(BuildContext context) {
    TextStyle textStyle = TextStyle(
        fontSize: 20, fontWeight: FontWeight.bold, color: Theme.of(context).textTheme.title.color);
    return ListView(children: <Widget>[
      Center(
          child: Text(S.of(context).statics_glyph_popular, style: textStyle)),
      FutureBuilder(
          future: DataModule().staticsPopularGlyphs(limit: 10),
          builder: (context, snapshot) {
            print('Glyph Learn: $snapshot');
            if (snapshot.connectionState == ConnectionState.done) {
              if (snapshot.data == null ||
                  (snapshot.data as List<CountResult>).isEmpty) {
                return _placeHolder(S.of(context).no_data);
              } else {
                return PieStaticsWidget(snapshot.data);
              }
            } else {
              return _placeHolder("${S.of(context).splash_loading}...");
            }
          }),
      Divider(height: 1),
      SizedBox(height: 8),
      Center(child: Text(S.of(context).statics_wrong_most, style: textStyle)),
      FutureBuilder(
          future: DataModule().staticsGlyphWrongMost(),
          builder: (context, snapshot) {
            print('Glyph wrong most: $snapshot');
            if (snapshot.connectionState == ConnectionState.done) {
              if (snapshot.data == null ||
                  (snapshot.data as List<CountResult>).isEmpty) {
                return _placeHolder(S.of(context).no_data);
              } else {
                return PieStaticsWidget(snapshot.data);
              }
            } else {
              return _placeHolder("${S.of(context).splash_loading}...");
            }
          })
    ]);
  }
}
@imaNNeo
Copy link
Owner

imaNNeo commented Dec 5, 2019

Hi, may I ask you to provide me a straight forward sample?
I mean all in one file with the main() function, I can run it and fix it ASAP.
Thanks!

@imaNNeo imaNNeo added bug Something isn't working and removed bug Something isn't working labels Dec 5, 2019
@hsj86715
Copy link
Author

hsj86715 commented Dec 6, 2019

Add the dependencies in your yaml

fl_chart: ^0.5.0
english_words: ^3.1.5

Copy the follow code into a dart file in you flutter app, and pay attention on line 106 to 119. The barChart and lineChart has the same problem, this is just a pieChart simple.

import 'package:flutter/material.dart';
import 'package:fl_chart/fl_chart.dart';
import 'package:english_words/english_words.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  MyHomePage({Key key, this.title}) : super(key: key);
  final String title;

  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  List<CountResult> pie1Data = List();
  List<CountResult> pie2Data = List();

  @override
  void initState() {
    // TODO: implement initState
    super.initState();
    generateWordPairs().take(10).forEach((pair) {
      CountResult result = CountResult();
      result.name = pair.toString();
      result.count = pair.toString().length;
      pie1Data.add(result);
    });
    generateWordPairs().skip(10).take(10).forEach((pair) {
      CountResult result = CountResult();
      result.name = pair.toString();
      result.count = pair.toString().length;
      pie2Data.add(result);
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: ListView(children: <Widget>[
        Center(child: Text('Pie 1')),
        PieStaticsWidget(pie1Data),
        Divider(height: 1),
        SizedBox(height: 8),
        Center(child: Text('Pie 2')),
        PieStaticsWidget(pie2Data)
      ]),
    );
  }
}

class PieStaticsWidget extends StatefulWidget {
  final List<CountResult> staticsData;

  PieStaticsWidget(this.staticsData);

  @override
  State<StatefulWidget> createState() {
    return _PieStaticsWidgetState();
  }
}

class _PieStaticsWidgetState extends State<PieStaticsWidget> {
  int _touchIdx;

  List<PieChartSectionData> _staticsSections(List<CountResult> results) {
    return List.generate(results.length, (i) {
      final isTouched = i == _touchIdx;
      final double fontSize = isTouched ? 18 : 14;
      final double radius = isTouched ? 100 : 80;
      return PieChartSectionData(
          color: Colors.primaries[i % Colors.primaries.length][500],
          value: results[i].count.toDouble(),
          title: results[i].count.toString(),
          radius: radius,
          titleStyle: TextStyle(
              fontSize: fontSize,
              fontWeight: FontWeight.bold,
              color: Colors.white));
    });
  }

  @override
  Widget build(BuildContext context) {
    return Row(
      crossAxisAlignment: CrossAxisAlignment.end,
      children: <Widget>[
        PieChart(PieChartData(
            pieTouchData: PieTouchData(touchCallback: (pieTouchResponse) {
              print(
                  'Touch RuntimeType: ${pieTouchResponse.touchInput.runtimeType}');
              print(
                  "TouchResponse.touchedSection: ${pieTouchResponse.touchedSection}"); //print null
              print(
                  "TouchResponse.touchedSectionIndex: ${pieTouchResponse.touchedSectionIndex}"); //print null
              setState(() {
                if (pieTouchResponse.touchInput is FlLongPressEnd ||
                    pieTouchResponse.touchInput is FlPanEnd) {
                  _touchIdx = -1;
                } else {
                  _touchIdx = pieTouchResponse.touchedSectionIndex;
                }
              });
            }),
            borderData: FlBorderData(show: false),
            sectionsSpace: 0,
            centerSpaceRadius: 40,
            sections: _staticsSections(widget.staticsData))),
        SizedBox(width: 2),
        Column(
            crossAxisAlignment: CrossAxisAlignment.start,
            children: List.generate(widget.staticsData.length, (i) {
              final isTouched = i == _touchIdx;
              return Padding(
                  padding: EdgeInsets.symmetric(vertical: 4),
                  child: Indicator(
                      textColor: isTouched
                          ? Theme.of(context).textTheme.title.color
                          : Theme.of(context).textTheme.display1.color,
                      color: Colors.primaries[i % Colors.primaries.length][500],
                      text: widget.staticsData[i].name,
                      isSquare: true));
            }))
      ],
    );
  }
}

class Indicator extends StatelessWidget {
  final Color color;
  final String text;
  final bool isSquare;
  final double size;
  final double textSize;
  final Color textColor;

  const Indicator({
    Key key,
    this.color,
    this.text,
    this.isSquare,
    this.size = 16,
    this.textSize = 14,
    this.textColor = Colors.black54,
  }) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Row(
      crossAxisAlignment: CrossAxisAlignment.center,
      children: <Widget>[
        Container(
          width: size,
          height: size,
          decoration: BoxDecoration(
            shape: isSquare ? BoxShape.rectangle : BoxShape.circle,
            color: color,
          ),
        ),
        const SizedBox(width: 4),
        Text(text,
            style: TextStyle(
                fontSize: textSize,
                fontWeight: FontWeight.bold,
                color: textColor))
      ],
    );
  }
}

class CountResult extends Comparable<CountResult> {
  String _name;
  int _count;

  String get name => _name;

  set name(String value) {
    _name = value;
  }

  int get count => _count;

  set count(int value) {
    _count = value;
  }

  @override
  String toString() {
    return 'CountResult{name: $_name, count: $_count}';
  }

  @override
  bool operator ==(Object other) =>
      identical(this, other) ||
      other is CountResult &&
          runtimeType == other.runtimeType &&
          _name == other._name &&
          _count == other._count;

  @override
  int get hashCode => _name.hashCode ^ _count.hashCode;

  @override
  int compareTo(CountResult other) {
    return _count.compareTo(other._count);
  }
}

@imaNNeo
Copy link
Owner

imaNNeo commented Dec 12, 2019

Hi man.
It has just been fixed in 0.6.0, check it out and feel free to tell me if the problem still remains.
Thanks for reporting, it was a critical bug in our system.

@imaNNeo imaNNeo closed this as completed Dec 12, 2019
@hsj86715
Copy link
Author

Tks for the good project , it's usefull and beautiful.

@imaNNeo
Copy link
Owner

imaNNeo commented Dec 24, 2019

You're welcome ;)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

2 participants