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

Helloi want to add a piechart to export, but it's not working, #596

Closed
atta1234 opened this issue Mar 13, 2021 · 22 comments
Closed

Helloi want to add a piechart to export, but it's not working, #596

atta1234 opened this issue Mar 13, 2021 · 22 comments
Labels
enhancement New feature or request

Comments

@atta1234
Copy link

child:pw.PieChart(
dataMap: dataMap,
animationDuration:
Duration(milliseconds: 800),
chartLegendSpacing: 32,
chartRadius:
MediaQuery.of(context).size.width /
3.2,
initialAngleInDegree: 0,
chartType: ChartType.disc,
ringStrokeWidth: 32,
legendOptions: LegendOptions(
showLegendsInRow: false,
legendPosition: LegendPosition.left,
showLegends: true,
legendTextStyle: TextStyle(
fontWeight: FontWeight.bold,
color: Colors.white,
),
),
chartValuesOptions: ChartValuesOptions(
showChartValueBackground: true,
showChartValues: true,
showChartValuesInPercentage: false,
showChartValuesOutside: false,
),
)),

@atta1234 atta1234 added enhancement New feature or request needs triage labels Mar 13, 2021
@atta1234 atta1234 changed the title Hllo i want to adda piechart to export, but it's not working, Helloi want to add a piechart to export, but it's not working, Mar 13, 2021
@DavBfr
Copy link
Owner

DavBfr commented Mar 13, 2021

Sorry, PieChart is not implemented.

@atta1234
Copy link
Author

Sorry, PieChart is not implemented.
any expectation on future update? or any direction for me to add this?

@DavBfr
Copy link
Owner

DavBfr commented Mar 13, 2021

You can add it. All the chart widgets are in this folder:
https://github.com/DavBfr/dart_pdf/tree/master/pdf/lib/src/widgets/chart

You can add a new PieChart widget here.
Some time ago, I tested a RadialGrid in this branch: https://github.com/DavBfr/dart_pdf/tree/chart-grid-radial

@atta1234
Copy link
Author

You can add it. All the chart widgets are in this folder:
https://github.com/DavBfr/dart_pdf/tree/master/pdf/lib/src/widgets/chart

You can add a new PieChart widget here.
Some time ago, I tested a RadialGrid in this branch: https://github.com/DavBfr/dart_pdf/tree/chart-grid-radial

thank you ,where to add this?

@DavBfr
Copy link
Owner

DavBfr commented Mar 13, 2021

Create a new file

@atta1234
Copy link
Author

Create a new file

please i don't know any thing about flutter packages, i just know how to install it,, please guid me with a little bit details, to support to that pichart widegt

@DavBfr
Copy link
Owner

DavBfr commented Mar 13, 2021

OK, no problem.

To facilitate, you can just work on a pie_chart.dart file in a new project, and I'll integrate it into the library.
If you want to know how to hack the library directly, I can help too.

@atta1234
Copy link
Author

OK, no problem.

To facilitate, you can just work on a pie_chart.dart file in a new project, and I'll integrate it into the library.
If you want to know how to hack the library directly, I can help too.

please, i need something in this pdf package to support that pie chart widget

@DavBfr
Copy link
Owner

DavBfr commented Mar 13, 2021

I would do something like that:

(pie_chart.dart)

import 'dart:math';

import 'package:pdf/pdf.dart';
import 'package:pdf/widgets.dart';

class PieGrid extends ChartGrid {
  PieGrid();

  late PdfRect gridBox;

  @override
  void layout(Context context, BoxConstraints constraints,
      {bool parentUsesSize = false}) {
    super.layout(context, constraints, parentUsesSize: parentUsesSize);

    final datasets = Chart.of(context).datasets;
    final size = constraints.biggest;

    gridBox = PdfRect(0, 0, size.x, size.y);

    for (final dataset in datasets) {
      assert(dataset is PieDataSet);

      dataset.layout(context, BoxConstraints.tight(gridBox.size));
      dataset.box = PdfRect.fromPoints(PdfPoint.zero, PdfPoint(size.x, size.y));

      if (dataset is PieDataSet) {
        // ToDo: Somehow calculate the real percentage of each dataset.value to calculate this
        dataset.angle = pi / 3;
      }
    }
  }

  @override
  PdfPoint toChart(PdfPoint p) {
    // ToDo: Calculate the coordinates here using sin/cos of angles
    return PdfPoint(
      p.x,
      p.y,
    );
  }

  @override
  void paint(Context context) {
    super.paint(context);

    final datasets = Chart.of(context).datasets;

    for (var dataSet in datasets) {
      dataSet.paint(context);
    }
  }
}

class PieDataSet extends Dataset {
  PieDataSet({
    required this.value,
    String? legend,
    PdfColor color = PdfColors.blue,
  }) : super(
          legend: legend,
          color: color,
        );

  final double value;

  late double angle;

  @override
  void layout(Context context, BoxConstraints constraints,
      {bool parentUsesSize = false}) {
    final size = constraints.biggest;
    box = PdfRect(0, 0, size.x, size.y);
  }

  @override
  void paint(Context context) {
    super.paint(context);

    final grid = Chart.of(context).grid;

    context.canvas
      // ToDo: draw the pie using moveTo, lineTo and bezierArc
      ..moveTo(100, 100)
      ..lineTo(10, 10)
      ..bezierArc(10, 10, 30, 30, 20, 200)
      ..lineTo(100, 100)
      ..setFillColor(color)
      ..fillPath();
  }
}

