Closed Deishelon closed 1 day ago
Hi @Deishelon,
Query 1: How to format 'low' and 'high' data points individually for the dataLabels.
You can achieve your requirement by using the onDataLabelRender callback in the SfCartesianChart. By using this, you can get ‘high’ and ‘low’ data points. When the onDataLabelRender callback is triggered, the high value will be called first, followed by the low value. You can format the dataLabel text separately by setting the bool property _isHigh to true to display high dataPoints and changing the _isHigh to false to display low dataPoints. We have provided a code snippet, screenshot, user guide documentation, and sample for your reference.
Code Snippet:
bool _isHigh = true;
body: SfCartesianChart(
isTransposed: true,
onDataLabelRender: (DataLabelRenderArgs dataLabelArgs) {
if (_isHigh) {
// It represents for high dataPoints.
final int millisecondsSinceEpoch = int.parse(dataLabelArgs.text!);
final dateTime =
DateTime.fromMillisecondsSinceEpoch(millisecondsSinceEpoch);
final String formattedDate = DateFormat.jm().format(dateTime);
dataLabelArgs.text = formattedDate;
} else {
// It represents for low dataPoints.
final int millisecondsSinceEpoch = int.parse(dataLabelArgs.text!);
final dateTime =
DateTime.fromMillisecondsSinceEpoch(millisecondsSinceEpoch);
final String formattedDate = DateFormat.jm().format(dateTime);
dataLabelArgs.text = formattedDate;
}
// Changing _isHigh boolean value to true when it is false and false when it is true.
_isHigh = !_isHigh;
},
},
UG Link,
https://help.syncfusion.com/flutter/cartesian-charts/callbacks#ondatalabelrender
Screeshot:
Query 2: How to format the text in the tooltip like in the dataLabels.
You can achieve your requirement by using the builder property in the TooltipBehavior. By using this, you can format the tooltip text, like in the dataLabels based on the seriesIndex. We have shared code snippet, screenshot, user guide documentation, and sample for your reference.
UG Link,
https://help.syncfusion.com/flutter/cartesian-charts/tooltip#tooltip-template
Code Snippet:
tooltipBehavior: TooltipBehavior(
enable: true,
builder: (data, point, series, pointIndex, seriesIndex) {
String tooltipHeader = series.name.toString();
const textStyle = TextStyle(color: Colors.white);
const padding = EdgeInsets.only(bottom: 5);
return ClipRRect(
borderRadius: BorderRadius.circular(15),
child: Container(
color: Colors.black26,
padding: const EdgeInsets.all(5),
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
Text(
tooltipHeader,
textAlign: TextAlign.center,
style: textStyle,
),
const Padding(padding: padding),
const SizedBox(
height: 2,
width: 80,
child: ColoredBox(color: Colors.white),
),
Text(' ${rangeData1[pointIndex].name}', style: textStyle),
Text(
'High : ${DateFormat.jm().format(
DateTime.fromMillisecondsSinceEpoch(seriesIndex == 0
? rangeData1[pointIndex].high
: rangeData2[pointIndex].high),
)}',
style: textStyle),
Text(
'Low : ${DateFormat.jm().format(
DateTime.fromMillisecondsSinceEpoch(seriesIndex == 0
? rangeData1[pointIndex].low
: rangeData2[pointIndex].low),
)}',
style: textStyle),
],
),
),
);
},
),
Screenshot:
Note: We have prepared the workaround sample based on the two series only.
Regards, Lokesh P.
Bug description
This is what I'm trying to achieve conceptually, so it's clear why this is an issue.
Imagine the following graph where on the X axis is time, and you show to the user the 'timeline' view of a given state (i.e connected/disconnected in my case)
Now, when using
SfCartesianChart
withRangeColumnSeries
I can provide 'low' and 'high' data points (vialowValueMapper
andhighValueMapper
) which would indicate the start end the end of the state event.However, when displayed back to the user the start&end would be printed as raw numbers (i.e milliseconds), which is expected:
However, now if one provides a
dataLabelMapper
one would expect that givenRangeColumnSeries
has two values thatdataLabelMapper
either would be called twice (one for low format, one for high format), or once but return 2 formatted strings (for low & high) - but this does not happen. When providingdataLabelMapper
it's called once, and you can only return one thing. which means low&high data points are formatted identically.See more in the code sample.
Steps to reproduce
RangeColumnSeries
whereprimaryYAxis
isDateTimeAxis
dataLabelMapper
to format themdataLabelMapper
provided the popup values are still 'raw'(See code samples for full info)
Code sample
No formatting (base code)
With this we can get this chart to show up: ![raw_numbers](https://github.com/syncfusion/flutter-widgets/assets/11800090/5edd9035-6c4a-4295-b1f9-af63a0056dd5) ```dart class RangeTimeData { final String name; final num low; final num high; RangeTimeData(this.name, this.low, this.high); } Widget timelineStateChart2(BuildContext context) { return SfCartesianChart( enableSideBySideSeriesPlacement: false, legend: const Legend(isVisible: true), primaryXAxis: CategoryAxis(majorGridLines: const MajorGridLines(width: 0)), primaryYAxis: DateTimeAxis(axisLine: const AxisLine(width: 0)), series: [ RangeColumnSeriesAdding formatter
Now, I've added a formatter (`dataLabelMapper: (RangeTimeData data, index) => "${data.low}-${data.high}-$index",`), just to demonstrate the point that both low and high contain the same value (even the index is `0` for both) ![both_formatted_same](https://github.com/syncfusion/flutter-widgets/assets/11800090/da90c728-c3ad-4f02-ba13-f150ef6f62dd) ```dart return SfCartesianChart( enableSideBySideSeriesPlacement: false, legend: const Legend(isVisible: true), primaryXAxis: CategoryAxis(majorGridLines: const MajorGridLines(width: 0)), primaryYAxis: DateTimeAxis(axisLine: const AxisLine(width: 0)), series: [ RangeColumnSeriesMultiple formatters
Same code as above, but now both `RangeColumnSeries` have formatter, but it seems like it formats only the first one (please note how the red box is missing any data format labels, but blue box has; but code has formatters for both): ![formatted_only_one](https://github.com/syncfusion/flutter-widgets/assets/11800090/a915a673-3531-493f-89a2-6ac90de25016) ```dart return SfCartesianChart( enableSideBySideSeriesPlacement: false, legend: const Legend(isVisible: true), primaryXAxis: CategoryAxis(majorGridLines: const MajorGridLines(width: 0)), primaryYAxis: DateTimeAxis(axisLine: const AxisLine(width: 0)), series: [ RangeColumnSeriesAlso, please note how the values in the popup is not formatted at all, despite
dataLabelMapper
provided.:Expected behaviour:
dataLabelMapper
to be able to format 'low' and 'high' data points individually -- maybe either via the 'index' (i.e 0 is low, and 1 is high) -- or can return a struct with 2 strings -- or have 2 data mappers lowDataLabelMapper & highDataLabelMapperScreenshots or Video
Demonstrated above with the code snippets.
Stack Traces
Not a crash - not relevant.
On which target platforms have you observed this bug?
Web, Linux
Flutter Doctor output
Doctor output
```console flutter doctor -v [✓] Flutter (Channel stable, 3.19.2, on Fedora Linux 39 (KDE Plasma) 6.8.6-200.fc39.x86_64, locale en_NZ.UTF-8) • Flutter version 3.19.2 on channel stable at /opt/flutter • Upstream repository https://github.com/flutter/flutter.git • Framework revision 7482962148 (8 weeks ago), 2024-02-27 16:51:22 -0500 • Engine revision 04817c99c9 • Dart version 3.3.0 • DevTools version 2.31.1 [!] Android toolchain - develop for Android devices (Android SDK version 34.0.0) • Android SDK at /home/deishelon/Android/Sdk ✗ cmdline-tools component is missing Run `path/to/sdkmanager --install "cmdline-tools;latest"` See https://developer.android.com/studio/command-line for more details. ✗ Android license status unknown. Run `flutter doctor --android-licenses` to accept the SDK licenses. See https://flutter.dev/docs/get-started/install/linux#android-setup for more details. [✓] Chrome - develop for the web • Chrome at google-chrome [✗] Linux toolchain - develop for Linux desktop • clang version 17.0.6 (Fedora 17.0.6-2.fc39) • cmake version 3.27.7 • ninja version 1.11.1 • pkg-config version 1.9.5 ✗ GTK 3.0 development libraries are required for Linux development. They are likely available from your distribution (e.g.: apt install libgtk-3-dev) [✓] Android Studio (version 2023.2) • Android Studio at /home/deishelon/.local/share/JetBrains/Toolbox/apps/android-studio • Flutter plugin can be installed from: 🔨 https://plugins.jetbrains.com/plugin/9212-flutter • Dart plugin can be installed from: 🔨 https://plugins.jetbrains.com/plugin/6351-dart • Java version OpenJDK Runtime Environment (build 17.0.9+0-17.0.9b1087.7-11185874) [✓] IntelliJ IDEA Ultimate Edition (version 2024.1) • IntelliJ at /home/deishelon/.local/share/JetBrains/Toolbox/apps/intellij-idea-ultimate • Flutter plugin version 79.0.3 • Dart plugin can be installed from: 🔨 https://plugins.jetbrains.com/plugin/6351-dart [✓] Connected device (2 available) • Linux (desktop) • linux • linux-x64 • Fedora Linux 39 (KDE Plasma) 6.8.6-200.fc39.x86_64 • Chrome (web) • chrome • web-javascript • Google Chrome 124.0.6367.60 [✓] Network resources • All expected network resources are available. ! Doctor found issues in 2 categories. ```