Compare commits
2 Commits
2e542a6c23
...
15fa17b606
Author | SHA1 | Date | |
---|---|---|---|
15fa17b606
|
|||
48c00cc1e6
|
149
lib/solver.dart
149
lib/solver.dart
@@ -7,13 +7,18 @@ import 'models/calculation_step.dart';
|
||||
|
||||
/// 帮助解析一元一次方程 ax+b=cx+d 的辅助类
|
||||
class LinearEquationParts {
|
||||
final double a, b, c, d;
|
||||
final Rational a, b, c, d;
|
||||
LinearEquationParts(this.a, this.b, this.c, this.d);
|
||||
}
|
||||
|
||||
class SolverService {
|
||||
/// 格式化数字,移除不必要的尾随零
|
||||
String _formatNumber(double value, {int precision = 4}) {
|
||||
String _formatNumber(dynamic value, {int precision = 4}) {
|
||||
if (value is Rational) {
|
||||
return _formatRational(value);
|
||||
} else if (value is FractionExpr) {
|
||||
return '\\frac{${value.numerator}}{${value.denominator}}';
|
||||
} else if (value is double) {
|
||||
String formatted = value.toStringAsFixed(precision);
|
||||
// 移除尾随的零和小数点
|
||||
formatted = formatted.replaceAll(RegExp(r'\.0+$'), '');
|
||||
@@ -22,6 +27,9 @@ class SolverService {
|
||||
formatted = formatted.substring(0, formatted.length - 1);
|
||||
}
|
||||
return formatted;
|
||||
} else {
|
||||
return value.toString();
|
||||
}
|
||||
}
|
||||
|
||||
/// 尝试对二次方程进行因式分解
|
||||
@@ -345,8 +353,8 @@ class SolverService {
|
||||
final parts = _parseLinearEquation(input, variable);
|
||||
final a = parts.a, b = parts.b, c = parts.c, d = parts.d;
|
||||
|
||||
final newA = _rationalFromDouble(a) - _rationalFromDouble(c);
|
||||
final newD = _rationalFromDouble(d) - _rationalFromDouble(b);
|
||||
final newA = a - c;
|
||||
final newD = d - b;
|
||||
|
||||
steps.add(
|
||||
CalculationStep(
|
||||
@@ -354,7 +362,15 @@ class SolverService {
|
||||
title: '移项',
|
||||
explanation: '将所有含 $variable 的项移到等式左边,常数项移到右边。',
|
||||
formula:
|
||||
'\$\$$a$variable ${c >= 0 ? '-' : '+'} ${c.abs()}$variable = $d ${b >= 0 ? '-' : '+'} ${b.abs()}\$\$',
|
||||
'\$\$${_formatNumber(a)}$variable ${_formatNumber(c) == '0'
|
||||
? ''
|
||||
: c >= Rational.zero
|
||||
? '-'
|
||||
: '+'} ${_formatNumber(c.abs())}$variable = ${_formatNumber(d)} ${_formatNumber(b) == '0'
|
||||
? ''
|
||||
: b >= Rational.zero
|
||||
? '-'
|
||||
: '+'} ${_formatNumber(b.abs())}\$\$',
|
||||
),
|
||||
);
|
||||
|
||||
@@ -364,7 +380,7 @@ class SolverService {
|
||||
title: '合并同类项',
|
||||
explanation: '合并等式两边的项。',
|
||||
formula:
|
||||
'\$\$${_formatNumber(newA.toDouble())}$variable = ${_formatNumber(newD.toDouble())}\$\$',
|
||||
'\$\$${_formatNumber(newA)}$variable = ${_formatNumber(newD)}\$\$',
|
||||
),
|
||||
);
|
||||
|
||||
@@ -380,14 +396,15 @@ class SolverService {
|
||||
CalculationStep(
|
||||
stepNumber: 3,
|
||||
title: '求解 $variable',
|
||||
explanation: '两边同时除以 $variable 的系数 ($newA)。',
|
||||
formula: '\$\$$variable = \\frac{$newD}{$newA}\$\$',
|
||||
explanation: '两边同时除以 $variable 的系数 (${_formatNumber(newA)})。',
|
||||
formula:
|
||||
'\$\$$variable = \\frac{${_formatNumber(newD)}}{${_formatNumber(newA)}}\$\$',
|
||||
),
|
||||
);
|
||||
|
||||
return CalculationResult(
|
||||
steps: steps,
|
||||
finalAnswer: '\$\$$variable = $x\$\$',
|
||||
finalAnswer: '\$\$$variable = ${_formatNumber(x)}\$\$',
|
||||
);
|
||||
}
|
||||
|
||||
@@ -801,8 +818,12 @@ class SolverService {
|
||||
final p1 = _parseTwoVariableLinear(equations[0]);
|
||||
final p2 = _parseTwoVariableLinear(equations[1]);
|
||||
|
||||
double a1 = p1[0], b1 = p1[1], c1 = p1[2];
|
||||
double a2 = p2[0], b2 = p2[1], c2 = p2[2];
|
||||
final a1Rat = _rationalFromDouble(p1[0]);
|
||||
final b1Rat = _rationalFromDouble(p1[1]);
|
||||
final c1Rat = _rationalFromDouble(p1[2]);
|
||||
final a2Rat = _rationalFromDouble(p2[0]);
|
||||
final b2Rat = _rationalFromDouble(p2[1]);
|
||||
final c2Rat = _rationalFromDouble(p2[2]);
|
||||
|
||||
steps.add(
|
||||
CalculationStep(
|
||||
@@ -813,43 +834,56 @@ class SolverService {
|
||||
'''
|
||||
\$\$
|
||||
\\begin{cases}
|
||||
${a1}x ${b1 >= 0 ? '+' : ''} ${b1}y = $c1 & (1) \\\\
|
||||
${a2}x ${b2 >= 0 ? '+' : ''} ${b2}y = $c2 & (2)
|
||||
${_formatNumber(a1Rat)}x ${_formatNumber(b1Rat) == '0'
|
||||
? ''
|
||||
: b1Rat >= Rational.zero
|
||||
? '+'
|
||||
: ''} ${_formatNumber(b1Rat)}y = ${_formatNumber(c1Rat)} & (1) \\\\
|
||||
${_formatNumber(a2Rat)}x ${_formatNumber(b2Rat) == '0'
|
||||
? ''
|
||||
: b2Rat >= Rational.zero
|
||||
? '+'
|
||||
: ''} ${_formatNumber(b2Rat)}y = ${_formatNumber(c2Rat)} & (2)
|
||||
\\end{cases}
|
||||
\$\$
|
||||
''',
|
||||
),
|
||||
);
|
||||
|
||||
final det =
|
||||
_rationalFromDouble(a1) * _rationalFromDouble(b2) -
|
||||
_rationalFromDouble(a2) * _rationalFromDouble(b1);
|
||||
final det = a1Rat * b2Rat - a2Rat * b1Rat;
|
||||
if (det == Rational.zero) {
|
||||
final infiniteCheck =
|
||||
_rationalFromDouble(a1) * _rationalFromDouble(c2) -
|
||||
_rationalFromDouble(a2) * _rationalFromDouble(c1);
|
||||
final infiniteCheck = a1Rat * c2Rat - a2Rat * c1Rat;
|
||||
return CalculationResult(
|
||||
steps: steps,
|
||||
finalAnswer: infiniteCheck == Rational.zero ? '有无穷多解' : '无解',
|
||||
);
|
||||
}
|
||||
|
||||
final newA1 = _rationalFromDouble(a1) * _rationalFromDouble(b2);
|
||||
final newC1 = _rationalFromDouble(c1) * _rationalFromDouble(b2);
|
||||
final newA2 = _rationalFromDouble(a2) * _rationalFromDouble(b1);
|
||||
final newC2 = _rationalFromDouble(c2) * _rationalFromDouble(b1);
|
||||
final newA1 = a1Rat * b2Rat;
|
||||
final newC1 = c1Rat * b2Rat;
|
||||
final newA2 = a2Rat * b1Rat;
|
||||
final newC2 = c2Rat * b1Rat;
|
||||
|
||||
steps.add(
|
||||
CalculationStep(
|
||||
stepNumber: 1,
|
||||
title: '消元',
|
||||
explanation: '为了消去变量 y,将方程(1)两边乘以 $b2,方程(2)两边乘以 $b1。',
|
||||
explanation:
|
||||
'为了消去变量 y,将方程(1)两边乘以 ${_formatNumber(b2Rat)},方程(2)两边乘以 ${_formatNumber(b1Rat)}。',
|
||||
formula:
|
||||
'''
|
||||
\$\$
|
||||
\\begin{cases}
|
||||
${_formatNumber(newA1.toDouble(), precision: 2)}x ${b1 * b2 >= 0 ? '+' : ''} ${_formatNumber((b1 * b2), precision: 2)}y = ${_formatNumber(newC1.toDouble(), precision: 2)} & (3) \\\\
|
||||
${_formatNumber(newA2.toDouble(), precision: 2)}x ${b1 * b2 >= 0 ? '+' : ''} ${_formatNumber((b1 * b2), precision: 2)}y = ${_formatNumber(newC2.toDouble(), precision: 2)} & (4)
|
||||
${_formatNumber(newA1)}x ${_formatNumber(b1Rat * b2Rat) == '0'
|
||||
? ''
|
||||
: b1Rat * b2Rat >= Rational.zero
|
||||
? '+'
|
||||
: ''} ${_formatNumber(b1Rat * b2Rat)}y = ${_formatNumber(newC1)} & (3) \\\\
|
||||
${_formatNumber(newA2)}x ${_formatNumber(b1Rat * b2Rat) == '0'
|
||||
? ''
|
||||
: b1Rat * b2Rat >= Rational.zero
|
||||
? '+'
|
||||
: ''} ${_formatNumber(b1Rat * b2Rat)}y = ${_formatNumber(newC2)} & (4)
|
||||
\\end{cases}
|
||||
\$\$
|
||||
''',
|
||||
@@ -865,7 +899,7 @@ ${_formatNumber(newA2.toDouble(), precision: 2)}x ${b1 * b2 >= 0 ? '+' : ''} ${_
|
||||
title: '相减',
|
||||
explanation: '将方程(3)减去方程(4),得到一个只含 x 的方程。',
|
||||
formula:
|
||||
'\$\$(${_formatNumber(newA1.toDouble(), precision: 2)} - ${_formatNumber(newA2.toDouble(), precision: 2)})x = ${_formatNumber(newC1.toDouble(), precision: 2)} - ${_formatNumber(newC2.toDouble(), precision: 2)} \\Rightarrow ${_formatNumber(xCoeff.toDouble(), precision: 2)}x = ${_formatNumber(constCoeff.toDouble(), precision: 2)}\$\$',
|
||||
'\$\$(${_formatNumber(newA1)} - ${_formatNumber(newA2)})x = ${_formatNumber(newC1)} - ${_formatNumber(newC2)} \\Rightarrow ${_formatNumber(xCoeff)}x = ${_formatNumber(constCoeff)}\$\$',
|
||||
),
|
||||
);
|
||||
|
||||
@@ -875,27 +909,27 @@ ${_formatNumber(newA2.toDouble(), precision: 2)}x ${b1 * b2 >= 0 ? '+' : ''} ${_
|
||||
stepNumber: 3,
|
||||
title: '解出 x',
|
||||
explanation: '求解上述方程得到 x 的值。',
|
||||
formula: '\$\$x = ${_formatNumber(x.toDouble())}\$\$',
|
||||
formula: '\$\$x = ${_formatNumber(x)}\$\$',
|
||||
),
|
||||
);
|
||||
|
||||
if (b1.abs() < 1e-9) {
|
||||
final yCoeff = b2;
|
||||
final yConst = c2 - a2 * x.toDouble();
|
||||
if (b1Rat.abs() < Rational(BigInt.from(1), BigInt.from(1000000000))) {
|
||||
final yCoeff = b2Rat;
|
||||
final yConst = c2Rat - a2Rat * x;
|
||||
final y = yConst / yCoeff;
|
||||
steps.add(
|
||||
CalculationStep(
|
||||
stepNumber: 4,
|
||||
title: '回代求解 y',
|
||||
explanation: '将 x = ${_formatNumber(x.toDouble())} 代入原方程(2)中。',
|
||||
explanation: '将 x = ${_formatNumber(x)} 代入原方程(2)中。',
|
||||
formula:
|
||||
'''
|
||||
\$\$
|
||||
\\begin{aligned}
|
||||
$a2(${_formatNumber(x.toDouble())}) + ${b2}y &= $c2 \\\\
|
||||
${a2 * x.toDouble()} + ${b2}y &= $c2 \\\\
|
||||
${b2}y &= $c2 - ${a2 * x.toDouble()} \\\\
|
||||
${b2}y &= ${c2 - a2 * x.toDouble()}
|
||||
${_formatNumber(a2Rat)}(${_formatNumber(x)}) + ${_formatNumber(b2Rat)}y &= ${_formatNumber(c2Rat)} \\\\
|
||||
${_formatNumber(a2Rat * x)} + ${_formatNumber(b2Rat)}y &= ${_formatNumber(c2Rat)} \\\\
|
||||
${_formatNumber(b2Rat)}y &= ${_formatNumber(c2Rat)} - ${_formatNumber(a2Rat * x)} \\\\
|
||||
${_formatNumber(b2Rat)}y &= ${_formatNumber(c2Rat - a2Rat * x)}
|
||||
\\end{aligned}
|
||||
\$\$
|
||||
''',
|
||||
@@ -906,31 +940,31 @@ ${b2}y &= ${c2 - a2 * x.toDouble()}
|
||||
stepNumber: 5,
|
||||
title: '解出 y',
|
||||
explanation: '求解得到 y 的值。',
|
||||
formula: '\$\$y = ${_formatNumber(y.toDouble())}\$\$',
|
||||
formula: '\$\$y = ${_formatNumber(y)}\$\$',
|
||||
),
|
||||
);
|
||||
return CalculationResult(
|
||||
steps: steps,
|
||||
finalAnswer:
|
||||
'\$\$x = ${_formatNumber(x.toDouble())}, \\quad y = ${_formatNumber(y.toDouble())}\$\$',
|
||||
'\$\$x = ${_formatNumber(x)}, \\quad y = ${_formatNumber(y)}\$\$',
|
||||
);
|
||||
} else {
|
||||
final yCoeff = b1;
|
||||
final yConst = c1 - a1 * x.toDouble();
|
||||
final yCoeff = b1Rat;
|
||||
final yConst = c1Rat - a1Rat * x;
|
||||
final y = yConst / yCoeff;
|
||||
steps.add(
|
||||
CalculationStep(
|
||||
stepNumber: 4,
|
||||
title: '回代求解 y',
|
||||
explanation: '将 x = ${_formatNumber(x.toDouble())} 代入原方程(1)中。',
|
||||
explanation: '将 x = ${_formatNumber(x)} 代入原方程(1)中。',
|
||||
formula:
|
||||
'''
|
||||
\$\$
|
||||
\\begin{aligned}
|
||||
$a1(${_formatNumber(x.toDouble())}) + ${b1}y &= $c1 \\\\
|
||||
${a1 * x.toDouble()} + ${b1}y &= $c1 \\\\
|
||||
${b1}y &= $c1 - ${a1 * x.toDouble()} \\\\
|
||||
${b1}y &= ${c1 - a1 * x.toDouble()}
|
||||
${_formatNumber(a1Rat)}(${_formatNumber(x)}) + ${_formatNumber(b1Rat)}y &= ${_formatNumber(c1Rat)} \\\\
|
||||
${_formatNumber(a1Rat * x)} + ${_formatNumber(b1Rat)}y &= ${_formatNumber(c1Rat)} \\\\
|
||||
${_formatNumber(b1Rat)}y &= ${_formatNumber(c1Rat)} - ${_formatNumber(a1Rat * x)} \\\\
|
||||
${_formatNumber(b1Rat)}y &= ${_formatNumber(c1Rat - a1Rat * x)}
|
||||
\\end{aligned}
|
||||
\$\$
|
||||
''',
|
||||
@@ -941,13 +975,13 @@ ${b1}y &= ${c1 - a1 * x.toDouble()}
|
||||
stepNumber: 5,
|
||||
title: '解出 y',
|
||||
explanation: '求解得到 y 的值。',
|
||||
formula: '\$\$y = ${_formatNumber(y.toDouble())}\$\$',
|
||||
formula: '\$\$y = ${_formatNumber(y)}\$\$',
|
||||
),
|
||||
);
|
||||
return CalculationResult(
|
||||
steps: steps,
|
||||
finalAnswer:
|
||||
'\$\$x = ${_formatNumber(x.toDouble())}, \\quad y = ${_formatNumber(y.toDouble())}\$\$',
|
||||
'\$\$x = ${_formatNumber(x)}, \\quad y = ${_formatNumber(y)}\$\$',
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -1218,10 +1252,10 @@ ${b1}y &= ${c1 - a1 * x.toDouble()}
|
||||
final rightCoeffs = _parsePolynomial(parts[1], variable);
|
||||
|
||||
return LinearEquationParts(
|
||||
(leftCoeffs[1] ?? 0.0),
|
||||
(leftCoeffs[0] ?? 0.0),
|
||||
(rightCoeffs[1] ?? 0.0),
|
||||
(rightCoeffs[0] ?? 0.0),
|
||||
_rationalFromDouble(leftCoeffs[1] ?? 0.0),
|
||||
_rationalFromDouble(leftCoeffs[0] ?? 0.0),
|
||||
_rationalFromDouble(rightCoeffs[1] ?? 0.0),
|
||||
_rationalFromDouble(rightCoeffs[0] ?? 0.0),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1702,7 +1736,18 @@ ${b1}y &= ${c1 - a1 * x.toDouble()}
|
||||
/// 格式化有理数为 LaTeX 分数形式
|
||||
String _formatRational(Rational r) {
|
||||
if (r.denominator == BigInt.one) return r.numerator.toString();
|
||||
return '\\frac{${r.numerator}}{${r.denominator}}';
|
||||
|
||||
// 简化分数
|
||||
final gcd = r.numerator.gcd(r.denominator);
|
||||
final num = r.numerator ~/ gcd;
|
||||
final den = r.denominator ~/ gcd;
|
||||
|
||||
// 处理负号,将其移到分子
|
||||
if (den < BigInt.zero) {
|
||||
return '\\frac{${-num}}{${-den}}';
|
||||
}
|
||||
|
||||
return '\\frac{$num}{$den}';
|
||||
}
|
||||
|
||||
/// 从因式分解形式计算二次方程的根
|
||||
|
@@ -32,10 +32,8 @@ class _GraphCardState extends State<GraphCard> {
|
||||
double? _manualY;
|
||||
|
||||
/// 生成函数图表的点
|
||||
({List<FlSpot> leftPoints, List<FlSpot> rightPoints}) _generatePlotPoints(
|
||||
String expression,
|
||||
double zoomFactor,
|
||||
) {
|
||||
({List<FlSpot> leftPoints, List<FlSpot> rightPoints, bool shouldSplit})
|
||||
_generatePlotPoints(String expression, double zoomFactor) {
|
||||
try {
|
||||
// 使用solver准备函数表达式(展开因式形式)
|
||||
String functionExpr = _solverService.prepareFunctionForGraphing(
|
||||
@@ -44,7 +42,7 @@ class _GraphCardState extends State<GraphCard> {
|
||||
|
||||
// 如果表达式不包含 x,返回空列表
|
||||
if (!functionExpr.contains('x') && !functionExpr.contains('X')) {
|
||||
return (leftPoints: [], rightPoints: []);
|
||||
return (leftPoints: [], rightPoints: [], shouldSplit: false);
|
||||
}
|
||||
|
||||
// 预处理表达式,确保格式正确
|
||||
@@ -72,6 +70,18 @@ class _GraphCardState extends State<GraphCard> {
|
||||
final parser = Parser(functionExpr);
|
||||
final expr = parser.parse();
|
||||
|
||||
// 检查函数在 x=0 处是否有垂直渐近线
|
||||
bool hasVerticalAsymptoteAtZero = false;
|
||||
try {
|
||||
final substituted = expr.substitute('x', DoubleExpr(0.0));
|
||||
final evaluated = substituted.evaluate();
|
||||
if (evaluated is DoubleExpr) {
|
||||
hasVerticalAsymptoteAtZero = !evaluated.value.isFinite;
|
||||
}
|
||||
} catch (e) {
|
||||
hasVerticalAsymptoteAtZero = true;
|
||||
}
|
||||
|
||||
// 根据缩放因子动态调整范围和步长
|
||||
final range = 10.0 * zoomFactor;
|
||||
final step = max(0.01, 0.05 / zoomFactor); // 更小的步长以获得更好的分辨率
|
||||
@@ -79,6 +89,7 @@ class _GraphCardState extends State<GraphCard> {
|
||||
// 生成点
|
||||
List<FlSpot> leftPoints = [];
|
||||
List<FlSpot> rightPoints = [];
|
||||
List<FlSpot> allPoints = [];
|
||||
for (double i = -range; i <= range; i += step) {
|
||||
// 跳过 x = 0 以避免在 y=1/x 等函数中的奇点
|
||||
if (i.abs() < 1e-10) continue;
|
||||
@@ -91,10 +102,14 @@ class _GraphCardState extends State<GraphCard> {
|
||||
if (evaluated is DoubleExpr) {
|
||||
final y = evaluated.value;
|
||||
if (y.isFinite && y.abs() <= 100.0) {
|
||||
final spot = FlSpot(i, y);
|
||||
allPoints.add(spot);
|
||||
if (hasVerticalAsymptoteAtZero) {
|
||||
if (i < 0) {
|
||||
leftPoints.add(FlSpot(i, y));
|
||||
leftPoints.add(spot);
|
||||
} else {
|
||||
rightPoints.add(FlSpot(i, y));
|
||||
rightPoints.add(spot);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -104,17 +119,30 @@ class _GraphCardState extends State<GraphCard> {
|
||||
}
|
||||
}
|
||||
|
||||
if (hasVerticalAsymptoteAtZero) {
|
||||
// 排序点按 x 值
|
||||
leftPoints.sort((a, b) => a.x.compareTo(b.x));
|
||||
rightPoints.sort((a, b) => a.x.compareTo(b.x));
|
||||
|
||||
debugPrint(
|
||||
'Generated ${leftPoints.length} left dots and ${rightPoints.length} right dots with zoom factor $zoomFactor',
|
||||
'Generated ${leftPoints.length} left dots and ${rightPoints.length} right dots with zoom factor $zoomFactor (split due to asymptote)',
|
||||
);
|
||||
return (leftPoints: leftPoints, rightPoints: rightPoints);
|
||||
return (
|
||||
leftPoints: leftPoints,
|
||||
rightPoints: rightPoints,
|
||||
shouldSplit: true,
|
||||
);
|
||||
} else {
|
||||
// 不需要分割,直接返回所有点
|
||||
allPoints.sort((a, b) => a.x.compareTo(b.x));
|
||||
debugPrint(
|
||||
'Generated ${allPoints.length} dots with zoom factor $zoomFactor (no split)',
|
||||
);
|
||||
return (leftPoints: allPoints, rightPoints: [], shouldSplit: false);
|
||||
}
|
||||
} catch (e) {
|
||||
debugPrint('Error generating plot points: $e');
|
||||
return (leftPoints: [], rightPoints: []);
|
||||
return (leftPoints: [], rightPoints: [], shouldSplit: false);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -280,7 +308,11 @@ class _GraphCardState extends State<GraphCard> {
|
||||
height: 340,
|
||||
child: Builder(
|
||||
builder: (context) {
|
||||
final (:leftPoints, :rightPoints) = _generatePlotPoints(
|
||||
final (
|
||||
:leftPoints,
|
||||
:rightPoints,
|
||||
:shouldSplit,
|
||||
) = _generatePlotPoints(
|
||||
widget.expression,
|
||||
widget.zoomFactor,
|
||||
);
|
||||
@@ -383,12 +415,15 @@ class _GraphCardState extends State<GraphCard> {
|
||||
},
|
||||
),
|
||||
),
|
||||
lineBarsData: [
|
||||
lineBarsData: shouldSplit
|
||||
? [
|
||||
if (leftPoints.isNotEmpty)
|
||||
LineChartBarData(
|
||||
spots: leftPoints,
|
||||
isCurved: true,
|
||||
color: Theme.of(context).colorScheme.primary,
|
||||
color: Theme.of(
|
||||
context,
|
||||
).colorScheme.primary,
|
||||
barWidth: 3,
|
||||
belowBarData: BarAreaData(show: false),
|
||||
dotData: FlDotData(show: false),
|
||||
@@ -397,7 +432,22 @@ class _GraphCardState extends State<GraphCard> {
|
||||
LineChartBarData(
|
||||
spots: rightPoints,
|
||||
isCurved: true,
|
||||
color: Theme.of(context).colorScheme.primary,
|
||||
color: Theme.of(
|
||||
context,
|
||||
).colorScheme.primary,
|
||||
barWidth: 3,
|
||||
belowBarData: BarAreaData(show: false),
|
||||
dotData: FlDotData(show: false),
|
||||
),
|
||||
]
|
||||
: [
|
||||
if (leftPoints.isNotEmpty)
|
||||
LineChartBarData(
|
||||
spots: leftPoints,
|
||||
isCurved: true,
|
||||
color: Theme.of(
|
||||
context,
|
||||
).colorScheme.primary,
|
||||
barWidth: 3,
|
||||
belowBarData: BarAreaData(show: false),
|
||||
dotData: FlDotData(show: false),
|
||||
|
Reference in New Issue
Block a user