Skip to content

Question: How to create this chart #287

@BroonDev

Description

@BroonDev

How can I make the tooltip identify bar and line grouping data? Instead of selecting one piece of data at a time.

image

const teste = [{
'index': 0,
'year': 'Abr/23',
'type': 'type1',
'value': 12.33,
'average': 17.58
},
{
'index': 1,
'year': 'Maio/23',
'type': 'type1',
'value': 12.33,
'average': 17.82
},
{
'index': 0,
'year': 'Abr/23',
'type': 'type2',
'value': 27.28,
'average': 17.58
},
{
'index': 1,
'year': 'Maio/23',
'type': 'type2',
'value': 27.76,
'average': 17.82
},]

const _kBaseGroupPaddingHorizontal = 32.0;
const _kMinBarSize = 4.0;

/// Changes the position of marks while also updating their width to match
/// the number of marks in a single band. Useful for bar charts when the
/// width of the bars can be dynamic.
@immutable
class DodgeSizeModifier extends Modifier {
@OverRide
AttributesGroups modify(
AttributesGroups 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 maxWidthPerAttributes = maxWidthInBand / numGroups;
final barHorizontalPadding = groupHorizontalPadding / 2;
final size =
    max(maxWidthPerAttributes - barHorizontalPadding, _kMinBarSize);

final bias = ratio * effectiveBand;

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

final AttributesGroups rst = [];
for (final group in groups) {
  final groupRst = <Attributes>[];
  for (final attributes in group) {
    final oldPosition = attributes.position;

    groupRst.add(Attributes(
      index: attributes.index,
      tag: attributes.tag,
      position: oldPosition
          .map(
            (point) => Offset(point.dx + accumulated + bias, point.dy),
          )
          .toList(),
      shape: attributes.shape,
      color: attributes.color,
      gradient: attributes.gradient,
      elevation: attributes.elevation,
      label: attributes.label,
      size: size,
    ));
  }
  rst.add(groupRst);
  accumulated += bias;
}

return rst;

}

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

class ChartTest extends StatelessWidget {
const ChartTest({super.key});

@OverRide
Widget build(BuildContext context) {
return Scaffold(
body: SingleChildScrollView(
child: Center(
child: Column(
children: [
Container(
margin: const EdgeInsets.only(top: 10),
width: 600,
height: 300,
child: Chart(
data: teste,
variables: {
'index': Variable(
accessor: (Map map) => map['index'].toString(),
),
'year': Variable(
accessor: (Map map) => map['year'] as String,
),
'type': Variable(
accessor: (Map map) => map['type'] as String,
),
'value': Variable(
accessor: (Map map) =>
map['value'] is num ? map['value'] as num : 0.0,
),
'average': Variable(
accessor: (Map map) =>
map['average'] is num ? map['average'] as num : 0.0,
),
},
marks: [
IntervalMark(
position: Varset('index') * Varset('value') / Varset('type'),
color: ColorEncode(
variable: 'type',
values: Defaults.colors2,
updaters: {
'tap': {false: (color) => color.withAlpha(100)}
}),
size: SizeEncode(value: 6),
modifiers: [DodgeSizeModifier()],
),
LineMark(
position:
Varset('index') * Varset('average') / Varset('type'),
color: ColorEncode(
value: Defaults.average,
//variable: 'average',
updaters: {
'tap': {false: (color) => color.withAlpha(100)}
}),
)
],
axes: [
AxisGuide(
tickLine: TickLine(),
variable: 'year',
label: LabelStyle(
rotation: 120,
textStyle: const TextStyle(
fontSize: 10,
color: Colors.black,
),
offset: const Offset(0, 7.5),
),
),
Defaults.verticalAxis,
],
selections: {
'tap': PointSelection(
dim: Dim.x,
nearest: true,
)
},
tooltip: TooltipGuide(),
),
),
],
),
)));
}
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions