oxyplot / oxyplot-xamarin

OxyPlot for Xamarin.Mac and Xamarin.Forms
MIT License
64 stars 59 forks source link

Several issues using OxyPlot.ImageSharp to export model to PNG #99

Open olivercortinas opened 4 years ago

olivercortinas commented 4 years ago

I am using the code provided here: https://github.com/oxyplot/oxyplot/tree/develop/Source/OxyPlot.ImageSharp to export chart model to PNG, i try several examples i have and allways get some errors, i will try to upload them all. I have this XAML for a pie chart:

<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:oxy="clr-namespace:OxyPlot.Xamarin.Forms;assembly=OxyPlot.Xamarin.Forms"
             x:Class="Charts.PieEx">
    <AbsoluteLayout>
        <Button Text="Capture" 
                x:Name="btnCapture" 
                Clicked="BtnCapture_Clicked" 
                WidthRequest="50"
                HeightRequest="30"
                FontSize="5"
                VerticalOptions="Start" 
                HorizontalOptions="CenterAndExpand"></Button>
        <oxy:PlotView Model="{Binding PieModel}" 
                      x:Name="rangeChartView"
                      BackgroundColor="White"
                      VerticalOptions="FillAndExpand" 
                      HorizontalOptions="FillAndExpand"
                      AbsoluteLayout.LayoutBounds="10,30,.9,.9"
                      AbsoluteLayout.LayoutFlags="WidthProportional,HeightProportional" />
    </AbsoluteLayout>
</ContentPage>

Then in the .cs i have this code when button is pressed:

        private void BtnCapture_Clicked(object sender, EventArgs e)
        {
            using (Stream stream = new MemoryStream())
            {
                var exporter = new PngExporter();
                exporter.Background = rangeChartView.Model.Background;
                exporter.Height = Convert.ToInt32(rangeChartView.Model.Height);
                exporter.Width = Convert.ToInt32(rangeChartView.Model.Width);
                exporter.Resolution = 180;
                exporter.Export(rangeChartView.Model, stream);
                Console.WriteLine(stream);
            }
            this.rangeChartView.Model);
        }

And create the pie chart content here:

        private PlotModel CreatePieChart()
        {
            var model = new PlotModel { Title = "Pie Chart" };

            var ps = new PieSeries
            {
                StrokeThickness = .25,
                InsideLabelPosition = .25,
                AngleSpan = 360,
                StartAngle = 0
            };

            // http://www.nationsonline.org/oneworld/world_population.htm
            // http://en.wikipedia.org/wiki/Continent
            ps.Slices.Add(new PieSlice("Africa", 1030) { IsExploded = false });
            ps.Slices.Add(new PieSlice("Americas", 929) { IsExploded = false });
            ps.Slices.Add(new PieSlice("Asia", 4157));
            ps.Slices.Add(new PieSlice("Europe", 739) { IsExploded = false });
            ps.Slices.Add(new PieSlice("Oceania", 35) { IsExploded = false });
            model.Series.Add(ps);
            return model;
        }

When i run on Android i get an exception on the class PngRenderingContext:

OxyPlot exception: One or more errors occurred. (Segoe UI could not be found) (Arial could not be found)

Seems that it couldn't fin de font when the code is reached on method GetFamilyOrFallbackOrThrow:

family = SystemFonts.Find(fontFamily);

In the class is defined:

static readonly string FallbackFontFamily = "Arial";`

Any clue why this is happening?

objorke commented 4 years ago

Should it be possible to specify the fallback font family? Then I think this is an issue for OxyPlot.ImageSharp and not oxyplot-xamarin

Did you try using "Droid Sans"?

https://forums.xamarin.com/discussion/33744/fontfamily-is-there-a-list-of-families-that-work-across-platforms

olivercortinas commented 4 years ago

I try it and didn't work, i change the code: static readonly string FallbackFontFamily = "Arial"; for this one: static readonly string FallbackFontFamily = GetFontPlatform(); with: private static string GetFontPlatform() { string font; switch (Device.RuntimePlatform) { case Device.iOS: font = "MarkerFelt-Thin"; break; case Device.macOS: font = "MarkerFelt-Thin"; break; case Device.Android: font = "Droid Sans"; break; default: font = "Comic Sans MS"; break; } return font; } and got the same error when run family = SystemFonts.Find(FallbackFontFamily); the return is (null) The library that is used si SixLabors.Fonts, so i try this: FontCollection.SystemFonts.Families to know the families availables but FontCollection is recognized but FontCollection.SystemFonts not, I'm not sure from where is the error, i think that should be missed something that load the fonts? Don't know.

olivercortinas commented 4 years ago

Should it be possible to specify the fallback font family? Then I think this is an issue for OxyPlot.ImageSharp and not oxyplot-xamarin

Did you try using "Droid Sans"?

https://forums.xamarin.com/discussion/33744/fontfamily-is-there-a-list-of-families-that-work-across-platforms

This issue is with SixLabors.Fonts.SystemFonts has an empty Families value, what could be the issue related to that? Just to be more clear, this is happening only when i test it on Android.