Flutter图表绘制插件flutter_chart_csx的使用

Flutter图表绘制插件flutter_chart_csx的使用

统一设置

BaseBean 作为统一对外暴露参数定义,适用于所有基础坐标轴的参数设置(不涉及坐标轴的可以不设置,例如:饼状图,多维图)。

class BaseBean {
  // xy轴线条的高度宽度
  double xyLineWidth;
  // x轴的颜色
  Color xColor;
  // y轴的颜色
  Color yColor;
  // 顶部的辅助线
  bool isShowBorderTop;
  // 右侧的辅助线
  bool isShowBorderRight;
  // y轴左侧刻度显示,不传则没有
  List<DialStyleY> yDialValues;
  // y轴显示副刻度是在左侧还是在右侧,默认左侧
  bool isLeftYDialSub;
  // 是否显示x轴文本
  bool isShowX;
  // y轴最大值
  double yMax;
  // xy轴默认的边距,不包含周围的标注文字高度,只是xy轴的方框距离周围容器的间距
  EdgeInsets basePadding;
  // x轴辅助线
  bool isShowHintX;
  // y轴的辅助线
  bool isShowHintY;
  // 辅助线颜色
  Color hintLineColor;
  // 辅助线宽度
  double hintLineWidth;
  // 辅助线是否为虚线
  bool isHintLineImaginary;
  // 是否显示x轴刻度
  bool isShowXScale;
  // 是否显示y轴刻度
  bool isShowYScale;
  // xy轴刻度的高度
  double rulerWidth;
  // x轴的单位。默认null,不绘制单位
  UnitXY? unitX;
  // y轴的单位。默认null,不绘制单位
  UnitXY? unitY;

  BaseBean({
    this.xyLineWidth = 2,
    this.xColor = defaultColor,
    this.yColor = defaultColor,
    this.isShowBorderTop = false,
    this.isShowBorderRight = false,
    this.yDialValues,
    this.isLeftYDialSub = true,
    this.isShowX = true,
    this.yMax = 100.0,
    this.basePadding = defaultBasePadding,
    this.isShowHintX = false,
    this.isShowHintY = false,
    this.hintLineColor = defaultColor,
    this.hintLineWidth = 1.0,
    this.isHintLineImaginary = false,
    this.isShowXScale = false,
    this.isShowYScale = false,
    this.rulerWidth = 4,
    this.unitX,
    this.unitY,
  });

y轴

class DialStyleY {
  // 刻度标志内容(y轴仅适用于内容为数值类型的)
  String title;
  // y轴获取的值,只读
  double get titleValue {
    if (title == null || title.isEmpty) {
      return 0;
    } else {
      return double.parse(title);
    }
  }
  
