Skip to content

Commit

Permalink
v0.9.3
Browse files Browse the repository at this point in the history
  • Loading branch information
entronad committed Apr 19, 2022
1 parent 5144a74 commit a9788ae
Show file tree
Hide file tree
Showing 10 changed files with 211 additions and 140 deletions.
9 changes: 9 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,12 @@
## 0.9.3

**2022-04-19**

- Fix: add key to Chart StatefulWidget: https://github.com/entronad/graphic/pull/75
- Fix: add dispose to Chart.dart: https://github.com/entronad/graphic/pull/79
- Add size argument to custom annotation renderer method for responsiveness: https://github.com/entronad/graphic/pull/82
- Fix Sector corner radius bug: https://github.com/entronad/graphic/issues/58

## 0.9.2

**2022-04-05**
Expand Down
31 changes: 30 additions & 1 deletion DEVLOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4052,6 +4052,20 @@ scale的formatter(tick)也应该允许返回null,并在渲染tick时判断

先不管扇面的gradient,让它也是按图元的。否则扇面堆叠等情况太复杂

关于鼠标移入移出事件:https://github.com/entronad/graphic/pull/63

实现是模仿的Flutter本身的tooltip

事件就叫 mouseEnter 和 mouseExit,因为它们只针对mouse,沿用自MouseRegion,由于MouseRegion本身有mouse字样,所以事件直接交 enter,exit,我们这里前面要加个mouse

目前来看好像没有合适的detail

关于rSector 中处理角度或半径不是从小到大导致的圆角问题,还是用添加符号的办法,而不是用固定从小到大法,这样能避免太死板,而且可能更简洁一些

给形状加边框的还是继续用自定义形状吧,这哥们后来没有提PR:https://github.com/entronad/graphic/issues/57



## TODO

area gradient 超出coord region的问题
Expand All @@ -4064,4 +4078,19 @@ Label还是LabelAttr 支持null

animation

树状等其它数据结构,实现treemap、桑基图等类型
树状等其它数据结构,实现treemap、桑基图等类型




介绍:

声明式

可交互

问题

1. 对nest的理解,group by
2. elevation作为一个 aes attr
4 changes: 2 additions & 2 deletions example/lib/main.dart
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import 'pages/polygon_custom.dart';
import 'pages/interaction_channel_dynamic.dart';
import 'pages/bigdata.dart';
import 'pages/echarts.dart';
// import 'pages/debug.dart';
import 'pages/debug.dart';

