Reputation: 14775
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
stacked-column-chart
(syncfusion_flutter_charts
),Grouped Bar Chart
(charts_flutter
)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
Note: Suggest me my JSON
string is wrong, you can create your own JSON
data and display the output
Upvotes: 1
Views: 679
Reputation: 6776
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,
};
}
Upvotes: 1