Flutter中如何读取assets目录下JSON数据实现折线图渲染?
Flutter 读取本地JSON绘制折线图实现步骤
1. 前置依赖配置
首先在项目pubspec.yaml中完成两项配置,配置完成后执行flutter pub get拉取依赖:
dependencies: flutter: sdk: flutter fl_chart: ^0.68.0 # 选用社区稳定维护的折线图组件库,填当前最新稳定版本即可 flutter: assets: - assets/measurelist.json # 确认本地JSON文件路径已正确声明
2. 修正现有页面的状态逻辑
你当前的loadData方法仅做了数据解析打印,没有将解析结果存入页面状态,需要先调整状态变量和数据加载逻辑,保证页面能拿到解析完成的测量数据:
class HomeState extends State<Home> { // 存储解析完成的测量数据 List<DataTitle> measureData = []; bool isLoading = true; Future loadData() async { final jsonString = await rootBundle.loadString('assets/measurelist.json'); final decodedJson = json.decode(jsonString); List<DataTitle> dataTileList = (decodedJson['measure'] as List) .map((jsonElement) => DataTitle.fromJson(jsonElement)) .toList(); // 加载完成后更新页面状态 setState(() { measureData = dataTileList; isLoading = false; }); } @override void initState() { super.initState(); loadData(); } }
3. 编写折线图渲染组件
在使用折线图组件的文件头部先引入依赖:import 'package:fl_chart/fl_chart.dart';
根据你的JSON数据结构,range_array作为横轴坐标值,force_array作为对应纵轴测量值,每个索引位对应一个坐标点。直接封装独立的折线图组件,按需配置折线样式、坐标点、坐标轴、提示框即可:
class MeasureLineChart extends StatelessWidget { final List<double> xValues; final List<double> yValues; const MeasureLineChart({super.key, required this.xValues, required this.yValues}); @override Widget build(BuildContext context) { // 组装折线点位数据 final List<FlSpot> spots = []; for(int i=0; i<xValues.length; i++){ spots.add(FlSpot(xValues[i], yValues[i])); } return Padding( padding: const EdgeInsets.all(16.0), child: LineChart( LineChartData( // 横轴范围适配数据 minX: xValues.reduce((a,b) => a<b?a:b) - 5, maxX: xValues.reduce((a,b) => a>b?a:b) + 5, // 纵轴范围适配数据 minY: 0, maxY: yValues.reduce((a,b) => a>b?a:b) + 20, // 网格线配置 gridData: const FlGridData(show: true, drawVerticalLine: true), // 图表边框配置 borderData: FlBorderData(show: true), // 坐标轴标题配置 titlesData: const FlTitlesData( topTitles: AxisTitles(sideTitles: SideTitles(showTitles: false)), rightTitles: AxisTitles(sideTitles: SideTitles(showTitles: false)), bottomTitles: AxisTitles( axisNameWidget: Text("位移值"), sideTitles: SideTitles(showTitles: true, reservedSize: 30) ), leftTitles: AxisTitles( axisNameWidget: Text("力值"), sideTitles: SideTitles(showTitles: true, reservedSize: 40) ) ), // 折线样式配置 lineBarsData: [ LineChartBarData( spots: spots, isCurved: true, color: Colors.blue, barWidth: 3, dotData: const FlDotData(show: true), ) ] ) ), ); } }
4. 整合组件到主页面
最后调整Home组件的build方法,处理加载状态,数据加载完成后传入解析好的数组渲染折线图即可:
@override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: const Text('JSON Chart'), ), body: isLoading ? const Center(child: CircularProgressIndicator()) : Center( // 默认取第一组测量数据传入图表,多组数据可用ListView循环渲染 child: MeasureLineChart( xValues: measureData.first.firstarray ?? [], yValues: measureData.first.secondarray ?? [], ) ), ); }
扩展说明:如果需要同一张图展示多组对比折线,只需要在
lineBarsData数组里追加更多LineChartBarData配置即可;折线颜色、点位大小、点击弹窗提示等效果,都可以直接在LineChartData的对应属性里调整。
内容的提问来源于stack exchange,提问作者Carlos Costa
相关产品推荐
相关产品推荐

