Put JSON Data in Flutter Stacked Chart

603 views Asked by At

I have try to put my JSON data in flutter Stacked Chart.

I already work on simple charts using JSON Data like bar, column, pie, Doughnut charts etc.

I have refer

  1. stacked-column-chart(syncfusion_flutter_charts),
  2. Grouped Bar Chart(charts_flutter)
  3. Stack Overflow Que-Ans

below like my API response/JSON String

 [{
        "name": "ABC",
        "subject": [{
                "name": "Math",
                "marks": "54"
            },
            {
                "name": "Physics",
                "marks": "65"
            }
        ]
    },
    {
        "name": "PQR",
        "subject": [{
                "name": "Chemistry",
                "marks": "53"
            },
            {
                "name": "Biology",
                "marks": "22"
            },
            {
                "name": "English",
                "marks": "7 "
            },
            {
                "name": "Math",
                "marks": "12"
            }
        ]
    }, {
        "name": "JKL",
        "subject": [{
                "name": "Chemistry",
                "marks": "53"
            },
            {
                "name": "Biology",
                "marks": "22"
            },
            {
                "name": "English",
                "marks": "79 "
            },
            {
                "name": "Math",
                "marks": "12"
            },
            {
                "name": "Physics",
                "marks": "72"
            }
        ]
    }
]

Or I want below type of graph using JSON Data

Wanted Stacked Graph

Note: Suggest me my JSON string is wrong, you can create your own JSON data and display the output

1

There are 1 answers

12
Dev On BEST ANSWER

Using charts_flutter. Please customize it for your usecase its a bare minimum implementation to validate that its working for your json.

   import 'package:flutter/material.dart';
import 'dart:math';
import 'package:flutter/material.dart';
import 'package:charts_flutter/flutter.dart' as charts;

import 'dart:convert';


class StackedBarChart extends StatelessWidget {

  final bool animate;

  StackedBarChart({this.animate = false});




  // EXCLUDE_FROM_GALLERY_DOCS_END

  @override
  Widget build(BuildContext context) {
    String jsonString = '[{"name":"ABC","subject":[{"name":"Math","marks":"54"},{"name":"Physics","marks":"65"}]},{"name":"PQR","subject":[{"name":"Chemistry","marks":"53"},{"name":"Biology","marks":"22"},{"name":"English","marks":"7 "},{"name":"Math","marks":"12"}]},{"name":"JKL","subject":[{"name":"Chemistry","marks":"53"},{"name":"Biology","marks":"22"},{"name":"English","marks":"79 "},{"name":"Math","marks":"12"},{"name":"Physics","marks":"72"}]}]';
    final studentMarks = studentMarksFromJson(jsonString);

    var subjects = <Subject?>{};
    var subjectsDist = <Subject?>{};
    int c=0;
    for (var stdnt in studentMarks) {
      for (var subjs in stdnt.subject) {
        if (!subjectsDist.where((element) => element?.name==subjs.name).isNotEmpty) {
          subjs.sno=c++;
          subjectsDist.add(subjs);
        }
      }
    }

    print(subjectsDist.length);

    List<List<OrdinalMarks>> SubjectData = [];
    for (var subjs in subjectsDist) {
      List<OrdinalMarks> marksData = [];
      for (var stdnt in studentMarks) {
        if (stdnt.subject
            .where((element) => element.name == subjs?.name).isNotEmpty) {
          var temp = stdnt.subject
              .where((element) => element.name == subjs?.name)
              .first;
          marksData.add(OrdinalMarks(temp.name, int.parse(temp.marks),stdnt.name));
        } else {
          marksData.add(OrdinalMarks(subjs!.name, 0,stdnt.name));
        }
      }
      SubjectData.add(marksData);
    }



    var palettes = charts.MaterialPalette.getOrderedPalettes(subjectsDist.length+2);



    int cnt=0;
    List<charts.Series<OrdinalMarks, String>> chartData = [
    ];

    for(var d in SubjectData)
      {
        chartData.add(new charts.Series<OrdinalMarks, String>(
          id: d.first.subjectName,
          domainFn: (OrdinalMarks m, _) => m.studentName,
          measureFn: (OrdinalMarks m, _) => m.marks,
          data: d,
          fillColorFn: ( subj, _) {
           // print(subj.subjectName+": subj.subjectName :" + pallets[subj.subjectName].toString()??charts.MaterialPalette.blue.shadeDefault.toString());
           return  palettes.elementAt( subjectsDist.where((element) => element?.name==subj.subjectName).first?.sno??0 ).shadeDefault; //pallets[subj.subjectName]??charts.MaterialPalette.blue.shadeDefault;
          },
          colorFn: ( subj, _) {
          //  print(subj.subjectName+": subj.subjectName :" + pallets[subj.subjectName].toString()??charts.MaterialPalette.blue.shadeDefault.toString());
            return palettes.elementAt(subjectsDist.where((element) => element?.name==subj.subjectName).first?.sno??0).shadeDefault;
          },
        ));

      }

    return Scaffold(
      // Use Obx(()=> to update Text() whenever count is changed.
        appBar: AppBar(title: Text("Chart")),

        // Replace the 8 lines Navigator.push by a simple Get.to(). You don't need context


        body:new charts.BarChart(
          chartData,
          animate: animate,
          behaviors: [new charts.SeriesLegend(showMeasures: true)],
          animationDuration: Duration(seconds: 3),



        ));
  }


}

/// Sample ordinal data type.
class OrdinalMarks {
  final String subjectName;
  final int marks;
  final String studentName;


  OrdinalMarks(this.subjectName, this.marks,this.studentName);
}


List<StudentMarks> studentMarksFromJson(String str) => List<StudentMarks>.from(json.decode(str).map((x) => StudentMarks.fromJson(x)));

String studentMarksToJson(List<StudentMarks> data) => json.encode(List<dynamic>.from(data.map((x) => x.toJson())));

class StudentMarks {
  StudentMarks({
    required this.name,
    required this.subject,
  });

  String name;
  List<Subject> subject;

  factory StudentMarks.fromJson(Map<String, dynamic> json) => StudentMarks(
    name: json["name"],
    subject: List<Subject>.from(json["subject"].map((x) => Subject.fromJson(x))),
  );

  Map<String, dynamic> toJson() => {
    "name": name,
    "subject":  List<dynamic>.from(subject.map((x) => x.toJson())),
  };
}

class Subject {
  Subject({
    required this.name,
    required this.marks,
  });

  String name;
  String marks;
  int? sno;

  factory Subject.fromJson(Map<String, dynamic> json) => Subject(
    name: json["name"],
    marks: json["marks"],
  );

  Map<String, dynamic> toJson() => {
    "name": name,
    "marks": marks,
  };
}