  // 刻度标志样式
  TextStyle titleStyle;
  // 与最大数值的比率,用来计算绘制刻度的位置使用
  double positionRetioy;
  // 两个刻度之间的标注文案(y轴在该刻度下面绘制),不需要的话不设置
  String centerSubTitle;
  // 标注文案样式,centerSubTitle有内容时有效
  TextStyle centerSubTextStyle;
  DialStyleY(
      {this.title,
       this.titleStyle,
       this.centerSubTitle,
       this.centerSubTextStyle,
       this.positionRetioy});
 }

x轴

class DialStyleX {
  // 刻度标志内容
  String title;
  // 刻度标志样式
  TextStyle titleStyle;
  // 与最大数值的比率,用来计算绘制刻度的位置使用
  double positionRetioy;
  DialStyleX({this.title, this.titleStyle, this.positionRetioy});
}

单独使用方法(参数解析)

1. 柱状图

柱状图 柱状图
/// bar-circle
Widget _buildChartBarCircle(context) {
  var chartBar = ChartBar(
    // x轴刻度显示,不传则没有,均匀分布x轴
    xDialValues: [
      ChartBarBeanX(
          title: '12-02',
          value: 100,
          titleStyle: TextStyle(color: Colors.white, fontSize: 10),
          gradualColor: [Colors.yellow, Colors.yellow]),
      ChartBarBeanX(
          title: '12-03',
          value: 70,
          titleStyle: TextStyle(color: Colors.red, fontSize: 10),
          gradualColor: [Colors.green, Colors.green])
    ],
    baseBean: BaseBean(
      yDialValues: [
        DialStyleY(
            title: '100',
            titleStyle: TextStyle(color: Colors.lightBlue, fontSize: 10),
            centerSubTitle: 'Calm',
            centerSubTextStyle: TextStyle(color: Colors.red, fontSize: 10),
            positionRetioy: 100 / 100),
        DialStyleY(
            title: '65',
            titleStyle: TextStyle(color: Colors.lightBlue, fontSize: 10),
            centerSubTitle: 'Aware',
            centerSubTextStyle: TextStyle(color: Colors.red, fontSize: 10),
            positionRetioy: 65 / 100),
        DialStyleY(
            title: '35',
            titleStyle: TextStyle(color: Colors.lightBlue, fontSize: 10),
            centerSubTitle: 'Focused',
            centerSubTextStyle: TextStyle(color: Colors.red, fontSize: 10),
            positionRetioy: 35 / 100)
      ],
      yMax: 100.0,
    ),
    size: Size(
        MediaQuery.of(context).size.width,
        MediaQuery.of(context).size.height / 5 * 1.8),
    // 柱状图的宽度,如果小的话按照这个显示,如果过于宽,则按照平均宽度减去最小间距5得出的宽度
    rectWidth: 50.0,
    duration: Duration(seconds: 2),
    // 柱体四周圆角,默认没有圆角
    borderRadius: BorderRadius.only(
        topLeft: Radius.circular(50), topRight: Radius.circular(50)),
  );
  return Card(
    shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(8)),
    margin: EdgeInsets.only(left: 16, right: 16, top: 8, bottom: 8),
    semanticContainer: true,
    color: Colors.blue.withOpacity(0.4),
    child: chartBar,
    clipBehavior: Clip.antiAlias,
  );
}

2. 饼状图

饼状图
/// pie
Widget _buildChartPie(context) {
  var chartPie = ChartPie(
    chartBeans: [
      ChartPieBean(
          type: '话费',
          value: 180,
          color: Colors.blueGrey,
          assistTextStyle: TextStyle(fontSize: 12, color: Colors.blueGrey)),
      ChartPieBean(
          type: '零食',
          value: 10,
          color: Colors.deepPurple,
          assistTextStyle: TextStyle(fontSize: 12, color: Colors.deepPurple)),
      ChartPieBean(
          type: '衣服',
          value: 1,
          color: Colors.green,
          assistTextStyle: TextStyle(fontSize: 12, color: Colors.green))
    ],
    // 辅助性文案显示的样式
    assistTextShowType: AssistTextShowType.OnlyName,
    // 开始画圆的位置(枚举)
    arrowBegainLocation: ArrowBegainLocation.Right,
    backgroundColor: Colors.white,
    assistBGColor: Color(0xFFF6F6F6),
    // 辅助性百分比显示的小数位数,(饼状图还是真实的比例)
    decimalDigits: 1,
    // 各个占比之间的分割线宽度,默认为0即不显示分割
    divisionWidth: 2,
    size: Size(
        MediaQuery.of(context).size.width, MediaQuery.of(context).size.width),
    // 圆盘的半径,设置太长会按照可承受(除去basebean的basepadding的限制之后)最小的宽或者高的长度的一半
    globalR: MediaQuery.of(context).size.width / 3,
    // 中心的圆半径
    centerR: 6,
    centerColor: Colors.white,
    centerWidget: Text(
      '测试中心widget',
      style: TextStyle(color: Colors.black, fontSize: 20),
    ),
  );
  return Card(
    shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(8)),
    margin: EdgeInsets.only(left: 16, right: 16, top: 8, bottom: 8),
    color: Colors.orangeAccent.withOpacity(0.6),
    clipBehavior: Clip.antiAlias,
    borderOnForeground: true,
    child: chartPie,
  );
}

3. 折线图

折线图 折线图 双折线
class _ChartLineState extends State&lt;ChartLinePage&gt; {
  ChartBeanSystem _chartLineBeanSystem;

