diff --git a/Plotly.NET.sln b/Plotly.NET.sln
index 623671b6c..5947c10fa 100644
--- a/Plotly.NET.sln
+++ b/Plotly.NET.sln
@@ -148,6 +148,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "04_distribution-charts", "0
docs\distribution-charts\point-density.fsx = docs\distribution-charts\point-density.fsx
docs\distribution-charts\splom.fsx = docs\distribution-charts\splom.fsx
docs\distribution-charts\violin-plots.fsx = docs\distribution-charts\violin-plots.fsx
+ docs\distribution-charts\pareto-chart.fsx = docs\distribution-charts\pareto-chart.fsx
EndProjectSection
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "01_chart-layout", "01_chart-layout", "{C7D0EF67-9A18-49DD-AC79-944E384BD8D0}"
diff --git a/docs/distribution-charts/pareto-chart.fsx b/docs/distribution-charts/pareto-chart.fsx
new file mode 100644
index 000000000..ab153ac40
--- /dev/null
+++ b/docs/distribution-charts/pareto-chart.fsx
@@ -0,0 +1,70 @@
+(**
+---
+title: Pareto chart
+category: Distribution Charts
+categoryindex: 5
+index: 9
+---
+*)
+
+(*** hide ***)
+
+(*** condition: prepare ***)
+#r "nuget: Newtonsoft.JSON, 13.0.1"
+#r "nuget: DynamicObj, 2.0.0"
+#r "nuget: Giraffe.ViewEngine.StrongName, 2.0.0-alpha1"
+#r "../../src/Plotly.NET/bin/Release/netstandard2.0/Plotly.NET.dll"
+
+Plotly.NET.Defaults.DefaultDisplayOptions <-
+ Plotly.NET.DisplayOptions.init (PlotlyJSReference = Plotly.NET.PlotlyJSReference.NoReference)
+
+(*** condition: ipynb ***)
+#if IPYNB
+#r "nuget: Plotly.NET, {{fsdocs-package-version}}"
+#r "nuget: Plotly.NET.Interactive, {{fsdocs-package-version}}"
+#endif // IPYNB
+
+(**
+# Pareto chart
+
+[](https://mybinder.org/v2/gh/plotly/plotly.net/gh-pages?urlpath=/tree/home/jovyan/{{fsdocs-source-basename}}.ipynb)
+[]({{root}}{{fsdocs-source-basename}}.ipynb)
+
+*Summary:* This example shows how to create a Pareto chart in F#.
+
+Let's first create some data for the purpose of creating example charts:
+
+*)
+
+open Plotly.NET
+
+let data =
+ [
+ "C#" , 420.
+ "F#" , 10008
+ "Smalltalk" , 777
+ "Pascal" , 543
+ "Perl" , 666
+ "VB.NET" , 640
+ "C" , 111
+ "ChucK" , 1230
+ "ARexx" , 4440
+ ]
+
+(**
+
+A Pareto chart is a type of chart that contains both bars and a line graph, where individual values are represented in descending order by bars, and the cumulative total is represented by the line.
+The chart is named for the Pareto principle, which, in turn, derives its name from Vilfredo Pareto, a noted Italian economist. [Source](https://en.wikipedia.org/wiki/Pareto_chart)
+*)
+
+let pareto = Chart.Pareto(keysValues = data, Name="Language", Label="Respondents")
+
+(*** condition: ipynb ***)
+#if IPYNB
+pareto
+#endif // IPYNB
+
+(***hide***)
+pareto |> GenericChart.toChartHTML
+(***include-it-raw***)
+
diff --git a/src/Plotly.NET.CSharp/ChartAPI/Chart2D.cs b/src/Plotly.NET.CSharp/ChartAPI/Chart2D.cs
index 336f4b4fd..53690e176 100644
--- a/src/Plotly.NET.CSharp/ChartAPI/Chart2D.cs
+++ b/src/Plotly.NET.CSharp/ChartAPI/Chart2D.cs
@@ -600,6 +600,48 @@ public static GenericChart Range(
UpperName: UpperName.ToOption(),
UseDefaults: UseDefaults.ToOption()
);
+
+ /// Creates a Pareto chart.
+ /// Sets the (key,value) pairs that are plotted as the size and key of each bar.
+ /// Sets the trace name. The trace name appear as the legend item and on hover
+ /// Sets the y axis label.
+ /// Determines whether or not grid lines are drawn. If "true", the grid lines are drawn for the pareto distribution figure; defaults to true.
+ public static GenericChart Pareto(
+ IEnumerable<(TLabel,double)> keysValues
+ , Optional Name
+ , Optional Label
+ , Optional ShowGrid
+ )
+ where TLabel : IConvertible
+ =>
+ Chart2D.Chart.Pareto(
+ keysValues.Select(t => t.ToTuple())
+ , Name: Name.ToOption()
+ , Label: Label.ToOption()
+ , ShowGrid: ShowGrid.ToOption()
+ );
+ /// Creates a Pareto chart.
+ /// Sets the labels that are matching the .
+ /// Sets the values that are plotted as the size of each bar.
+ /// Sets the trace name. The trace name appear as the legend item and on hover
+ /// Sets the y axis label.
+ /// Determines whether or not grid lines are drawn. If "true", the grid lines are drawn for the pareto distribution figure; defaults to true.
+ public static GenericChart Pareto(
+ IEnumerable labels
+ , IEnumerable values
+ , Optional Name
+ , Optional Label
+ , Optional ShowGrid
+ )
+ where TLabel : IConvertible
+ =>
+ Chart2D.Chart.Pareto(
+ labels
+ , values
+ , Name: Name.ToOption()
+ , Label: Label.ToOption()
+ , ShowGrid: ShowGrid.ToOption()
+ );
/// Creates an Area chart, which uses a Line plotted between the given datums in a 2D space, additionally colouring the area between the line and the Y Axis.
/// Sets the x coordinates of the plotted data.
diff --git a/src/Plotly.NET.CSharp/TupleExtensions.cs b/src/Plotly.NET.CSharp/TupleExtensions.cs
new file mode 100644
index 000000000..119e469f0
--- /dev/null
+++ b/src/Plotly.NET.CSharp/TupleExtensions.cs
@@ -0,0 +1,12 @@
+namespace Plotly.NET.CSharp;
+
+///
+/// Convenience to convert from C# struct tuple literals to the value tuple ones.
+///
+internal static class TupleExtensions
+{
+ ///
+ /// Converts a 2 tuple.
+ ///
+ internal static Tuple ToTuple(this ValueTuple t) => Tuple.Create(t.Item1, t.Item2);
+}
\ No newline at end of file
diff --git a/src/Plotly.NET/ChartAPI/Chart2D.fs b/src/Plotly.NET/ChartAPI/Chart2D.fs
index 053914b97..9ab0c17bc 100644
--- a/src/Plotly.NET/ChartAPI/Chart2D.fs
+++ b/src/Plotly.NET/ChartAPI/Chart2D.fs
@@ -1547,8 +1547,80 @@ module Chart2D =
?UpperName = UpperName,
?UseDefaults = UseDefaults
)
-
-
+
+ /// Creates a Pareto chart.
+ /// Sets the (key,value) pairs that are plotted as the size and key of each bar.
+ /// Sets the trace name. The trace name appear as the legend item and on hover
+ /// Sets the y axis label.
+ /// Determines whether or not grid lines are drawn. If "true", the grid lines are drawn for the pareto distribution figure; defaults to true.
+ []
+ static member Pareto
+ (
+ keysValues: seq<#IConvertible * float>
+ , [] ?Name: string
+ , [] ?Label: string
+ , [] ?ShowGrid: bool
+ ) =
+ let orderedLabels, orderedValues =
+ keysValues
+ |> Seq.sortByDescending snd
+ |> Seq.unzip
+
+ let sum = orderedValues |> Seq.sum
+ let topPaddingRatio = 0.05
+ let cumulativeSum =
+ Seq.scan (+) 0. orderedValues
+ |> Seq.skip 1
+
+ let paretoValues =
+ Seq.zip orderedLabels cumulativeSum
+ |> Seq.map (fun (label,value) -> label, value / sum * 100.)
+
+ let bars = Chart.Column(Seq.zip orderedLabels orderedValues,?Name=Name)
+
+ let lines =
+ Chart.Line(
+ paretoValues
+ , Name = "Cumulative %"
+ , ShowLegend = true
+ , ShowMarkers = true
+ , Marker = Marker.init(Size = 8, Symbol = StyleParam.MarkerSymbol.Cross, Angle = 45.)
+ )
+ |> Chart.withAxisAnchor (Y = 2)
+
+ [bars;lines]
+ |> Chart.combine
+ |> Chart.withYAxisStyle (
+ ?TitleText = Label
+ , Id = StyleParam.SubPlotId.YAxis 1
+ , ShowGrid = false
+ , MinMax = (0.,sum * (1.+topPaddingRatio))
+ )
+ |> Chart.withYAxisStyle (
+ TitleText = "%"
+ , Side = StyleParam.Side.Right
+ , Id = StyleParam.SubPlotId.YAxis 2
+ , MinMax = (0.,100. * (1.+topPaddingRatio))
+ , Overlaying = StyleParam.LinearAxisId.Y 1
+ , ?ShowGrid = ShowGrid
+ )
+
+ /// Creates a Pareto chart.
+ /// Sets the labels that are matching the .
+ /// Sets the values that are plotted as the size of each bar.
+ /// Sets the trace name. The trace name appear as the legend item and on hover
+ /// Sets the y axis label.
+ /// Determines whether or not grid lines are drawn. If "true", the grid lines are drawn for the pareto distribution figure; defaults to true.
+ static member Pareto
+ (
+ labels: seq<#IConvertible>
+ , values: seq
+ , [] ?Name: string
+ , [] ?Label: string
+ , [] ?ShowGrid: bool
+ ) =
+ Chart.Pareto(Seq.zip labels values, ?Name=Name, ?Label=Label, ?ShowGrid=ShowGrid)
+
/// Creates an Area chart, which uses a Line plotted between the given datums in a 2D space, additionally colouring the area between the line and the Y Axis.
/// Sets the x coordinates of the plotted data.
/// Sets the y coordinates of the plotted data.