动态更改 LineChart 的线条颜色

Posted

技术标签:

【中文标题】动态更改 LineChart 的线条颜色【英文标题】:Changing LineChart's line color dynamically 【发布时间】:2022-01-19 01:03:33 【问题描述】:

我目前正在构建一个患者跟踪应用程序,患者可以在测量时随时保存血压。根据他们输入的数据,构建了一个图表。在同一张图上,我同时显示了舒张期和收缩期。我想要的是改变图形线的颜色,如果它低于或超过阈值。例如。对于舒张期,如果它低于 60 或超过 100,我希望这条线从该点变为红色,直到输入一个介于 60-100 之间的新数据。

抱歉,如果代码难以阅读,但仍处于原型阶段。这是我当前的代码:

class Graph extends StatefulWidget 
  @override
  _GraphState createState() => _GraphState();


class _GraphState extends State<Graph> 
  final kTansiyon = [80, 70, 63, 76, 82, 90];
  final kTimes = [7, 13.6, 15.8, 17, 20, 22];
  final bTansiyon = [121, 136, 117, 120, 110, 112];
  final bTimes = [10, 11, 12, 20, 21, 22];

  List<FlSpot> createSpots(List<int> tansiyon, List<int> times) 
    List<FlSpot> retVal = [];
    if (tansiyon.length != times.length) 
      return null;
     else 
      for (int i = 0; i < tansiyon.length; i++) 
        retVal.add(FlSpot(
            times.elementAt(i).toDouble(), tansiyon.elementAt(i).toDouble()));
      
    
    return retVal;
  

  List<Color> kgradientColors = [
    const Color(0xff23b6e6),
  ];

  List<Color> bgradientColors = [Colors.grey];
  @override
  Widget build(BuildContext context) 
    return LineChart(
      LineChartData(
          minX: 0,
          minY: 0,
          maxX: 24,
          maxY: 150,
          titlesData: FlTitlesData(
            show: true,
            bottomTitles: SideTitles(
                showTitles: true,
                reservedSize: 35,
                getTextStyles: (BuildContext context, value) => const TextStyle(
                    color: Colors.grey,
                    fontWeight: FontWeight.bold,
                    fontSize: 10),
                getTitles: (value) 
                  switch (value.toInt()) 
                    case 4:
                      return '4:00';
                      break;
                    case 8:
                      return '8:00';
                      break;
                    case 12:
                      return '12:00';
                      break;
                    case 16:
                      return '16:00';
                      break;
                    case 20:
                      return '20:00';
                      break;
                    case 24:
                      return '00:00';
                      break;
                  
                  return '';
                ),
            leftTitles: SideTitles(
              showTitles: true,
              getTextStyles: (BuildContext context, value) => const TextStyle(
                  color: Colors.grey,
                  fontWeight: FontWeight.bold,
                  fontSize: 10),
              getTitles: (value) 
                if (value % 10 == 0) 
                  return '$value.toInt()';
                
                return '';
              ,
            ),
          ),
          gridData: FlGridData(
            show: false,
            drawVerticalLine: true,
            getDrawingHorizontalLine: (value) 
              return FlLine(
                color: const Color(0xff37434d),
                strokeWidth: 1,
              );
            ,
            getDrawingVerticalLine: (value) 
              return FlLine(
                color: const Color(0xff37434d),
                strokeWidth: 1,
              );
            ,
          ),
          borderData: FlBorderData(
            show: true,
            border: Border.all(color: const Color(0xff37434d), width: 1),
          ),
          lineBarsData: [
            LineChartBarData(
              spots: [
                FlSpot(9, 80),
                FlSpot(12, 77),
                FlSpot(15, 80),
                FlSpot(18, 90),
                FlSpot(21, 62),
              ],
              isCurved: true,
              colors: kgradientColors,
              barWidth: 5,
              isStrokeCapRound: true,
              dotData: FlDotData(
                show: false,
              ),
              belowBarData: BarAreaData(
                show: true,
                colors: kgradientColors
                    .map((color) => color.withOpacity(0.3))
                    .toList(),
              ),
            ),
            LineChartBarData(
              spots: [
                FlSpot(7, 120),
                FlSpot(9, 130),
                FlSpot(11, 116),
                FlSpot(22, 128),
                FlSpot(23, 123),
              ],
              isCurved: true,
              colors: bgradientColors,
              barWidth: 5,
              isStrokeCapRound: true,
              dotData: FlDotData(
                show: false,
              ),
              belowBarData: BarAreaData(
                show: true,
                colors: bgradientColors
                    .map((color) => color.withOpacity(0.3))
                    .toList(),
              ),
            ),
            LineChartBarData(
              spots: [],
              isCurved: true,
              colors: bgradientColors,
              barWidth: 5,
              isStrokeCapRound: true,
              dotData: FlDotData(
                show: false,
              ),
              belowBarData: BarAreaData(
                show: true,
                colors: bgradientColors
                    .map((color) => color.withOpacity(0.3))
                    .toList(),
              ),
            )
          ]),
    );
  

