1
- using ApexCharts . Series ;
2
- using BlazorApexCharts ;
1
+ using ApexCharts . Internal ;
3
2
using Microsoft . AspNetCore . Components ;
4
3
using Microsoft . JSInterop ;
5
4
using System ;
@@ -16,7 +15,6 @@ namespace ApexCharts
16
15
/// <typeparam name="TItem">The data type of the items to display in the chart</typeparam>
17
16
public partial class ApexChart < TItem > : IDisposable where TItem : class
18
17
{
19
- [ Inject ] private IServiceProvider ServiceProvider { get ; set ; }
20
18
[ Inject ] private IJSRuntime JSRuntime { get ; set ; }
21
19
22
20
/// <summary>
@@ -176,20 +174,18 @@ public partial class ApexChart<TItem> : IDisposable where TItem : class
176
174
/// </remarks>
177
175
[ Parameter ] public GroupPoints GroupPoints { get ; set ; }
178
176
179
- private ChartSerializer chartSerializer = new ( ) ;
180
-
181
177
/// <summary>
182
178
/// The collection of data series to display on the chart
183
179
/// </summary>
184
180
public List < IApexSeries < TItem > > Series => apexSeries ;
185
181
186
- private DotNetObjectReference < ApexChart < TItem > > ObjectReference ;
187
182
private ElementReference ChartContainer { get ; set ; }
188
183
private List < IApexSeries < TItem > > apexSeries = new ( ) ;
189
184
private bool isReady ;
190
185
private bool forceRender = true ;
191
186
private string chartId ;
192
187
private HoverData < TItem > tooltipData ;
188
+ private JSHandler < TItem > JSHandler ;
193
189
194
190
/// <inheritdoc cref="Chart.Id"/>
195
191
public string ChartId => chartId ;
@@ -200,7 +196,7 @@ protected override async Task OnAfterRenderAsync(bool firstRender)
200
196
if ( firstRender && isReady == false )
201
197
{
202
198
isReady = true ;
203
- ObjectReference = DotNetObjectReference . Create ( this ) ;
199
+ JSHandler = new JSHandler < TItem > ( this , ChartContainer , JSRuntime ) ;
204
200
}
205
201
206
202
if ( isReady && forceRender )
@@ -417,7 +413,7 @@ private void FixLineDataSelection()
417
413
if ( Options . Tooltip == null ) { Options . Tooltip = new Tooltip ( ) ; }
418
414
if ( Options . Markers == null ) { Options . Markers = new Markers ( ) ; }
419
415
420
- if ( ( Options . Markers . Size == null || Options . Markers . Size <= 0 ) && ( Options . Markers . Sizes == null || ! Options . Markers . Sizes . Any ( ) ) )
416
+ if ( Options . Markers . Size == null || ! Options . Markers . Size . Any ( ) || Options . Markers . Size . Any ( x => x <= 0 ) )
421
417
{
422
418
Options . Markers . Size = 5 ;
423
419
}
@@ -429,9 +425,7 @@ private void FixLineDataSelection()
429
425
430
426
private string Serialize ( object data )
431
427
{
432
- var serializerOptions = chartSerializer . GetOptions < TItem > ( ) ;
433
- var json = JsonSerializer . Serialize ( data , serializerOptions ) ;
434
- return json ;
428
+ return JsonSerializer . Serialize ( data , ChartSerializer . GetOptions < TItem > ( ) ) ;
435
429
}
436
430
437
431
/// <summary>
@@ -726,7 +720,6 @@ private void PrepareChart()
726
720
FixLineDataSelection ( ) ;
727
721
UpdateDataForNoAxisCharts ( ) ;
728
722
SetDotNetFormatters ( ) ;
729
- SetEvents ( ) ;
730
723
SetCustomTooltip ( ) ;
731
724
}
732
725
@@ -747,26 +740,12 @@ private void SetCustomTooltip()
747
740
Options . Tooltip . Custom = customTooltip ;
748
741
}
749
742
750
- private void SetEvents ( )
751
- {
752
- Options . HasDataPointSelection = OnDataPointSelection . HasDelegate ;
753
- Options . HasDataPointEnter = OnDataPointEnter . HasDelegate || ApexPointTooltip != null ;
754
- Options . HasDataPointLeave = OnDataPointLeave . HasDelegate ;
755
- Options . HasLegendClick = OnLegendClicked . HasDelegate ;
756
- Options . HasMarkerClick = OnMarkerClick . HasDelegate ;
757
- Options . HasXAxisLabelClick = OnXAxisLabelClick . HasDelegate ;
758
- Options . HasSelection = OnSelection . HasDelegate ;
759
- Options . HasBrushScrolled = OnBrushScrolled . HasDelegate ;
760
- Options . HasZoomed = OnZoomed . HasDelegate ;
761
- }
762
-
763
743
private async Task RenderChartAsync ( )
764
744
{
765
745
await Task . Yield ( ) ;
766
746
forceRender = false ;
767
747
PrepareChart ( ) ;
768
- var jsonOptions = Serialize ( Options ) ;
769
- await JSRuntime . InvokeVoidAsync ( "blazor_apexchart.renderChart" , ObjectReference , ChartContainer , jsonOptions ) ;
748
+ await JSHandler . RenderChartAsync ( ) ;
770
749
await OnRendered . InvokeAsync ( ) ;
771
750
}
772
751
@@ -861,269 +840,13 @@ public virtual void Dispose()
861
840
InvokeAsync ( async ( ) => { await JSRuntime . InvokeVoidAsync ( "blazor_apexchart.destroyChart" , Options . Chart . Id ) ; } ) ;
862
841
}
863
842
864
- if ( ObjectReference != null )
865
- {
866
- ObjectReference . Dispose ( ) ;
867
- }
868
- }
869
-
870
- /// <summary>
871
- /// Callback from JavaScript to get a formatted Y-axis value
872
- /// </summary>
873
- /// <param name="value">Details from JavaScript</param>
874
- /// <remarks>
875
- /// Will execute <see cref="FormatYAxisLabel"/>
876
- /// </remarks>
877
- [ JSInvokable ( "JSGetFormattedYAxisValue" ) ]
878
- public string JSGetFormattedYAxisValue ( object value )
879
- {
880
- if ( value == null ) { return "" ; }
881
- if ( FormatYAxisLabel == null ) { return value . ToString ( ) ; }
882
-
883
- if ( decimal . TryParse ( value . ToString ( ) , out var decimalValue ) )
884
- {
885
- return FormatYAxisLabel . Invoke ( decimalValue ) ;
886
- }
887
-
888
- return value . ToString ( ) ;
889
- }
890
-
891
- /// <summary>
892
- /// Callback from JavaScript on zoom
893
- /// </summary>
894
- /// <param name="jSZoomed">Details from JavaScript</param>
895
- /// <remarks>
896
- /// Will execute <see cref="OnZoomed"/>
897
- /// </remarks>
898
- [ JSInvokable ( "JSZoomed" ) ]
899
- public void JSZoomed ( JSZoomed jSZoomed )
900
- {
901
- var data = new ZoomedData < TItem >
902
- {
903
- Chart = this ,
904
- YAxis = jSZoomed . YAxis ,
905
- XAxis = jSZoomed . XAxis
906
- } ;
907
-
908
- OnZoomed . InvokeAsync ( data ) ;
909
- }
910
-
911
- /// <summary>
912
- /// Callback from JavaScript on selection updated
913
- /// </summary>
914
- /// <param name="jsSelection">Details from JavaScript</param>
915
- /// <remarks>
916
- /// Will execute <see cref="OnBrushScrolled"/>
917
- /// </remarks>
918
- [ JSInvokable ( "JSBrushScrolled" ) ]
919
- public void JSBrushScrolled ( JSSelection jsSelection )
920
- {
921
- var selectionData = new SelectionData < TItem >
922
- {
923
- Chart = this ,
924
- YAxis = jsSelection . YAxis ,
925
- XAxis = jsSelection . XAxis
926
- } ;
927
-
928
- OnBrushScrolled . InvokeAsync ( selectionData ) ;
929
- }
930
-
931
- /// <summary>
932
- /// Callback from JavaScript on selection updated
933
- /// </summary>
934
- /// <param name="jsSelection">Details from JavaScript</param>
935
- /// <remarks>
936
- /// Will execute <see cref="OnSelection"/>
937
- /// </remarks>
938
- [ JSInvokable ( "JSSelected" ) ]
939
- public void JSSelected ( JSSelection jsSelection )
940
- {
941
- var selectionData = new SelectionData < TItem >
942
- {
943
- Chart = this ,
944
- YAxis = jsSelection . YAxis ,
945
- XAxis = jsSelection . XAxis
946
- } ;
947
-
948
- OnSelection . InvokeAsync ( selectionData ) ;
949
- }
950
-
951
- /// <summary>
952
- /// Callback from JavaScript on a legend item clicked
953
- /// </summary>
954
- /// <param name="jsLegendClicked">Details from JavaScript</param>
955
- /// <remarks>
956
- /// Will execute <see cref="OnLegendClicked"/>
957
- /// </remarks>
958
- [ JSInvokable ( "JSLegendClicked" ) ]
959
- public void JSLegendClicked ( JSLegendClicked jsLegendClicked )
960
- {
961
- var series = Options . Series . ElementAt ( jsLegendClicked . SeriesIndex ) ;
962
- var legendClicked = new LegendClicked < TItem >
963
- {
964
- Series = series ,
965
- Collapsed = jsLegendClicked . Collapsed
966
- } ;
967
-
968
- //Invert if Toggle series is set to flase (default == true)
969
- var toggleSeries = Options ? . Legend ? . OnItemClick ? . ToggleDataSeries ;
970
-
971
- if ( toggleSeries != false )
972
- {
973
- legendClicked . Collapsed = ! legendClicked . Collapsed ;
974
- }
975
-
976
- OnLegendClicked . InvokeAsync ( legendClicked ) ;
977
- }
978
-
979
- /// <summary>
980
- /// Callback from JavaScript on an X-axis label clicked
981
- /// </summary>
982
- /// <param name="jsXAxisLabelClick">Details from JavaScript</param>
983
- /// <remarks>
984
- /// Will execute <see cref="OnXAxisLabelClick"/>
985
- /// </remarks>
986
- [ JSInvokable ( "JSXAxisLabelClick" ) ]
987
- public void JSXAxisLabelClick ( JSXAxisLabelClick jsXAxisLabelClick )
988
- {
989
- if ( OnXAxisLabelClick . HasDelegate )
990
- {
991
- var data = new XAxisLabelClicked < TItem > ( ) ;
992
- data . LabelIndex = jsXAxisLabelClick . LabelIndex ;
993
- data . Caption = jsXAxisLabelClick . Caption ;
994
- data . SeriesPoints = new List < SeriesDataPoint < TItem > > ( ) ;
995
-
996
- foreach ( var series in Options . Series )
997
- {
998
- data . SeriesPoints . Add ( new SeriesDataPoint < TItem >
999
- {
1000
- Series = series ,
1001
- DataPoint = series . Data . ElementAt ( jsXAxisLabelClick . LabelIndex )
1002
- } ) ;
1003
- }
1004
-
1005
- OnXAxisLabelClick . InvokeAsync ( data ) ;
1006
- }
1007
- }
1008
-
1009
- /// <summary>
1010
- /// Callback from JavaScript on marker clicked
1011
- /// </summary>
1012
- /// <param name="selectedDataPoints">Details from JavaScript</param>
1013
- /// <remarks>
1014
- /// Will execute <see cref="OnMarkerClick"/>
1015
- /// </remarks>
1016
- [ JSInvokable ( "JSMarkerClick" ) ]
1017
- public void JSMarkerClick ( JSDataPointSelection selectedDataPoints )
1018
- {
1019
- if ( OnMarkerClick . HasDelegate )
1020
- {
1021
- var series = Options . Series . ElementAt ( selectedDataPoints . SeriesIndex ) ;
1022
- var dataPoint = series . Data . ElementAt ( selectedDataPoints . DataPointIndex ) ;
1023
-
1024
- var selection = new SelectedData < TItem >
1025
- {
1026
- Chart = this ,
1027
- Series = series ,
1028
- DataPoint = dataPoint ,
1029
- IsSelected = selectedDataPoints . SelectedDataPoints ? . Any ( e => e != null && e . Any ( e => e != null && e . HasValue ) ) ?? false ,
1030
- DataPointIndex = selectedDataPoints . DataPointIndex ,
1031
- SeriesIndex = selectedDataPoints . SeriesIndex
1032
- } ;
1033
-
1034
- OnMarkerClick . InvokeAsync ( selection ) ;
1035
- }
1036
- }
1037
-
1038
- /// <summary>
1039
- /// Callback from JavaScript on data point selected
1040
- /// </summary>
1041
- /// <param name="selectedDataPoints">Details from JavaScript</param>
1042
- /// <remarks>
1043
- /// Will execute <see cref="OnDataPointSelection"/>
1044
- /// </remarks>
1045
- [ JSInvokable ( "JSDataPointSelected" ) ]
1046
- public void JSDataPointSelected ( JSDataPointSelection selectedDataPoints )
1047
- {
1048
- if ( OnDataPointSelection . HasDelegate )
1049
- {
1050
- var series = Options . Series . ElementAt ( selectedDataPoints . SeriesIndex ) ;
1051
- var dataPoint = series . Data . ElementAt ( selectedDataPoints . DataPointIndex ) ;
1052
-
1053
- var selection = new SelectedData < TItem >
1054
- {
1055
- Chart = this ,
1056
- Series = series ,
1057
- DataPoint = dataPoint ,
1058
- IsSelected = selectedDataPoints . SelectedDataPoints . Any ( e => e != null && e . Any ( e => e != null && e . HasValue ) ) ,
1059
- DataPointIndex = selectedDataPoints . DataPointIndex ,
1060
- SeriesIndex = selectedDataPoints . SeriesIndex
1061
- } ;
1062
-
1063
- OnDataPointSelection . InvokeAsync ( selection ) ;
1064
- }
1065
- }
1066
-
1067
- /// <summary>
1068
- /// Callback from JavaScript on data point enter
1069
- /// </summary>
1070
- /// <param name="selectedDataPoints">Details from JavaScript</param>
1071
- /// <remarks>
1072
- /// Will execute <see cref="OnDataPointEnter"/>
1073
- /// </remarks>
1074
- [ JSInvokable ( "JSDataPointEnter" ) ]
1075
- public void JSDataPointEnter ( JSDataPointSelection selectedDataPoints )
1076
- {
1077
- if ( OnDataPointEnter . HasDelegate || ApexPointTooltip != null )
1078
- {
1079
- var series = Options . Series . ElementAt ( selectedDataPoints . SeriesIndex ) ;
1080
- var dataPoint = series . Data . ElementAt ( selectedDataPoints . DataPointIndex ) ;
1081
-
1082
- var hoverData = new HoverData < TItem >
1083
- {
1084
- Chart = this ,
1085
- Series = series ,
1086
- DataPoint = dataPoint ,
1087
- DataPointIndex = selectedDataPoints . DataPointIndex ,
1088
- SeriesIndex = selectedDataPoints . SeriesIndex
1089
- } ;
1090
-
1091
- OnDataPointEnter . InvokeAsync ( hoverData ) ;
1092
-
1093
- if ( ApexPointTooltip != null )
1094
- {
1095
- tooltipData = hoverData ;
1096
- StateHasChanged ( ) ;
1097
- }
1098
- }
843
+ JSHandler ? . Dispose ( ) ;
1099
844
}
1100
845
1101
- /// <summary>
1102
- /// Callback from JavaScript on data point leave
1103
- /// </summary>
1104
- /// <param name="selectedDataPoints">Details from JavaScript</param>
1105
- /// <remarks>
1106
- /// Will execute <see cref="OnDataPointLeave"/>
1107
- /// </remarks>
1108
- [ JSInvokable ( "JSDataPointLeave" ) ]
1109
- public void JSDataPointLeave ( JSDataPointSelection selectedDataPoints )
846
+ internal void UpdateTooltipData ( HoverData < TItem > tooltipData )
1110
847
{
1111
- if ( OnDataPointLeave . HasDelegate )
1112
- {
1113
- var series = Options . Series . ElementAt ( selectedDataPoints . SeriesIndex ) ;
1114
- var dataPoint = series . Data . ElementAt ( selectedDataPoints . DataPointIndex ) ;
1115
-
1116
- var hoverData = new HoverData < TItem >
1117
- {
1118
- Chart = this ,
1119
- Series = series ,
1120
- DataPoint = dataPoint ,
1121
- DataPointIndex = selectedDataPoints . DataPointIndex ,
1122
- SeriesIndex = selectedDataPoints . SeriesIndex
1123
- } ;
1124
-
1125
- OnDataPointLeave . InvokeAsync ( hoverData ) ;
1126
- }
848
+ this . tooltipData = tooltipData ;
849
+ StateHasChanged ( ) ;
1127
850
}
1128
851
}
1129
852
}
0 commit comments