Skip to main content

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:

PropertyTypeDescription
symbolStringRequired - Symbol to display
intervalStringRequired - Timeframe
themeString'light' or 'dark'
libraryPathStringRequired - URL to the charting library JS file
customDatafeedScriptStringJavaScript code for your datafeed
onChartReadyVoidCallbackCallback 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:

  1. CDN: Upload to a CDN and use the URL
  2. Local Server: Serve from your local development server
  3. 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