And to use it:

    pdf.addPage(
      pw.Page(
        pageFormat: PdfPageFormat.standard.landscape,
        build: (context) => pw.Chart(
          grid: PieGrid(),
          datasets: <pw.Dataset>[
            PieDataSet(legend: 'A', value: 20),
            PieDataSet(legend: 'B', value: 40),
            PieDataSet(legend: 'C', value: 30),
            PieDataSet(legend: 'D', value: 90),
          ],
        ),
      ),
    );

@atta1234
Copy link
Author

image
i have create pie_chart.dart under lib, getting two error,
The parameter type 'dynamic' is incompatible with the field type 'double'.
require. this .value and second one double late double angle Unexpected text 'late'.

@DavBfr
Copy link
Owner

DavBfr commented Mar 13, 2021

Yes, it's using Flutter 2.0 with null-safety

@atta1234
Copy link
Author

image

@DavBfr
Copy link
Owner

DavBfr commented Mar 13, 2021

Try this one, the basic is working:

import 'dart:math';

import 'package:pdf/pdf.dart';
import 'package:pdf/widgets.dart';

class PieGrid extends ChartGrid {
  PieGrid();

  late PdfRect gridBox;

  @override
  void layout(Context context, BoxConstraints constraints,
      {bool parentUsesSize = false}) {
    super.layout(context, constraints, parentUsesSize: parentUsesSize);

    final datasets = Chart.of(context).datasets;
    final size = constraints.biggest;

    gridBox = PdfRect(0, 0, size.x, size.y);

    var total = 0.0;

    for (final dataset in datasets) {
      assert(dataset is PieDataSet);

      dataset.layout(context, BoxConstraints.tight(gridBox.size));
      dataset.box = PdfRect.fromPoints(PdfPoint.zero, PdfPoint(size.x, size.y));

      if (dataset is PieDataSet) {
        total += dataset.value;
        dataset.angleStart = pi / 3;
        dataset.angleEnd = pi / 3 + pi / 6;
      }
    }

    final unit = pi / total * 2;
    var angle = 0.0;

    for (final dataset in datasets) {
      if (dataset is PieDataSet) {
        dataset.angleStart = angle;
        angle += dataset.value * unit;
        dataset.angleEnd = angle;
      }
    }
  }

  @override
  PdfPoint toChart(PdfPoint p) {
    throw UnimplementedError('Useless for pie charts');
  }

  @override
  void paint(Context context) {
    super.paint(context);

    final datasets = Chart.of(context).datasets;

    for (var dataSet in datasets) {
      dataSet.paint(context);
    }
  }
}

class PieDataSet extends Dataset {
  PieDataSet({
    required this.value,
    String? legend,
    required PdfColor color,
  }) : super(
          legend: legend,
          color: color,
        );

  final double value;

  late double angleStart;

  late double angleEnd;

  @override
  void layout(Context context, BoxConstraints constraints,
      {bool parentUsesSize = false}) {
    final size = constraints.biggest;
    box = PdfRect(0, 0, size.x, size.y);
  }

  @override
  void paint(Context context) {
    super.paint(context);

    // final grid = Chart.of(context).grid;
    final cx = box!.width / 2;
    final cy = box!.height / 2;
    final len = min(box!.width / 2, box!.height / 2);

    final sx = cx + sin(angleStart) * len;
    final sy = cy + cos(angleStart) * len;
    final ex = cx + sin(angleEnd) * len;
    final ey = cy + cos(angleEnd) * len;

    context.canvas
      ..moveTo(cx, cy)
      ..lineTo(sx, sy)
      ..bezierArc(sx, sy, len, len, ex, ey)
      ..lineTo(cx, cy)
      ..setFillColor(color)
      ..fillPath();
  }
}

@DavBfr
Copy link
Owner

DavBfr commented Mar 13, 2021

Screen Shot 2021-03-13 at 15 15 33

@atta1234
Copy link
Author

sorry i have waste a lot of your time, but still getting those two error

@atta1234
Copy link
Author

i have upgraded my flutter to latest two day ago

@DavBfr
Copy link
Owner

DavBfr commented Mar 13, 2021

You have to use this in your pubspec.yaml:

environment:
  sdk: ">=2.12.0-0 <3.0.0"

@atta1234
Copy link
Author

```yaml
  sdk: ">=2.12.0-0 <3.0.0"

ok thank you the error are gone now thanks a lot dear,,

@atta1234
Copy link
Author

but the sdk create more issue when i update, and create lot of build errors

@atta1234
Copy link
Author

Hello sir, i come up with soloution, i repaint the widegt to image,

but when i add the image now like this

pdf.addPage(pw.Page(build: (pw.Context context) {
return pw.Center(
child: pw.Image(imageInMemory),
); // Center
}));

it's giving the below error
The argument type 'Uint8List' can't be assigned to the parameter type 'PdfImage'.

@atta1234
Copy link
Author

i have created the image and displayed in container
GlobalKey _globalKey = new GlobalKey();

bool _isLoading = false;
final _formKey = GlobalKey();
final _scaffoldKey = GlobalKey();

bool inside = false;
Uint8List imageInMemory;

Future _capturePng() async {
try {
print('inside');
inside = true;
RenderRepaintBoundary boundary =
_globalKey.currentContext.findRenderObject();
ui.Image image = await boundary.toImage(pixelRatio: 6.0);
ByteData byteData =
await image.toByteData(format: ui.ImageByteFormat.png);
Uint8List pngBytes = byteData.buffer.asUint8List();
// String bs64 = base64Encode(pngBytes);
// print(pngBytes);
// print(bs64);
print('png done');
setState(() {
imageInMemory = pngBytes;
inside = false;
});
return pngBytes;
} catch (e) {
print(e);
}
}

@atta1234
Copy link
Author

Hello sir

@DavBfr DavBfr closed this as completed Mar 19, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

2 participants