我有一些代码应基于Json文件返回一些图形。 在下面的示例中,我应该返回4个图,而是重新运行3个图,然后得到一个错误索引。
我不知道索引错误在哪里。
import 'dart:convert';
import 'package:charts_flutter/flutter.dart' as charts;
import 'package:flutter/material.dart';
import 'dart:async';
import 'package:http/http.dart' as http;
import 'dart:math';
class Graficos extends StatefulWidget {
@override
_GraficosState createState() => _GraficosState();
}
class _GraficosState extends State<Graficos> {
List<charts.Series> seriesList;
int qteMeses = 12;
var jsonData;
List<Widget> todosGraficos = List();
bool primeirociclo = true;
TextEditingController editingController = TextEditingController();
List<LinearSales> dados = List();
List<double> precos = List();
double menorPreco = 0;
double maiorPreco = 0;
var graficos = <Widget>[];
final myController = TextEditingController();
var staticTicks;
var duplicateItems = List<String>();
var items = List<String>();
@override
void initState() {
super.initState();
_Carregar();
}
Future<String> _Carregar() async {
primeirociclo = true;
print('local');
var response = await _funcaoJson();
if (response.length != null) {
}
return 'ok';
}
@override
Widget build(BuildContext context) {
return Container(
height: MediaQuery.of(context).size.height,
width: MediaQuery.of(context).size.width,
child: jsonData == null ?
Container() :
ListView(
padding: const EdgeInsets.all(10.0),
physics: AlwaysScrollableScrollPhysics(),
children: <Widget>[
Container(
height: MediaQuery.of(context).size.height / 10,
width: MediaQuery.of(context).size.width,
child: Row(
children: <Widget>[
Expanded(
child: TextField(
onChanged: (value) {
filterSearchResults(value);
},
controller: editingController,
decoration: InputDecoration(
labelText: "Pesquisa",
hintText: "Pesquisa",
prefixIcon: Icon(Icons.search),
border: OutlineInputBorder(
borderRadius: BorderRadius.all(
Radius.circular(25.0)))),
),
)
],
),
),
Container(
height: MediaQuery.of(context).size.height / 10,
width: MediaQuery.of(context).size.width,
child: Row(
children: <Widget>[
Expanded(
child: TextFormField(
controller: myController,
keyboardType: TextInputType.number,
decoration: new InputDecoration(
hintText: 'Quantidade de meses',
),
),
),
RaisedButton(
color: Colors.lightBlue,
child: Text('Gerar Gráfico', style: TextStyle(
fontWeight: FontWeight.bold, fontSize: 16),
),
onPressed: () async {
qteMeses = int.parse(myController.text);
await _funcaoJson();
},
),
],
),
),
ListView.builder(
shrinkWrap: true,
physics: NeverScrollableScrollPhysics(),
scrollDirection: Axis.vertical,
itemCount: jsonData['pesquisa_total'][0]['pesquisas'][0]['items'].length,
itemBuilder: (BuildContext context, int index) {
dados.clear();
precos.clear();
montaGrafico(index);
return todosGraficos[index];
},
),
]));
}
void montaGrafico(int index) {
if (jsonData['pesquisa_total'][0]['pesquisas'][0]['items'][index]['ranking'] !=null) {
for (var i = qteMeses; i >= 0; i--) {
dados.add(
LinearSales(new DateTime(int.parse(
((jsonData['pesquisa_total'][0]['pesquisas'][i]['data_publicacao'])
.toString()).split("\/")[2]), int.parse(
((jsonData['pesquisa_total'][0]['pesquisas'][i]['data_publicacao'])
.toString()).split("\/")[1]), int.parse(
((jsonData['pesquisa_total'][0]['pesquisas'][i]['data_publicacao'])
.toString()).split("\/")[0])), double.parse(
(jsonData['pesquisa_total'][0]['pesquisas'][i]['items'][index]['ranking'][0]['preco']
.toString()).replaceAll(',', '.'))),
);
precos.add(double.parse(
(jsonData['pesquisa_total'][0]['pesquisas'][i]['items'][index]['ranking'][0]['preco']
.toString()).replaceAll(',', '.')));
}
}
if (jsonData['pesquisa_total'][0]['pesquisas'][0]['items'][index]['ranking'] !=null) {
seriesList = _pegaDados(dados);
}
Widget grafico;
if (jsonData['pesquisa_total'][0]['pesquisas'][0]['items'][index]['ranking'] !=null) {
grafico = Container(
height: MediaQuery.of(context).size.height * 0.4,
width: MediaQuery.of(context).size.width * 0.7,
child: new charts.TimeSeriesChart(
seriesList,
domainAxis: new charts.DateTimeAxisSpec(
tickProviderSpec: charts.DayTickProviderSpec(increments: [30]),
),
primaryMeasureAxis: new charts.AxisSpec(
tickProviderSpec: new charts.StaticNumericTickProviderSpec(
staticTicks)),
behaviors: [
new charts.ChartTitle(
jsonData['pesquisa_total'][0]['pesquisas'][0]['items'][index]['nome_produto'].toString(),
behaviorPosition: charts.BehaviorPosition.top,
titleOutsideJustification: charts.OutsideJustification.start,
innerPadding: 18),
new charts.ChartTitle('Mes',
behaviorPosition: charts.BehaviorPosition.bottom,
titleOutsideJustification:
charts.OutsideJustification.middleDrawArea),
new charts.ChartTitle('Preço',
behaviorPosition: charts.BehaviorPosition.start,
titleOutsideJustification:
charts.OutsideJustification.middleDrawArea),
new charts.PanAndZoomBehavior(),
new charts.RangeAnnotation([
new charts.RangeAnnotationSegment(new DateTime(int.parse(
((jsonData['pesquisa_total'][0]['pesquisas'][qteMeses]['data_publicacao'])
.toString()).split("\/")[2]), int.parse(
((jsonData['pesquisa_total'][0]['pesquisas'][qteMeses]['data_publicacao'])
.toString()).split("\/")[1]), int.parse(
((jsonData['pesquisa_total'][0]['pesquisas'][qteMeses]['data_publicacao'])
.toString()).split("\/")[0])),
new DateTime.now(),
charts.RangeAnnotationAxisType.domain),
new charts.LineAnnotationSegment(
maiorPreco, charts.RangeAnnotationAxisType.measure,
endLabel: 'Maior Preco: $maiorPreco',
color: charts.MaterialPalette.gray.shade400),
new charts.LineAnnotationSegment(
menorPreco, charts.RangeAnnotationAxisType.measure,
startLabel: 'Menor preco: $menorPreco',
color: charts.MaterialPalette.gray.shade400),
]),
]),
);
} else {
grafico = Divider();
}
todosGraficos.add(grafico);
print(todosGraficos.length);
}
List<charts.Series<LinearSales, DateTime>> _pegaDados(List<LinearSales> data) {
menorPreco = precos.reduce(min);
maiorPreco = precos.reduce(max);
double tickPreco = (menorPreco - 0.2);
staticTicks = <charts.TickSpec<double>>[
new charts.TickSpec(
tickPreco,
label: tickPreco.toStringAsPrecision(3),
),
new charts.TickSpec(tickPreco + 0.2),
new charts.TickSpec(tickPreco + 0.4),
new charts.TickSpec(tickPreco + 0.6),
new charts.TickSpec(tickPreco + 0.8),
];
print(data);
dados = data;
return [
new charts.Series<LinearSales, DateTime>(
id: 'Preço',
displayName: 'Preço',
domainFn: (LinearSales sales, _) => sales.mes,
measureFn: (LinearSales sales, _) => sales.sales,
data: data,
)
];
}
Future<String> _funcaoJson() async {
/*var data = await http.get(
'http://itajuba.myscriptcase.com/scriptcase/devel/conf/grp/Procon/libraries/php/pesquisa_total.php?id=3&meses=$qteMeses&fornecedor_id=23');
*/
String httpJson = 'http://itajuba.myscriptcase.com/scriptcase/devel/conf/grp/Procon/libraries/php/pesquisa_total.php';
var response = await http.post(httpJson, body: {
'id': '3',
'meses': qteMeses.toString(),
'fornecedor_id': '23'
});
setState(() {
jsonData = jsonDecode(response.body);
});
return 'Sucesso';
}
void filterSearchResults(String query) {
List<String> dummySearchList = List<String>();
dummySearchList.addAll(duplicateItems);
if(query.isNotEmpty) {
List<String> dummyListData = List<String>();
dummySearchList.forEach((item) {
if(item.contains(query)) {
dummyListData.add(item);
}
});
setState(() {
items.clear();
items.addAll(dummyListData);
});
return;
} else {
setState(() {
items.clear();
items.addAll(duplicateItems);
});
}
}
}
class LinearSales {
final DateTime mes;
final double sales;
LinearSales(this.mes, this.sales);
}
I/flutter (32442): ══╡ EXCEPTION CAUGHT BY WIDGETS LIBRARY ╞═══════════════════════════════════════════════════════════ I/flutter (32442): The following RangeError was thrown building: I/flutter (32442): RangeError (index): Invalid value: Not in range 0..6, inclusive: 8 I/flutter (32442): I/flutter (32442): When the exception was thrown, this was the stack:
有人可以帮助我确定索引错误的地方吗?
答案 0 :(得分:0)
我发现问题出在哪里,我的后端人员本月又添加了2种产品,所以当我进入itemCount时:jsonData ['pesquisa_total'] [0] ['pesquisas'] [0] ['items' ] .length为8,但例如itemCount:jsonData ['pesquisa_total'] [0] ['pesquisas'] [4] ['items']。length为6,所以存在索引错误。