  @override
  void initState() {
    _chartLineBeanSystem = ChartBeanSystem(
      // x轴的字体样式
      xTitleStyle: TextStyle(color: Colors.grey, fontSize: 12),
      // 是否显示x轴的文字,用来处理多个线条绘制的时候,同一x轴坐标不需要绘制多次,则只需要将多条线中一个标记绘制即可
      isDrawX: true,
      lineWidth: 2,
      // 线条点的特殊处理,如果内容不为空,则在点上面会绘制,这个是圆点半径参数
      pointRadius: 0,
      // 标记是否为曲线
      isCurve: false,
      // 点集合
      chartBeans: [
        ChartLineBean(x: '12-01', y: 30),
        ChartLineBean(x: '12-02', y: 88),
        ChartLineBean(x: '12-03', y: 20),
        ChartLineBean(x: '12-04', y: 67),
        ChartLineBean(x: '12-05', y: 10),
        ChartLineBean(x: '12-06', y: 40),
        ChartLineBean(x: '12-07', y: 10),
      ],
      // Line渐变色,从曲线到x轴从上到下的闭合颜色集
      shaderColors: [
        Colors.blue.withOpacity(0.3),
        Colors.blue.withOpacity(0.1)
      ],
      // 曲线或折线的颜色
      lineColor: Colors.red,
    );
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(ChartLinePage.title),
      ),
      body: _buildChartLine(context),
    );
  }

  /// line
  Widget _buildChartLine(context) {
    var chartLine = ChartLine(
      chartBeanSystems: [_chartLineBeanSystem],
      size: Size(
          MediaQuery.of(context).size.width,
          MediaQuery.of(context).size.height / 5 * 1.6),
      baseBean: BaseBean(
        xColor: Colors.black,
        yColor: Colors.white,
        yDialValues: [
          DialStyleY(
            title: '0',
            titleStyle: TextStyle(fontSize: 10.0, color: Colors.black),
            positionRetioy: 0 / 100.0,
          ),
          DialStyleY(
            title: '35',
            titleStyle: TextStyle(fontSize: 10.0, color: Colors.black),
            positionRetioy: 35 / 100.0,
          ),
          DialStyleY(
            title: '65',
            titleStyle: TextStyle(fontSize: 10.0, color: Colors.black),
            positionRetioy: 65 / 100.0,
          ),
          DialStyleY(
            title: '100',
            titleStyle: TextStyle(fontSize: 10.0, color: Colors.black),
            positionRetioy: 100 / 100.0,
          )
        ],
        yMax: 100,
        isShowHintX: true,
        isHintLineImaginary: true,
      ),
    );
    return Card(
      shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(8)),
      margin: EdgeInsets.only(left: 16, right: 16, top: 8, bottom: 8),
      semanticContainer: true,
      color: Colors.yellow.withOpacity(0.4),
      child: chartLine,
      clipBehavior: Clip.antiAlias,
    );
  }
}

4. 多维图

多维图 多维图 多维图
Widget _buildWidget(BuildContext context) {
  var chartLine = ChartDimensionality(
    // 维度划分的重要参数
    dimensionalityDivisions: [
      ChartBeanDimensionality(
        tip: '选择性专注力',
        tipStyle: TextStyle(color: Colors.lightBlueAccent, fontSize: 15),
      ),
      ChartBeanDimensionality(
        tip: '持续性专注力',
        tipStyle: TextStyle(color: Colors.lightBlueAccent, fontSize: 15),
      ),
      ChartBeanDimensionality(
        tip: '转换性专注力',
        tipStyle: TextStyle(color: Colors.lightBlueAccent, fontSize: 15),
      ),
      ChartBeanDimensionality(
        tip: '分配性专注力',
        tipStyle: TextStyle(color: Colors.lightBlueAccent, fontSize: 15),
      ),
      ChartBeanDimensionality(
        tip: '视觉性专注力',
        tipStyle: TextStyle(color: Colors.lightBlueAccent, fontSize: 15),
      ),
      ChartBeanDimensionality(
        tip: '玩儿呢',
        tipStyle: TextStyle(color: Colors.lightBlueAccent, fontSize: 15),
      )
    ],
    // 维度填充数据的重要内容
    dimensionalityTags: [
      DimensionalityBean(
        tagColor: Color(0xFFB1E3AD).withOpacity(0.6),
        tagTitleStyle: TextStyle(color: Color(0xFF666666), fontSize: 16.0),
        tagTitle: '初次评测',
        tagContents: [0.2, 0.4, 0.8, 1.0, 0.1, 0.5],
      ),
      DimensionalityBean(
        tagColor: Color(0xFFF88282).withOpacity(0.6),
        tagTitleStyle: TextStyle(color: Color(0xFF666666), fontSize: 16.0),
        tagTitle: '本次评测',
        tagContents: [0.8, 0.9, 0.8, 1.0, 0.7, 0.9],
      )
    ],
    size: Size(
        MediaQuery.of(context).size.width,
        MediaQuery.of(context).size.height / 5 * 1.6),
    // 背景网是否为虚线
    isDotted: false,
    // 线宽
    lineWidth: 2,
    centerR: 150,
    backgroundColor: Colors.white,
    // 线条颜色
    lineColor: Colors.blueAccent,
    // 阶层:维度图从中心到最外层有几圈
    dimensionalityNumber: 4,
  );
  return Card(
    shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(8)),
    margin: EdgeInsets.only(left: 16, right: 16, top: 8, bottom: 8),
    semanticContainer: true,
    color: Colors.green.withOpacity(0.5),
    child: chartLine,
    clipBehavior: Clip.antiAlias,
  );
}

