chart_flutter图(Line)左右移动,横坐标支持自定义
charts_flutter: ^0.10.0先看图片要是需要柱状图支持左右滚动的可以看官方案例,若是想看中文解释的可以看这篇文章,因为有这篇文章所以我这边也只是展示部分配置文件代码。解决问题:1.支持左右滚动behaviors: [new charts.SlidingViewport(),new charts.PanAndZoomBehavior(),],//配置初始状态展示个数domainAx
·
charts_flutter: ^0.10.0
先看图片
要是需要柱状图支持左右滚动的可以看官方案例,若是想看中文解释的可以看这篇文章,因为有这篇文章所以我这边也只是展示部分配置文件代码。
解决问题:
1.支持左右滚动
behaviors: [
new charts.SlidingViewport(),
new charts.PanAndZoomBehavior(),
],
//配置初始状态展示个数
domainAxis: new charts.NumericAxisSpec(
viewport: new charts.NumericExtents(0, 6)
),
2.横坐标自定义代码
因为line 横坐标默认返回的数据是 num 类型的,我是将x轴的数据提前放到一个数组内,然后通过有序数组取出对应数据。
domainAxis: new charts.NumericAxisSpec(
charts.BasicNumericTickFormatterSpec((val) {
return "${val}点";
})),
3.自定义tooltip
目前版本应该是不支持触碰某个节点,如下图显示对应数据。不过在issues上有大佬讨论出暂时的解决方案,有兴趣的可以去看看issues 。要是显示各点数据是个特别重要的功能,还是换个插件类似fl_chart,不过这个好像是不支持左右滚动的😂😂。
完整代码
line模块我做了简单的分装还不够完善,上述的配置项位置在代码中都有体现,不过这边代码是为了本人自己寻找方便!!
import 'dart:math';
import 'package:charts_flutter/flutter.dart';
import 'package:flutter/material.dart';
import 'package:charts_flutter/src/text_element.dart' as textElement;
import 'package:charts_flutter/src/text_style.dart' as style;
import 'package:charts_flutter/flutter.dart' as charts;
import 'package:flutter/material.dart';
class ChartFlutterLine extends StatefulWidget {
final List<charts.Series> seriesList;
final bool animate;
List xAxisData; //x轴数据
int viewportCount;
ChartFlutterLine(
this.seriesList, {
this.animate,
this.xAxisData,
this.viewportCount = 6,
});
/// Creates a [LineChart] with sample data and no transition.
factory ChartFlutterLine.withSampleData(chartData) {
return new ChartFlutterLine(
_createSampleData(chartData["seriesData"]),
// Disable animations for image tests.
animate: chartData["animate"] ?? false,
xAxisData: chartData["xAxisData"],
viewportCount: chartData["viewportCount"],
);
}
/// Create one series with sample hard coded data.
static List<charts.Series<LinearSales, int>> _createSampleData(
Map<String, List<List>> seriesData) {
List<Color> colors = [
charts.MaterialPalette.blue.shadeDefault,
charts.MaterialPalette.red.shadeDefault,
charts.MaterialPalette.purple.shadeDefault,
charts.MaterialPalette.cyan.shadeDefault,
charts.MaterialPalette.yellow.shadeDefault,
charts.MaterialPalette.deepOrange.shadeDefault,
charts.MaterialPalette.lime.shadeDefault,
charts.MaterialPalette.indigo.shadeDefault,
charts.MaterialPalette.pink.shadeDefault,
charts.MaterialPalette.teal.shadeDefault,
charts.MaterialPalette.gray.shadeDefault,
];
List<charts.Series<LinearSales, int>> data = [];
List _keys = seriesData.keys.toList();
int _len = seriesData.length;
for (int i = 0; i < _len; i++) {
int _xAxisindex = 0;
List<LinearSales> itemData = [];
seriesData[_keys[i]].forEach((item) {
itemData.add(new LinearSales(index: _xAxisindex, sales: item[1]));
_xAxisindex++;
});
// print("xAxis:${xAxis}");
int _colorLen = colors.length;
data.add(new charts.Series<LinearSales, int>(
id: _keys[i],
colorFn: (_, __) => colors[i % _colorLen],
domainFn: (LinearSales sales, _) => sales.index,
measureFn: (LinearSales sales, _) => sales.sales,
data: itemData,
// keyFn: (LinearSales row, _) => '${row.sales}%',
));
}
return data;
}
@override
_ChartFlutterLineState createState() => _ChartFlutterLineState();
}
class _ChartFlutterLineState extends State<ChartFlutterLine> {
Map _data = {}; //tootlip显示数据
@override
Widget build(BuildContext context) {
return new charts.LineChart(widget.seriesList,
domainAxis: new charts.NumericAxisSpec(
viewport: new charts.NumericExtents(0, widget.viewportCount ?? 6),
tickFormatterSpec: charts.BasicNumericTickFormatterSpec((val) {
int _len = widget.xAxisData.length;
// print("widget.xAxisData:${widget.xAxisData}");
if (widget.xAxisData != null &&
_len > 0 &&
_len > val.round() &&
val.round() >= 0) {
return "${widget.xAxisData[val.round()] ?? val}";
}
return "";
})),
defaultRenderer: new charts.LineRendererConfig(
includeArea: true,
// stacked: true,
),
behaviors: [
new charts.SlidingViewport(),
new charts.PanAndZoomBehavior(),
new charts.SeriesLegend(
// horizontalFirst: false,
// desiredMaxRows: 2,
cellPadding: new EdgeInsets.only(right: 4.0, top: 1, bottom: 1),
entryTextStyle: charts.TextStyleSpec(fontSize: 10),
position: charts.BehaviorPosition.bottom),
charts.LinePointHighlighter(
symbolRenderer: CustomCircleSymbolRenderer(data: _data))
],
selectionModels: [
charts.SelectionModelConfig(
type: charts.SelectionModelType.info,
changedListener: (charts.SelectionModel model) {
if (model.hasDatumSelection) {
int _len = widget.seriesList.length;
Map _seleted = {};
for (int i = 0; i < _len; i++) {
_seleted.addAll({
widget.seriesList[i].id: widget.seriesList[i]
.measureFn(model.selectedDatum[0].index)
});
}
_data.addAll({"seleted": _seleted});
}
})
],
animate: widget.animate);
}
}
/// Sample linear data type.
class LinearSales {
final int index;
final int year;
final int sales;
LinearSales({this.year, this.sales, this.index});
}
class CustomCircleSymbolRenderer extends CircleSymbolRenderer {
final data;
CustomCircleSymbolRenderer({this.data});
@override
void paint(ChartCanvas canvas, Rectangle<num> bounds,
{List<int> dashPattern,
Color fillColor,
FillPatternType fillPattern,
Color strokeColor,
double strokeWidthPx}) {
super.paint(canvas, bounds,
dashPattern: dashPattern,
fillColor: fillColor,
strokeColor: strokeColor,
strokeWidthPx: strokeWidthPx);
// print("bounds.left:${bounds.left}");
// print("data:${data}");
Map _seleted = data["seleted"];
int _len = _seleted.length;
List _valList = _seleted.values.toList();
List _keysList = _seleted.keys.toList();
canvas.drawRect(
Rectangle(bounds.left < 250 ? 240 : 20, 0, 100, 18 * _len + 15),
fill: Color(r: 0, g: 0, b: 0, a: 30));
for (int i = 0; i < _len; i++) {
var textStyle = style.TextStyle();
textStyle.color = Color.black;
textStyle.fontSize = 12;
canvas.drawText(
textElement.TextElement(
_keysList[i] + " " + _valList[i].toString(),
style: textStyle,
),
bounds.left < 250 ? 245 : 25,
i * 18 + 10);
}
}
}
更多推荐
已为社区贡献1条内容
所有评论(0)