@@ -343,6 +343,55 @@ module ChartExtensions =
343
343
( fun ( ch : GenericChart ) ->
344
344
GenericChart.addLayout layout ch)
345
345
346
+ // Set the LayoutGrid options of a Chart
347
+ [<CompiledName( " WithLayoutGrid" ) >]
348
+ static member withLayoutGrid ( layoutGrid : LayoutGrid ) =
349
+ ( fun ( ch : GenericChart ) ->
350
+ let layout =
351
+ GenericChart.getLayout ch
352
+ |> Layout.SetLayoutGrid layoutGrid
353
+ GenericChart.setLayout layout ch)
354
+
355
+ // Set the LayoutGrid options of a Chart
356
+ [<CompiledName( " WithLayoutGridStyle" ) >]
357
+ static member withLayoutGridStyle ( [<Optional; DefaultParameterValue( null ) >] ? SubPlots : StyleParam.AxisId [] [],
358
+ [<Optional; DefaultParameterValue( null ) >] ? XAxes : StyleParam.AxisId [],
359
+ [<Optional; DefaultParameterValue( null ) >] ? YAxes : StyleParam.AxisId [],
360
+ [<Optional; DefaultParameterValue( null ) >] ? Rows : int ,
361
+ [<Optional; DefaultParameterValue( null ) >] ? Columns : int ,
362
+ [<Optional; DefaultParameterValue( null ) >] ? RowOrder : StyleParam.LayoutGridRowOrder ,
363
+ [<Optional; DefaultParameterValue( null ) >] ? Pattern : StyleParam.LayoutGridPattern ,
364
+ [<Optional; DefaultParameterValue( null ) >] ? XGap : float ,
365
+ [<Optional; DefaultParameterValue( null ) >] ? YGap : float ,
366
+ [<Optional; DefaultParameterValue( null ) >] ? Domain : Domain ,
367
+ [<Optional; DefaultParameterValue( null ) >] ? XSide : StyleParam.LayoutGridXSide ,
368
+ [<Optional; DefaultParameterValue( null ) >] ? YSide : StyleParam.LayoutGridYSide
369
+ ) =
370
+ ( fun ( ch : GenericChart ) ->
371
+ let layout = GenericChart.getLayout ch
372
+ let updatedGrid =
373
+ let currentGrid =
374
+ match layout.TryGetTypedValue< LayoutGrid> " grid" with
375
+ | Some grid -> grid
376
+ | None -> LayoutGrid()
377
+ currentGrid
378
+ |> LayoutGrid.style(
379
+ ?SubPlots = SubPlots,
380
+ ?XAxes = XAxes ,
381
+ ?YAxes = YAxes ,
382
+ ?Rows = Rows ,
383
+ ?Columns = Columns ,
384
+ ?RowOrder = RowOrder,
385
+ ?Pattern = Pattern ,
386
+ ?XGap = XGap ,
387
+ ?YGap = YGap ,
388
+ ?Domain = Domain ,
389
+ ?XSide = XSide ,
390
+ ?YSide = YSide
391
+ )
392
+ let updatedLayout = layout |> Layout.SetLayoutGrid updatedGrid
393
+ GenericChart.setLayout updatedLayout ch)
394
+
346
395
[<CompiledName( " WithConfig" ) >]
347
396
static member withConfig ( config : Config ) =
348
397
( fun ( ch : GenericChart ) ->
@@ -441,8 +490,136 @@ module ChartExtensions =
441
490
static member Combine ( gCharts : seq < GenericChart >) =
442
491
GenericChart.combine gCharts
443
492
493
+ ///Creates a Grid containing the given plots as subplots with the dimensions of the input (amount of columns equal to the largest inner sequence).
494
+ ///
495
+ ///Parameters:
496
+ ///
497
+ ///sharedAxes : Wether the subplots share one xAxis per column and one yAxis per row or not. (default:TopToBottom)
498
+ ///
499
+ ///rowOrder : the order in which the rows of the grid will be rendered (default:false)
500
+ ///
501
+ ///xGap : The space between columns of the grid relative to the x dimension of the grid
502
+ ///
503
+ ///yGap : The space between rows of the grid relative to the y dimension of the grid
504
+ ///
505
+ ///Use Chart.withLayoutGridStyle to further style the grid object contained in the returned chart.
506
+ [<CompiledName( " Grid" ) >]
507
+ static member Grid (( gCharts : seq < #seq < GenericChart >>),
508
+ [<Optional; DefaultParameterValue( false ) >] ? sharedAxes : bool ,
509
+ [<Optional; DefaultParameterValue( null ) >] ? rowOrder : StyleParam.LayoutGridRowOrder ,
510
+ [<Optional; DefaultParameterValue( 0.05 ) >] ? xGap ,
511
+ [<Optional; DefaultParameterValue( 0.05 ) >] ? yGap
512
+ ) =
513
+
514
+ let sharedAxes = defaultArg sharedAxes false
515
+ let rowOrder = defaultArg rowOrder StyleParam.LayoutGridRowOrder.TopToBottom
516
+ let xGap = defaultArg xGap 0.05
517
+ let yGap = defaultArg yGap 0.05
518
+
519
+ let nRows = Seq.length gCharts
520
+ let nCols = gCharts |> Seq.maxBy Seq.length |> Seq.length
521
+ let pattern = if sharedAxes then StyleParam.LayoutGridPattern.Coupled else StyleParam.LayoutGridPattern.Independent
522
+
523
+ let generateDomainRanges ( count : int ) ( gap : float ) =
524
+ [| 0. .. ( 1. / ( float count)) .. 1. |]
525
+ |> fun doms ->
526
+ doms
527
+ |> Array.windowed 2
528
+ |> Array.mapi ( fun i x ->
529
+ if i = 0 then
530
+ x.[ 0 ], ( x.[ 1 ] - ( gap / 2. ))
531
+ elif i = ( doms.Length - 1 ) then
532
+ ( x.[ 0 ] + ( gap / 2. )), x.[ 1 ]
533
+ else
534
+ ( x.[ 0 ] + ( gap / 2. )) , ( x.[ 1 ] - ( gap / 2. ))
535
+ )
536
+
537
+ let yDomains = generateDomainRanges nRows yGap
538
+ let xDomains = generateDomainRanges nCols xGap
539
+
540
+ gCharts
541
+ |> Seq.mapi ( fun rowIndex row ->
542
+ row |> Seq.mapi ( fun colIndex gChart ->
543
+ let xdomain = xDomains.[ colIndex]
544
+ let ydomain = yDomains.[ rowIndex]
545
+
546
+ let newXIndex , newYIndex =
547
+ ( if sharedAxes then colIndex + 1 else (( nRows * rowIndex) + ( colIndex + 1 ))),
548
+ ( if sharedAxes then rowIndex + 1 else (( nRows * rowIndex) + ( colIndex + 1 )))
549
+
550
+
551
+ let xaxis , yaxis , layout =
552
+ let layout = GenericChart.getLayout gChart
553
+ let xAxisName , yAxisName = StyleParam.AxisId.X 1 |> StyleParam.AxisId.toString, StyleParam.AxisId.Y 1 |> StyleParam.AxisId.toString
554
+
555
+ let updateXAxis index domain axis =
556
+ axis |> Axis.LinearAxis.style( Anchor= StyleParam.AxisAnchorId.X index, Domain= StyleParam.Range.MinMax domain)
557
+
558
+ let updateYAxis index domain axis =
559
+ axis |> Axis.LinearAxis.style( Anchor= StyleParam.AxisAnchorId.Y index, Domain= StyleParam.Range.MinMax domain)
560
+ match ( layout.TryGetTypedValue< Axis.LinearAxis> xAxisName),( layout.TryGetTypedValue< Axis.LinearAxis> yAxisName) with
561
+ | Some x, Some y ->
562
+ // remove axis
563
+ DynObj.remove layout xAxisName
564
+ DynObj.remove layout yAxisName
565
+
566
+ x |> updateXAxis newXIndex xdomain,
567
+ y |> updateYAxis newYIndex ydomain,
568
+ layout
569
+
570
+ | Some x, None ->
571
+ // remove x - axis
572
+ DynObj.remove layout xAxisName
573
+
574
+ x |> updateXAxis newXIndex xdomain,
575
+ Axis.LinearAxis.init( Anchor= StyleParam.AxisAnchorId.Y newYIndex , Domain= StyleParam.Range.MinMax ydomain),
576
+ layout
577
+
578
+ | None, Some y ->
579
+ // remove y - axis
580
+ DynObj.remove layout yAxisName
581
+
582
+ Axis.LinearAxis.init( Anchor= StyleParam.AxisAnchorId.X newXIndex, Domain= StyleParam.Range.MinMax xdomain),
583
+ y |> updateYAxis newYIndex ydomain,
584
+ layout
585
+ | None, None ->
586
+ Axis.LinearAxis.init( Anchor= StyleParam.AxisAnchorId.X newXIndex, Domain= StyleParam.Range.MinMax xdomain),
587
+ Axis.LinearAxis.init( Anchor= StyleParam.AxisAnchorId.Y newYIndex, Domain= StyleParam.Range.MinMax ydomain),
588
+ layout
589
+
590
+ gChart
591
+ |> GenericChart.setLayout layout
592
+ |> Chart.withAxisAnchor( X= newXIndex, Y= newYIndex)
593
+ |> Chart.withX_ Axis( xaxis, newXIndex)
594
+ |> Chart.withY_ Axis( yaxis, newYIndex)
595
+ )
596
+ )
597
+ |> Seq.map Chart.Combine
598
+ |> Chart.Combine
599
+ |> Chart.withLayoutGrid(
600
+ LayoutGrid.init(
601
+ Rows= nRows, Columns= nCols, XGap= xGap, YGap= yGap, Pattern= pattern, RowOrder= rowOrder
602
+ )
603
+ )
604
+
605
+ ///Creates a chart stack from the input charts by stacking them on top of each other starting from the first chart.
606
+ ///
607
+ ///Parameters:
608
+ ///
609
+ ///sharedAxis : wether the stack has a shared x axis (default:true)
610
+ [<CompiledName( " SingleStack" ) >]
611
+ static member SingleStack ( charts : #seq<GenericChart> ,
612
+ [<Optional; DefaultParameterValue( true ) >] ? sharedXAxis : bool ) =
613
+
614
+ let sharedAxis = defaultArg sharedXAxis true
615
+ let singleCol = seq {
616
+ for i = 0 to (( Seq.length charts) - 1 ) do
617
+ yield seq { Seq.item i charts}
618
+ }
619
+ Chart.Grid( gCharts = singleCol, sharedAxes = sharedAxis, rowOrder = StyleParam.LayoutGridRowOrder.BottomToTop)
444
620
445
621
/// Create a combined chart with the given charts merged
622
+ [<Obsolete( " Use Chart.Grid for multi column grid charts or singleStack for one-column stacked charts." ) >]
446
623
[<CompiledName( " Stack" ) >]
447
624
static member Stack ( [<Optional; DefaultParameterValue( null ) >] ? Columns : int ,
448
625
[<Optional; DefaultParameterValue( null ) >] ? Space ) =
0 commit comments