Skip to content

Commit

Permalink
improv: add custom modifier example
Browse files Browse the repository at this point in the history
  • Loading branch information
bernardobelchior committed May 2, 2022
1 parent b348746 commit accff22
Showing 1 changed file with 104 additions and 0 deletions.
104 changes: 104 additions & 0 deletions example/lib/pages/polygon_custom.dart
@@ -1,3 +1,5 @@
import 'dart:math';

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

Expand Down Expand Up @@ -638,6 +640,54 @@ class PolygonCustomPage extends StatelessWidget {
],
),
),
Container(
child: const Text(
'Custom Modifier',
style: TextStyle(fontSize: 20),
),
padding: const EdgeInsets.fromLTRB(20, 40, 20, 5),
),
Container(
child: const Text(
'- With dodge and size modifier that scales the interval element width to fit within its band',
),
padding: const EdgeInsets.fromLTRB(10, 5, 10, 0),
alignment: Alignment.centerLeft,
),
Container(
margin: const EdgeInsets.only(top: 10),
width: 350,
height: 300,
child: Chart(
padding: (_) => const EdgeInsets.fromLTRB(40, 5, 10, 40),
data: adjustData,
variables: {
'index': Variable(
accessor: (Map map) => map['index'].toString(),
),
'type': Variable(
accessor: (Map map) => map['type'] as String,
),
'value': Variable(
accessor: (Map map) => map['value'] as num,
),
},
elements: [
IntervalElement(
position:
Varset('index') * Varset('value') / Varset('type'),
color: ColorAttr(
variable: 'type', values: Defaults.colors10),
size: SizeAttr(value: 2),
modifiers: [DodgeSizeModifier()],
)
],
axes: [
Defaults.horizontalAxis..tickLine = TickLine(),
Defaults.verticalAxis,
],
),
),
Container(
child: const Text(
'Candlestick Chart',
Expand Down Expand Up @@ -734,3 +784,57 @@ class PolygonCustomPage extends StatelessWidget {
);
}
}

const _kBaseGroupPaddingHorizontal = 32.0;
const _kMinBarSize = 4.0;

/// Changes the position of elements while also updating their width to match
/// the number of elements in a single band. Useful for bar charts when the
/// width of the bars can be dynamic.
@immutable
class DodgeSizeModifier extends Modifier {
@override
void modify(AesGroups groups, Map<String, ScaleConv<dynamic, num>> scales,
AlgForm form, CoordConv coord, Offset origin) {
final xField = form.first[0];
final band = (scales[xField]! as DiscreteScaleConv).band;

final ratio = 1 / groups.length;
final numGroups = groups.length;
final groupHorizontalPadding = _kBaseGroupPaddingHorizontal / numGroups;
final invertedGroupPaddingHorizontal =
coord.invertDistance(groupHorizontalPadding, Dim.x);

final effectiveBand = band - 2 * invertedGroupPaddingHorizontal;

final maxWidth = coord.convert(const Offset(1, 0)).dx;
final maxWidthInBand = effectiveBand * maxWidth;
final maxWidthPerAes = maxWidthInBand / numGroups;
final barHorizontalPadding = groupHorizontalPadding / 2;
final size = max(maxWidthPerAes - barHorizontalPadding, _kMinBarSize);

final bias = ratio * effectiveBand;

// Negatively shift half of the total bias.
var accumulated = -bias * (numGroups + 1) / 2;

for (final group in groups) {
for (final aes in group) {
final oldPosition = aes.position;
aes.position = oldPosition
.map(
(point) => Offset(point.dx + accumulated + bias, point.dy),
)
.toList();

aes.size = size;
}
accumulated += bias;
}
}

@override
bool equalTo(Object other) {
return super == other;
}
}

0 comments on commit accff22

Please sign in to comment.