550 lines
23 KiB
Dart
550 lines
23 KiB
Dart
import 'dart:math';
|
|
|
|
import 'package:fl_chart/fl_chart.dart';
|
|
import 'package:flutter/cupertino.dart';
|
|
import 'package:flutter/material.dart';
|
|
import 'package:flutter_scatter/flutter_scatter.dart';
|
|
import 'package:konectar_events/model/affiliationsmodel.dart';
|
|
import 'package:konectar_events/model/allsessionnotesmodel.dart';
|
|
import 'package:konectar_events/model/neweventsmodel.dart';
|
|
import 'package:konectar_events/model/specialtymodel.dart';
|
|
import 'package:konectar_events/utils/appcolors.dart';
|
|
import 'package:konectar_events/utils/constants.dart';
|
|
import 'package:konectar_events/viewmodel/eventsprovider.dart';
|
|
import 'package:konectar_events/viewmodel/hcpprofprovider.dart';
|
|
import 'package:konectar_events/widgets/chartline.dart';
|
|
import 'package:konectar_events/widgets/piechart.dart';
|
|
import 'package:konectar_events/widgets/word_cloud.dart';
|
|
import 'package:provider/provider.dart';
|
|
import 'package:zoom_widget/zoom_widget.dart';
|
|
|
|
class EventsInsights extends StatefulWidget {
|
|
EventsList eventsdetail;
|
|
String eventid;
|
|
String eid;
|
|
|
|
List<FlutterHashtag> kFlutterHashtags = [];
|
|
List<Specialty> specialtyList = [];
|
|
List<AllSessionNotesResponse> allSessionNotes = [];
|
|
Affiliations affiliations;
|
|
EventsInsights(
|
|
{super.key,
|
|
required this.eventsdetail,
|
|
required this.eid,
|
|
required this.eventid,
|
|
required this.kFlutterHashtags,
|
|
required this.affiliations,
|
|
required this.allSessionNotes,
|
|
required this.specialtyList});
|
|
|
|
@override
|
|
State<EventsInsights> createState() => _EventsInsightsState();
|
|
}
|
|
|
|
class _EventsInsightsState extends State<EventsInsights> {
|
|
String _value = 'My Events Insights';
|
|
|
|
int count = 0;
|
|
String wordstring = '';
|
|
bool isClientOverview = false;
|
|
Matrix4 matrix = Matrix4.identity();
|
|
|
|
@override
|
|
void initState() {
|
|
WidgetsBinding.instance.addPostFrameCallback((timeStamp) {
|
|
init();
|
|
});
|
|
|
|
super.initState();
|
|
}
|
|
|
|
init() async {
|
|
// await Provider.of<EventsProvider>(context, listen: false)
|
|
// .getAllSessionNotesFromApi(widget.eid);
|
|
setState(() {});
|
|
}
|
|
|
|
@override
|
|
void dispose() {
|
|
super.dispose();
|
|
Provider.of<EventsProvider>(context, listen: false).allSessionNotes = [];
|
|
}
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
final screenSize = MediaQuery.of(context).size;
|
|
final ratio = screenSize.width / (screenSize.height / 2);
|
|
return Consumer<EventsProvider>(
|
|
builder: (BuildContext context, provider, Widget? child) {
|
|
List<Widget> widgets = <Widget>[];
|
|
for (var i = 0; i < widget.kFlutterHashtags.length; i++) {
|
|
widgets.add(ScatterItem(widget.kFlutterHashtags[i], i));
|
|
}
|
|
return Scaffold(
|
|
backgroundColor: AppColors.bgcolor,
|
|
body: Padding(
|
|
padding: const EdgeInsets.symmetric(horizontal: 12.0),
|
|
child: SingleChildScrollView(
|
|
child: Column(
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
children: [
|
|
Container(
|
|
child: Wrap(
|
|
children: [
|
|
Padding(
|
|
padding: const EdgeInsets.only(
|
|
right: 2.0, bottom: 30, top: 10.0),
|
|
child: CupertinoSwitch(
|
|
activeColor: Color.fromARGB(255, 0, 71, 132),
|
|
value: isClientOverview,
|
|
onChanged: (value) async {
|
|
isClientOverview = value;
|
|
if (isClientOverview) {
|
|
provider.isLoadingInsights = true;
|
|
await provider.callInsightsDataForClientSpecific(
|
|
widget.eventsdetail, true);
|
|
|
|
setState(() {});
|
|
} else {
|
|
await provider.callInsightsDataForClientSpecific(
|
|
widget.eventsdetail, false);
|
|
setState(() {});
|
|
}
|
|
setState(() {});
|
|
},
|
|
),
|
|
),
|
|
Padding(
|
|
padding: const EdgeInsets.only(
|
|
right: 8.0, top: 20.0, bottom: 20),
|
|
child: !isClientOverview
|
|
? const Text(
|
|
'Client Overview',
|
|
style:
|
|
TextStyle(fontSize: 15, color: Colors.grey),
|
|
)
|
|
: const Text(
|
|
'Client Overview',
|
|
style: TextStyle(
|
|
fontSize: 15,
|
|
),
|
|
),
|
|
)
|
|
],
|
|
),
|
|
),
|
|
provider.isLoadingInsights
|
|
? Center(
|
|
child: CircularProgressIndicator(
|
|
color: AppColors.blueColor,
|
|
),
|
|
)
|
|
: _buildCharts(provider, widgets),
|
|
widget.allSessionNotes.isNotEmpty
|
|
? labelWidget("Session Notes")
|
|
: SizedBox.shrink(),
|
|
widget.allSessionNotes.isEmpty
|
|
? SizedBox.shrink()
|
|
: Card(
|
|
surfaceTintColor: Colors.white,
|
|
child: Container(
|
|
padding: EdgeInsets.all(4.0),
|
|
margin: EdgeInsets.all(4.0),
|
|
// height: screenSize.height / 3,
|
|
width: screenSize.width,
|
|
constraints: BoxConstraints(
|
|
maxHeight: widget.allSessionNotes.length > 3
|
|
? screenSize.height
|
|
: 400,
|
|
minHeight: 400),
|
|
// height: double.minPositive,
|
|
decoration: BoxDecoration(
|
|
borderRadius:
|
|
BorderRadius.all(Radius.circular(20)),
|
|
color: Colors.white,
|
|
),
|
|
child: widget.allSessionNotes.isNotEmpty
|
|
? ListView.separated(
|
|
padding: EdgeInsets.zero,
|
|
itemCount: widget.allSessionNotes.length,
|
|
itemBuilder: (context, index) {
|
|
return ExpansionTile(
|
|
initiallyExpanded: false,
|
|
shape: Border(),
|
|
expandedCrossAxisAlignment:
|
|
CrossAxisAlignment.start,
|
|
expandedAlignment: Alignment.topLeft,
|
|
childrenPadding: EdgeInsets.all(8.0),
|
|
title: Text(
|
|
"Session: ${widget.allSessionNotes[index].sessionName}",
|
|
style: TextStyle(
|
|
fontSize: 15,
|
|
fontWeight: FontWeight.bold,
|
|
)),
|
|
subtitle: Padding(
|
|
padding:
|
|
const EdgeInsets.only(top: 8.0),
|
|
child: Text(
|
|
"Speaker: ${widget.allSessionNotes[index].firstName}",
|
|
// maxLines: 3,
|
|
style: TextStyle(
|
|
// decoration: TextDecoration.underline,
|
|
// decorationColor: Colors.blue,
|
|
// //fontFamily: "SourceSerif",
|
|
//color: Colors.grey[700],
|
|
|
|
//fontWeight: FontWeight.bold,
|
|
fontSize: 14),
|
|
),
|
|
),
|
|
children: List.generate(
|
|
widget.allSessionNotes[index]
|
|
.addedBy!.length, (i) {
|
|
return Container(
|
|
padding: EdgeInsets.all(8.0),
|
|
// width: isTablet
|
|
// ? MediaQuery.of(context).size.width * 0.25
|
|
// : MediaQuery.of(context).size.width * 0.5,
|
|
child: Column(
|
|
crossAxisAlignment:
|
|
CrossAxisAlignment.start,
|
|
children: [
|
|
Text(
|
|
"\"${widget.allSessionNotes[index].notes![i]}\"",
|
|
maxLines: 3,
|
|
style: TextStyle(
|
|
// decoration: TextDecoration.underline,
|
|
// decorationColor: Colors.blue,
|
|
//fontFamily: "SourceSerif",
|
|
color: Colors.grey[900],
|
|
fontStyle:
|
|
FontStyle.italic,
|
|
fontSize: 14),
|
|
),
|
|
SizedBox(
|
|
height: 5,
|
|
),
|
|
Padding(
|
|
padding: const EdgeInsets
|
|
.symmetric(vertical: 8.0),
|
|
child: Row(
|
|
mainAxisAlignment:
|
|
MainAxisAlignment.start,
|
|
children: [
|
|
Text(
|
|
"Added by ${widget.allSessionNotes[index].addedBy![i]}",
|
|
style: TextStyle(
|
|
color: Colors
|
|
.grey[900],
|
|
fontSize: 13),
|
|
),
|
|
Text(
|
|
" On ${widget.allSessionNotes[index].createdOn![i]}",
|
|
style: TextStyle(
|
|
color: Colors
|
|
.grey[900],
|
|
fontSize: 13),
|
|
),
|
|
],
|
|
),
|
|
),
|
|
widget.allSessionNotes[index]
|
|
.addedBy!.length >
|
|
1
|
|
? (i + 1) !=
|
|
widget
|
|
.allSessionNotes[
|
|
index]
|
|
.addedBy!
|
|
.length
|
|
? Divider(
|
|
//color: Colors.grey[900],
|
|
)
|
|
: SizedBox.shrink()
|
|
: SizedBox.shrink(),
|
|
],
|
|
),
|
|
);
|
|
}),
|
|
//),
|
|
// Text(
|
|
// "Notes : ${sessionNotesList[index]}",
|
|
// maxLines: 3,
|
|
// style: TextStyle(
|
|
// // decoration: TextDecoration.underline,
|
|
// // decorationColor: Colors.blue,
|
|
// fontFamily: "SourceSerif",
|
|
// color: Colors.grey[700],
|
|
|
|
// //fontStyle: FontStyle.italic,
|
|
// fontSize: 14),
|
|
// ),
|
|
);
|
|
},
|
|
separatorBuilder:
|
|
(BuildContext context, int index) {
|
|
return Divider();
|
|
},
|
|
// separatorBuilder: (context, index) {
|
|
// return Divider();
|
|
// },
|
|
)
|
|
: Center(
|
|
child: Text("No added session notes"))),
|
|
),
|
|
],
|
|
),
|
|
),
|
|
),
|
|
);
|
|
});
|
|
}
|
|
|
|
Widget _buildCharts(EventsProvider provider, List<Widget> widgets) {
|
|
final screenSize = MediaQuery.of(context).size;
|
|
final ratio = screenSize.width / (screenSize.height / 2);
|
|
List<int> affCountList = [];
|
|
int maximum = 0;
|
|
if (widget.affiliations.affiliationCount.isNotEmpty) {
|
|
for (var obj in widget.affiliations.affiliationCount) {
|
|
affCountList.add(int.parse(obj));
|
|
}
|
|
maximum = affCountList.reduce(max);
|
|
}
|
|
|
|
return Column(
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
children: [
|
|
widgets.isNotEmpty
|
|
? labelWidget("Topics Discussed")
|
|
: SizedBox.shrink(),
|
|
widgets.isNotEmpty
|
|
? Card(
|
|
surfaceTintColor: Colors.white,
|
|
child: Container(
|
|
padding: EdgeInsets.all(2.0),
|
|
margin: EdgeInsets.all(2.0),
|
|
height: screenSize.height / 2,
|
|
width: screenSize.width,
|
|
decoration: BoxDecoration(
|
|
color: Colors.white,
|
|
borderRadius: BorderRadius.all(Radius.circular(20))),
|
|
child: Center(
|
|
// child: Zoom(
|
|
// backgroundColor: Colors.white,
|
|
// initTotalZoomOut: true,
|
|
// centerOnScale: false,
|
|
// scrollWeight: 5,
|
|
child: FittedBox(
|
|
child: Scatter(
|
|
fillGaps: true,
|
|
delegate:
|
|
ArchimedeanSpiralScatterDelegate(ratio: ratio),
|
|
children: widgets,
|
|
// ),
|
|
),
|
|
),
|
|
),
|
|
),
|
|
)
|
|
: SizedBox.shrink(),
|
|
provider.specialtyList.isEmpty
|
|
? SizedBox.shrink()
|
|
: SizedBox(
|
|
height: 20,
|
|
),
|
|
provider.specialtyList.isNotEmpty
|
|
? labelWidget("Specialty of speakers")
|
|
: SizedBox.shrink(),
|
|
provider.specialtyList.isNotEmpty
|
|
? Card(
|
|
surfaceTintColor: Colors.white,
|
|
child: Container(
|
|
padding: EdgeInsets.all(2.0),
|
|
margin: EdgeInsets.all(5.0),
|
|
height: screenSize.height / 2,
|
|
width: screenSize.width,
|
|
decoration: BoxDecoration(
|
|
borderRadius: BorderRadius.all(Radius.circular(20)),
|
|
color: Colors.white,
|
|
),
|
|
child: CustomPieChart(
|
|
specialtyList: widget.specialtyList,
|
|
),
|
|
),
|
|
)
|
|
: SizedBox.shrink(),
|
|
provider.specialtyList.isEmpty
|
|
? SizedBox.shrink()
|
|
: SizedBox(
|
|
height: 20,
|
|
),
|
|
provider.affiliations.affiliationCount.isNotEmpty
|
|
? labelWidget("Speaker counts by providers")
|
|
: SizedBox.shrink(),
|
|
provider.affiliations.affiliationCount.isNotEmpty
|
|
? Card(
|
|
surfaceTintColor: Colors.white,
|
|
child: Container(
|
|
padding: EdgeInsets.all(12.0),
|
|
// margin: EdgeInsets.all(10.0),
|
|
// height: screenSize.height / 3,
|
|
width: screenSize.width,
|
|
decoration: BoxDecoration(
|
|
borderRadius: BorderRadius.all(Radius.circular(20)),
|
|
color: Colors.white,
|
|
),
|
|
child: Column(
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
children: List.generate(
|
|
widget.affiliations.affiliationCount.length, (index) {
|
|
return ChartLine(
|
|
title: widget.affiliations.affiliationNames[index],
|
|
number: int.parse(
|
|
widget.affiliations.affiliationCount[index]),
|
|
rate: int.parse(widget.affiliations
|
|
.affiliationCount[index]) ==
|
|
maximum
|
|
? 1
|
|
: int.parse(widget
|
|
.affiliations.affiliationCount[index]) /
|
|
maximum);
|
|
}),
|
|
)),
|
|
)
|
|
: SizedBox.shrink(),
|
|
provider.specialtyList.isEmpty
|
|
? SizedBox.shrink()
|
|
: SizedBox(
|
|
height: 20,
|
|
)
|
|
],
|
|
);
|
|
}
|
|
|
|
Widget labelWidget(String title) {
|
|
return Text(
|
|
title,
|
|
style: TextStyle(
|
|
color: Colors.black,
|
|
fontWeight: FontWeight.bold,
|
|
fontSize: 17,
|
|
),
|
|
maxLines: 2,
|
|
softWrap: true,
|
|
overflow: TextOverflow.ellipsis,
|
|
);
|
|
}
|
|
|
|
Widget bargraph() {
|
|
return BarChart(BarChartData(
|
|
borderData: FlBorderData(
|
|
border: const Border(
|
|
top: BorderSide(width: 1),
|
|
right: BorderSide(width: 1),
|
|
left: BorderSide.none,
|
|
bottom: BorderSide.none,
|
|
)),
|
|
groupsSpace: 10,
|
|
barGroups: [
|
|
BarChartGroupData(
|
|
x: 1,
|
|
barRods: [
|
|
BarChartRodData(
|
|
fromY: 0, toY: 10, width: 15, color: Colors.amber),
|
|
],
|
|
groupVertically: false),
|
|
BarChartGroupData(x: 2, groupVertically: false, barRods: [
|
|
BarChartRodData(fromY: 0, toY: 10, width: 15, color: Colors.amber),
|
|
]),
|
|
BarChartGroupData(x: 3, groupVertically: false, barRods: [
|
|
BarChartRodData(fromY: 0, toY: 15, width: 15, color: Colors.amber),
|
|
]),
|
|
BarChartGroupData(x: 4, groupVertically: false, barRods: [
|
|
BarChartRodData(fromY: 0, toY: 10, width: 15, color: Colors.amber),
|
|
]),
|
|
BarChartGroupData(x: 5, groupVertically: false, barRods: [
|
|
BarChartRodData(fromY: 0, toY: 11, width: 15, color: Colors.amber),
|
|
]),
|
|
BarChartGroupData(x: 6, groupVertically: false, barRods: [
|
|
BarChartRodData(fromY: 0, toY: 10, width: 15, color: Colors.amber),
|
|
]),
|
|
BarChartGroupData(x: 7, groupVertically: false, barRods: [
|
|
BarChartRodData(fromY: 0, toY: 10, width: 15, color: Colors.amber),
|
|
]),
|
|
BarChartGroupData(x: 8, groupVertically: false, barRods: [
|
|
BarChartRodData(fromY: 0, toY: 10, width: 15, color: Colors.amber),
|
|
]),
|
|
]));
|
|
}
|
|
}
|
|
|
|
class PieChartWidget extends StatelessWidget {
|
|
final List<Sector> sectors;
|
|
|
|
const PieChartWidget(this.sectors, {Key? key}) : super(key: key);
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
return AspectRatio(
|
|
aspectRatio: 1.0,
|
|
child: PieChart(PieChartData(
|
|
sections: _chartSections(sectors),
|
|
centerSpaceRadius: 58.0,
|
|
)));
|
|
}
|
|
|
|
List<PieChartSectionData> _chartSections(List<Sector> sectors) {
|
|
final List<PieChartSectionData> list = [];
|
|
for (var sector in sectors) {
|
|
const double radius = 40.0;
|
|
final data = PieChartSectionData(
|
|
color: sector.color,
|
|
value: sector.value,
|
|
radius: radius,
|
|
title: sector.title,
|
|
);
|
|
list.add(data);
|
|
}
|
|
return list;
|
|
}
|
|
}
|
|
|
|
class SmallPieChartWidget extends StatelessWidget {
|
|
final List<Sector> sectors;
|
|
|
|
const SmallPieChartWidget(this.sectors, {Key? key}) : super(key: key);
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
return AspectRatio(
|
|
aspectRatio: 2.0,
|
|
child: PieChart(PieChartData(
|
|
sections: _chartSections(sectors),
|
|
centerSpaceRadius: 2.0,
|
|
)));
|
|
}
|
|
|
|
List<PieChartSectionData> _chartSections(List<Sector> sectors) {
|
|
final List<PieChartSectionData> list = [];
|
|
for (var sector in sectors) {
|
|
const double radius = 100.0;
|
|
final data = PieChartSectionData(
|
|
color: sector.color,
|
|
value: sector.value,
|
|
radius: radius,
|
|
title: sector.title,
|
|
);
|
|
list.add(data);
|
|
}
|
|
return list;
|
|
}
|
|
}
|
|
|
|
class Sector {
|
|
final Color color;
|
|
final double value;
|
|
final String title;
|
|
Sector({required this.color, required this.value, required this.title});
|
|
}
|