Exporting Chart as Picture File leads to ArgumentException
Hello,
I have a method, that creates a Chart without showing it anywhere and saving it as picture file.
However, this leads to an ArgumentException:
System.ArgumentException: Value does not fall within the expected range.
at Syncfusion.UI.Xaml.Charts.ChartBase.Save(String fileName, StorageFolder folderLocation)
at System.Threading.WinRTSynchronizationContextBase.Invoker.InvokeCore()
I tested the chart by showing it in an DialogBox instead of exporting and it looked just fine, so it seems the Save-Method is responsible for the error.
You can find my code below:
public async Task ExportChart(int width = 1920, int height = 1080)
{
//Create base chart
var exportChart = new SfChart();
var foreground = new SolidColorBrush(Color.FromArgb(255, 234, 172, 42));
exportChart.PrimaryAxis = new DateTimeAxis()
{
LabelFormat = "dd/MM - HH:mm",
Foreground = foreground,
LabelsIntersectAction = AxisLabelsIntersectAction.Auto
};
exportChart.SecondaryAxis = new NumericalAxis()
{
RangePadding = NumericalPadding.Round,
Foreground = foreground,
Header = new TextBlock() { Foreground = foreground, Text = MarketAsset + "/" + BaseAsset }
};
//Get Technical Indicator Charts
NumericalAxis yAxis = new NumericalAxis()
{
Header = "Indicators",
Foreground = foreground,
OpposedPosition = true
};
List
- > seriesList = new List
- >();
foreach (IndicatorLineCollection ilc in IndicatorLines)
{
seriesList.Add(await ilc.RenderIndicatorLines(yAxis)); //this method generates some FastLineSeries-Charts which get added to the main chart below.
}
//Create Static Candles Chart and add TIs
var chartCollection = new ChartSeriesCollection();
var candleChart = new FastCandleBitmapSeries()
{
Label = "Candles",
Foreground = foreground,
ItemsSource = Candles,
BearFillColor = new SolidColorBrush(Color.FromArgb(255, 203, 25, 25)),
BullFillColor = new SolidColorBrush(Colors.Green),
XBindingPath = "Date",
Open = "Open",
High = "High",
Low = "Low",
Close = "Close"
};
chartCollection.Add(candleChart);
foreach (List seriesCollection in seriesList)
{
foreach (FastLineSeries series in seriesCollection)
{
chartCollection.Add(series);
}
}
exportChart.Series = chartCollection;
exportChart.Measure(new Size(width, height));
exportChart.Arrange(new Rect(0, 0, width, height));
exportChart.GetType().GetMethod("RenderSeries", BindingFlags.NonPublic |
BindingFlags.Instance).Invoke(exportChart, null);
exportChart.UpdateLayout();
//Save PNG
StorageFile storageFile = await ApplicationData.Current.LocalCacheFolder.CreateFileAsync("ExportedChart.png", CreationCollisionOption.ReplaceExisting);
Guid encoder = BitmapEncoder.PngEncoderId;
exportChart.Save(await storageFile.OpenAsync(FileAccessMode.ReadWrite), encoder);
}
Greetings
Alexander
SIGN IN To post a reply.
3 Replies
DD
Devakumar Dhanapoosanam
Syncfusion Team
March 3, 2020 12:08 PM UTC
Greetings from Syncfusion.
We would like to let you know that we don’t have support to Save the chart image in UWP without adding it to any Hierarchy. This is a FrameWork level limitation. Since we have used the RenderTargetBitmap to Save chart.
Please refer the below link for more details
Please let us know if you need any further assistance.
Regards,
Devakumar D
AL
Alexander
April 26, 2020 03:44 PM UTC
Hello,
I have found a solution, if anyone ever stumbles across this problem:
Though it does show the chart for a few miliseconds, however this is fully acceptable for my usecase..
public async Task ExportChart(int width = 1920, int height = 1080)
{
await CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(CoreDispatcherPriority.High, async () =>
{
try
{
//Create app window
var appWindow = await AppWindow.TryCreateAsync();
appWindow.RequestMoveAdjacentToCurrentView();
appWindow.RequestSize(new Size(width, height));
appWindow.Title = "Export Chart";
//Create your chart here
var exportChart = new SfChart();
(......)
exportChart.Measure(new Size(width, height));
exportChart.Arrange(new Rect(0, 0, width, height));
exportChart.GetType().GetMethod("RenderSeries", BindingFlags.NonPublic |
BindingFlags.Instance).Invoke(exportChart, null);
exportChart.UpdateLayout();
//Fill AppWindow
Frame appWindowContentFrame = new Frame();
ElementCompositionPreview.SetAppWindowContent(appWindow, appWindowContentFrame);
var windowGrid = new Grid();
windowGrid.ColumnDefinitions.Add(new ColumnDefinition() { Width = new GridLength(1.0, GridUnitType.Star) });
windowGrid.RowDefinitions.Add(new RowDefinition() { Height = new GridLength(1.0, GridUnitType.Star) });
windowGrid.HorizontalAlignment = HorizontalAlignment.Stretch;
windowGrid.VerticalAlignment = VerticalAlignment.Stretch;
//Move chart to appWindow
appWindowContentFrame.Content = new Page() { Content = windowGrid };
windowGrid.Children.Add(exportChart);
await appWindow.TryShowAsync();
//Save PNG
StorageFile storageFile = await ApplicationData.Current.LocalCacheFolder.CreateFileAsync("ExportedChart.png", CreationCollisionOption.ReplaceExisting);
Guid encoder = BitmapEncoder.PngEncoderId;
exportChart.Save(await storageFile.OpenAsync(FileAccessMode.ReadWrite), encoder);
//Close AppWindow
await appWindow.CloseAsync();
}
catch (Exception)
{
//You can add exception handling here, if you want
}
});
}
Greetings
Alexander
SJ
Suyamburaja Jayakumar
Syncfusion Team
April 27, 2020 06:50 AM UTC
Hi Alexander,
We are glad to hear that your requirement has been achieved.
Please let us know if you need any further assistance on this.
Regards,
Suyamburaja J.
SIGN IN To post a reply.
- 3 Replies
- 3 Participants
-
AL Alexander
- Mar 1, 2020 06:42 PM UTC
- Apr 27, 2020 06:50 AM UTC