Flutter
The charting library provides a Flutter widget that renders charts using a WebView.
Installation
Add the dependency to your pubspec.yaml:
dependencies:
flutter:
sdk: flutter
webview_flutter: ^4.0.0
Important: WebView-Based
The Flutter widget uses a WebView to render the chart, since the charting library requires browser APIs.
Basic Usage
1. Import the Widget
import 'package:financial_charting_library/flutter/financial_chart.dart';
2. Use in Your Widget
import 'package:flutter/material.dart';
import 'package:financial_charting_library/flutter/financial_chart.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Financial Chart',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: const ChartScreen(),
);
}
}
class ChartScreen extends StatelessWidget {
const ChartScreen({super.key});
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Financial Chart'),
),
body: FinancialChart(
symbol: 'AAPL',
interval: '1D',
theme: 'light',
libraryPath: 'https://your-cdn.com/financial-charting-library.js',
onChartReady: () {
print('Chart is Ready!');
},
),
);
}
}
Widget Properties
The FinancialChart widget accepts these properties:
| Property | Type | Description |
|---|---|---|
symbol | String | Required - Symbol to display |
interval | String | Required - Timeframe |
theme | String | 'light' or 'dark' |
libraryPath | String | Required - URL to the charting library JS file |
customDatafeedScript | String | JavaScript code for your datafeed |
onChartReady | VoidCallback | Callback when chart is ready |
Providing a Datafeed
You need to provide a datafeed by injecting JavaScript code:
import 'package:flutter/material.dart';
import 'package:financial_charting_library/flutter/financial_chart.dart';
class ChartScreen extends StatelessWidget {
const ChartScreen({super.key});
@override
Widget build(BuildContext context) {
// Define your datafeed as a JavaScript string
const String customDatafeedScript = '''
class MyDataFeed {
onReady(callback) {
setTimeout(() => callback({
supported_resolutions: ['1', '5', '15', '1D', '1W']
}), 0);
}
resolveSymbol(symbolName, onSymbolResolvedCallback, onResolveErrorCallback) {
onSymbolResolvedCallback({
name: symbolName,
full_name: symbolName,
description: symbolName,
type: 'stock',
session: '24x7',
timezone: 'Etc/UTC',
minmov: 1,
pricescale: 100,
has_intraday: true,
supported_resolutions: ['1', '5', '15', '1D', '1W'],
volume_precision: 2,
data_status: 'streaming',
});
}
getBars(symbolInfo, resolution, periodParams, onHistoryCallback, onErrorCallback) {
const bars = [];
let time = periodParams.from * 1000;
const to = periodParams.to * 1000;
while (time < to) {
bars.push({
time: time,
open: 100 + Math.random() * 10,
high: 110 + Math.random() * 10,
low: 90 + Math.random() * 10,
close: 100 + Math.random() * 10,
volume: 1000
});
time += 86400000;
}
onHistoryCallback(bars, { noData: false });
}
subscribeBars(symbolInfo, resolution, onRealtimeCallback, subscribeUID, onResetCacheNeededCallback) {}
unsubscribeBars(subscriberUID) {}
}
const datafeed = new MyDataFeed();
''';
return Scaffold(
appBar: AppBar(
title: const Text('Financial Chart'),
),
body: FinancialChart(
symbol: 'AAPL',
interval: '1D',
theme: 'light',
libraryPath: 'https://your-cdn.com/financial-charting-library.js',
customDatafeedScript: customDatafeedScript,
onChartReady: () {
print('Chart is Ready!');
},
),
);
}
}
Complete Example
Here's a full example with controls:
import 'package:flutter/material.dart';
import 'package:financial_charting_library/flutter/financial_chart.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Financial Chart - Flutter',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: const ChartScreen(),
);
}
}
class ChartScreen extends StatefulWidget {
const ChartScreen({super.key});
@override
State<ChartScreen> createState() => _ChartScreenState();
}
class _ChartScreenState extends State<ChartScreen> {
String symbol = 'AAPL';
String theme = 'light';
static const String customDatafeedScript = '''
class MyDataFeed {
onReady(callback) {
setTimeout(() => callback({
supported_resolutions: ['1', '5', '15', '1D', '1W']
}), 0);
}
resolveSymbol(symbolName, onSymbolResolvedCallback, onResolveErrorCallback) {
onSymbolResolvedCallback({
name: symbolName,
full_name: symbolName,
description: symbolName,
type: 'stock',
session: '24x7',
timezone: 'Etc/UTC',
minmov: 1,
pricescale: 100,
has_intraday: true,
supported_resolutions: ['1', '5', '15', '1D', '1W'],
volume_precision: 2,
data_status: 'streaming',
});
}
getBars(symbolInfo, resolution, periodParams, onHistoryCallback, onErrorCallback) {
const bars = [];
let time = periodParams.from * 1000;
const to = periodParams.to * 1000;
while (time < to) {
bars.push({
time: time,
open: 100 + Math.random() * 10,
high: 110 + Math.random() * 10,
low: 90 + Math.random() * 10,
close: 100 + Math.random() * 10,
volume: 1000
});
time += 86400000;
}
onHistoryCallback(bars, { noData: false });
}
subscribeBars(symbolInfo, resolution, onRealtimeCallback, subscribeUID, onResetCacheNeededCallback) {}
unsubscribeBars(subscriberUID) {}
}
const datafeed = new MyDataFeed();
''';
void changeSymbol(String newSymbol) {
setState(() {
symbol = newSymbol;
});
}
void toggleTheme() {
setState(() {
theme = theme == 'light' ? 'dark' : 'light';
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Financial Chart - Flutter'),
),
body: Column(
children: [
// Controls
Padding(
padding: const EdgeInsets.all(8.0),
child: Wrap(
spacing: 8,
children: [
ElevatedButton(
onPressed: () => changeSymbol('AAPL'),
child: const Text('AAPL'),
),
ElevatedButton(
onPressed: () => changeSymbol('GOOGL'),
child: const Text('GOOGL'),
),
ElevatedButton(
onPressed: () => changeSymbol('MSFT'),
child: const Text('MSFT'),
),
ElevatedButton(
onPressed: toggleTheme,
child: Text('Toggle Theme ($theme)'),
),
],
),
),
// Chart
Expanded(
child: FinancialChart(
key: ValueKey('$symbol-$theme'), // Force rebuild on change
symbol: symbol,
interval: '1D',
theme: theme,
libraryPath: 'https://your-cdn.com/financial-charting-library.js',
customDatafeedScript: customDatafeedScript,
onChartReady: () {
print('Chart is Ready!');
},
),
),
],
),
);
}
}
Hosting the Library
You need to host the charting library JavaScript file. Options include:
- CDN: Upload to a CDN and use the URL
- Local Server: Serve from your local development server
- App Assets: Include as an asset in your app
// Using a CDN (production)
libraryPath: 'https://your-cdn.com/financial-charting-library.js'
// Using local assets
libraryPath: 'assets/financial-charting-library.js'
Platform Configuration
Android
Make sure your AndroidManifest.xml has internet permission:
<uses-permission android:name="android.permission.INTERNET"/>
iOS
No special configuration needed.
Next Steps
- Learn about DataFeed implementation
- Explore Chart Configuration
- Add Custom Indicators