这就是它目前的样子:

graph

提前致谢。

【问题讨论】:

【参考方案1】:

所以这是其中一行的当前代码:

LineChartBarData(
  spots: [
    FlSpot(9, 80),
    FlSpot(12, 77),
    FlSpot(15, 80),
    FlSpot(18, 90),
    FlSpot(21, 62),
  ],
  isCurved: true,
  colors: kgradientColors,
  barWidth: 5,
  isStrokeCapRound: true,
  dotData: FlDotData(
    show: false,
  ),
  belowBarData: BarAreaData(
    show: true,
    colors: kgradientColors
      .map((color) => color.withOpacity(0.3))
         .toList(),
  ),
),

您需要做的第一件事是将点的占位符值分解为一个我们可以引用的变量,以确定要使用的线条颜色。

List<FlSpot> spots = [
  FlSpot(9, 80),
  FlSpot(12, 77),
  FlSpot(15, 80),
  FlSpot(18, 90),
  FlSpot(21, 62),
];

然后我们定义两个不同的颜色集,而不是kgradientColors,一个用于红线,一个用于蓝线。

List<Color> redColors = [
  Colors.red,
];

List<Color> blueColors = [
  Colors.blue,
];

然后我们可以定义一个辅助函数,根据点中的最后一个值是否在 60 到 100 之间来选择正确的颜色集:

List<Color> get lineColors => spots.last.y <= 100 && spots.last.y >= 60
    ? blueColors
    : redColors;

然后在LineChartBarData中使用:

LineChartBarData(
  spots: spots,
  isCurved: true,
  colors: lineColors,
  barWidth: 5,
  isStrokeCapRound: true,
  dotData: FlDotData(
    show: false,
  ),
  belowBarData: BarAreaData(
    show: true,
    colors: lineColors
      .map((color) => color.withOpacity(0.3))
         .toList(),
  ),
),

【讨论】:

此代码 sn-p 更改线条下方的颜色。我想自己改变线条的颜色。 LineChartBarData内有两个地方设置colors,第一个控制线条本身的颜色,第二个控制线条下方的颜色。 我会尽快尝试并通知您,非常感谢您的努力:) 我删除了 belowBarData 部分并使用了 LineChartBarData 的颜色部分,但它仍然不起作用。这条线总是蓝色的。 我意识到我可能误导了你。我想要的是改变超过阈值的部分的颜色。例如。该线在 87 处为蓝色,下一个值为 117。连接 87 和 117 的曲线中高于 100 的部分为红色。下一个值是 90。曲线在 100 之前仍然是红色的,在 100-90 之间它会再次变回蓝色。

以上是关于动态更改 LineChart 的线条颜色的主要内容,如果未能解决你的问题,请参考以下文章

Python:如果超出特定范围,是不是可以更改绘图中的线条颜色?

是否可以更改文本框下方线条/边框的颜色(条目)

无法在 MATLAB 图中更改线条颜色

如何根据列值更改线条的颜色

Eclipse Neon:如何更改所选线条的颜色?

Matplotlib - 在 hline 上方/下方更改线条颜色