diff --git a/README.md b/README.md index c3dbd4cbe..6cd059cad 100644 --- a/README.md +++ b/README.md @@ -426,7 +426,7 @@ _controller.scale(100); For more detailed information, check out these documentation files: -- [How Chart Library Works](doc/how_chart_lib_works.md) +- [How Chart Library Works](doc/core_concepts/how_chart_lib_works.md) - [Data Series](doc/data_series.png) - [Data Painters](doc/data_painters.png) - [Drawing Tools](doc/drawing_tools.md) diff --git a/doc/README.md b/doc/README.md new file mode 100644 index 000000000..50708d3a5 --- /dev/null +++ b/doc/README.md @@ -0,0 +1,137 @@ +# Deriv Chart Documentation + +
+ Deriv Chart +

A powerful, customizable Flutter charting library for financial applications

+
+ +Welcome to the Deriv Chart documentation! This comprehensive guide will help you understand and use the Deriv Chart library effectively, whether you're a user of the library or a contributor to its development. + +## Key Features + +- **Multiple Chart Types**: Line, Candlestick, OHLC, and Hollow Candlestick charts +- **Technical Indicators**: Built-in support for popular indicators (Moving Averages, RSI, MACD, etc.) +- **Interactive Drawing Tools**: Trend lines, Fibonacci tools, and more for technical analysis +- **Real-time Updates**: Efficient handling of streaming data +- **Customizable Themes**: Fully customizable appearance to match your app's design +- **Responsive Design**: Works across different screen sizes and orientations +- **High Performance**: Optimized rendering for smooth scrolling and zooming + +## Quick Start + +```dart +import 'package:flutter/material.dart'; +import 'package:deriv_chart/deriv_chart.dart'; + +void main() { + runApp(const MyApp()); +} + +class MyApp extends StatelessWidget { + const MyApp({Key? key}) : super(key: key); + + @override + Widget build(BuildContext context) { + return MaterialApp( + home: Scaffold( + appBar: AppBar(title: const Text('Deriv Chart Example')), + body: Center( + child: SizedBox( + height: 300, + child: Chart( + mainSeries: LineSeries([ + Tick(epoch: DateTime.now().subtract(const Duration(minutes: 5)), quote: 100), + Tick(epoch: DateTime.now().subtract(const Duration(minutes: 4)), quote: 120), + Tick(epoch: DateTime.now().subtract(const Duration(minutes: 3)), quote: 110), + Tick(epoch: DateTime.now().subtract(const Duration(minutes: 2)), quote: 130), + Tick(epoch: DateTime.now().subtract(const Duration(minutes: 1)), quote: 125), + Tick(epoch: DateTime.now(), quote: 140), + ]), + pipSize: 2, + ), + ), + ), + ), + ); + } +} +``` + +## Table of Contents + +- [Getting Started](#getting-started) +- [Core Concepts](#core-concepts) +- [Features](#features) +- [Advanced Usage](#advanced-usage) +- [API Reference](#api-reference) +- [Examples](#examples) +- [Contributing](#contributing) +- [Support](#support) + +## Getting Started + +If you're new to the Deriv Chart library, start here to learn the basics: + +- [Installation](getting_started/installation.md) - How to install and set up the library +- [Basic Usage](getting_started/basic_usage.md) - Create your first chart +- [Chart Types](getting_started/chart_types.md) - Learn about different chart types +- [Configuration](getting_started/configuration.md) - Understand configuration options +- [Advanced Features](getting_started/advanced_features.md) - Learn about indicators, annotations, markers, and drawing tools + +## Core Concepts + +Understand the fundamental concepts behind the Deriv Chart library: + +- [Architecture](core_concepts/architecture.md) - Overview of the library's architecture +- [Coordinate System](core_concepts/coordinate_system.md) - How coordinates are managed +- [Rendering Pipeline](core_concepts/rendering_pipeline.md) - How data is rendered + +## Features + +Explore the features available in the Deriv Chart library: + +### Chart Elements + +- [Annotations](features/annotations.md) - Add horizontal and vertical barriers +- [Markers](features/markers.md) - Highlight specific points +- [Crosshair](features/crosshair.md) - Inspect data with precision + +### Technical Analysis + +- [Indicators](features/indicators/overview.md) - Add technical indicators + +- [Drawing Tools](features/drawing_tools/overview.md) - Use interactive layer drawing tools + +### Interactive Layer + +- [Interactive Layer](core_concepts/interactive_layer.md) - Understand the interactive layer architecture + +## Advanced Usage + +Take your charts to the next level with advanced techniques: + +- [Custom Themes guid](advanced_usage/custom_themes.md) - Create custom chart themes + +## Showcase App + +The `showcase_app` directory contains a complete Flutter application that demonstrates all the features of the Deriv Chart library. You can use this app as a reference for your own implementation. + +
+ Showcase App +
+ +## Contributing + +Learn how to contribute to the Deriv Chart library: + +- [Contribution Guidelines](contribution.md) - How to contribute + +## Compatibility + +- **Flutter**: 3.10.1 or higher +- **Dart**: 3.0.0 or higher +- **Platforms**: iOS, Android, Web, macOS, Windows, Linux + +## License + +The Deriv Chart library is licensed under the [MIT License](../LICENSE). diff --git a/doc/advanced_usage/custom_themes.md b/doc/advanced_usage/custom_themes.md new file mode 100644 index 000000000..4a9db7804 --- /dev/null +++ b/doc/advanced_usage/custom_themes.md @@ -0,0 +1,384 @@ +# Custom Themes + +This document explains how to create and use custom themes in the Deriv Chart library to customize the appearance of your charts. + +## Introduction to Chart Themes + +The Deriv Chart library uses themes to control the visual appearance of charts. Themes define colors, styles, and other visual properties for various chart elements, such as: + +- Background colors +- Grid lines and labels +- Crosshair appearance +- Default series styles +- Annotation styles + +The library provides default light and dark themes, but you can create custom themes to match your application's design. + +## Default Themes + +The Deriv Chart library includes two default themes: + +1. **ChartDefaultLightTheme**: A light theme with a white background and dark text +2. **ChartDefaultDarkTheme**: A dark theme with a dark background and light text + +By default, the chart automatically uses the appropriate theme based on the application's brightness: + +```dart +Chart( + mainSeries: LineSeries(ticks), + pipSize: 2, + // Theme is automatically selected based on Theme.of(context).brightness +) +``` + +You can explicitly specify a theme: + +```dart +Chart( + mainSeries: LineSeries(ticks), + pipSize: 2, + theme: ChartDefaultDarkTheme(), +) +``` + +## Creating a Custom Theme + +There are two approaches to creating a custom theme: + +1. **Extending a default theme**: Override specific properties of a default theme +2. **Implementing the ChartTheme interface**: Create a completely custom theme + +### Extending a Default Theme + +The easiest way to create a custom theme is to extend one of the default themes and override specific properties: + +```dart +class CustomDarkTheme extends ChartDefaultDarkTheme { + @override + GridStyle get gridStyle => GridStyle( + gridLineColor: Colors.yellow, + xLabelStyle: textStyle( + textStyle: caption2, + color: Colors.yellow, + fontSize: 13, + ), + yLabelStyle: textStyle( + textStyle: caption2, + color: Colors.yellow, + fontSize: 13, + ), + ); + + @override + CrosshairStyle get crosshairStyle => CrosshairStyle( + lineColor: Colors.orange, + labelBackgroundColor: Colors.orange.withOpacity(0.8), + labelTextStyle: textStyle( + textStyle: caption1, + color: Colors.white, + ), + ); +} +``` + +### Implementing the ChartTheme Interface + +For complete control, you can implement the `ChartTheme` interface: + +```dart +class CompletelyCustomTheme implements ChartTheme { + @override + Color get backgroundColor => Colors.black; + + @override + GridStyle get gridStyle => GridStyle( + gridLineColor: Colors.grey[800]!, + xLabelStyle: TextStyle( + color: Colors.grey[400], + fontSize: 12, + ), + yLabelStyle: TextStyle( + color: Colors.grey[400], + fontSize: 12, + ), + ); + + @override + CrosshairStyle get crosshairStyle => CrosshairStyle( + lineColor: Colors.white, + labelBackgroundColor: Colors.white.withOpacity(0.8), + labelTextStyle: TextStyle( + color: Colors.black, + fontSize: 12, + ), + ); + + @override + LineStyle get defaultLineStyle => LineStyle( + color: Colors.blue, + thickness: 2, + ); + + @override + CandleStyle get defaultCandleStyle => CandleStyle( + positiveColor: Colors.green, + negativeColor: Colors.red, + wickWidth: 1, + bodyWidth: 8, + ); + + @override + OHLCStyle get defaultOHLCStyle => OHLCStyle( + positiveColor: Colors.green, + negativeColor: Colors.red, + thickness: 1, + width: 8, + ); + + @override + HollowCandleStyle get defaultHollowCandleStyle => HollowCandleStyle( + positiveColor: Colors.green, + negativeColor: Colors.red, + wickWidth: 1, + bodyWidth: 8, + hollowPositiveColor: Colors.transparent, + ); + + @override + HorizontalBarrierStyle get defaultHorizontalBarrierStyle => HorizontalBarrierStyle( + color: Colors.purple, + isDashed: true, + lineThickness: 1, + labelBackgroundColor: Colors.purple.withOpacity(0.8), + labelTextStyle: TextStyle( + color: Colors.white, + fontSize: 12, + ), + ); + + @override + VerticalBarrierStyle get defaultVerticalBarrierStyle => VerticalBarrierStyle( + color: Colors.orange, + isDashed: true, + lineThickness: 1, + labelBackgroundColor: Colors.orange.withOpacity(0.8), + labelTextStyle: TextStyle( + color: Colors.white, + fontSize: 12, + ), + ); + + // Implement all other required properties... + + @override + TextStyle textStyle({ + required TextStyle textStyle, + required Color color, + double? fontSize, + FontWeight? fontWeight, + }) { + return textStyle.copyWith( + color: color, + fontSize: fontSize, + fontWeight: fontWeight, + ); + } +} +``` + +## Theme Properties + +The `ChartTheme` interface defines numerous properties that control the appearance of different chart elements: + +### Core Properties + +- `backgroundColor`: The background color of the chart +- `gridStyle`: The style of the grid lines and labels +- `crosshairStyle`: The style of the crosshair + +### Series Styles + +- `defaultLineStyle`: The default style for line series +- `defaultCandleStyle`: The default style for candle series +- `defaultOHLCStyle`: The default style for OHLC series +- `defaultHollowCandleStyle`: The default style for hollow candle series + +### Annotation Styles + +- `defaultHorizontalBarrierStyle`: The default style for horizontal barriers +- `defaultVerticalBarrierStyle`: The default style for vertical barriers +- `defaultTickIndicatorStyle`: The default style for tick indicators + +### Marker Styles + +- `defaultMarkerStyle`: The default style for markers +- `defaultActiveMarkerStyle`: The default style for active markers +- `defaultEntryTickStyle`: The default style for entry tick markers +- `defaultExitTickStyle`: The default style for exit tick markers + +## Style Classes + +The Deriv Chart library provides several style classes that define the appearance of specific chart elements: + +### GridStyle + +Controls the appearance of grid lines and labels: + +```dart +GridStyle( + gridLineColor: Colors.grey[300]!, + xLabelStyle: TextStyle( + color: Colors.grey[600], + fontSize: 12, + ), + yLabelStyle: TextStyle( + color: Colors.grey[600], + fontSize: 12, + ), +) +``` + +### CrosshairStyle + +Controls the appearance of the crosshair: + +```dart +CrosshairStyle( + lineColor: Colors.blue, + lineThickness: 1, + lineDashPattern: [5, 5], // Dashed line + labelBackgroundColor: Colors.blue.withOpacity(0.8), + labelTextStyle: TextStyle( + color: Colors.white, + fontSize: 12, + ), + labelPadding: EdgeInsets.symmetric(horizontal: 8, vertical: 4), + labelBorderRadius: 4, +) +``` + +### LineStyle + +Controls the appearance of line series: + +```dart +LineStyle( + color: Colors.blue, + thickness: 2, + isDashed: false, + dashPattern: [5, 5], +) +``` + +### CandleStyle + +Controls the appearance of candle series: + +```dart +CandleStyle( + positiveColor: Colors.green, + negativeColor: Colors.red, + wickWidth: 1, + bodyWidth: 8, +) +``` + +### OHLCStyle + +Controls the appearance of OHLC series: + +```dart +OHLCStyle( + positiveColor: Colors.green, + negativeColor: Colors.red, + thickness: 1, + width: 8, +) +``` + +### HorizontalBarrierStyle + +Controls the appearance of horizontal barriers: + +```dart +HorizontalBarrierStyle( + color: Colors.purple, + isDashed: true, + lineThickness: 1, + labelBackgroundColor: Colors.purple.withOpacity(0.8), + labelTextStyle: TextStyle( + color: Colors.white, + fontSize: 12, + ), +) +``` + +## Using Custom Themes + +To use a custom theme, pass it to the `theme` parameter of the `Chart` widget: + +```dart +Chart( + mainSeries: LineSeries(ticks), + pipSize: 2, + theme: CustomDarkTheme(), +) +``` + +## Dynamic Theme Switching + +You can dynamically switch between themes based on user preferences or system settings: + +```dart +class ThemeSwitcherExample extends StatefulWidget { + final List ticks; + + const ThemeSwitcherExample({ + Key? key, + required this.ticks, + }) : super(key: key); + + @override + State createState() => _ThemeSwitcherExampleState(); +} + +class _ThemeSwitcherExampleState extends State { + bool _isDarkMode = true; + + @override + Widget build(BuildContext context) { + return Column( + children: [ + Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Text('Light'), + Switch( + value: _isDarkMode, + onChanged: (value) { + setState(() { + _isDarkMode = value; + }); + }, + ), + Text('Dark'), + ], + ), + Expanded( + child: Chart( + mainSeries: LineSeries(widget.ticks), + pipSize: 2, + theme: _isDarkMode ? ChartDefaultDarkTheme() : ChartDefaultLightTheme(), + ), + ), + ], + ); + } +} +``` + +## Next Steps + +Now that you understand how to create and use custom themes in the Deriv Chart library, you can explore: + +- [API Reference](../api_reference/chart_widget.md) - Explore the complete API diff --git a/doc/architecture.md b/doc/architecture.md deleted file mode 100644 index e69de29bb..000000000 diff --git a/doc/core_concepts/architecture.md b/doc/core_concepts/architecture.md new file mode 100644 index 000000000..3dd995547 --- /dev/null +++ b/doc/core_concepts/architecture.md @@ -0,0 +1,397 @@ +# Chart Architecture + +This document provides a comprehensive overview of the Deriv Chart library's architecture, explaining the key components and how they interact with each other. + +## High-Level Architecture + +The Deriv Chart library follows a layered architecture with clear separation of concerns: + +``` +┌─────────────────────────┐ +│ XAxisWrapper │ +│ ┌───────────────────┐ │ +│ │ GestureManager │ │ +│ │ ┌─────────────┐ │ │ +│ │ │ Chart │ │ │ +│ │ │ │ │ │ +│ │ └─────────────┘ │ │ +│ └───────────────────┘ │ +└─────────────────────────┘ +``` + +### Key Components + +1. **XAxisWrapper**: The outermost layer that: + - Provides platform-specific X-axis implementations (web/mobile) + - Manages chart data entries and live data state + - Handles data fit mode and zoom level (msPerPx) + - Controls scroll animation and visible area changes + - Provides the conversion functions for the coordinate system to convert epoch to X position in the canvas and vice versa. These conversion functions are shared among all components of the chart. + +2. **GestureManager**: The middle layer that: + - Handles user interactions (pan, zoom, tap) + - Manages gesture states and animations + - Controls chart navigation and interaction behavior + +3. **Chart**: The core component that: + - Contains MainChart and optional BottomCharts + - Coordinates shared X-axis between charts + - Manages Y-axis for each chart section + - Renders data visualization + - Each chart provides the conversion functions for the coordinate system to convert the quote to Y position in the canvas and vice versa + +This layered structure ensures: +- Clear separation of concerns +- Platform-specific adaptations +- Consistent user interaction handling +- Coordinated data visualization + +## Chart Structure + +The Chart widget has a vertical structure with multiple chart areas: + +``` +┌─────────────────────────┐ +│ Chart │ +│ │ +│ ┌───────────────────┐ │ +│ │ MainChart │ │ +│ │ (Main Data) │ │ +│ └───────────────────┘ │ +│ │ +│ ┌───────────────────┐ │ +│ │ BottomCharts │ │ +│ │(Bottom Indicators)│ │ +│ └───────────────────┘ │ +│ ... │ +│ ... │ +│ ... │ +└─────────────────────────┘ +``` + +### MainChart + +The MainChart is the primary chart area that: +- Displays market data (line, candlestick charts) +- Shows overlay indicators (like Moving Average) +- Supports drawing tools for technical analysis +- Displays crosshair for price/time inspection +- Renders visual elements like barriers and markers + +### BottomCharts + +BottomCharts are additional chart areas that: +- Display separate indicator charts (like RSI, MACD) +- Have independent Y-axis scaling +- Share the same X-axis viewport with MainChart +- Can be added/removed dynamically + +## Widget Hierarchy + +The chart library implements a hierarchical structure of chart widgets: + +``` +┌─────────────────────┐ +│ BasicChart │ +│ (Base Features) │ +└─────────┬─────────┬─┘ + │ │ + ▼ ▼ + ┌─────────┐ ┌─────────┐ + │MainChart│ │BottomChart + └─────────┘ └─────────┘ +``` + +### BasicChart + +BasicChart serves as the foundation for all chart widgets, providing: +- Single MainSeries for data visualization +- Y-axis range management +- Coordinate conversion functions +- Y-axis scaling and animations +- Grid lines and labels +- User interactions for Y-axis scaling + +### MainChart + +MainChart extends BasicChart to create the primary chart area by adding: +- Support for multiple ChartData types +- Crosshair functionality +- Drawing tools +- Overlay indicators + +### BottomChart + +BottomChart extends BasicChart to create secondary chart areas that: +- Display technical indicators with independent Y-axis scaling +- Maintain separate Y-axis ranges while sharing X-axis viewport +- Support dynamic addition/removal of indicators +- Sync zooming and scrolling with MainChart + +## Coordinate System + +The chart uses a coordinate system based on time (X-axis) and price (Y-axis): + +### X-Axis Coordinates + +The X-axis is managed by the XAxisWrapper and uses: +- **rightBoundEpoch**: The timestamp at the right edge of the chart +- **msPerPx**: Milliseconds per pixel (zoom level) +- **leftBoundEpoch**: Calculated as `rightBoundEpoch - screenWidth * msPerPx` + +### Y-Axis Coordinates + +The Y-axis is managed by each chart (MainChart and BottomCharts) and uses: +- **topBoundQuote**: The maximum price in the visible area +- **bottomBoundQuote**: The minimum price in the visible area +- **quotePerPx**: Price units per pixel + +### Coordinate Conversion + +The chart provides conversion functions: +Provided by XAxisWrapper and specifically XAxisModel which is provided at the root of the chart widget hierarchy: + - `xFromEpoch`: Converts timestamp to X-coordinate + - `yFromQuote`: Converts price to Y-coordinate + +Provided by each chart widget (main chart and bottom charts) to components in each chart. +- `epochFromX`: Converts X-coordinate to timestamp +- `quoteFromY`: Converts Y-coordinate to price + +These functions enable plotting any data point on the canvas and handling user interactions. + +For detailed information about the coordinate system implementation and usage, see [Coordinate System](coordinate_system.md). + +## Data Visualization + +The chart library uses a flexible data visualization system built around the `ChartData` interface: + +``` +┌─────────────┐ +│ ChartData │ +└──────┬──────┘ + │ + ▼ +┌─────────────┐ +│ Series │ +└──────┬──────┘ + │ + ▼ +┌─────────────┐ +│ DataSeries │ +└──────┬──────┘ + │ + ├─────────────┬─────────────┬─────────────┐ + │ │ │ │ + ▼ ▼ ▼ ▼ +┌─────────────┐┌─────────────┐┌─────────────┐┌─────────────┐ +│ LineSeries ││CandleSeries ││ OHLCSeries ││ Indicators │ +└─────────────┘└─────────────┘└─────────────┘└─────────────┘ +``` + +### ChartData + +ChartData is an abstract class representing any data that can be displayed on the chart, including: +- Series data (lines, candles) +- Annotations (barriers) +- Markers + +The `ChartData` interface defines the core contract for all visual elements that can be rendered on a chart. It provides methods for: +- Data updates based on viewport changes +- Min/max value calculation for Y-axis scaling +- Custom painting on the canvas + +### Series + +Series is the base class for all chart series, handling: +- Data management +- Range calculation +- Painter creation + +### DataSeries + +DataSeries extends Series to handle sequential sorted data. +Every chart type and many indicators are an implementation of this class. + +### Specific Series Types + +- **LineSeries**: Displays line charts from tick data +- **CandleSeries**: Displays candlestick charts from OHLC data +- **OHLCSeries**: Displays OHLC charts from OHLC data +- **Indicator Series**: Displays technical indicators + +### Rendering Process + +The data visualization system follows a 4-step rendering pipeline that is triggered whenever the viewport changes: + +1. **Viewport Changes**: User interactions trigger zoom or scroll events +2. **Data Update**: Chart data objects update their visible data based on new viewport bounds +3. **Y-Axis Calculation**: Overall min/max values are calculated for proper scaling +4. **Painting**: Custom painters render all visual elements on the canvas + +For detailed information about how ChartData rendering works, including the complete rendering pipeline, coordinate mapping, and optimization techniques, see [Rendering Pipeline](rendering_pipeline.md). + +## Painter System + +The chart uses a custom painting system to render data: + +``` +┌─────────────────┐ +│ SeriesPainter │ +└────────┬────────┘ + │ + ▼ +┌─────────────────┐ +│ DataPainter │ +└────────┬────────┘ + │ + ├─────────────┬─────────────┬─────────────┐ + │ │ │ │ + ▼ ▼ ▼ ▼ +┌─────────────┐┌─────────────┐┌─────────────┐┌─────────────┐ +│ LinePainter ││CandlePainter││OHLCPainter ││ScatterPainter +└─────────────┘└─────────────┘└─────────────┘└─────────────┘ +``` + +### SeriesPainter + +SeriesPainter is an abstract class responsible for painting Series data on the canvas. + +### DataPainter + +DataPainter extends SeriesPainter to provide common painting functionality for DataSeries. + +### Specific Painters + +- **LinePainter**: Paints line data +- **CandlePainter**: Paints candlestick data +- **OHLCPainter**: Paints OHLC data +- **ScatterPainter**: Paints scatter plot data + +## Interactive Layer + +The Interactive Layer manages user interactions with drawing tools and provides a sophisticated state-based architecture for handling drawing tool creation, selection, and manipulation. + +``` +┌─────────────────────────┐ +│ Interactive Layer │ +└─────────────┬───────────┘ + │ + ▼ +┌─────────────────────────┐ +│ InteractiveState │ +└─────────────┬───────────┘ + │ + ├─────────────────┬─────────────────┬─────────────────┐ + │ │ │ │ + ▼ ▼ ▼ ▼ +┌─────────────────┐┌─────────────────┐┌─────────────────┐┌─────────────────┐ +│ NormalState ││SelectedToolState││ AddingToolState ││ HoverState │ +└─────────────────┘└─────────────────┘└─────────────────┘└─────────────────┘ +``` + +### Key Components + +The Interactive Layer consists of several key components: + +- **InteractiveState**: Defines different modes of interaction (normal, selected, adding) +- **InteractiveLayerBehaviour**: Provides platform-specific interaction handling and customizes state transitions +- **DrawingV2**: The base interface for all drawable elements on the chart +- **InteractableDrawing**: Concrete implementations of drawing tools that can be interacted with +- **DrawingAddingPreview**: Specialized components for handling the drawing creation process + +### InteractiveState + +InteractiveState defines the current mode of interaction with the chart: + +- **NormalState**: Default state when no tools are selected +- **SelectedToolState**: Active when a drawing tool is selected +- **AddingToolState**: Active when a new drawing tool is being created +- **HoverState**: A mixin that provides hover functionality + +### Drawing Tool States + +Each drawing tool has its own state: + +- **normal**: Default state +- **selected**: Tool is selected +- **hovered**: Pointer is hovering over the tool +- **adding**: Tool is being created +- **dragging**: Tool is being moved +- **animating**: Tool is being animated + +For detailed information about the Interactive Layer architecture, components, and implementation details, see [Interactive Layer](interactive_layer.md). + +## Theme System + +The chart library includes a theming system: + +``` +┌─────────────────┐ +│ ChartTheme │ +└────────┬────────┘ + │ + ├─────────────────┬─────────────────┐ + │ │ │ + ▼ ▼ ▼ +┌─────────────────┐┌─────────────────┐┌─────────────────┐ +│DefaultDarkTheme ││DefaultLightTheme││ CustomTheme │ +└─────────────────┘└─────────────────┘└─────────────────┘ +``` + +### ChartTheme + +ChartTheme is an interface defining all themeable aspects of the chart: + +- Grid style +- Axis style +- Crosshair style +- Series styles +- Annotation styles +- Background colors + +### Default Themes + +- **ChartDefaultDarkTheme**: Default dark theme +- **ChartDefaultLightTheme**: Default light theme + +### Custom Themes + +Users can create custom themes by: +- Implementing the ChartTheme interface +- Extending one of the default themes and overriding specific properties + +For detailed information about creating and customizing themes, see [Custom Themes](../advanced_usage/custom_themes.md). + +## DerivChart + +DerivChart is a wrapper around the Chart widget that: +- Provides UI for adding/removing indicators and drawing tools +- Manages saving/restoring selected indicators and tools +- Handles indicator and drawing tool configurations + +``` +┌─────────────────────────┐ +│ DerivChart │ +│ ┌───────────────────┐ │ +│ │ Chart │ │ +│ └───────────────────┘ │ +│ │ +│ ┌───────────────────┐ │ +│ │ AddOnsRepository │ │ +│ └───────────────────┘ │ +└─────────────────────────┘ +``` + +### AddOnsRepository + +AddOnsRepository is a ChangeNotifier that: +- Manages a list of add-ons (indicators or drawing tools) +- Handles saving/loading from SharedPreferences +- Provides methods for adding, removing, and updating add-ons + +## Next Steps + +Now that you understand the architecture of the Deriv Chart library, you can explore: + +- [Coordinate System](coordinate_system.md) - Understand how coordinates are managed +- [Rendering Pipeline](rendering_pipeline.md) - Explore how data is rendered on the canvas diff --git a/doc/core_concepts/coordinate_system.md b/doc/core_concepts/coordinate_system.md new file mode 100644 index 000000000..50d1efba3 --- /dev/null +++ b/doc/core_concepts/coordinate_system.md @@ -0,0 +1,232 @@ +# Coordinate System + +This document explains the coordinate system used in the Deriv Chart library, how it maps data points to screen coordinates, and how it handles scrolling and zooming. + +## Overview + +The Deriv Chart library uses a coordinate system that maps: +- Time (epochs) to X-coordinates on the screen +- Price (quotes) to Y-coordinates on the screen + +``` +Y-axis (Price) + ^ + | + | • (epoch2, quote2) + | + | • (epoch1, quote1) + | + | + +---------------------------------> X-axis (Time) +``` + +This mapping is essential for: +- Rendering data points at the correct positions +- Handling user interactions (taps, drags) +- Implementing scrolling and zooming +- Supporting crosshair functionality +- Enabling drawing tools and annotations + +## X-Axis Coordinate System + +The X-axis represents time and is managed by the `XAxisWrapper` component, which serves as the foundation for horizontal positioning across the entire chart. + +### Key Concepts + +1. **rightBoundEpoch**: The timestamp at the right edge of the chart +2. **msPerPx**: Milliseconds per pixel (zoom level) +3. **leftBoundEpoch**: The timestamp at the left edge of the chart +4. **visibleTimeRange**: The time range currently visible on the chart + +``` + leftBoundEpoch rightBoundEpoch + | | + v v + +------------------+-----------------------------------+ + | | | + | Past (not | Visible Area | Future (not + | visible) | | visible) + | | | + +------------------+----------------------------------+ + |<------- screenWidth (px) ------->| + |<------ visibleTimeRange -------->| + | (screenWidth * msPerPx) | +``` + +### Calculations + +The relationship between these values is: + +``` +leftBoundEpoch = rightBoundEpoch - screenWidth * msPerPx +visibleTimeRange = screenWidth * msPerPx +``` + +Where: +- `screenWidth` is the width of the chart in pixels +- `msPerPx` determines how many milliseconds each pixel represents (zoom level) + +### Coordinate Conversion + +The `XAxisModel` provides functions to convert between epochs and X-coordinates: + +- **xFromEpoch**: Converts a timestamp (epoch) to an X-coordinate on the screen +- **epochFromX**: Converts an X-coordinate on the screen to a timestamp (epoch) + +These conversion functions are essential for mapping data points to screen positions and interpreting user interactions. + +### Scrolling + +Scrolling is implemented by changing the `rightBoundEpoch`: +- Scrolling right (into the past): Decrease `rightBoundEpoch` +- Scrolling left (into the future): Increase `rightBoundEpoch` + +The `scrollBy` method adjusts the `rightBoundEpoch` based on the number of pixels scrolled, converting pixels to milliseconds using the current `msPerPx` value. + +#### Edge Cases and Constraints + +- **Live Data**: When displaying live data, the `rightBoundEpoch` may be constrained to the current time or the latest data point +- **Historical Limits**: The chart may impose limits on how far back in time users can scroll +- **Smooth Scrolling**: The chart implements momentum-based scrolling for a natural feel + +### Zooming + +Zooming is implemented by changing the `msPerPx`: +- Zooming in: Decrease `msPerPx` (fewer milliseconds per pixel) +- Zooming out: Increase `msPerPx` (more milliseconds per pixel) + +The `scale` method updates the `msPerPx` value while maintaining the position of a focal point (typically the center of the chart or the point under the user's finger). This ensures that the chart zooms in or out around the expected point. + +#### Zoom Constraints + +The chart implements min and max zoom levels to ensure usability. The `msPerPx` value is constrained between minimum and maximum values to prevent users from zooming too far in or out. + +## Y-Axis Coordinate System + +The Y-axis represents price and is managed by each chart component (MainChart and BottomCharts) independently, allowing different scales for different types of data. + +### Key Concepts + +1. **topBoundQuote**: The maximum price in the visible area +2. **bottomBoundQuote**: The minimum price in the visible area +3. **topPadding** and **bottomPadding**: Padding to add above and below the data +4. **quotePerPx**: Price units per pixel +5. **visibleQuoteRange**: The price range currently visible on the chart + +``` + ^ + | topPadding + +------------------+ + | | + | topBoundQuote | + | | + | | + | Visible | + | Quote Range | + | | + | | + | bottomBoundQuote| + | | + +------------------+ + | bottomPadding | + v +``` + +### Calculations + +The relationship between these values is: + +``` +quotePerPx = (topBoundQuote - bottomBoundQuote) / (height - topPadding - bottomPadding) +visibleQuoteRange = topBoundQuote - bottomBoundQuote +``` + +Where: +- `height` is the height of the chart in pixels +- `topPadding` and `bottomPadding` are the padding values in pixels + +### Coordinate Conversion + +The `BasicChart` provides functions to convert between quotes and Y-coordinates: + +- **yFromQuote**: Converts a price value (quote) to a Y-coordinate on the screen +- **quoteFromY**: Converts a Y-coordinate on the screen to a price value (quote) + +These conversion functions are essential for mapping data points to screen positions and interpreting user interactions. + +### Y-Axis Scaling + +The Y-axis scale is determined by: +1. Finding the minimum and maximum values in the visible data +2. Adding padding to ensure data doesn't touch the edges +3. Adjusting for a consistent scale when animating + +## Grid System + +The grid system uses the coordinate system to place grid lines and labels at appropriate intervals, enhancing readability and providing visual reference points. + +## Coordinate System in Action + +### Handling User Interactions + +To convert a user tap to a data point: + +The `onTap` method converts screen coordinates from a tap event to epoch and quote values using the coordinate conversion functions. This allows the chart to determine which data point the user tapped on. + +### Drawing Tools and Annotations + +Drawing tools and annotations use the coordinate system to position themselves on the chart: + +The `drawHorizontalLine` and `drawVerticalLine` methods demonstrate how to draw horizontal and vertical lines at specific price levels or timestamps. These are used for barriers, support/resistance levels, and other annotations. + +## Shared X-Axis, Independent Y-Axes + +The Deriv Chart library uses a shared X-axis for all charts (MainChart and BottomCharts) but independent Y-axes: + +``` ++------------------------------------------+ +| | +| MainChart (Y-axis for price data) | +| | ++------------------------------------------+ +| | +| BottomChart 1 (Y-axis for RSI) | +| | ++------------------------------------------+ +| | +| BottomChart 2 (Y-axis for MACD) | +| | ++------------------------------------------+ + ^ + | + Shared X-axis +``` + +1. The `XAxisWrapper` provides a single `XAxisModel` that is shared by all charts +2. Each chart (MainChart and BottomCharts) has its own Y-axis calculations + +This allows: +- Synchronized scrolling and zooming across all charts +- Independent Y-axis scaling for each chart based on its data range +- Consistent time alignment across all indicators + +### Implementation Details + +The `Chart` widget organizes the MainChart and BottomCharts in a vertical column. Each chart receives the same XAxisModel instance, ensuring that they share the same X-axis viewport. Each chart maintains its own Y-axis calculations based on its specific data. + +## Integration with Other Components + +The coordinate system integrates with other components of the Deriv Chart library: + +- **Interactive Layer**: Uses the coordinate system to position drawing tools +- **Data Series**: Converts data points to screen coordinates for rendering +- **Indicators**: Calculate values based on data and render using the coordinate system +- **Annotations**: Position themselves on the chart using the coordinate system + +## Next Steps + +Now that you understand the coordinate system used in the Deriv Chart library, you can explore: + +- [Rendering Pipeline](rendering_pipeline.md) - Learn how data is rendered on the canvas +- [Architecture](architecture.md) - Understand the overall architecture of the library +- [Interactive Layer](../features/drawing_tools/overview.md) - Learn about the interactive drawing tools \ No newline at end of file diff --git a/doc/how_chart_lib_works.md b/doc/core_concepts/how_chart_lib_works.md similarity index 99% rename from doc/how_chart_lib_works.md rename to doc/core_concepts/how_chart_lib_works.md index 2a56a52e4..40209c232 100644 --- a/doc/how_chart_lib_works.md +++ b/doc/core_concepts/how_chart_lib_works.md @@ -142,7 +142,7 @@ The market data(input data of chart) is a list of _Ticks_ or _OHLC_. Chart widget is a Canvas that we paint all data of chart inside this Canvas. -![plot](chart_scheme.png) +![plot](../chart_scheme.png) this widget has X-Axis and Y-Axis enabled by default. @@ -202,7 +202,7 @@ Zooming in the chart happens by updating **msPerPx**. ## Data Visualisation -![plot](data_series.png) +![plot](../data_series.png) We have an abstract class named **ChartData** that represents any type of data that the chart takes and makes it paint its self on the chart's canvas including _Line_, _Candle_ data, _Markers_, _barriers_, etc. A **ChartData** can be anything that shows some data on the chart. The chart can take a bunch of ChartData objects and paint them on its canvas. @@ -246,7 +246,7 @@ They have the `createPainter` object to paint the **BarrierObject** that gets in # Painter classes -![plot](data_painters.png) +![plot](../data_painters.png) **SeriesPainter** is an abstract class responsible for painting its [series] data. @@ -329,7 +329,7 @@ Chart has its own default dark and light themes that switch depending on Theme.o - Maintains its own Y-axis range and scaling while sharing the X-axis viewport - Can be dynamically added, removed, or reordered - Supports user interactions like zooming and scrolling in sync with MainChart -![plot](basic-chart.png) +![plot](../basic-chart.png) # Chart @@ -342,7 +342,7 @@ Chart has its own default dark and light themes that switch depending on Theme.o \*if you want to have indicators and drawing tools in the chart, you should use **\*DerivChart** instead of **Chart\*\*** -![plot](deriv-chart.png) +![plot](../deriv-chart.png) # Widgets @@ -362,7 +362,7 @@ CustomDraggableSheet is a wrapper widget to be used combined with a bottom sheet ### Drawing Tools -For a brief explanation of how drawing tools work, please refer to [Drawing Tools](drawing_tools.md) section. +For a brief explanation of how drawing tools work, please refer to [Drawing Tools](../drawing_tools.md) section. ### Interactive Layer (New Implementation) diff --git a/doc/interactive_layer.md b/doc/core_concepts/interactive_layer.md similarity index 99% rename from doc/interactive_layer.md rename to doc/core_concepts/interactive_layer.md index b37ee0d34..5c2475918 100644 --- a/doc/interactive_layer.md +++ b/doc/core_concepts/interactive_layer.md @@ -227,7 +227,7 @@ This architecture provides a clean separation of concerns and makes it easy to a The following diagram illustrates the architecture and flow of the Interactive Layer, including the relationships between InteractiveStates, InteractiveLayerBehaviour, and DrawingAddingPreview: -![Interactive Layer Architecture Diagram](diagrams/interactive_layer_architecture.svg) +![Interactive Layer Architecture Diagram](../diagrams/interactive_layer_architecture.svg) ### Flow Explanation: @@ -273,7 +273,7 @@ To illustrate how the Interactive Layer components work together in practice, le ### Sequence Diagram -![Horizontal Line Adding Sequence Diagram](diagrams/horizontal_line_sequence.svg) +![Horizontal Line Adding Sequence Diagram](../diagrams/horizontal_line_sequence.svg) ### Flow Explanation diff --git a/doc/core_concepts/rendering_pipeline.md b/doc/core_concepts/rendering_pipeline.md new file mode 100644 index 000000000..4ec98c5d0 --- /dev/null +++ b/doc/core_concepts/rendering_pipeline.md @@ -0,0 +1,119 @@ +# Rendering Pipeline + +This document explains the rendering pipeline used in the Deriv Chart library, detailing how data flows from raw market data to visual elements on the screen. + +## Overview + +The rendering pipeline in the Deriv Chart library follows a clear 4-step process that is triggered whenever the viewport changes (through zooming or scrolling): + +1. **Viewport Changes**: User interaction triggers zoom or scroll events +2. **Data Update**: Chart data objects update their visible data based on new viewport bounds +3. **Y-Axis Calculation**: Overall min/max values are calculated for proper scaling +4. **Painting**: Custom painters render all visual elements on the canvas + +This pipeline ensures efficient rendering and a responsive user experience, even with large datasets. + +## Rendering Process Steps + +### Step 1: Viewport Changes +When users zoom or scroll the chart, the viewport boundaries change. This triggers the rendering pipeline by updating the left and right epoch boundaries that define what data should be visible. + +### Step 2: Chart Data Update +Each chart data object's [`update(leftEpoch, rightEpoch)`](../api_reference/chart_data.md:25) method is called with the new viewport boundaries. During this update: +- Each chart data object calculates which data points fall within the visible range +- Min/max values are recalculated based on the visible data subset +- Data transformations (like indicator calculations) are applied if needed + +### Step 3: Y-Axis Min/Max Calculation +The chart collects the min/max values from all chart data instances to determine the overall Y-axis scaling: +- Each chart data object provides its [`minValue`](../api_reference/chart_data.md:26) and [`maxValue`](../api_reference/chart_data.md:27) +- The chart calculates the overall minimum and maximum across all data objects +- Y-axis bounds are set with appropriate padding for optimal visualization + +### Step 4: Custom Paint Rendering +The [`paint`](../api_reference/chart_data.md:30) method of the custom painter is called, which: +- Triggers each chart data object's [`paint`](../api_reference/chart_data.md:30) method +- Provides coordinate conversion functions ([`EpochToX`](../api_reference/coordinate_system.md:10), [`QuoteToY`](../api_reference/coordinate_system.md:15)) +- Renders all visual elements in the correct layer order + +## The ChartData Interface + +At the core of the rendering pipeline is the `ChartData` interface, which defines the contract for all visual elements except for drawing tool that can be rendered on a chart: + +```dart +abstract class ChartData { + late String id; + bool didUpdate(ChartData? oldData); + bool shouldRepaint(ChartData? oldData); + void update(int leftEpoch, int rightEpoch); + double get minValue; + double get maxValue; + int? getMinEpoch(); + int? getMaxEpoch(); + void paint( + Canvas canvas, + Size size, + EpochToX epochToX, + QuoteToY quoteToY, + AnimationInfo animationInfo, + ChartConfig chartConfig, + ChartTheme theme, + ChartScaleModel chartScaleModel, + ); +} +``` + +All chart elements implement this interface, including: +- Chart types (LineSeries, CandleSeries, OHLCSeries, HollowCandleSeries) +- Technical indicators (both overlay and bottom indicators) +- Annotations (horizontal barriers, vertical barriers, tick indicators) +- Markers and other visual elements + +The `ChartData` interface provides a unified way for the chart to: +1. Calculate visible data based on the current viewport +2. Determine min/max values for proper scaling +3. Paint elements on the canvas with appropriate coordinate transformations + +## Data Processing + +The data processing stage prepares raw market data for visualization by filtering visible data and calculating min/max values within the current viewport. + +## Coordinate Mapping + +The coordinate mapping stage converts data points to screen coordinates using transformation functions that map time values to X-coordinates and price values to Y-coordinates. + +## Layer Composition + +The chart uses multiple layers that are composited together: + +1. **Grid Layer**: Background grid lines and labels +2. **Data Layer**: Main data series and overlay indicators +3. **Annotation Layer**: Barriers and other annotations +4. **Marker Layer**: Markers and active markers +5. **Crosshair Layer**: Crosshair lines and labels +6. **Interactive Layer**: Drawing tools and user interactions + +## Optimization Techniques + +The rendering pipeline includes several optimization techniques: + +- **Binary Search**: Efficiently finds visible data range +- **Path Optimization**: Uses paths instead of individual line segments for better performance +- **Caching**: Indicator values are cached to avoid recalculation +- **Viewport Clipping**: Only elements within the viewport are rendered + +## Painter Architecture + +The library uses a decoupled painter architecture where: + +- Each visual element type has specialized painters ([`LinePainter`](../api_reference/painters.md:10), [`CandlePainter`](../api_reference/painters.md:20), etc.) +- Painters can be reused across different chart data implementations +- Complex elements can compose multiple painters together + +## Next Steps + +Now that you understand the rendering pipeline used in the Deriv Chart library, you can explore: + +- [Architecture](architecture.md) - Learn about the overall architecture of the library +- [Coordinate System](coordinate_system.md) - Understand how coordinates are managed +- [API Reference](../api_reference/chart_widget.md) - Explore the complete API \ No newline at end of file diff --git a/doc/drawing_tools.md b/doc/drawing_tools.md index 79c18f49b..283b77a15 100644 --- a/doc/drawing_tools.md +++ b/doc/drawing_tools.md @@ -107,7 +107,7 @@ Chart( ### Legacy Drawing Tools Implementation -The following sections describe the implementation details of the legacy drawing tools system. If you're using the new V2 implementation with `useDrawingToolsV2: true`, please refer to the [Interactive Layer documentation](interactive_layer.md) for detailed information about its architecture and components. +The following sections describe the implementation details of the legacy drawing tools system. If you're using the new V2 implementation with `useDrawingToolsV2: true`, please refer to the [Interactive Layer documentation](core_concepts/interactive_layer.md) for detailed information about its architecture and components. The process initiates by opening the drawing tools dialog and selecting a preferred drawing tool. Subsequently, the user can add specific taps on the Deriv chart to start drawing with default configurations. diff --git a/doc/features/annotations.md b/doc/features/annotations.md new file mode 100644 index 000000000..1d0722c6b --- /dev/null +++ b/doc/features/annotations.md @@ -0,0 +1,402 @@ +# Chart Annotations + +This document explains how to use annotations in the Deriv Chart library to highlight specific price levels, time points, and other significant areas on the chart. + +## Introduction to Annotations + +Annotations are visual elements added to a chart to highlight important information. Unlike drawing tools, which are interactive and can be manipulated by users, annotations are typically static elements that are programmatically added to the chart. + +The Deriv Chart library provides several types of annotations: +- Horizontal barriers (price levels) +- Vertical barriers (time points) +- Tick indicators (specific data points) + +## Horizontal Barriers + +Horizontal barriers are horizontal lines that highlight specific price levels on the chart. They are commonly used to mark support and resistance levels, target prices, or entry and exit points. + +### Basic Usage + +```dart +Chart( + mainSeries: LineSeries(ticks), + pipSize: 2, + annotations: [ + HorizontalBarrier( + 125.50, // Price level + title: 'Resistance', // Optional label + ), + ], +) +``` + +### Customizing Horizontal Barriers + +You can customize the appearance of horizontal barriers using the `HorizontalBarrierStyle` class: + +```dart +HorizontalBarrier( + 125.50, + title: 'Resistance', + style: HorizontalBarrierStyle( + color: Colors.red, + isDashed: true, + lineThickness: 1.5, + labelBackgroundColor: Colors.red.withOpacity(0.8), + labelTextStyle: TextStyle( + color: Colors.white, + fontSize: 12, + fontWeight: FontWeight.bold, + ), + ), +) +``` + +### Controlling Visibility Behavior + +You can control how horizontal barriers behave when they are outside the visible price range using the `visibility` parameter: + +```dart +HorizontalBarrier( + 125.50, + title: 'Resistance', + visibility: HorizontalBarrierVisibility.forceToStayOnRange, +) +``` + +Available visibility options: +- `HorizontalBarrierVisibility.normal`: The barrier is only visible when its price level is within the visible range +- `HorizontalBarrierVisibility.forceToStayOnRange`: The barrier is always visible, even if its price level is outside the visible range (it will be shown at the edge of the chart) + +## Vertical Barriers + +Vertical barriers are vertical lines that highlight specific time points on the chart. They are commonly used to mark significant events, announcements, or trading sessions. + +### Basic Usage + +```dart +Chart( + mainSeries: LineSeries(ticks), + pipSize: 2, + annotations: [ + VerticalBarrier( + DateTime(2023, 1, 15, 12, 0), // Time point + title: 'Market Open', // Optional label + ), + ], +) +``` + +### Customizing Vertical Barriers + +You can customize the appearance of vertical barriers using the `VerticalBarrierStyle` class: + +```dart +VerticalBarrier( + DateTime(2023, 1, 15, 12, 0), + title: 'Market Open', + style: VerticalBarrierStyle( + color: Colors.blue, + isDashed: true, + lineThickness: 1.5, + labelBackgroundColor: Colors.blue.withOpacity(0.8), + labelTextStyle: TextStyle( + color: Colors.white, + fontSize: 12, + fontWeight: FontWeight.bold, + ), + ), +) +``` + +## Tick Indicators + +Tick indicators are special annotations that highlight specific data points on the chart. They combine a horizontal barrier with a marker to show a specific tick's price and time. + +### Basic Usage + +```dart +Chart( + mainSeries: LineSeries(ticks), + pipSize: 2, + annotations: [ + TickIndicator( + ticks.last, // The tick to highlight + ), + ], +) +``` + +### Customizing Tick Indicators + +Tick indicators are a subclass of `HorizontalBarrier`, so they can be customized in the same way: + +```dart +TickIndicator( + ticks.last, + style: HorizontalBarrierStyle( + color: Colors.green, + isDashed: false, + lineThickness: 1.5, + labelBackgroundColor: Colors.green.withOpacity(0.8), + labelTextStyle: TextStyle( + color: Colors.white, + fontSize: 12, + fontWeight: FontWeight.bold, + ), + ), +) +``` + +By default, tick indicators use `HorizontalBarrierVisibility.forceToStayOnRange` to ensure they are always visible. + +## Multiple Annotations + +You can add multiple annotations to a chart by including them in the `annotations` list: + +```dart +Chart( + mainSeries: LineSeries(ticks), + pipSize: 2, + annotations: [ + // Horizontal barriers + HorizontalBarrier(125.50, title: 'Resistance'), + HorizontalBarrier(115.75, title: 'Support'), + + // Vertical barriers + VerticalBarrier(DateTime(2023, 1, 15, 12, 0), title: 'Market Open'), + VerticalBarrier(DateTime(2023, 1, 15, 20, 0), title: 'Market Close'), + + // Tick indicator + TickIndicator(ticks.last), + ], +) +``` + +## Dynamic Annotations + +You can dynamically update annotations based on data changes or user interactions: + +```dart +class DynamicAnnotationsExample extends StatefulWidget { + final List ticks; + + const DynamicAnnotationsExample({ + Key? key, + required this.ticks, + }) : super(key: key); + + @override + State createState() => _DynamicAnnotationsExampleState(); +} + +class _DynamicAnnotationsExampleState extends State { + late List _annotations; + + @override + void initState() { + super.initState(); + _updateAnnotations(); + } + + void _updateAnnotations() { + // Calculate average price + double sum = 0; + for (final tick in widget.ticks) { + sum += tick.quote; + } + final averagePrice = sum / widget.ticks.length; + + // Create annotations + _annotations = [ + HorizontalBarrier( + averagePrice, + title: 'Average: ${averagePrice.toStringAsFixed(2)}', + style: HorizontalBarrierStyle( + color: Colors.purple, + isDashed: true, + ), + ), + TickIndicator(widget.ticks.last), + ]; + } + + @override + void didUpdateWidget(DynamicAnnotationsExample oldWidget) { + super.didUpdateWidget(oldWidget); + if (widget.ticks != oldWidget.ticks) { + _updateAnnotations(); + } + } + + @override + Widget build(BuildContext context) { + return Chart( + mainSeries: LineSeries(widget.ticks), + pipSize: 2, + annotations: _annotations, + ); + } +} +``` + +## Custom Annotations + +You can create custom annotations by extending the `ChartAnnotation` class: + +```dart +class RangeAnnotation extends ChartAnnotation { + final double upperValue; + final double lowerValue; + final String? title; + final Color color; + + RangeAnnotation({ + required this.upperValue, + required this.lowerValue, + this.title, + this.color = Colors.blue, + super.id, + }); + + @override + ChartObject createObject() { + return RangeObject( + upperValue: upperValue, + lowerValue: lowerValue, + title: title, + ); + } + + @override + SeriesPainter createPainter() { + return RangeAnnotationPainter(this); + } +} + +class RangeObject extends ChartObject { + final double upperValue; + final double lowerValue; + final String? title; + + RangeObject({ + required this.upperValue, + required this.lowerValue, + this.title, + }); + + @override + bool isOnValueRange(double minValue, double maxValue) { + return upperValue >= minValue || lowerValue <= maxValue; + } + + @override + bool isOnEpochRange(int minEpoch, int maxEpoch) { + return true; // Range spans the entire x-axis + } +} + +class RangeAnnotationPainter extends SeriesPainter { + final RangeAnnotation annotation; + + RangeAnnotationPainter(this.annotation) : super(annotation); + + @override + void onPaint( + Canvas canvas, + Size size, + double Function(DateTime) xFromEpoch, + double Function(double) yFromQuote, + ) { + final upperY = yFromQuote(annotation.upperValue); + final lowerY = yFromQuote(annotation.lowerValue); + + // Draw the range rectangle + final paint = Paint() + ..color = annotation.color.withOpacity(0.2) + ..style = PaintingStyle.fill; + + canvas.drawRect( + Rect.fromPoints( + Offset(0, upperY), + Offset(size.width, lowerY), + ), + paint, + ); + + // Draw the range borders + final borderPaint = Paint() + ..color = annotation.color + ..strokeWidth = 1 + ..style = PaintingStyle.stroke; + + canvas.drawLine( + Offset(0, upperY), + Offset(size.width, upperY), + borderPaint, + ); + + canvas.drawLine( + Offset(0, lowerY), + Offset(size.width, lowerY), + borderPaint, + ); + + // Draw the title if provided + if (annotation.title != null) { + final textPainter = TextPainter( + text: TextSpan( + text: annotation.title, + style: TextStyle( + color: annotation.color, + fontSize: 12, + fontWeight: FontWeight.bold, + ), + ), + textDirection: TextDirection.ltr, + ); + + textPainter.layout(); + textPainter.paint( + canvas, + Offset(10, upperY + 5), + ); + } + } +} +``` + +Usage of the custom annotation: + +```dart +Chart( + mainSeries: LineSeries(ticks), + pipSize: 2, + annotations: [ + RangeAnnotation( + upperValue: 130.0, + lowerValue: 120.0, + title: 'Trading Range', + color: Colors.orange, + ), + ], +) +``` + +## Best Practices + +When using annotations, consider the following best practices: + +1. **Use sparingly**: Too many annotations can clutter the chart and make it difficult to read +2. **Use consistent styling**: Use consistent colors and styles for similar types of annotations +3. **Provide clear labels**: Use descriptive labels to explain the significance of each annotation +4. **Update dynamically**: Update annotations when relevant data changes +5. **Consider visibility**: Ensure annotations are visible against the chart background + +## Next Steps + +Now that you understand how to use annotations in the Deriv Chart library, you can explore: + +- [Markers](markers.md) - Learn how to use markers to highlight specific points +- [Crosshair](crosshair.md) - Understand how to use the crosshair for precise data inspection +- [Drawing Tools](drawing_tools/overview.md) - Explore interactive drawing tools for technical analysis \ No newline at end of file diff --git a/doc/features/crosshair.md b/doc/features/crosshair.md new file mode 100644 index 000000000..102e8bebc --- /dev/null +++ b/doc/features/crosshair.md @@ -0,0 +1,327 @@ +# Crosshair + +This document explains how to use and customize the crosshair feature in the Deriv Chart library, which provides precise data inspection capabilities. + +## Introduction to Crosshair + +The crosshair is a tool that helps users inspect specific data points on a chart. It consists of horizontal and vertical lines that intersect at the point of interest, along with labels showing the exact time and price values at that point. + +In the Deriv Chart library, the crosshair is activated by a long press on the chart and can be customized to suit different needs. + +## Basic Usage + +By default, the crosshair is enabled in the Chart widget: + +```dart +Chart( + mainSeries: LineSeries(ticks), + pipSize: 2, + // Crosshair is enabled by default +) +``` + +You can explicitly enable or disable the crosshair: + +```dart +Chart( + mainSeries: LineSeries(ticks), + pipSize: 2, + showCrosshair: true, // or false to disable +) +``` + +## Crosshair Behavior + +The crosshair in the Deriv Chart library has the following behavior: + +1. **Activation**: The crosshair is activated by a long press on the chart +2. **Movement**: Once activated, the crosshair follows the user's finger or cursor as they move across the chart +3. **Deactivation**: The crosshair is deactivated when the user releases their finger or cursor +4. **Data Display**: The crosshair shows the exact time and price values at the intersection point +5. **Snap to Data**: The crosshair can snap to the nearest data point for more precise inspection + +## Customizing Crosshair Appearance + +You can customize the appearance of the crosshair by providing a custom theme with a `CrosshairStyle`: + +```dart +class CustomTheme extends ChartDefaultDarkTheme { + @override + CrosshairStyle get crosshairStyle => CrosshairStyle( + lineColor: Colors.orange, + lineThickness: 1, + lineDashPattern: [5, 5], // Dashed line + labelBackgroundColor: Colors.orange.withOpacity(0.8), + labelTextStyle: TextStyle( + color: Colors.white, + fontSize: 12, + fontWeight: FontWeight.bold, + ), + labelPadding: EdgeInsets.symmetric(horizontal: 8, vertical: 4), + labelBorderRadius: 4, + ); +} + +// Using the custom theme +Chart( + mainSeries: LineSeries(ticks), + pipSize: 2, + theme: CustomTheme(), +) +``` + +## Crosshair Callbacks + +The Chart widget provides callbacks to respond to crosshair events: + +```dart +Chart( + mainSeries: LineSeries(ticks), + pipSize: 2, + onCrosshairAppeared: () { + print('Crosshair appeared'); + // Provide haptic feedback or update UI + HapticFeedback.lightImpact(); + }, + onCrosshairDisappeared: () { + print('Crosshair disappeared'); + // Update UI or perform cleanup + }, +) +``` + +These callbacks are useful for: +- Providing haptic feedback when the crosshair appears +- Updating other UI elements based on crosshair state +- Logging user interactions for analytics + +## Crosshair with Multiple Charts + +When using multiple charts (main chart and bottom charts), the crosshair is synchronized across all charts: + +```dart +Chart( + mainSeries: CandleSeries(candles), + bottomConfigs: [ + RSIIndicatorConfig(period: 14), + MACDIndicatorConfig(), + ], + pipSize: 2, + // Crosshair will be synchronized across all charts +) +``` + +This synchronization ensures that: +1. The vertical line of the crosshair aligns across all charts +2. Each chart shows its own horizontal line and price label +3. Only one time label is shown (typically at the bottom) + +## Crosshair Data Inspection + +The crosshair helps users inspect data in several ways: + +### Price Inspection + +The horizontal line and label show the exact price at the crosshair position: + +``` +Price: 125.50 +``` + +### Time Inspection + +The vertical line and label show the exact time at the crosshair position: + +``` +Time: 2023-01-15 12:30:45 +``` + +### Data Point Inspection + +When the crosshair snaps to a data point, it can show additional information about that point: + +For candlestick charts: +``` +O: 125.00 H: 126.50 +L: 124.75 C: 125.50 +``` + +For indicator charts: +``` +RSI: 65.75 +``` + +## Implementing Custom Crosshair Behavior + +You can implement custom crosshair behavior by combining the crosshair with other features: + +### Example: Displaying Detailed Information in a Tooltip + +```dart +class CrosshairTooltipExample extends StatefulWidget { + final List candles; + + const CrosshairTooltipExample({ + Key? key, + required this.candles, + }) : super(key: key); + + @override + State createState() => _CrosshairTooltipExampleState(); +} + +class _CrosshairTooltipExampleState extends State { + Candle? _selectedCandle; + Offset? _tooltipPosition; + + @override + Widget build(BuildContext context) { + return Stack( + children: [ + Chart( + mainSeries: CandleSeries(widget.candles), + pipSize: 2, + onLongPressStart: (details) { + _updateSelectedCandle(details.localPosition); + }, + onLongPressMoveUpdate: (details) { + _updateSelectedCandle(details.localPosition); + }, + onLongPressEnd: (details) { + setState(() { + _selectedCandle = null; + _tooltipPosition = null; + }); + }, + ), + if (_selectedCandle != null && _tooltipPosition != null) + Positioned( + left: _tooltipPosition!.dx + 10, + top: _tooltipPosition!.dy - 70, + child: Container( + padding: EdgeInsets.all(8), + decoration: BoxDecoration( + color: Colors.black.withOpacity(0.8), + borderRadius: BorderRadius.circular(4), + ), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisSize: MainAxisSize.min, + children: [ + Text( + 'Date: ${_formatDate(_selectedCandle!.epoch)}', + style: TextStyle(color: Colors.white), + ), + Text( + 'Open: ${_selectedCandle!.open.toStringAsFixed(2)}', + style: TextStyle(color: Colors.white), + ), + Text( + 'High: ${_selectedCandle!.high.toStringAsFixed(2)}', + style: TextStyle(color: Colors.white), + ), + Text( + 'Low: ${_selectedCandle!.low.toStringAsFixed(2)}', + style: TextStyle(color: Colors.white), + ), + Text( + 'Close: ${_selectedCandle!.close.toStringAsFixed(2)}', + style: TextStyle(color: Colors.white), + ), + ], + ), + ), + ), + ], + ); + } + + void _updateSelectedCandle(Offset position) { + // Find the candle at the position + // This is a simplified example - in a real app, you would use the chart's + // coordinate conversion functions to find the exact candle + final index = (position.dx / context.size!.width * widget.candles.length).floor(); + if (index >= 0 && index < widget.candles.length) { + setState(() { + _selectedCandle = widget.candles[index]; + _tooltipPosition = position; + }); + } + } + + String _formatDate(DateTime date) { + return '${date.year}-${date.month.toString().padLeft(2, '0')}-${date.day.toString().padLeft(2, '0')}'; + } +} +``` + +### Example: Synchronizing Crosshair Between Multiple Charts + +```dart +class SynchronizedCrosshairExample extends StatefulWidget { + final List candles; + + const SynchronizedCrosshairExample({ + Key? key, + required this.candles, + }) : super(key: key); + + @override + State createState() => _SynchronizedCrosshairExampleState(); +} + +class _SynchronizedCrosshairExampleState extends State { + final _controller1 = ChartController(); + final _controller2 = ChartController(); + + @override + Widget build(BuildContext context) { + return Column( + children: [ + Expanded( + child: Chart( + mainSeries: CandleSeries(widget.candles), + pipSize: 2, + controller: _controller1, + onVisibleAreaChanged: (leftEpoch, rightEpoch) { + // Synchronize the visible area of the second chart + _controller2.scrollTo(DateTime.fromMillisecondsSinceEpoch(leftEpoch)); + _controller2.scale(_controller1.msPerPx); + }, + ), + ), + Expanded( + child: Chart( + mainSeries: LineSeries(widget.candles.map((c) => Tick(epoch: c.epoch, quote: c.close)).toList()), + pipSize: 2, + controller: _controller2, + onVisibleAreaChanged: (leftEpoch, rightEpoch) { + // Synchronize the visible area of the first chart + _controller1.scrollTo(DateTime.fromMillisecondsSinceEpoch(leftEpoch)); + _controller1.scale(_controller2.msPerPx); + }, + ), + ), + ], + ); + } +} +``` + +## Best Practices + +When using the crosshair feature, consider the following best practices: + +1. **Provide feedback**: Use the `onCrosshairAppeared` callback to provide haptic feedback when the crosshair appears +2. **Customize appearance**: Customize the crosshair appearance to match your app's theme +3. **Consider visibility**: Ensure the crosshair is visible against the chart background +4. **Enhance with tooltips**: Consider adding custom tooltips to provide more detailed information +5. **Test on different devices**: Test the crosshair behavior on different devices and screen sizes + +## Next Steps + +Now that you understand how to use the crosshair feature in the Deriv Chart library, you can explore: + +- [Annotations](annotations.md) - Learn how to use annotations to highlight specific areas +- [Markers](markers.md) - Learn how to use markers to highlight specific points +- [Drawing Tools](drawing_tools/overview.md) - Explore interactive drawing tools for technical analysis \ No newline at end of file diff --git a/doc/features/drawing_tools/overview.md b/doc/features/drawing_tools/overview.md new file mode 100644 index 000000000..b3f217002 --- /dev/null +++ b/doc/features/drawing_tools/overview.md @@ -0,0 +1,362 @@ +# Drawing Tools Overview + +This document provides an overview of the drawing tools available in the Deriv Chart library, explaining their purpose, categories, and how to use them. + +## Introduction to Drawing Tools + +Drawing tools allow traders to add visual elements to charts for technical analysis. These tools help identify patterns, trends, support and resistance levels, and other significant price points. The Deriv Chart library provides a comprehensive set of drawing tools to enhance chart analysis. + +## Drawing Tool Categories + +The Deriv Chart library organizes drawing tools into several categories: + +### Lines and Channels + +Lines and channels help identify trends, support and resistance levels, and price patterns. + +Available line and channel tools: +- Horizontal Line +- Vertical Line +- Trend Line +- Ray Line +- Extended Line +- Parallel Channel +- Regression Channel + +[Learn more about Lines and Channels](lines_and_channels.md) + +### Fibonacci Tools + +Fibonacci tools are based on the Fibonacci sequence and ratios, which are believed to have significance in financial markets. + +Available Fibonacci tools: +- Fibonacci Retracement +- Fibonacci Extension +- Fibonacci Fan +- Fibonacci Arc +- Fibonacci Time Zones + +[Learn more about Fibonacci Tools](fibonacci_tools.md) + +### Geometric Shapes + +Geometric shapes help identify chart patterns and areas of interest. + +Available geometric shapes: +- Rectangle +- Triangle +- Ellipse +- Polygon +- Arc + +### Text and Annotations + +Text and annotations allow adding notes and labels to the chart. + +Available text and annotation tools: +- Text +- Callout +- Arrow +- Label + +## Interactive Layer Architecture + +The Deriv Chart library implements drawing tools using an Interactive Layer that manages user interactions: + +``` +┌─────────────────────────┐ +│ Interactive Layer │ +└─────────────┬───────────┘ + │ + ▼ +┌─────────────────────────┐ +│ InteractiveState │ +└─────────────┬───────────┘ + │ + ├─────────────────┬─────────────────┬─────────────────┐ + │ │ │ │ + ▼ ▼ ▼ ▼ +┌─────────────────┐┌─────────────────┐┌─────────────────┐┌─────────────────┐ +│ NormalState ││SelectedToolState││ AddingToolState ││ HoverState │ +└─────────────────┘└─────────────────┘└─────────────────┘└─────────────────┘ +``` + +The Interactive Layer: +- Handles user gestures (taps, drags, hovers) +- Manages the lifecycle of drawing tools +- Implements a state pattern for different interaction modes +- Controls the visual appearance of drawing tools + +## Using Drawing Tools in the Chart + +### Basic Usage with DerivChart + +The `DerivChart` widget provides built-in UI for adding and managing drawing tools: + +```dart +DerivChart( + mainSeries: CandleSeries(candles), + granularity: 60, + activeSymbol: 'R_100', + pipSize: 2, +) +``` + +This includes: +- A drawing tools button in the chart toolbar +- A drawing tools menu for selecting tools +- Tool-specific configuration options +- Persistent storage of drawing tools + +### Custom Drawing Tools Management + +For more control, you can create your own `AddOnsRepository` for drawing tools: + +```dart +final drawingToolsRepo = AddOnsRepository( + createAddOn: (Map map) => DrawingToolConfig.fromJson(map), + onEditCallback: (int index) { + // Handle editing of drawing tool at index + }, + sharedPrefKey: 'R_100_drawing_tools', +); + +// Load saved drawing tools +await drawingToolsRepo.loadFromPrefs( + await SharedPreferences.getInstance(), + 'R_100_drawing_tools', +); + +// Use the repository with DerivChart +DerivChart( + mainSeries: CandleSeries(candles), + drawingToolsRepo: drawingToolsRepo, + granularity: 60, + pipSize: 2, +) +``` + +## Drawing Tool States + +Each drawing tool can be in one of the following states: + +- **normal**: Default state when the tool is displayed but not being interacted with +- **selected**: The tool is selected and can be manipulated +- **hovered**: The user's pointer is hovering over the tool +- **adding**: The tool is in the process of being created +- **dragging**: The tool is being moved or resized + +These states determine how the tool is rendered and how it responds to user interactions. + +## Drawing Tool Interaction Flow + +The typical flow for adding and interacting with drawing tools is: + +1. **Tool Selection**: User selects a drawing tool from the menu +2. **Tool Creation**: User taps on the chart to define the tool's points + - For a line: tap for start point, tap for end point + - For a rectangle: tap for one corner, tap for opposite corner + - For more complex tools: multiple taps to define all required points +3. **Tool Manipulation**: After creation, the tool can be: + - Selected by tapping on it + - Moved by dragging it + - Resized by dragging its control points + - Configured through the properties panel + - Deleted using the delete button or keyboard + +## Drawing Tool Configuration + +Each drawing tool has its own configuration options: + +### Style Properties + +Common style properties include: +- Line color +- Line thickness +- Line style (solid, dashed, etc.) +- Fill color and opacity +- Text properties (for tools with labels) + +### Tool-Specific Properties + +Each tool type has specific properties: + +- **Fibonacci Retracement**: Levels, labels, colors +- **Trend Line**: Extension options, label options +- **Rectangle**: Border style, fill options +- **Text**: Font, size, alignment + +## Example: Adding a Trend Line + +```dart +// Create a trend line configuration +final trendLineConfig = TrendLineConfig( + style: DrawingPaintStyle( + color: Colors.blue, + thickness: 2, + isDashed: false, + ), +); + +// Add it to the repository +drawingToolsRepo.add(trendLineConfig); +``` + +## Example: Customizing a Drawing Tool + +```dart +// Get the existing tool +final existingTool = drawingToolsRepo.items[0] as TrendLineConfig; + +// Create an updated version +final updatedTool = TrendLineConfig( + id: existingTool.id, // Keep the same ID + style: DrawingPaintStyle( + color: Colors.red, + thickness: 3, + isDashed: true, + ), +); + +// Update it in the repository +drawingToolsRepo.updateAt(0, updatedTool); +``` + +## Implementing Custom Drawing Tools + +You can create custom drawing tools by implementing the required classes: + +1. **DrawingToolConfig**: Configuration for the tool +2. **InteractableDrawing**: The drawing implementation +3. **DrawingCreator**: Logic for creating the drawing + +### Example: Custom Drawing Tool + +```dart +// Configuration +class CustomToolConfig extends DrawingToolConfig { + final DrawingPaintStyle style; + + CustomToolConfig({ + required this.style, + super.id, + }); + + @override + String get name => 'Custom Tool'; + + @override + InteractableDrawing createDrawing() => CustomInteractableDrawing( + style: style, + ); + + @override + Map toJson() => { + 'id': id, + 'type': 'CustomTool', + 'style': style.toJson(), + }; + + factory CustomToolConfig.fromJson(Map json) => CustomToolConfig( + id: json['id'], + style: DrawingPaintStyle.fromJson(json['style']), + ); +} + +// Drawing Implementation +class CustomInteractableDrawing extends InteractableDrawing { + final List points = []; + + CustomInteractableDrawing({ + required DrawingPaintStyle style, + }) : super(style: style); + + @override + bool hitTest(Offset point) { + // Implement hit testing logic + if (points.length < 2) return false; + + for (int i = 0; i < points.length - 1; i++) { + if (isPointNearLine(point, points[i], points[i + 1])) { + return true; + } + } + + return false; + } + + @override + void paint(Canvas canvas, Size size) { + if (points.length < 2) return; + + final paint = Paint() + ..color = style.color + ..strokeWidth = style.thickness + ..style = PaintingStyle.stroke; + + final path = Path(); + path.moveTo(points.first.dx, points.first.dy); + + for (int i = 1; i < points.length; i++) { + path.lineTo(points[i].dx, points[i].dy); + } + + canvas.drawPath(path, paint); + } + + @override + void onDrag(Offset delta) { + for (int i = 0; i < points.length; i++) { + points[i] = points[i] + delta; + } + } + + bool isPointNearLine(Offset point, Offset lineStart, Offset lineEnd) { + // Calculate distance from point to line + final double lineLength = (lineEnd - lineStart).distance; + if (lineLength == 0) return false; + + final double t = ((point.dx - lineStart.dx) * (lineEnd.dx - lineStart.dx) + + (point.dy - lineStart.dy) * (lineEnd.dy - lineStart.dy)) / + (lineLength * lineLength); + + if (t < 0) { + return (point - lineStart).distance < 10; + } else if (t > 1) { + return (point - lineEnd).distance < 10; + } else { + final Offset projection = lineStart + (lineEnd - lineStart) * t; + return (point - projection).distance < 10; + } + } +} + +// Drawing Creator +class CustomToolCreator extends DrawingCreator { + @override + void onTap(Offset position) { + if (drawing == null) { + drawing = CustomInteractableDrawing( + style: config.style, + ); + (drawing as CustomInteractableDrawing).points.add(position); + } else { + (drawing as CustomInteractableDrawing).points.add(position); + + // If we have enough points, complete the drawing + if ((drawing as CustomInteractableDrawing).points.length >= 3) { + onAddDrawing(); + } + } + } +} +``` + +## Next Steps + +Now that you understand the drawing tools available in the Deriv Chart library, you can explore: + +- [Lines and Channels](lines_and_channels.md) - Learn about line and channel tools +- [Fibonacci Tools](fibonacci_tools.md) - Learn about Fibonacci tools +- [Custom Tools](custom_tools.md) - Learn how to create custom drawing tools +- [Interactive Layer](../interactive_layer.md) - Understand the interactive layer architecture \ No newline at end of file diff --git a/doc/features/indicators/overview.md b/doc/features/indicators/overview.md new file mode 100644 index 000000000..02045522c --- /dev/null +++ b/doc/features/indicators/overview.md @@ -0,0 +1,370 @@ +# Technical Indicators Overview + +This document provides an overview of the technical indicators available in the Deriv Chart library, explaining their purpose, categories, and how to use them. + +## Introduction to Technical Indicators + +Technical indicators are mathematical calculations based on price, volume, or open interest of a security or contract. They are used to forecast price direction and to generate trading signals. The Deriv Chart library provides a comprehensive set of technical indicators to help traders analyze market data and make informed decisions. + +## Indicator Categories + +The Deriv Chart library organizes indicators into several categories: + +### Moving Averages + +Moving averages smooth out price data to create a single flowing line, making it easier to identify trends. They are the building blocks for many other technical indicators. + +Available moving averages: +- Simple Moving Average (SMA) +- Exponential Moving Average (EMA) +- Double Exponential Moving Average (DEMA) +- Triple Exponential Moving Average (TEMA) +- Triangular Moving Average (TRIMA) +- Weighted Moving Average (WMA) +- Modified Moving Average (MMA) +- Least Squares Moving Average (LSMA) +- Hull Moving Average (HMA) +- Variable Moving Average (VMA) +- Welles Wilder Smoothing Moving Average (WWSMA) +- Zero-Lag Exponential Moving Average (ZELMA) + +[Learn more about Moving Averages](moving_averages.md) + +### Oscillators + +Oscillators are indicators that fluctuate above and below a centerline or between upper and lower bounds. They help identify overbought or oversold conditions and potential trend reversals. + +Available oscillators: +- Relative Strength Index (RSI) +- Stochastic Momentum Index (SMI) +- Moving Average Convergence Divergence (MACD) +- Awesome Oscillator +- Williams %R +- Rate of Change (ROC) +- Chande Momentum Oscillator (CMO) +- Gator Oscillator + +[Learn more about Oscillators](oscillators.md) + +### Trend Indicators + +Trend indicators help identify the direction of the market trend and potential changes in that direction. + +Available trend indicators: +- Average Directional Index (ADX) +- Parabolic SAR +- Ichimoku Cloud + +[Learn more about Trend Indicators](trend_indicators.md) + +### Volatility Indicators + +Volatility indicators measure the rate of price movement, regardless of direction. They help traders identify potential breakouts or periods of consolidation. + +Available volatility indicators: +- Bollinger Bands +- Average True Range (ATR) +- Standard Deviation +- Variance + +[Learn more about Volatility Indicators](volatility.md) + +### Channel Indicators + +Channel indicators create bands that contain price movement, helping traders identify potential support and resistance levels. + +Available channel indicators: +- Donchian Channel +- Moving Average Envelope +- Fixed Channel Bands (FCB) + +## Using Indicators in the Chart + +The Deriv Chart library provides two ways to add indicators to your charts: + +1. **Overlay Indicators**: These indicators share the same Y-axis as the main chart and are drawn on top of it. +2. **Bottom Indicators**: These indicators have their own Y-axis and are drawn below the main chart. + +### Adding Indicators + +You can add indicators to your chart using the `overlayConfigs` and `bottomConfigs` parameters: + +```dart +Chart( + mainSeries: CandleSeries(candles), + // Overlay indicators (on the main chart) + overlayConfigs: [ + // Bollinger Bands + BollingerBandsIndicatorConfig( + period: 20, + standardDeviation: 2, + movingAverageType: MovingAverageType.exponential, + upperLineStyle: LineStyle(color: Colors.purple), + middleLineStyle: LineStyle(color: Colors.black), + lowerLineStyle: LineStyle(color: Colors.blue), + ), + // Simple Moving Average + MAIndicatorConfig( + period: 14, + type: MovingAverageType.simple, + lineStyle: LineStyle(color: Colors.red), + ), + ], + // Bottom indicators (separate charts) + bottomConfigs: [ + // Relative Strength Index + RSIIndicatorConfig( + period: 14, + lineStyle: LineStyle(color: Colors.green), + oscillatorLinesConfig: OscillatorLinesConfig( + overboughtValue: 70, + oversoldValue: 30, + ), + showZones: true, + ), + // Moving Average Convergence Divergence + MACDIndicatorConfig( + fastPeriod: 12, + slowPeriod: 26, + signalPeriod: 9, + lineStyle: LineStyle(color: Colors.blue), + signalLineStyle: LineStyle(color: Colors.red), + histogramStyle: HistogramStyle( + positiveColor: Colors.green, + negativeColor: Colors.red, + ), + ), + ], + pipSize: 2, +) +``` + +### Using DerivChart for Indicator Management + +The `DerivChart` widget provides a more user-friendly way to manage indicators: + +```dart +DerivChart( + mainSeries: CandleSeries(candles), + granularity: 60, + activeSymbol: 'R_100', + pipSize: 2, +) +``` + +This widget includes UI controls for adding, removing, and configuring indicators. It also saves indicator settings to persistent storage. + +### Creating a Custom Indicator Repository + +For more control over indicator management, you can create your own `AddOnsRepository`: + +```dart +final indicatorsRepo = AddOnsRepository( + createAddOn: (Map map) => IndicatorConfig.fromJson(map), + onEditCallback: (int index) { + // Handle editing of indicator at index + }, + sharedPrefKey: 'R_100', +); + +// Load saved indicators +await indicatorsRepo.loadFromPrefs( + await SharedPreferences.getInstance(), + 'R_100', +); + +// Add an indicator +indicatorsRepo.add(RSIIndicatorConfig(period: 14)); + +// Remove an indicator +indicatorsRepo.removeAt(0); + +// Update an indicator +indicatorsRepo.updateAt(0, RSIIndicatorConfig(period: 21)); + +// Use the repository with DerivChart +DerivChart( + mainSeries: CandleSeries(candles), + indicatorsRepo: indicatorsRepo, + granularity: 60, + pipSize: 2, +) +``` + +## Indicator Configuration + +Each indicator has its own configuration class that extends `IndicatorConfig`. These classes provide parameters to customize the indicator's behavior and appearance. + +### Common Configuration Parameters + +Most indicators share these common parameters: + +- **period**: The number of data points used in the calculation +- **lineStyle**: The style of the indicator line (color, thickness, etc.) +- **offset**: The number of periods to shift the indicator (positive for right, negative for left) + +### Example: RSI Configuration + +```dart +RSIIndicatorConfig( + period: 14, + lineStyle: LineStyle( + color: Colors.green, + thickness: 1, + ), + oscillatorLinesConfig: OscillatorLinesConfig( + overboughtValue: 70, + oversoldValue: 30, + overboughtStyle: LineStyle(color: Colors.red), + oversoldStyle: LineStyle(color: Colors.green), + ), + showZones: true, +) +``` + +### Example: Bollinger Bands Configuration + +```dart +BollingerBandsIndicatorConfig( + period: 20, + standardDeviation: 2, + movingAverageType: MovingAverageType.exponential, + upperLineStyle: LineStyle(color: Colors.purple), + middleLineStyle: LineStyle(color: Colors.black), + lowerLineStyle: LineStyle(color: Colors.blue), +) +``` + +## Creating Custom Indicators + +You can create custom indicators by extending the appropriate base classes: + +1. Create a configuration class that extends `IndicatorConfig` +2. Create a series class that extends `AbstractSingleIndicatorSeries` or `Series` +3. Create a painter class that extends `DataPainter` + +Example of a custom indicator: + +```dart +// Configuration +class CustomIndicatorConfig extends IndicatorConfig { + final int period; + final LineStyle lineStyle; + + CustomIndicatorConfig({ + required this.period, + this.lineStyle = const LineStyle(), + super.id, + }); + + @override + String get name => 'Custom ($period)'; + + @override + bool get isOverlay => true; + + @override + Series createSeries(List candles) => CustomIndicatorSeries( + candles, + period: period, + lineStyle: lineStyle, + ); + + @override + Map toJson() => { + 'id': id, + 'type': 'Custom', + 'period': period, + 'lineStyle': lineStyle.toJson(), + }; + + factory CustomIndicatorConfig.fromJson(Map json) => CustomIndicatorConfig( + id: json['id'], + period: json['period'], + lineStyle: LineStyle.fromJson(json['lineStyle']), + ); +} + +// Series +class CustomIndicatorSeries extends AbstractSingleIndicatorSeries { + final int period; + final LineStyle lineStyle; + + CustomIndicatorSeries( + List candles, { + required this.period, + required this.lineStyle, + }) : super(candles); + + @override + List _calculateIndicatorValues() { + final result = []; + + // Custom calculation logic + for (int i = period - 1; i < candles.length; i++) { + double sum = 0; + for (int j = 0; j < period; j++) { + sum += candles[i - j].close; + } + final value = sum / period; + + result.add(Tick( + epoch: candles[i].epoch, + quote: value, + )); + } + + return result; + } + + @override + SeriesPainter createPainter() => CustomIndicatorPainter(this); +} + +// Painter +class CustomIndicatorPainter extends DataPainter { + final CustomIndicatorSeries series; + + CustomIndicatorPainter(this.series) : super(series); + + @override + void onPaintData( + Canvas canvas, + Size size, + List data, + double Function(DateTime) xFromEpoch, + double Function(double) yFromQuote, + ) { + if (data.isEmpty) return; + + final path = Path(); + final paint = Paint() + ..color = series.lineStyle.color + ..strokeWidth = series.lineStyle.thickness + ..style = PaintingStyle.stroke; + + path.moveTo( + xFromEpoch(data.first.epoch), + yFromQuote(data.first.quote), + ); + + for (int i = 1; i < data.length; i++) { + path.lineTo( + xFromEpoch(data[i].epoch), + yFromQuote(data[i].quote), + ); + } + + canvas.drawPath(path, paint); + } +} +``` + +## Next Steps + +Now that you understand the technical indicators available in the Deriv Chart library, you can explore: + +- [Moving Averages](moving_averages.md) - Learn about moving average indicators +- [Oscillators](oscillators.md) - Learn about oscillator indicators +- [Volatility Indicators](volatility.md) - Learn about volatility indicators +- [Custom Indicators](custom_indicators.md) - Learn how to create custom indicators \ No newline at end of file diff --git a/doc/features/markers.md b/doc/features/markers.md new file mode 100644 index 000000000..ec88a3d07 --- /dev/null +++ b/doc/features/markers.md @@ -0,0 +1,476 @@ +# Chart Markers + +This document explains how to use markers in the Deriv Chart library to highlight specific points on the chart and enable user interactions with those points. + +## Introduction to Markers + +Markers are visual elements that highlight specific data points on a chart. Unlike annotations, which typically span across the chart (like horizontal or vertical lines), markers are attached to specific data points and can respond to user interactions. + +The Deriv Chart library provides several types of markers: +- Standard markers (up, down, neutral) +- Active markers (highlighted markers with special interaction behavior) +- Entry and exit tick markers + +## MarkerSeries + +All markers are managed through the `MarkerSeries` class, which is passed to the `Chart` widget: + +```dart +Chart( + mainSeries: LineSeries(ticks), + pipSize: 2, + markerSeries: MarkerSeries([ + // List of markers + ]), +) +``` + +## Standard Markers + +Standard markers highlight specific data points on the chart. They can be configured with different styles and can respond to user interactions. + +### Basic Usage + +```dart +Chart( + mainSeries: LineSeries(ticks), + pipSize: 2, + markerSeries: MarkerSeries([ + Marker.up( + epoch: ticks[5].epoch, + quote: ticks[5].quote, + onTap: () { + print('Up marker tapped'); + }, + ), + Marker.down( + epoch: ticks[10].epoch, + quote: ticks[10].quote, + onTap: () { + print('Down marker tapped'); + }, + ), + Marker.neutral( + epoch: ticks[15].epoch, + quote: ticks[15].quote, + onTap: () { + print('Neutral marker tapped'); + }, + ), + ]), +) +``` + +### Marker Types + +The Deriv Chart library provides three types of standard markers: + +1. **Up Marker**: Typically used to indicate a positive event or an entry point + ```dart + Marker.up( + epoch: DateTime.now(), + quote: 125.50, + onTap: () {}, + ) + ``` + +2. **Down Marker**: Typically used to indicate a negative event or an exit point + ```dart + Marker.down( + epoch: DateTime.now(), + quote: 120.75, + onTap: () {}, + ) + ``` + +3. **Neutral Marker**: Used for general points of interest + ```dart + Marker.neutral( + epoch: DateTime.now(), + quote: 123.00, + onTap: () {}, + ) + ``` + +### Customizing Markers + +You can customize markers by providing a custom `MarkerStyle`: + +```dart +Marker.up( + epoch: ticks[5].epoch, + quote: ticks[5].quote, + style: MarkerStyle( + color: Colors.green, + size: 12, + borderWidth: 2, + borderColor: Colors.white, + ), + onTap: () {}, +) +``` + +## Active Marker + +An active marker is a special marker that is highlighted and can have additional interaction behaviors. Typically, only one marker can be active at a time. + +### Basic Usage + +```dart +Chart( + mainSeries: LineSeries(ticks), + pipSize: 2, + markerSeries: MarkerSeries( + [ + // Standard markers + Marker.up(epoch: ticks[5].epoch, quote: ticks[5].quote, onTap: () {}), + Marker.down(epoch: ticks[10].epoch, quote: ticks[10].quote, onTap: () {}), + ], + // Active marker + activeMarker: ActiveMarker( + epoch: ticks[5].epoch, + quote: ticks[5].quote, + onTap: () { + print('Active marker tapped'); + }, + onOutsideTap: () { + print('Tapped outside active marker'); + // Remove active marker + }, + ), + ), +) +``` + +### Active Marker Properties + +The `ActiveMarker` class has the following properties: + +- `epoch`: The timestamp of the marker +- `quote`: The price level of the marker +- `onTap`: Callback when the marker is tapped +- `onOutsideTap`: Callback when the user taps outside the marker + +### Dynamic Active Marker + +You can dynamically update the active marker based on user interactions: + +```dart +class DynamicMarkerExample extends StatefulWidget { + final List ticks; + + const DynamicMarkerExample({ + Key? key, + required this.ticks, + }) : super(key: key); + + @override + State createState() => _DynamicMarkerExampleState(); +} + +class _DynamicMarkerExampleState extends State { + ActiveMarker? _activeMarker; + + @override + Widget build(BuildContext context) { + return Chart( + mainSeries: LineSeries(widget.ticks), + pipSize: 2, + markerSeries: MarkerSeries( + widget.ticks.asMap().entries.map((entry) { + final index = entry.key; + final tick = entry.value; + + // Add a marker every 5 ticks + if (index % 5 == 0) { + return Marker.neutral( + epoch: tick.epoch, + quote: tick.quote, + onTap: () { + setState(() { + _activeMarker = ActiveMarker( + epoch: tick.epoch, + quote: tick.quote, + onTap: () { + print('Active marker tapped'); + }, + onOutsideTap: () { + setState(() { + _activeMarker = null; + }); + }, + ); + }); + }, + ); + } + return null; + }).whereType().toList(), + activeMarker: _activeMarker, + ), + ); + } +} +``` + +## Entry and Exit Tick Markers + +Entry and exit tick markers are special markers that highlight the entry and exit points of a trade or analysis period. + +### Basic Usage + +```dart +Chart( + mainSeries: LineSeries(ticks), + pipSize: 2, + markerSeries: MarkerSeries( + [], // No standard markers + entryTick: Tick( + epoch: ticks.first.epoch, + quote: ticks.first.quote, + ), + exitTick: Tick( + epoch: ticks.last.epoch, + quote: ticks.last.quote, + ), + ), +) +``` + +### Customizing Entry and Exit Tick Markers + +You can customize the appearance of entry and exit tick markers by providing custom styles: + +```dart +Chart( + mainSeries: LineSeries(ticks), + pipSize: 2, + markerSeries: MarkerSeries( + [], + entryTick: Tick( + epoch: ticks.first.epoch, + quote: ticks.first.quote, + ), + exitTick: Tick( + epoch: ticks.last.epoch, + quote: ticks.last.quote, + ), + entryTickStyle: MarkerStyle( + color: Colors.green, + size: 10, + borderWidth: 2, + borderColor: Colors.white, + ), + exitTickStyle: MarkerStyle( + color: Colors.red, + size: 10, + borderWidth: 2, + borderColor: Colors.white, + ), + ), +) +``` + +## Combining Different Marker Types + +You can combine different types of markers in a single chart: + +```dart +Chart( + mainSeries: LineSeries(ticks), + pipSize: 2, + markerSeries: MarkerSeries( + [ + // Standard markers + Marker.up(epoch: ticks[5].epoch, quote: ticks[5].quote, onTap: () {}), + Marker.down(epoch: ticks[10].epoch, quote: ticks[10].quote, onTap: () {}), + ], + // Active marker + activeMarker: ActiveMarker( + epoch: ticks[5].epoch, + quote: ticks[5].quote, + onTap: () {}, + onOutsideTap: () {}, + ), + // Entry and exit ticks + entryTick: Tick( + epoch: ticks.first.epoch, + quote: ticks.first.quote, + ), + exitTick: Tick( + epoch: ticks.last.epoch, + quote: ticks.last.quote, + ), + ), +) +``` + +## Markers with Real-Time Data + +When working with real-time data, you can update markers as new data arrives: + +```dart +class RealTimeMarkerExample extends StatefulWidget { + final Stream tickStream; + + const RealTimeMarkerExample({ + Key? key, + required this.tickStream, + }) : super(key: key); + + @override + State createState() => _RealTimeMarkerExampleState(); +} + +class _RealTimeMarkerExampleState extends State { + final List _ticks = []; + final List _markers = []; + + @override + void initState() { + super.initState(); + widget.tickStream.listen(_onNewTick); + } + + void _onNewTick(Tick tick) { + setState(() { + _ticks.add(tick); + + // Add a marker for significant price movements + if (_ticks.length > 1) { + final previousTick = _ticks[_ticks.length - 2]; + final priceDifference = tick.quote - previousTick.quote; + + if (priceDifference.abs() > 1.0) { + _markers.add( + priceDifference > 0 + ? Marker.up( + epoch: tick.epoch, + quote: tick.quote, + onTap: () {}, + ) + : Marker.down( + epoch: tick.epoch, + quote: tick.quote, + onTap: () {}, + ), + ); + } + } + }); + } + + @override + Widget build(BuildContext context) { + return Chart( + mainSeries: LineSeries(_ticks), + pipSize: 2, + markerSeries: MarkerSeries(_markers), + ); + } +} +``` + +## Custom Markers + +You can create custom markers by extending the `Marker` class: + +```dart +class CustomMarker extends Marker { + final IconData icon; + final Color color; + + CustomMarker({ + required DateTime epoch, + required double quote, + required this.icon, + required this.color, + VoidCallback? onTap, + }) : super( + epoch: epoch, + quote: quote, + type: MarkerType.neutral, // Use neutral as base type + onTap: onTap, + ); + + // Override the paint method to customize the marker appearance + @override + void paint(Canvas canvas, Offset center, double scale) { + final paint = Paint() + ..color = color + ..style = PaintingStyle.fill; + + // Draw a circle background + canvas.drawCircle(center, 10 * scale, paint); + + // Draw the icon + final textPainter = TextPainter( + text: TextSpan( + text: String.fromCharCode(icon.codePoint), + style: TextStyle( + color: Colors.white, + fontSize: 12 * scale, + fontFamily: icon.fontFamily, + ), + ), + textDirection: TextDirection.ltr, + ); + + textPainter.layout(); + textPainter.paint( + canvas, + Offset( + center.dx - textPainter.width / 2, + center.dy - textPainter.height / 2, + ), + ); + } +} +``` + +Usage of the custom marker: + +```dart +Chart( + mainSeries: LineSeries(ticks), + pipSize: 2, + markerSeries: MarkerSeries([ + CustomMarker( + epoch: ticks[5].epoch, + quote: ticks[5].quote, + icon: Icons.star, + color: Colors.orange, + onTap: () { + print('Star marker tapped'); + }, + ), + CustomMarker( + epoch: ticks[10].epoch, + quote: ticks[10].quote, + icon: Icons.warning, + color: Colors.red, + onTap: () { + print('Warning marker tapped'); + }, + ), + ]), +) +``` + +## Best Practices + +When using markers, consider the following best practices: + +1. **Use sparingly**: Too many markers can clutter the chart and make it difficult to read +2. **Provide interaction feedback**: Use the `onTap` callback to provide feedback when a marker is tapped +3. **Use appropriate marker types**: Use up markers for positive events, down markers for negative events, and neutral markers for general points of interest +4. **Consider visibility**: Ensure markers are visible against the chart background +5. **Handle edge cases**: Ensure markers are still visible when they are at the edges of the chart + +## Next Steps + +Now that you understand how to use markers in the Deriv Chart library, you can explore: + +- [Annotations](annotations.md) - Learn how to use annotations to highlight specific areas +- [Crosshair](crosshair.md) - Understand how to use the crosshair for precise data inspection +- [Drawing Tools](drawing_tools/overview.md) - Explore interactive drawing tools for technical analysis \ No newline at end of file diff --git a/doc/getting_started/advanced_features.md b/doc/getting_started/advanced_features.md new file mode 100644 index 000000000..eb45e7453 --- /dev/null +++ b/doc/getting_started/advanced_features.md @@ -0,0 +1,508 @@ +# Advanced Features + +This guide covers advanced features of the Deriv Chart library, including technical indicators, markers, annotations, and drawing tools. + +## Technical Indicators + +The Deriv Chart library provides support for technical indicators that can be displayed either on the main chart (overlay) or in separate charts below the main chart. + +### Adding Indicators to Chart Widget + +You can directly add indicators to the `Chart` widget using the `overlayConfigs` and `bottomConfigs` parameters: + +```dart +Chart( + mainSeries: CandleSeries(candles), + pipSize: 2, + granularity: 60000, + // Indicators displayed on the main chart + overlayConfigs: [ + BollingerBandsIndicatorConfig( + period: 20, + deviation: 2, + maType: MAType.sma, + ), + ], + // Indicators displayed in separate charts below the main chart + bottomConfigs: [ + RSIIndicatorConfig( + period: 14, + overbought: 70, + oversold: 30, + ), + SMIIndicatorConfig( + period: 14, + signalPeriod: 3, + ), + ], +) +``` + +### Using DerivChart for Indicator Management + +For more advanced usage, including saving indicator settings, you can use the `DerivChart` widget with an `AddOnsRepository`: + +```dart +// Create a repository for indicators +final indicatorsRepo = AddOnsRepository( + createAddOn: (Map map) => IndicatorConfig.fromJson(map), + sharedPrefKey: 'R_100', // Use the symbol code for saving settings +); + +// Add indicators to the repository +indicatorsRepo.add(BollingerBandsIndicatorConfig( + period: 20, + deviation: 2, + maType: MAType.sma, +)); + +indicatorsRepo.add(RSIIndicatorConfig( + period: 14, + overbought: 70, + oversold: 30, +)); + +// Use the repository with DerivChart +DerivChart( + mainSeries: CandleSeries(candles), + granularity: 60000, + activeSymbol: 'R_100', + pipSize: 4, + indicatorsRepo: indicatorsRepo, +) +``` + +### Automatic Repository Management + +If you don't provide repositories to `DerivChart`, it will: +- Automatically instantiate its own `indicatorsRepo` and `drawingToolsRepo` +- Display UI icons over the chart to open built-in dialogs for adding, editing, and removing indicators and drawing tools +- Handle saving and loading configurations using the `activeSymbol` as the storage key +- Manage all UI interactions internally + +```dart +// DerivChart with automatic repository management +DerivChart( + mainSeries: CandleSeries(candles), + granularity: 60000, + activeSymbol: 'R_100', + pipSize: 4, + // No indicatorsRepo or drawingToolsRepo provided +) +``` + +### External Repository Management + +If you provide your own repositories, `DerivChart` will: +- Use the provided repositories instead of creating its own +- Not display the built-in UI icons, assuming you'll handle UI interactions externally +- Still apply the indicators and drawing tools from the repositories to the chart + +```dart +// DerivChart with external repository management +DerivChart( + mainSeries: CandleSeries(candles), + granularity: 60000, + activeSymbol: 'R_100', + pipSize: 4, + indicatorsRepo: myIndicatorsRepo, // Externally managed repository + drawingToolsRepo: myDrawingToolsRepo, // Externally managed repository +) +``` + +When using external repositories, you're responsible for: +- Initializing the repositories +- Adding, editing, and removing items from the repositories +- Providing your own UI for managing indicators and drawing tools if needed + +### Available Indicators + +The library includes a comprehensive set of built-in indicators. Here are some of the most commonly used ones: + +| Indicator | Type | Description | +|-----------|------|-------------| +| Bollinger Bands | Overlay | Shows volatility and potential price levels | +| Moving Average | Overlay | Smooths price data to show trends | +| RSI | Bottom | Relative Strength Index measures momentum | +| MACD | Bottom | Moving Average Convergence Divergence | +| Stochastic Oscillator | Bottom | Compares closing price to price range | +| Awesome Oscillator | Bottom | Shows market momentum | +| Ichimoku Cloud | Overlay | Comprehensive trend indicator showing support/resistance | +| Parabolic SAR | Overlay | Identifies potential reversals in market trend | +| ATR | Bottom | Average True Range measures volatility | +| Williams %R | Bottom | Momentum indicator showing overbought/oversold levels | + +This is not an exhaustive list. For a complete list of all available indicators and their implementation details, refer to the [GitHub repository](https://github.com/deriv-com/flutter-chart/tree/master/lib/src/deriv_chart/chart/data_visualization/chart_series/indicators_series). + +## Annotations + +Annotations allow you to add visual elements to the chart, such as horizontal and vertical barriers. + +### Horizontal Barriers + +Horizontal barriers mark specific price levels on the chart: + +```dart +Chart( + mainSeries: LineSeries(ticks), + pipSize: 2, + annotations: [ + HorizontalBarrier( + 125.0, // Price level + title: 'Resistance', + style: HorizontalBarrierStyle( + color: Colors.red, + isDashed: true, + titleBackgroundColor: Colors.red.withOpacity(0.8), + textStyle: TextStyle(color: Colors.white), + labelShape: LabelShape.rectangle, + labelHeight: 24, + labelPadding: 4, + ), + visibility: HorizontalBarrierVisibility.forceToStayOnRange, + ), + ], +) +``` + +### Vertical Barriers + +Vertical barriers mark specific time points on the chart: + +```dart +Chart( + mainSeries: LineSeries(ticks), + pipSize: 2, + annotations: [ + VerticalBarrier( + ticks[2].epoch, // Time point + title: 'Event', + style: VerticalBarrierStyle( + color: Colors.blue, + isDashed: false, + titleBackgroundColor: Colors.blue.withOpacity(0.8), + textStyle: TextStyle(color: Colors.white), + labelPosition: VerticalBarrierLabelPosition.auto, + ), + ), + ], +) +``` + +### Tick Indicators + +Tick indicators highlight specific data points on the chart: + +```dart +Chart( + mainSeries: LineSeries(ticks), + pipSize: 2, + annotations: [ + TickIndicator( + ticks.last, + style: HorizontalBarrierStyle( + labelShape: LabelShape.pentagon, + ), + visibility: HorizontalBarrierVisibility.normal, + ), + ], +) +``` + +### Combined Barriers + +You can also create barriers that have both horizontal and vertical components: + +```dart +Chart( + mainSeries: LineSeries(ticks), + pipSize: 2, + annotations: [ + CombinedBarrier( + ticks.last, + title: 'Combined Barrier', + horizontalBarrierStyle: HorizontalBarrierStyle( + color: Colors.purple, + isDashed: true, + ), + ), + ], +) +``` + +## Markers + +Markers allow you to highlight specific points on the chart with interactive elements. + +### Basic Markers + +```dart +Chart( + mainSeries: LineSeries(ticks), + pipSize: 2, + markerSeries: MarkerSeries([ + Marker.up( + epoch: ticks[1].epoch, + quote: ticks[1].quote, + onTap: () { + print('Up marker tapped'); + } + ), + Marker.down( + epoch: ticks[3].epoch, + quote: ticks[3].quote, + onTap: () { + print('Down marker tapped'); + } + ), + ]), +) +``` + +### Active Marker + +You can also display an active marker that responds to user interactions: + +```dart +Chart( + mainSeries: LineSeries(ticks), + pipSize: 2, + markerSeries: MarkerSeries( + [ + Marker.up(epoch: ticks[1].epoch, quote: ticks[1].quote, onTap: () {}), + Marker.down(epoch: ticks[3].epoch, quote: ticks[3].quote, onTap: () {}), + ], + activeMarker: ActiveMarker( + epoch: ticks[1].epoch, + quote: ticks[1].quote, + onTap: () { + print('Active marker tapped'); + }, + onOutsideTap: () { + print('Tapped outside active marker'); + // Remove active marker + }, + ), + ), +) +``` + +### Entry and Exit Ticks + +You can highlight entry and exit points on the chart: + +```dart +Chart( + mainSeries: LineSeries(ticks), + pipSize: 2, + markerSeries: MarkerSeries( + [], + entryTick: Tick(epoch: ticks[0].epoch, quote: ticks[0].quote), + exitTick: Tick(epoch: ticks.last.epoch, quote: ticks.last.quote), + ), +) +``` + +### Custom Marker Icons + +You can customize the appearance of markers by providing a custom marker icon painter: + +```dart +Chart( + mainSeries: LineSeries(ticks), + pipSize: 2, + markerSeries: MarkerSeries( + markers, + markerIconPainter: CustomMarkerIconPainter(), + ), +) +``` + +## Drawing Tools + +The Deriv Chart library supports interactive drawing tools that allow users to draw on the chart. + +### Using Drawing Tools with DerivChart + +The `DerivChart` widget provides built-in support for drawing tools: + +```dart +DerivChart( + mainSeries: CandleSeries(candles), + granularity: 60000, + activeSymbol: 'R_100', + pipSize: 4, + drawingToolsRepo: myDrawingToolsRepo, // Optional +) +``` + +### Managing Drawing Tools + +Similar to indicators, drawing tools can be managed automatically by DerivChart or through an external repository: + +```dart +// Create a repository for drawing tools +final drawingToolsRepo = AddOnsRepository( + createAddOn: (Map map) => DrawingToolConfig.fromJson(map), + sharedPrefKey: 'R_100', +); + +// Add drawing tools to the repository +drawingToolsRepo.add(LineDrawingToolConfig( + // Configuration options +)); + +// Use the repository with DerivChart +DerivChart( + mainSeries: CandleSeries(candles), + granularity: 60000, + activeSymbol: 'R_100', + pipSize: 4, + drawingToolsRepo: drawingToolsRepo, +) +``` + +### Available Drawing Tools + +The library includes several built-in drawing tools: + +- Line +- Horizontal Line +- Vertical Line +- Trend Line +- Rectangle +- Channel +- Fibonacci Fan +- Ray + +## Real-World Example + +Here's a complete example showing how to use advanced features in a real application: + +```dart +class AdvancedChartScreen extends StatefulWidget { + @override + _AdvancedChartScreenState createState() => _AdvancedChartScreenState(); +} + +class _AdvancedChartScreenState extends State { + final List candles = []; // Your data source + final ChartController controller = ChartController(); + late AddOnsRepository indicatorsRepo; + late AddOnsRepository drawingToolsRepo; + + @override + void initState() { + super.initState(); + + // Initialize repositories + indicatorsRepo = AddOnsRepository( + createAddOn: (Map map) => IndicatorConfig.fromJson(map), + sharedPrefKey: 'R_100', + ); + + drawingToolsRepo = AddOnsRepository( + createAddOn: (Map map) => DrawingToolConfig.fromJson(map), + sharedPrefKey: 'R_100', + ); + + // Add default indicators + indicatorsRepo.add(BollingerBandsIndicatorConfig( + period: 20, + deviation: 2, + maType: MAType.sma, + )); + + indicatorsRepo.add(RSIIndicatorConfig( + period: 14, + overbought: 70, + oversold: 30, + )); + + // Load chart data + _fetchChartData(); + } + + void _fetchChartData() { + // Fetch your chart data here + // When data is received, update the state + setState(() { + // Update candles with new data + }); + } + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar(title: Text('Advanced Chart')), + body: candles.isEmpty + ? Center(child: CircularProgressIndicator()) + : DerivChart( + mainSeries: CandleSeries(candles), + granularity: 60000, + activeSymbol: 'R_100', + pipSize: 4, + controller: controller, + indicatorsRepo: indicatorsRepo, + drawingToolsRepo: drawingToolsRepo, + isLive: true, + annotations: [ + HorizontalBarrier( + candles.map((c) => c.close).reduce(max) * 1.05, + title: 'Resistance', + style: HorizontalBarrierStyle( + color: Colors.red, + isDashed: true, + ), + ), + TickIndicator( + Tick( + epoch: candles.last.epoch, + quote: candles.last.close, + ), + style: HorizontalBarrierStyle( + labelShape: LabelShape.pentagon, + hasBlinkingDot: true, + ), + ), + ], + markerSeries: MarkerSeries( + [ + Marker.up( + epoch: candles[5].epoch, + quote: candles[5].high, + onTap: () => print('Marker tapped'), + ), + ], + entryTick: Tick( + epoch: candles.first.epoch, + quote: candles.first.open, + ), + exitTick: Tick( + epoch: candles.last.epoch, + quote: candles.last.close, + ), + ), + onVisibleAreaChanged: (leftEpoch, rightEpoch) { + // Load more historical data if needed + if (leftEpoch < candles.first.epoch) { + _loadMoreHistory(); + } + }, + ), + ); + } + + void _loadMoreHistory() { + // Load more historical data + } +} +``` + +## Next Steps + +Now that you understand the advanced features of the Deriv Chart library, you can explore: + +- [Indicators Reference](../features/indicators/reference.md) - Detailed information about all available indicators +- [Drawing Tools Reference](../features/drawing_tools/reference.md) - Detailed information about all available drawing tools +- [Custom Indicators](../advanced_usage/custom_indicators.md) - Learn how to create custom indicators \ No newline at end of file diff --git a/doc/getting_started/basic_usage.md b/doc/getting_started/basic_usage.md new file mode 100644 index 000000000..5051fcd2e --- /dev/null +++ b/doc/getting_started/basic_usage.md @@ -0,0 +1,230 @@ +# Basic Usage + +This guide will walk you through the basic usage of the Deriv Chart library, showing you how to create different types of charts and customize them. + +## Creating a Simple Chart + +To create a basic chart, you need to: + +1. Import the library +2. Create a data series +3. Pass the data series to the Chart widget + +Here's a simple example of a line chart: + +```dart +import 'package:flutter/material.dart'; +import 'package:deriv_chart/deriv_chart.dart'; + +class SimpleChartExample extends StatelessWidget { + const SimpleChartExample({Key? key}) : super(key: key); + + @override + Widget build(BuildContext context) { + // Create sample data + final ticks = [ + Tick(epoch: DateTime.now().subtract(const Duration(minutes: 5)), quote: 100), + Tick(epoch: DateTime.now().subtract(const Duration(minutes: 4)), quote: 120), + Tick(epoch: DateTime.now().subtract(const Duration(minutes: 3)), quote: 110), + Tick(epoch: DateTime.now().subtract(const Duration(minutes: 2)), quote: 130), + Tick(epoch: DateTime.now().subtract(const Duration(minutes: 1)), quote: 125), + Tick(epoch: DateTime.now(), quote: 140), + ]; + + // Create the chart + return SizedBox( + height: 300, + child: Chart( + mainSeries: LineSeries(ticks), + pipSize: 2, // Number of decimal places for price values + ), + ); + } +} +``` + +## Chart Data Types + +The Deriv Chart library supports two main types of data: + +1. **Tick Data**: Simple time-price pairs, used for line charts +2. **OHLC Data**: Open-High-Low-Close data, used for candlestick and OHLC charts + +### Tick Data Example + +```dart +final ticks = [ + Tick(epoch: DateTime.now().subtract(const Duration(minutes: 5)), quote: 100), + Tick(epoch: DateTime.now().subtract(const Duration(minutes: 4)), quote: 120), + // More ticks... +]; +``` + +### OHLC (Candle) Data Example + +```dart +final candles = [ + Candle( + epoch: DateTime.now().subtract(const Duration(minutes: 5)), + open: 100, + high: 120, + low: 95, + close: 110, + ), + Candle( + epoch: DateTime.now().subtract(const Duration(minutes: 4)), + open: 110, + high: 130, + low: 105, + close: 125, + ), + // More candles... +]; +``` + +## Chart Types + +The Deriv Chart library supports several chart types: + +### Line Chart + +```dart +Chart( + mainSeries: LineSeries(ticks), + pipSize: 2, + granularity: 60000, // 60000 milliseconds (1 minute) interval +) +``` + +### Candlestick Chart + +```dart +Chart( + mainSeries: CandleSeries(candles), + pipSize: 2, + granularity: 60000, // 60000 milliseconds (1 minute) interval per candle +) +``` + +### OHLC Chart + +```dart +Chart( + mainSeries: OHLCSeries(candles), + pipSize: 2, + granularity: 60000, // 60000 milliseconds (1 minute) interval per candle +) +``` + +### Hollow Candlestick Chart + +```dart +Chart( + mainSeries: HollowCandleSeries(candles), + pipSize: 2, + granularity: 60000, // 60000 milliseconds (1 minute) interval per candle +) +``` + +## Basic Customization + +### Styling the Chart + +You can customize the appearance of your charts by providing style objects: + +```dart +Chart( + mainSeries: CandleSeries( + candles, + style: CandleStyle( + positiveColor: Colors.green, + negativeColor: Colors.red, + neutralColor: Colors.grey, + ), + ), + pipSize: 2, +) +``` + +### Adding Annotations + +You can add horizontal or vertical barriers to mark specific price levels or time points: + +```dart +Chart( + mainSeries: LineSeries(ticks), + pipSize: 2, + annotations: [ + HorizontalBarrier( + 125.0, + title: 'Resistance', + style: HorizontalBarrierStyle( + color: Colors.red, + isDashed: true, + ), + ), + VerticalBarrier( + ticks[2].epoch, + title: 'Event', + style: VerticalBarrierStyle( + color: Colors.blue, + isDashed: false, + ), + ), + ], +) +``` + +### Adding Tick Indicators + +Tick indicators are special annotations that highlight specific data points: + +```dart +Chart( + mainSeries: LineSeries(ticks), + pipSize: 2, + annotations: [ + TickIndicator(ticks.last), + ], +) +``` + +## Handling User Interactions + +### Listening to Visible Area Changes + +You can listen to changes in the visible area of the chart (scrolling and zooming): + +```dart +Chart( + mainSeries: LineSeries(ticks), + pipSize: 2, + onVisibleAreaChanged: (int leftEpoch, int rightEpoch) { + print('Visible area changed: $leftEpoch to $rightEpoch'); + // Load more data if needed + }, +) +``` + +### Listening to Crosshair Events + +You can listen to when the crosshair appears on the chart: + +```dart +Chart( + mainSeries: LineSeries(ticks), + pipSize: 2, + onCrosshairAppeared: () { + print('Crosshair appeared'); + // Provide haptic feedback or update UI + }, +) +``` + +## Next Steps + +Now that you understand the basics of using the Deriv Chart library, you can explore: + +- [Chart Types](chart_types.md) - Learn more about different chart types +- [Configuration](configuration.md) - Discover more configuration options +- [Advanced Features](advanced_features.md) - Learn about technical indicators, annotations, markers, and drawing tools \ No newline at end of file diff --git a/doc/getting_started/chart_types.md b/doc/getting_started/chart_types.md new file mode 100644 index 000000000..efabe3949 --- /dev/null +++ b/doc/getting_started/chart_types.md @@ -0,0 +1,278 @@ +# Chart Types + +The Deriv Chart library supports various chart types for visualizing financial data. This guide explains each chart type, its use cases, and how to implement it. + +## Overview + +The chart type is determined by the `mainSeries` parameter passed to the `Chart` widget. Each chart type is represented by a different series class: + +- `LineSeries` - Line chart +- `CandleSeries` - Candlestick chart +- `OHLCSeries` - OHLC (Open-High-Low-Close) chart +- `HollowCandleSeries` - Hollow candlestick chart + +## Line Chart + +Line charts connect data points with straight lines, showing the price movement over time. They are useful for visualizing trends and are often used for tick data or when a simpler visualization is preferred. + +### Implementation + +```dart +Chart( + mainSeries: LineSeries(ticks), + pipSize: 2, + granularity: 60000, // 60000 milliseconds (1 minute) interval +) +``` + +### Data Requirements + +Line charts require a list of `Tick` objects, each containing an `epoch` (timestamp) and a `quote` (price). + +```dart +final ticks = [ + Tick(epoch: DateTime.now().subtract(const Duration(minutes: 5)), quote: 100), + Tick(epoch: DateTime.now().subtract(const Duration(minutes: 4)), quote: 120), + // More ticks... +]; +``` + +### Customization + +You can customize the appearance of the line chart using the `LineStyle` class: + +```dart +Chart( + mainSeries: LineSeries( + ticks, + style: LineStyle( + color: Colors.blue, + thickness: 2, + isDashed: false, + ), + ), + pipSize: 2, +) +``` + +### Example + +Line Chart Example + +## Candlestick Chart + +Candlestick charts display price movements using "candles" that show the open, high, low, and close prices. They are widely used in financial analysis as they provide a comprehensive view of price action. + +### Implementation + +```dart +Chart( + mainSeries: CandleSeries(candles), + pipSize: 2, + granularity: 60000, // 60000 milliseconds (1 minute) interval per candle +) +``` + +### Data Requirements + +Candlestick charts require a list of `Candle` objects, each containing an `epoch` (timestamp), `open`, `high`, `low`, and `close` prices. + +```dart +final candles = [ + Candle( + epoch: DateTime.now().subtract(const Duration(minutes: 5)), + open: 100, + high: 120, + low: 95, + close: 110, + ), + // More candles... +]; +``` + +### Customization + +You can customize the appearance of the candlestick chart using the `CandleStyle` class: + +```dart +Chart( + mainSeries: CandleSeries( + candles, + style: CandleStyle( + positiveColor: Colors.green, + negativeColor: Colors.red, + neutralColor: Colors.grey, + ), + ), + pipSize: 2, + granularity: 60000, // 60000 milliseconds (1 minute) interval +) +``` + +### Example + +Candlestick Chart Example + +## OHLC Chart + +OHLC (Open-High-Low-Close) charts display price movements using horizontal lines to represent the open and close prices, with vertical lines showing the high and low prices. They provide the same information as candlestick charts but in a different visual format. + +### Implementation + +```dart +Chart( + mainSeries: OHLCSeries(candles), + pipSize: 2, + granularity: 60000, // 60000 milliseconds (1 minute) interval per candle +) +``` + +### Data Requirements + +OHLC charts use the same `Candle` objects as candlestick charts. + +### Customization + +You can customize the appearance of the OHLC chart using the `OHLCStyle` class: + +```dart +Chart( + mainSeries: OHLCSeries( + candles, + style: CandleStyle( + positiveColor: Colors.green, + negativeColor: Colors.red, + neutralColor: Colors.grey, + ), + ), + pipSize: 2, + granularity: 60000, // 60000 milliseconds (1 minute) interval +) +``` + +## Hollow Candlestick Chart + +Hollow candlestick charts are a variation of standard candlestick charts where bullish candles (close > open) are hollow and bearish candles (close < open) are filled. This can make it easier to distinguish between bullish and bearish price movements. + +### Implementation + +```dart +Chart( + mainSeries: HollowCandleSeries(candles), + pipSize: 2, + granularity: 60000, // 60000 milliseconds (1 minute) interval per candle +) +``` + +### Data Requirements + +Hollow candlestick charts use the same `Candle` objects as standard candlestick charts. + +### Customization + +You can customize the appearance of the hollow candlestick chart using the `HollowCandleStyle` class: + +```dart +Chart( + mainSeries: HollowCandleSeries( + candles, + style: CandleStyle( + positiveColor: Colors.green, + negativeColor: Colors.red, + neutralColor: Colors.grey, + ), + ), + pipSize: 2, + granularity: 60000, // 60000 milliseconds (1 minute) interval +) +``` + +## Switching Between Chart Types + +You can dynamically switch between chart types by updating the `mainSeries` parameter: + +```dart +class ChartTypeSwitcherExample extends StatefulWidget { + const ChartTypeSwitcherExample({Key? key}) : super(key: key); + + @override + State createState() => _ChartTypeSwitcherExampleState(); +} + +class _ChartTypeSwitcherExampleState extends State { + ChartType _chartType = ChartType.candle; + final List _candles = [/* Your candle data */]; + final List _ticks = [/* Your tick data */]; + + @override + Widget build(BuildContext context) { + return Column( + children: [ + Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Radio( + value: ChartType.line, + groupValue: _chartType, + onChanged: (value) => setState(() => _chartType = value!), + ), + const Text('Line'), + Radio( + value: ChartType.candle, + groupValue: _chartType, + onChanged: (value) => setState(() => _chartType = value!), + ), + const Text('Candle'), + Radio( + value: ChartType.ohlc, + groupValue: _chartType, + onChanged: (value) => setState(() => _chartType = value!), + ), + const Text('OHLC'), + Radio( + value: ChartType.hollowCandle, + groupValue: _chartType, + onChanged: (value) => setState(() => _chartType = value!), + ), + const Text('Hollow Candle'), + ], + ), + Expanded( + child: Chart( + mainSeries: _getMainSeries(), + pipSize: 2, + granularity: 60000, // 60000 milliseconds (1 minute) interval + ), + ), + ], + ); + } + + Series _getMainSeries() { + switch (_chartType) { + case ChartType.line: + return LineSeries(_ticks); + case ChartType.candle: + return CandleSeries(_candles); + case ChartType.ohlc: + return OHLCSeries(_candles); + case ChartType.hollowCandle: + return HollowCandleSeries(_candles); + } + } +} + +enum ChartType { line, candle, ohlc, hollowCandle } +``` + +### Example + +Chart Type Switching + +## Next Steps + +Now that you understand the different chart types available in the Deriv Chart library, you can explore: + +- [Configuration](configuration.md) - Learn about more configuration options +- [Indicators](../features/indicators/overview.md) - Add technical indicators to your charts +- [Drawing Tools](../features/drawing_tools/overview.md) - Enable interactive drawing tools \ No newline at end of file diff --git a/doc/getting_started/configuration.md b/doc/getting_started/configuration.md new file mode 100644 index 000000000..bd1f07dd5 --- /dev/null +++ b/doc/getting_started/configuration.md @@ -0,0 +1,197 @@ +# Configuration Options + +The Deriv Chart library provides numerous configuration options to customize the appearance and behavior of your charts. This guide explains the available options and how to use them. + +## Chart Widget Configuration + +The `Chart` widget accepts various parameters to customize its behavior and appearance: + +### Basic Configuration + +```dart +Chart( + mainSeries: LineSeries(ticks), + pipSize: 2, + granularity: 60000, // 60000 milliseconds (1 minute) + theme: ChartDefaultDarkTheme(), + controller: ChartController(), +) +``` + +### Core Parameters + +| Parameter | Type | Description | +|-----------|------|-------------| +| `mainSeries` | `Series` | The primary data series to display (required) | +| `pipSize` | `int` | Number of decimal places for price values (default: 2) | +| `granularity` | `int` | Time interval in milliseconds for candles or average ms difference between consecutive ticks (default: 60000) | +| `theme` | `ChartTheme` | Theme for the chart (default: based on app theme) | +| `controller` | `ChartController` | Controller for programmatic chart manipulation | + +### Data Series Parameters + +| Parameter | Type | Description | +|-----------|------|-------------| +| `overlaySeries` | `List` | Additional series to display on the main chart | +| `bottomSeries` | `List` | Series to display in separate charts below the main chart | +| `markerSeries` | `MarkerSeries` | Markers to display on the chart | +| `overlayConfigs` | `List` | Technical indicators to display on the main chart | +| `bottomConfigs` | `List` | Technical indicators to display in separate charts below the main chart | + +### Visual Parameters + +| Parameter | Type | Description | +|-----------|------|-------------| +| `annotations` | `List` | Annotations to display on the chart (barriers, etc.) | +| `showCrosshair` | `bool` | Whether to display crosshair on long press (default: true) | +| `showDataFitButton` | `bool` | Whether to display the data fit button (default: true) | +| `showScrollToLastTickButton` | `bool` | Whether to display scroll to last tick button (default: true) | +| `loadingAnimationColor` | `Color` | The color of the loading animation | +| `chartAxisConfig` | `ChartAxisConfig` | Configuration for chart axes including grid and labels | + +### Callback Parameters + +| Parameter | Type | Description | +|-----------|------|-------------| +| `onVisibleAreaChanged` | `Function(int leftEpoch, int rightEpoch)` | Called when the visible area changes due to scrolling or zooming | +| `onQuoteAreaChanged` | `Function(double minQuote, double maxQuote)` | Called when the visible quote area changes | +| `onCrosshairAppeared` | `VoidCallback` | Called when the crosshair appears | +| `onCrosshairDisappeared` | `VoidCallback` | Called when the crosshair disappears | +| `onCrosshairHover` | `OnCrosshairHoverCallback` | Called when the crosshair cursor is hovered/moved | + +## PipSize + +The `pipSize` parameter determines the number of decimal places displayed for price values on the Y-axis. For example: + +- `pipSize: 2` displays prices as 123.45 +- `pipSize: 3` displays prices as 123.456 +- `pipSize: 0` displays prices as 123 + +```dart +Chart( + mainSeries: LineSeries(ticks), + pipSize: 3, +) +``` + +## Granularity + +The `granularity` parameter specifies the time interval in milliseconds for candle charts. It affects how candles are grouped and displayed: + +- `granularity: 60000` represents 1-minute candles +- `granularity: 300000` represents 5-minute candles +- `granularity: 3600000` represents 1-hour candles + +```dart +Chart( + mainSeries: CandleSeries(candles), + pipSize: 2, + granularity: 300000, // 5-minute candles (300000 milliseconds) +) +``` + +## Theme Customization + +You can customize the appearance of the chart by providing a custom theme: + +```dart +class CustomTheme extends ChartDefaultDarkTheme { + @override + GridStyle get gridStyle => GridStyle( + gridLineColor: Colors.yellow, + xLabelStyle: textStyle( + textStyle: caption2, + color: Colors.yellow, + fontSize: 13, + ), + ); + + @override + CrosshairStyle get crosshairStyle => CrosshairStyle( + lineColor: Colors.orange, + labelBackgroundColor: Colors.orange.withOpacity(0.8), + labelTextStyle: textStyle( + textStyle: caption1, + color: Colors.white, + ), + ); +} + +// Using the custom theme +Chart( + mainSeries: LineSeries(ticks), + pipSize: 2, + theme: CustomTheme(), +) +``` + +## Chart Controller + +The `ChartController` allows programmatic control of the chart: + +```dart +final controller = ChartController(); + +// In your widget +Chart( + mainSeries: LineSeries(ticks), + pipSize: 2, + controller: controller, +) + +// Programmatically control the chart +controller.scrollToLastTick(); // Scroll to the most recent data +controller.scale(100); // Zoom the chart +controller.scroll(100); // Scroll by 100 pixels +``` + +### Available Controller Methods + +| Method | Description | +|--------|-------------| +| `scrollToLastTick({bool animate = false})` | Scroll to the most recent data with optional animation | +| `scale(double scale)` | Set the zoom level | + +## Advanced Features + +The Deriv Chart library provides several advanced features that can enhance your charts: + +### Technical Indicators + +| Parameter | Type | Description | +|-----------|------|-------------| +| `overlayConfigs` | `List` | Technical indicators to display on the main chart | +| `bottomConfigs` | `List` | Technical indicators to display in separate charts below the main chart | + +### Annotations + +| Parameter | Type | Description | +|-----------|------|-------------| +| `annotations` | `List` | Visual elements like horizontal/vertical barriers and tick indicators | + +### Markers + +| Parameter | Type | Description | +|-----------|------|-------------| +| `markerSeries` | `MarkerSeries` | Highlight specific points on the chart with interactive markers | + +For detailed information and examples of these advanced features, see the [Advanced Features](advanced_features.md) documentation. + +## DerivChart Widget + +The `DerivChart` widget is a wrapper around the `Chart` widget that provides additional functionality for managing indicators and drawing tools: + +| Parameter | Type | Description | +|-----------|------|-------------| +| `activeSymbol` | `String` | Symbol code for saving indicator settings | +| `indicatorsRepo` | `AddOnsRepository` | Repository for managing indicators | +| `drawingToolsRepo` | `AddOnsRepository` | Repository for managing drawing tools | + +For detailed information about using the DerivChart widget, see the [Advanced Features](advanced_features.md) documentation. + +## Next Steps + +Now that you understand the configuration options available in the Deriv Chart library, you can explore: + +- [Advanced Features](advanced_features.md) - Learn about technical indicators, annotations, markers, and drawing tools +- [Custom Themes](../advanced_usage/custom_themes.md) - Learn about advanced customization options \ No newline at end of file diff --git a/doc/getting_started/installation.md b/doc/getting_started/installation.md new file mode 100644 index 000000000..629818b09 --- /dev/null +++ b/doc/getting_started/installation.md @@ -0,0 +1,94 @@ +# Installation Guide + +This guide will help you install and set up the Deriv Chart library in your Flutter project. + +## Requirements + +Before installing the Deriv Chart library, ensure your project meets the following requirements: + +- Dart SDK: >=3.0.0 <4.0.0 +- Flutter: >=3.10.1 + +## Adding the Package + +Add the Deriv Chart library to your project by including it in your `pubspec.yaml` file: + +```yaml +dependencies: + deriv_chart: ^0.3.7 # Replace with the latest version +``` + +Alternatively, you can use the Flutter CLI to add the package: + +```bash +flutter pub add deriv_chart +``` + +## Importing the Library + +After adding the package to your project, import it in your Dart files: + +```dart +import 'package:deriv_chart/deriv_chart.dart'; +``` + +## Verifying Installation + +To verify that the library is correctly installed, you can create a simple chart: + +```dart +import 'package:flutter/material.dart'; +import 'package:deriv_chart/deriv_chart.dart'; + +void main() { + runApp(const MyApp()); +} + +class MyApp extends StatelessWidget { + const MyApp({Key? key}) : super(key: key); + + @override + Widget build(BuildContext context) { + return MaterialApp( + home: Scaffold( + appBar: AppBar(title: const Text('Deriv Chart Example')), + body: Center( + child: SizedBox( + height: 300, + child: Chart( + mainSeries: LineSeries([ + Tick(epoch: DateTime.now().subtract(const Duration(minutes: 5)), quote: 100), + Tick(epoch: DateTime.now().subtract(const Duration(minutes: 4)), quote: 120), + Tick(epoch: DateTime.now().subtract(const Duration(minutes: 3)), quote: 110), + Tick(epoch: DateTime.now().subtract(const Duration(minutes: 2)), quote: 130), + Tick(epoch: DateTime.now().subtract(const Duration(minutes: 1)), quote: 125), + Tick(epoch: DateTime.now(), quote: 140), + ]), + pipSize: 2, + ), + ), + ), + ), + ); + } +} +``` + +## Dependencies + +The Deriv Chart library depends on the following packages: + +- deriv_technical_analysis: ^1.1.1 +- provider: ^6.0.5 +- shared_preferences: ^2.1.0 +- intl: ^0.19.0 + +These dependencies are automatically installed when you add the Deriv Chart library to your project. + +## Next Steps + +Now that you have installed the Deriv Chart library, you can proceed to: + +- [Basic Usage](basic_usage.md) - Learn how to create and customize charts +- [Chart Types](chart_types.md) - Explore different chart types available +- [Configuration](configuration.md) - Understand configuration options \ No newline at end of file