final routes = {
'/': (context) => const HomePage(),
Expand All @@ -18,7 +18,7 @@ final routes = {
const InteractionChannelDynamicPage(),
'/examples/Bigdata': (context) => BigdataPage(),
'/examples/Echarts': (context) => EchartsPage(),
// '/examples/Debug': (context) => DebugPage(),
'/examples/Debug': (context) => DebugPage(),
};

class MyApp extends StatelessWidget {
Expand Down
199 changes: 92 additions & 107 deletions example/lib/pages/debug.dart
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,30 @@ import 'package:flutter/material.dart';
import 'package:graphic/graphic.dart';
import 'package:graphic_example/data.dart';

class Sector extends CustomPainter {
@override
void paint(Canvas canvas, Size size) {
canvas.drawPath(
Paths.rSector(
center: Offset(175, 150),
r: 20,
r0: 90,
startAngle: 0,
endAngle: -1.6,
clockwise: true,
topLeft: Radius.circular(5),
topRight: Radius.circular(5),
bottomRight: Radius.circular(5),
bottomLeft: Radius.circular(5),
),
Paint(),
);
}

@override
bool shouldRepaint(covariant CustomPainter oldDelegate) => true;
}

class DebugPage extends StatelessWidget {
DebugPage({Key? key}) : super(key: key);

Expand All @@ -16,41 +40,41 @@ class DebugPage extends StatelessWidget {
return Scaffold(
body: Center(
child: Container(
// Commenting out the next two lines is causing the problem
// width: 600,
// height: 400,
margin: const EdgeInsets.only(top: 10),
width: 350,
height: 300,
child: Chart(
data: [
{'year': DateTime(2010), 'price': 10},
{'year': DateTime(2011), 'price': 8},
{'year': DateTime(2012), 'price': 12},
{'year': DateTime(2013), 'price': 16},
{'year': DateTime(2014), 'price': 9},
{'year': DateTime(2015), 'price': 17},
{'year': DateTime(2016), 'price': 13},
],
data: basicData,
variables: {
'year': Variable(
accessor: (Map map) => map['year'] as DateTime,
'genre': Variable(
accessor: (Map map) => map['genre'] as String,
),
'price': Variable(
accessor: (Map map) => map['price'] as int,
'sold': Variable(
accessor: (Map map) => map['sold'] as num,
scale: LinearScale(min: 0),
),
},
elements: [LineElement()],
elements: [
IntervalElement(
label: LabelAttr(
encoder: (tuple) => Label(tuple['sold'].toString())),
color: ColorAttr(
variable: 'genre',
values: Defaults.colors10,
),
shape: ShapeAttr(
value: RectShape(
borderRadius: BorderRadius.all(Radius.circular(5)))),
size: SizeAttr(value: 10),
)
],
coord: PolarCoord(transposed: true),
axes: [
Defaults.horizontalAxis,
Defaults.verticalAxis,
Defaults.radialAxis..label = null,
Defaults.circularAxis,
],
selections: {
// 'tooltipMouse': PointSelection(
// on: {GestureType.hover},
// devices: {PointerDeviceKind.mouse},
// ),
'p': PointSelection(),
},
crosshair: CrosshairGuide(),
),
// child: CustomPaint(painter: Sector()),
),
),
);
Expand All @@ -67,99 +91,60 @@ class DebugPage extends StatelessWidget {
// class _DebugPageState extends State<DebugPage> {
// final GlobalKey<ScaffoldState> _scaffoldKey = GlobalKey<ScaffoldState>();

// final rdm = Random();

// List<Map> data = [];

// @override
// void initState() {
// const cv = -7;

// data = [
// {'genre': 'Sports', 'sold': cv},
// {'genre': 'Strategy', 'sold': cv},
// {'genre': 'Action', 'sold': cv},
// {'genre': 'Shooter', 'sold': cv},
// {'genre': 'Other', 'sold': cv},
// ];
// int _enterCounter = 0;
// int _exitCounter = 0;
// double x = 0.0;
// double y = 0.0;

// // data = [
// // {'genre': 'Sports', 'sold': rdm.nextInt(300)},
// // {'genre': 'Strategy', 'sold': rdm.nextInt(300)},
// // {'genre': 'Action', 'sold': rdm.nextInt(300)},
// // {'genre': 'Shooter', 'sold': rdm.nextInt(300)},
// // {'genre': 'Other', 'sold': rdm.nextInt(300)},
// // ];
// void _incrementEnter(PointerEvent details) {
// setState(() {
// _enterCounter++;
// });
// }

// final timer = Timer.periodic(Duration(seconds: 3), (_) {
// setState(() {
// data = [
// {'genre': 'Sports', 'sold': rdm.nextInt(300)},
// {'genre': 'Strategy', 'sold': rdm.nextInt(300)},
// {'genre': 'Action', 'sold': rdm.nextInt(300)},
// {'genre': 'Shooter', 'sold': rdm.nextInt(300)},
// {'genre': 'Other', 'sold': rdm.nextInt(300)},
// ];
// });
// void _incrementExit(PointerEvent details) {
// setState(() {
// _exitCounter++;
// });
// }

// super.initState();
// void _updateLocation(PointerEvent details) {
// setState(() {
// x = details.position.dx;
// y = details.position.dy;
// });
// }

// @override
// Widget build(BuildContext context) {
// return Scaffold(
// key: _scaffoldKey,
// appBar: AppBar(
// title: const Text('Debug'),
// ),
// backgroundColor: Colors.white,
// body: SingleChildScrollView(
// child: Center(
// child: Column(
// children: <Widget>[
// Container(
// margin: const EdgeInsets.only(top: 10),
// width: 650,
// height: 300,
// child: Chart(
// // rebuild: true,
// data: data,
// variables: {
// 'genre': Variable(
// accessor: (Map map) => map['genre'] as String,
// ),
// 'sold': Variable(
// accessor: (Map map) => map['sold'] as num,
// ),
// },
// elements: [IntervalElement()],
// axes: [
// Defaults.horizontalAxis,
// Defaults.verticalAxis,
// ],
// selections: {
// 'tap': PointSelection(
// on: {
// GestureType.hover,
// GestureType.tap,
// },
// dim: 1,
// )
// },
// tooltip: TooltipGuide(
// backgroundColor: Colors.black,
// elevation: 5,
// textStyle: Defaults.textStyle,
// variables: ['genre', 'sold'],
// body: Center(
// child: ConstrainedBox(
// constraints: BoxConstraints.tight(const Size(300.0, 200.0)),
// child: MouseRegion(
// onEnter: _incrementEnter,
// onHover: _updateLocation,
// onExit: _incrementExit,
// child: Container(
// color: Colors.lightBlueAccent,
// child: Column(
// mainAxisAlignment: MainAxisAlignment.center,
// children: <Widget>[
// const Text(
// 'You have entered or exited this box this many times:'),
// Text(
// '$_enterCounter Entries\n$_exitCounter Exits',
// style: Theme.of(context).textTheme.headline4,
// ),
// Text(
// 'The cursor is here: (${x.toStringAsFixed(2)}, ${y.toStringAsFixed(2)})',
// ),
// crosshair: CrosshairGuide(),
// ),
// ],
// ),
// ],
// ),
// ),
// ),
// ),
// )
// );
// }
// }
4 changes: 3 additions & 1 deletion lib/src/chart/chart.dart
Original file line number Diff line number Diff line change
Expand Up @@ -222,6 +222,8 @@ class _ChartState<D> extends State<Chart<D>> {
void initState() {
super.initState();

// The mouse enter and exit implementation is the same as Flutter's tooltip:
// https://github.com/flutter/flutter/blob/master/packages/flutter/lib/src/material/tooltip.dart#L354
_mouseIsConnected = RendererBinding.instance!.mouseTracker.mouseIsConnected;

RendererBinding.instance!.mouseTracker
Expand All @@ -232,7 +234,7 @@ class _ChartState<D> extends State<Chart<D>> {
void dispose() {
super.dispose();

RendererBinding.instance.mouseTracker
RendererBinding.instance!.mouseTracker
.removeListener(_handleMouseTrackerChange);
}

Expand Down
41 changes: 34 additions & 7 deletions lib/src/interaction/gesture.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import 'dart:ui';

import 'package:flutter/gestures.dart';
import 'package:flutter/widgets.dart';
import 'package:graphic/src/chart/chart.dart';
import 'package:graphic/src/dataflow/operator.dart';

import 'signal.dart';
Expand All @@ -20,18 +21,44 @@ import 'signal.dart';
/// - [Listener], which responses to common pointer events that compose [hover]
/// and [scroll] gestures.
enum GestureType {
/// Triggered when a mouse pointer has entered this widget.
/// Triggered when a mouse pointer has entered this chart.
///
/// This callback is triggered when the pointer, with or without buttons
/// pressed, has started to be contained by the region of this widget.
/// This is triggered when the pointer, with or without buttons
/// pressed, has started to be contained by the region of this chart. More
/// specifically, this is triggered by the following cases:
///
/// * This chart has appeared under a pointer.
/// * This chart has moved to under a pointer.
/// * A new pointer has been added to somewhere within this chart.
/// * An existing pointer has moved into this chart.
///
/// This is not always matched by an [mouseExit]. If the [Chart]
/// is unmounted while being hovered by a pointer, the [mouseExit] of the chart
/// will not be emitted. For more details, see [mouseEnter].
///
/// A gesture of this type has no details.
mouseEnter,

/// Triggered when a mouse pointer has exited this widget when the widget is
/// Triggered when a mouse pointer has exited this chart when the chart is
/// still mounted.
///
/// This callback is triggered when the pointer, with or without buttons
/// pressed, has stopped being contained by the region of this widget, except
/// when the exit is caused by the disappearance of this widget.
/// This is triggered when the pointer, with or without buttons
/// pressed, has stopped being contained by the region of this chart, except
/// when the exit is caused by the disappearance of this chart. More
/// specifically, this is triggered by the following cases:
///
/// * A pointer that is hovering this chart has moved away.
/// * A pointer that is hovering this chart has been removed.
/// * This chart, which is being hovered by a pointer, has moved away.
///
/// And is __not__ triggered by the following case:
///
/// * This chart, which is being hovered by a pointer, has disappeared.
///
/// This means that a [mouseExit] might not be matched by a
/// [mouseEnter].
///
/// A gesture of this type has no details.
mouseExit,

/// A tap with a primary button has occurred.
Expand Down
Loading

0 comments on commit a9788ae

Please sign in to comment.