5. 专注力曲线图

专注力曲线图 专注力曲线gif
class _FNDoubleLinePageState extends State&lt;FNDoubleLinePage&gt; {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(FNDoubleLinePage.title),
      ),
      body: ChangeNotifierProvider(
        create: (_) => ChartFocusDoubleLineProvider(),
        child: Consumer&lt;ChartFocusDoubleLineProvider&gt;(
            builder: (context, provider, child) {
          return Card(
            shape:
                RoundedRectangleBorder(borderRadius: BorderRadius.circular(8)),
            margin: EdgeInsets.only(left: 16, right: 16, top: 8, bottom: 8),
            semanticContainer: true,
            color: Colors.white,
            child: ChartLineFocus(
              size: Size(
                  MediaQuery.of(context).size.width,
                  MediaQuery.of(context).size.height / 5 * 1.6),
              // 专注力曲线的数组,数组中的每一个元素都是一条线,支持多条曲线绘制
              focusChartBeans: provider.focusChartBeanMains,
              // 这里的参数不再赘述,基础设置已介绍完备
              baseBean: BaseBean(
                isShowHintX: true,
                isShowHintY: false,
                hintLineColor: Colors.blue,
                isHintLineImaginary: false,
                isLeftYDialSub: false,
                yMax: 100.0,
                yDialValues: provider.yArr,
              ),
              xMax: 60,
              xDialValues: provider.xArr,
            ),
            clipBehavior: Clip.antiAlias,
          );
        }),
      ),
    );
  }
}

// 专注力曲线的每一条线的模型内容
class FocusChartBeanMain {
  // 数据显示点集合
  List&lt;ChartBeanFocus&gt; chartBeans;
  // 曲线或折线的颜色
  Color lineColor = Colors.lightBlueAccent;
  // 曲线或折线的线宽
  double lineWidth = 4;
  // 是否是曲线
  bool isCurve = true;
  // 是否需要触摸(针对静态图),触摸之后的显示参数在ChartLineFocus里面有设置,目前仅支持一条触摸线显示,多条线的话只显示第一条支持触摸的线的触摸
  bool touchEnable = false;
  // 是否显示占位点(每一个值的位置以空心点的形式展示,占位点的颜色目前按照y轴辅助文案的颜色显示)
  bool showSite = false;
  // 内部的渐变颜色。不设置的话默认按照解释文案的分层显示,如果设置,即为整体颜色渐变显示
  List&lt;Color&gt; gradualColors;
  // beans的时间轴如果断开,true: 是继续上一个有数值的值绘制,还是 false:断开。按照多条绘制,默认true
  bool isLinkBreak = true;
  // 结束回调
  VoidCallback canvasEnd;

  FocusChartBeanMain(
      {this.chartBeans,
      this.lineColor,
      this.lineWidth,
      this.isCurve = true,
      this.touchEnable = false,
      this.showSite = false,
      this.gradualColors,
      this.isLinkBreak,
      this.canvasEnd});
}

6. 记忆力图表游戏结果

ResultMemory(
  contentWidth: 500,
  extraJson: pic_extraJson,
  // isShow: true,
  backgroundColor: Colors.orange,
)

7. 线性指示器

