초기 커밋

This commit is contained in:
2026-03-01 07:55:59 +09:00
commit b0262d6bab
67 changed files with 4660 additions and 0 deletions

View File

@@ -0,0 +1,84 @@
import 'package:fl_chart/fl_chart.dart';
import 'package:flutter/material.dart';
class BarChartWidget extends StatelessWidget {
const BarChartWidget({
required this.barGroups,
this.title,
this.maxY,
this.bottomTitles,
this.barColor,
super.key,
});
final List<BarChartGroupData> barGroups;
final String? title;
final double? maxY;
final Widget Function(double, TitleMeta)? bottomTitles;
final Color? barColor;
@override
Widget build(BuildContext context) {
final theme = Theme.of(context);
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
if (title != null)
Padding(
padding: const EdgeInsets.only(bottom: 16),
child: Text(
title!,
style: theme.textTheme.titleMedium?.copyWith(
fontWeight: FontWeight.bold,
),
),
),
Expanded(
child: BarChart(
BarChartData(
maxY: maxY,
gridData: const FlGridData(show: false),
borderData: FlBorderData(show: false),
titlesData: FlTitlesData(
topTitles: const AxisTitles(
sideTitles: SideTitles(showTitles: false),
),
rightTitles: const AxisTitles(
sideTitles: SideTitles(showTitles: false),
),
bottomTitles: AxisTitles(
sideTitles: SideTitles(
showTitles: true,
getTitlesWidget: bottomTitles ??
(value, meta) => SideTitleWidget(
meta: meta,
child: Text(
value.toInt().toString(),
style: theme.textTheme.bodySmall,
),
),
),
),
leftTitles: AxisTitles(
sideTitles: SideTitles(
showTitles: true,
reservedSize: 40,
getTitlesWidget: (value, meta) => SideTitleWidget(
meta: meta,
child: Text(
value.toInt().toString(),
style: theme.textTheme.bodySmall,
),
),
),
),
),
barGroups: barGroups,
),
),
),
],
);
}
}

View File

@@ -0,0 +1,117 @@
import 'package:fl_chart/fl_chart.dart';
import 'package:flutter/material.dart';
class LineChartWidget extends StatelessWidget {
const LineChartWidget({
required this.spots,
this.title,
this.lineColor,
this.gradientColors,
this.minY,
this.maxY,
this.showGrid = true,
this.bottomTitles,
this.leftTitles,
super.key,
});
final List<FlSpot> spots;
final String? title;
final Color? lineColor;
final List<Color>? gradientColors;
final double? minY;
final double? maxY;
final bool showGrid;
final Widget Function(double, TitleMeta)? bottomTitles;
final Widget Function(double, TitleMeta)? leftTitles;
@override
Widget build(BuildContext context) {
final theme = Theme.of(context);
final primaryColor = lineColor ?? theme.colorScheme.primary;
final colors = gradientColors ??
[
primaryColor,
primaryColor.withValues(alpha: 0.3),
];
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
if (title != null)
Padding(
padding: const EdgeInsets.only(bottom: 16),
child: Text(
title!,
style: theme.textTheme.titleMedium?.copyWith(
fontWeight: FontWeight.bold,
),
),
),
Expanded(
child: LineChart(
LineChartData(
gridData: FlGridData(show: showGrid),
titlesData: FlTitlesData(
topTitles: const AxisTitles(
sideTitles: SideTitles(showTitles: false),
),
rightTitles: const AxisTitles(
sideTitles: SideTitles(showTitles: false),
),
bottomTitles: AxisTitles(
sideTitles: SideTitles(
showTitles: true,
getTitlesWidget: bottomTitles ??
(value, meta) => SideTitleWidget(
meta: meta,
child: Text(
value.toInt().toString(),
style: theme.textTheme.bodySmall,
),
),
),
),
leftTitles: AxisTitles(
sideTitles: SideTitles(
showTitles: true,
reservedSize: 40,
getTitlesWidget: leftTitles ??
(value, meta) => SideTitleWidget(
meta: meta,
child: Text(
value.toInt().toString(),
style: theme.textTheme.bodySmall,
),
),
),
),
),
borderData: FlBorderData(show: false),
minY: minY,
maxY: maxY,
lineBarsData: [
LineChartBarData(
spots: spots,
isCurved: true,
color: primaryColor,
barWidth: 3,
isStrokeCapRound: true,
dotData: const FlDotData(show: false),
belowBarData: BarAreaData(
show: true,
gradient: LinearGradient(
colors: colors,
begin: Alignment.topCenter,
end: Alignment.bottomCenter,
),
),
),
],
),
),
),
],
);
}
}

View File

@@ -0,0 +1,100 @@
import 'package:fl_chart/fl_chart.dart';
import 'package:flutter/material.dart';
class PieChartWidget extends StatelessWidget {
const PieChartWidget({
required this.sections,
this.title,
this.centerText,
this.showLegend = true,
this.legendItems,
super.key,
});
final List<PieChartSectionData> sections;
final String? title;
final String? centerText;
final bool showLegend;
final List<LegendItem>? legendItems;
@override
Widget build(BuildContext context) {
final theme = Theme.of(context);
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
if (title != null)
Padding(
padding: const EdgeInsets.only(bottom: 16),
child: Text(
title!,
style: theme.textTheme.titleMedium?.copyWith(
fontWeight: FontWeight.bold,
),
),
),
Expanded(
child: Row(
children: [
Expanded(
flex: 2,
child: PieChart(
PieChartData(
sections: sections,
centerSpaceRadius: 40,
sectionsSpace: 2,
),
),
),
if (showLegend && legendItems != null)
Expanded(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.start,
children: legendItems!
.map(
(item) => Padding(
padding: const EdgeInsets.symmetric(vertical: 4),
child: Row(
children: [
Container(
width: 12,
height: 12,
decoration: BoxDecoration(
color: item.color,
borderRadius: BorderRadius.circular(3),
),
),
const SizedBox(width: 8),
Expanded(
child: Text(
item.label,
style: theme.textTheme.bodySmall,
overflow: TextOverflow.ellipsis,
),
),
],
),
),
)
.toList(),
),
),
],
),
),
],
);
}
}
class LegendItem {
const LegendItem({
required this.label,
required this.color,
});
final String label;
final Color color;
}