线性指示器
LinearPercentIndicator(
  width: 140.0,
  lineHeight: 14.0,
  percentModel: PercentModel(
    percent: 0.7,
    fillColor: Colors.green,
  ),
  centerSet: CenterSet(
      center: Text(
    '70.0%',
    style: TextStyle(fontSize: 12.0),
  )),
  strokeCap: StrokeCap.square,
  backgroundGradient: ColorGradientModel(color: Colors.orange),
  progressGradient: ColorGradientModel(
    linearGradient: LinearGradient(
      colors: [Colors.red, Colors.blue],
    ),
  ),
)

8. 弧形指示器

弧形指示器 弧形指示器
CircularPercentIndicator(
  size: 100.0,
  percentModel: PercentModel(
    percent: 0.5,
  ),
  animationSet: AnimationSet(
    animationDuration: 2000,
  ),
  progressModel: LineModel(
    width: 10.0,
    color: Colors.red,
  ),
  backgroundModel: LineModel(
    color: Colors.orange,
  ),
  arcType: ArcType.HALF,
  center: Text(
    '40 hours',
    style: TextStyle(fontWeight: FontWeight.bold, fontSize: 14.0),
  ),
  strokeCap: StrokeCap.butt,
),

9. 常用小组件

常用小组件
// 方形选中和非选中“对勾”
CustomCheckbox(
  strokeWidth: 3,
  strokeColor: Colors.orange,
  normalBorderColor: Colors.cyan,
  fillColor: Colors.red,
  radius: 3,
  value: _checked,
  onChanged: _onChange,
),

// 圆形选中和非选中“对勾”
DoneWidget(
  outline: true,
  value: _checked,
  color: Colors.orange,
  normalBorderColor: Colors.cyan,
  onChanged: _onChange,
),

更多关于Flutter图表绘制插件flutter_chart_csx的使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter图表绘制插件flutter_chart_csx的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


当然,下面是一个关于如何使用 flutter_chart_csx 插件在 Flutter 中绘制图表的代码示例。这个示例将展示如何绘制一个简单的折线图。

首先,确保你已经在 pubspec.yaml 文件中添加了 flutter_chart_csx 依赖:

dependencies:
  flutter:
    sdk: flutter
  flutter_chart_csx: ^最新版本号  # 请替换为实际的最新版本号

然后,运行 flutter pub get 来获取依赖。

接下来,在你的 Dart 文件中使用 flutter_chart_csx 来绘制图表。以下是一个完整的示例:

import 'package:flutter/material.dart';
import 'package:flutter_chart_csx/flutter_chart_csx.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Chart Example',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: ChartExamplePage(),
    );
  }
}

class ChartExamplePage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Flutter Chart Example'),
      ),
      body: Center(
        child: Container(
          width: 300,
          height: 300,
          child: LineChart(
            data: LineChartData(
              datasets: [
                LineChartDataset(
                  label: 'Dataset 1',
                  data: [
                    LineChartDataPoint(x: 1, y: 20),
                    LineChartDataPoint(x: 2, y: 30),
                    LineChartDataPoint(x: 3, y: 40),
                    LineChartDataPoint(x: 4, y: 25),
                    LineChartDataPoint(x: 5, y: 50),
                  ],
                  borderColor: Colors.blue,
                  backgroundColor: Colors.blue.withOpacity(0.2),
                  borderWidth: 2,
                ),
              ],
            ),
          ),
        ),
      ),
    );
  }
}

// 假设 LineChart, LineChartData, LineChartDataset, LineChartDataPoint 等类已经在 flutter_chart_csx 包中定义
// 如果实际包中的类名或属性有所不同,请根据实际情况调整

解释

  1. 依赖添加:在 pubspec.yaml 中添加 flutter_chart_csx 依赖。
  2. 导入包:在 Dart 文件中导入 flutter_chart_csx 包。
  3. 构建应用:使用 MaterialAppScaffold 构建一个简单的 Flutter 应用。
  4. 绘制图表:使用 LineChart 小部件并传入 LineChartData,其中包含数据集 LineChartDataset 和数据点 LineChartDataPoint

注意

  • 确保 flutter_chart_csx 插件的最新版本和类名与示例代码一致。由于插件可能会更新,因此类名和属性可能会有所不同。
  • 如果插件的 API 有所更改,请参考插件的官方文档或源代码进行调整。

这个示例展示了如何使用 flutter_chart_csx 插件绘制一个简单的折线图。你可以根据需要进一步自定义和扩展图表的功能。

回到顶部