Repository: Eremex/controls-demo Branch: main Commit: 04d656ce78ce Files: 455 Total size: 1.2 MB Directory structure: gitextract_lif3ay9j/ ├── .github/ │ └── workflows/ │ ├── deploy.yml │ ├── publish.yml │ ├── release-tag.yml │ └── test.yml ├── .gitignore ├── DemoCenter/ │ ├── DemoCenter/ │ │ ├── App.axaml │ │ ├── App.axaml.cs │ │ ├── AssemblyInfo.cs │ │ ├── DemoCenter.csproj │ │ ├── DemoData/ │ │ │ ├── ApparelProducts.cs │ │ │ ├── CsvClasses/ │ │ │ │ ├── CarInfo.cs │ │ │ │ ├── CsvClasses.cs │ │ │ │ ├── CsvColumnData.cs │ │ │ │ ├── StockInfo.cs │ │ │ │ └── StockProduct.cs │ │ │ ├── CsvSources.cs │ │ │ ├── ElementsSources.cs │ │ │ ├── EmployeesData.cs │ │ │ ├── Enums.cs │ │ │ ├── InfrastructureData.cs │ │ │ ├── OrderData.cs │ │ │ ├── ProjectTasksData.cs │ │ │ ├── SalesData.cs │ │ │ └── csv/ │ │ │ ├── Bitcoin Historical Data.csv │ │ │ ├── CarImages/ │ │ │ │ ├── convert.bat │ │ │ │ └── readme.txt │ │ │ ├── cars.csv │ │ │ ├── logarithmic.csv │ │ │ ├── mechs.csv │ │ │ ├── orgchat.csv │ │ │ ├── spacexlaunches.csv │ │ │ ├── stockProducts.csv │ │ │ ├── yachtNames.csv │ │ │ └── yachts.csv │ │ ├── Helpers/ │ │ │ ├── HeatmapHelper.cs │ │ │ └── ThemedSyntaxHighlighter.cs │ │ ├── ProductsData/ │ │ │ ├── BarsGroupInfo.cs │ │ │ ├── CartesianChartGroupInfo.cs │ │ │ ├── CommonControlsGroupInfo.cs │ │ │ ├── DataGridGroupInfo.cs │ │ │ ├── DeveloperToolsGroupInfo.cs │ │ │ ├── EditorsGroupInfo.cs │ │ │ ├── Graphics3DControlGroupInfo.cs │ │ │ ├── GroupInfo.cs │ │ │ ├── HeatmapGroupInfo.cs │ │ │ ├── PageInfo.cs │ │ │ ├── PolarChartGroupInfo.cs │ │ │ ├── ProductInfoBase.cs │ │ │ ├── Products.cs │ │ │ ├── PropertyGridGroupInfo.cs │ │ │ ├── RibbonGroupInfo.cs │ │ │ ├── SmithChartGroupInfo.cs │ │ │ ├── StandardControlsGroupInfo.cs │ │ │ ├── TreeListGroupInfo.cs │ │ │ └── UseCasesGroupInfo.cs │ │ ├── Resources/ │ │ │ ├── Colors.Dark.axaml │ │ │ ├── Colors.Light.axaml │ │ │ ├── Graphics3D/ │ │ │ │ └── Models/ │ │ │ │ └── robot_arm_2.fbx │ │ │ ├── Highlighters/ │ │ │ │ ├── Axaml-Highlight-Dark.xshd │ │ │ │ ├── Axaml-Highlight-Light.xshd │ │ │ │ ├── CSharp-Highlight-Dark.xshd │ │ │ │ └── CSharp-Highlight-Light.xshd │ │ │ ├── SearchPanel.axaml │ │ │ ├── SharedResources.axaml │ │ │ ├── SharedStyles.axaml │ │ │ ├── SvgIconsBrowserViewResources.Designer.cs │ │ │ └── SvgIconsBrowserViewResources.resx │ │ ├── Resources.Designer.cs │ │ ├── Resources.resx │ │ ├── Resources.ru.resx │ │ ├── Resources.zh-Hans.resx │ │ ├── ViewLocator.cs │ │ ├── ViewModels/ │ │ │ ├── Bars/ │ │ │ │ ├── BarItemsPageViewModel.cs │ │ │ │ ├── BarsGroupViewModel.cs │ │ │ │ ├── BarsOverviewPageViewModel.cs │ │ │ │ ├── ContextMenuPageViewModel.cs │ │ │ │ └── ToolbarAndMenuPageViewModel.cs │ │ │ ├── Charts/ │ │ │ │ ├── CartesianAreaSeriesViewViewModel.cs │ │ │ │ ├── CartesianCandlestickAggregationViewModel.cs │ │ │ │ ├── CartesianCandlestickSeriesViewViewModel.cs │ │ │ │ ├── CartesianChartAxesPageViewModel.cs │ │ │ │ ├── CartesianChartLargeDataPageViewModel.cs │ │ │ │ ├── CartesianChartLogarithmicScalePageViewModel.cs │ │ │ │ ├── CartesianChartRealtimePageViewModel.cs │ │ │ │ ├── CartesianEmptyPointsViewModel.cs │ │ │ │ ├── CartesianFullStackedAreaSeriesViewViewModel.cs │ │ │ │ ├── CartesianLineSeriesViewViewModel.cs │ │ │ │ ├── CartesianLollipopSeriesViewViewModel.cs │ │ │ │ ├── CartesianPointSeriesViewViewModel.cs │ │ │ │ ├── CartesianRangeAreaSeriesViewViewModel.cs │ │ │ │ ├── CartesianScatterLineSeriesViewViewModel.cs │ │ │ │ ├── CartesianSideBySideBarSeriesViewViewModel.cs │ │ │ │ ├── CartesianSideBySideRangeBarSeriesViewViewModel.cs │ │ │ │ ├── CartesianStackedAreaSeriesViewViewModel.cs │ │ │ │ ├── CartesianStepAreaSeriesViewViewModel.cs │ │ │ │ ├── CartesianStepLineSeriesViewViewModel.cs │ │ │ │ ├── CartesianStripsAndConstantLinesViewModel.cs │ │ │ │ ├── ChartElementViewModels/ │ │ │ │ │ ├── AxisViewModel.cs │ │ │ │ │ ├── ConstantLineViewModel.cs │ │ │ │ │ ├── CustomLabelFormatter.cs │ │ │ │ │ ├── LogarithmicAxisViewModel.cs │ │ │ │ │ ├── SeriesViewModel.cs │ │ │ │ │ └── ViewViewModel.cs │ │ │ │ ├── ChartsPageViewModel.cs │ │ │ │ ├── Data/ │ │ │ │ │ ├── ClusterDataAdapter.cs │ │ │ │ │ ├── RealtimeDataGenerator.cs │ │ │ │ │ └── SmithSampleDataAdapter.cs │ │ │ │ ├── HeatmapColorProvidersViewModel.cs │ │ │ │ ├── HeatmapRealTimeViewModel.cs │ │ │ │ ├── PolarAreaSeriesViewViewModel.cs │ │ │ │ ├── PolarEmptyPointsViewModel.cs │ │ │ │ ├── PolarLineSeriesViewViewModel.cs │ │ │ │ ├── PolarPointSeriesViewViewModel.cs │ │ │ │ ├── PolarRangeAreaSeriesViewViewModel.cs │ │ │ │ ├── PolarScatterLineSeriesViewViewModel.cs │ │ │ │ ├── PolarStripsAndConstantLinesViewModel.cs │ │ │ │ ├── SmithLineSeriesViewViewModel.cs │ │ │ │ └── SmithPointSeriesViewViewModel.cs │ │ │ ├── CommonControls/ │ │ │ │ ├── CommonControlsGroupViewModel.cs │ │ │ │ ├── MessageBoxPageViewModel.cs │ │ │ │ ├── SplitContainerControlPageViewModel.cs │ │ │ │ └── TabControlPageViewModel.cs │ │ │ ├── DataGrid/ │ │ │ │ ├── DataGridColumnBandsViewModel.cs │ │ │ │ ├── DataGridDataEditorsViewModel.cs │ │ │ │ ├── DataGridDragDropPageViewModel.cs │ │ │ │ ├── DataGridExportViewModel.cs │ │ │ │ ├── DataGridFilteringViewModel.cs │ │ │ │ ├── DataGridFixedColuimnsViewModel.cs │ │ │ │ ├── DataGridGroupingPageViewModel.cs │ │ │ │ ├── DataGridLargeDataPageViewModel.cs │ │ │ │ ├── DataGridLiveDataPageViewModel.cs │ │ │ │ ├── DataGridMultipleSelectionPageViewModel.cs │ │ │ │ ├── DataGridPageViewModel.cs │ │ │ │ ├── DataGridRowAutoHeightViewModel.cs │ │ │ │ └── DataGridValidationViewModel.cs │ │ │ ├── DesktopOnlyViewModel.cs │ │ │ ├── DockManager/ │ │ │ │ └── IdeLayoutPageViewModel.cs │ │ │ ├── Editors/ │ │ │ │ ├── ColorEditorPageViewModel.cs │ │ │ │ ├── ComboBoxEditorPageViewModel.cs │ │ │ │ ├── DateEditorPageViewModel.cs │ │ │ │ ├── EditorsGroupViewModel.cs │ │ │ │ ├── EditorsOverviewPageViewModel.cs │ │ │ │ ├── EnumSourcePageViewModel.cs │ │ │ │ ├── HyperlinkEditorPageViewModel.cs │ │ │ │ ├── MemoEditorPageViewModel.cs │ │ │ │ ├── SegmentedEditorPageViewModel.cs │ │ │ │ ├── SpinEditorPageViewModel.cs │ │ │ │ └── TextEditingPageViewModel.cs │ │ │ ├── Graphics3DControl/ │ │ │ │ ├── Graphics3DControlCameraViewModel.cs │ │ │ │ ├── Graphics3DControlHighlightingViewModel.cs │ │ │ │ ├── Graphics3DControlLightsViewModel.cs │ │ │ │ ├── Graphics3DControlLinesViewModel.cs │ │ │ │ ├── Graphics3DControlOverviewViewModel.cs │ │ │ │ ├── Graphics3DControlPointsViewModel.cs │ │ │ │ ├── Graphics3DControlRobotArmViewModel.cs │ │ │ │ ├── Graphics3DControlSimpleMaterialsViewModel.cs │ │ │ │ ├── Graphics3DControlSkyboxViewModel.cs │ │ │ │ ├── Graphics3DControlStlViewModel.cs │ │ │ │ ├── Graphics3DControlTexturedMaterialsViewModel.cs │ │ │ │ ├── Graphics3DControlTransformationViewModel.cs │ │ │ │ ├── Graphics3DControlViewModel.cs │ │ │ │ ├── MeshViewModel.cs │ │ │ │ └── Model3DLoader.cs │ │ │ ├── MainViewModel.cs │ │ │ ├── PageViewModelBase.cs │ │ │ ├── PropertyGrid/ │ │ │ │ ├── PropertyGridDataEditorsViewModel.cs │ │ │ │ ├── PropertyGridGroupViewModel.cs │ │ │ │ └── PropertyGridTabItemsViewModel.cs │ │ │ ├── Ribbon/ │ │ │ │ ├── RibbonGroupViewModel.cs │ │ │ │ └── WordPadExampleViewModel.cs │ │ │ ├── StandardControls/ │ │ │ │ ├── PrimitivesPageViewModel.cs │ │ │ │ ├── ProgressBarPageViewModel.cs │ │ │ │ ├── SliderPageViewModel.cs │ │ │ │ ├── StandardControlsGroupViewModel.cs │ │ │ │ ├── StandardControlsOverviewPageViewModel.cs │ │ │ │ └── UseCasesGroupViewModel.cs │ │ │ ├── Tools/ │ │ │ │ ├── DeveloperToolsGroupViewModel.cs │ │ │ │ └── SvgIconsBrowserViewModel.cs │ │ │ ├── TreeList/ │ │ │ │ ├── FolderBrowserPageViewModel.cs │ │ │ │ ├── TreeListColumnBandsViewModel.cs │ │ │ │ ├── TreeListDataEditorsPageViewModel.cs │ │ │ │ ├── TreeListExportViewModel.cs │ │ │ │ ├── TreeListFilteringPageViewModel.cs │ │ │ │ ├── TreeListGroupViewModel.cs │ │ │ │ └── TreeListMultipleSelectionPageViewModel.cs │ │ │ └── UseCases/ │ │ │ └── FinancialServices/ │ │ │ ├── MortgageCalculatorViewModel.cs │ │ │ └── SampleMortgageCalculator.cs │ │ ├── Views/ │ │ │ ├── Bars/ │ │ │ │ ├── BarItemsPageView.axaml │ │ │ │ ├── BarItemsPageView.axaml.cs │ │ │ │ ├── BarsGroupView.axaml │ │ │ │ ├── BarsGroupView.axaml.cs │ │ │ │ ├── BarsOverviewPageView.axaml │ │ │ │ ├── BarsOverviewPageView.axaml.cs │ │ │ │ ├── ContextMenuPageView.axaml │ │ │ │ ├── ContextMenuPageView.axaml.cs │ │ │ │ ├── Helpers/ │ │ │ │ │ ├── Converters.cs │ │ │ │ │ ├── ScaleDecorator.cs │ │ │ │ │ └── TextBoxHelper.cs │ │ │ │ ├── ToolbarAndMenuPageView.axaml │ │ │ │ └── ToolbarAndMenuPageView.axaml.cs │ │ │ ├── Charts/ │ │ │ │ ├── CartesianAreaSeriesViewView.axaml │ │ │ │ ├── CartesianAreaSeriesViewView.axaml.cs │ │ │ │ ├── CartesianCandlestickAggregationView.axaml │ │ │ │ ├── CartesianCandlestickAggregationView.axaml.cs │ │ │ │ ├── CartesianCandlestickSeriesViewView.axaml │ │ │ │ ├── CartesianCandlestickSeriesViewView.axaml.cs │ │ │ │ ├── CartesianChartAxesPageView.axaml │ │ │ │ ├── CartesianChartAxesPageView.axaml.cs │ │ │ │ ├── CartesianChartLargeDataPageView.axaml │ │ │ │ ├── CartesianChartLargeDataPageView.axaml.cs │ │ │ │ ├── CartesianChartLogarithmicScalePageView.axaml │ │ │ │ ├── CartesianChartLogarithmicScalePageView.axaml.cs │ │ │ │ ├── CartesianChartRealtimePageView.axaml │ │ │ │ ├── CartesianChartRealtimePageView.axaml.cs │ │ │ │ ├── CartesianEmptyPointsView.axaml │ │ │ │ ├── CartesianEmptyPointsView.axaml.cs │ │ │ │ ├── CartesianFullStackedAreaSeriesViewView.axaml │ │ │ │ ├── CartesianFullStackedAreaSeriesViewView.axaml.cs │ │ │ │ ├── CartesianLineSeriesViewView.axaml │ │ │ │ ├── CartesianLineSeriesViewView.axaml.cs │ │ │ │ ├── CartesianLollipopSeriesViewView.axaml │ │ │ │ ├── CartesianLollipopSeriesViewView.axaml.cs │ │ │ │ ├── CartesianPointSeriesViewView.axaml │ │ │ │ ├── CartesianPointSeriesViewView.axaml.cs │ │ │ │ ├── CartesianRangeAreaSeriesViewView.axaml │ │ │ │ ├── CartesianRangeAreaSeriesViewView.axaml.cs │ │ │ │ ├── CartesianScatterLineSeriesViewView.axaml │ │ │ │ ├── CartesianScatterLineSeriesViewView.axaml.cs │ │ │ │ ├── CartesianSideBySideBarSeriesViewView.axaml │ │ │ │ ├── CartesianSideBySideBarSeriesViewView.axaml.cs │ │ │ │ ├── CartesianSideBySideRangeBarSeriesViewView.axaml │ │ │ │ ├── CartesianSideBySideRangeBarSeriesViewView.axaml.cs │ │ │ │ ├── CartesianStackedAreaSeriesViewView.axaml │ │ │ │ ├── CartesianStackedAreaSeriesViewView.axaml.cs │ │ │ │ ├── CartesianStepAreaSeriesViewView.axaml │ │ │ │ ├── CartesianStepAreaSeriesViewView.axaml.cs │ │ │ │ ├── CartesianStepLineSeriesViewView.axaml │ │ │ │ ├── CartesianStepLineSeriesViewView.axaml.cs │ │ │ │ ├── CartesianStripsAndConstantLinesView.axaml │ │ │ │ ├── CartesianStripsAndConstantLinesView.axaml.cs │ │ │ │ ├── HeatmapColorProvidersView.axaml │ │ │ │ ├── HeatmapColorProvidersView.axaml.cs │ │ │ │ ├── HeatmapRealTimeView.axaml │ │ │ │ ├── HeatmapRealTimeView.axaml.cs │ │ │ │ ├── PolarAreaSeriesViewView.axaml │ │ │ │ ├── PolarAreaSeriesViewView.axaml.cs │ │ │ │ ├── PolarEmptyPointsView.axaml │ │ │ │ ├── PolarEmptyPointsView.axaml.cs │ │ │ │ ├── PolarLineSeriesViewView.axaml │ │ │ │ ├── PolarLineSeriesViewView.axaml.cs │ │ │ │ ├── PolarPointSeriesViewView.axaml │ │ │ │ ├── PolarPointSeriesViewView.axaml.cs │ │ │ │ ├── PolarRangeAreaSeriesViewView.axaml │ │ │ │ ├── PolarRangeAreaSeriesViewView.axaml.cs │ │ │ │ ├── PolarScatterLineSeriesViewView.axaml │ │ │ │ ├── PolarScatterLineSeriesViewView.axaml.cs │ │ │ │ ├── PolarStripsAndConstantLinesView.axaml │ │ │ │ ├── PolarStripsAndConstantLinesView.axaml.cs │ │ │ │ ├── SmithLineSeriesViewView.axaml │ │ │ │ ├── SmithLineSeriesViewView.axaml.cs │ │ │ │ ├── SmithPointSeriesViewView.axaml │ │ │ │ └── SmithPointSeriesViewView.axaml.cs │ │ │ ├── CommonControls/ │ │ │ │ ├── CommonControlsGroupView.axaml │ │ │ │ ├── CommonControlsGroupView.axaml.cs │ │ │ │ ├── MessageBoxPageView.axaml │ │ │ │ ├── MessageBoxPageView.axaml.cs │ │ │ │ ├── SplitContainerControlPageView.axaml │ │ │ │ ├── SplitContainerControlPageView.axaml.cs │ │ │ │ ├── TabControlPageView.axaml │ │ │ │ └── TabControlPageView.axaml.cs │ │ │ ├── Converters/ │ │ │ │ └── EnumRadioButtonConverter.cs │ │ │ ├── DataGrid/ │ │ │ │ ├── DataGridColumnBandsView.axaml │ │ │ │ ├── DataGridColumnBandsView.axaml.cs │ │ │ │ ├── DataGridDataEditorsView.axaml │ │ │ │ ├── DataGridDataEditorsView.axaml.cs │ │ │ │ ├── DataGridDragDropPageView.axaml │ │ │ │ ├── DataGridDragDropPageView.axaml.cs │ │ │ │ ├── DataGridExportView.axaml │ │ │ │ ├── DataGridExportView.axaml.cs │ │ │ │ ├── DataGridFilteringView.axaml │ │ │ │ ├── DataGridFilteringView.axaml.cs │ │ │ │ ├── DataGridFixedColumnsView.axaml │ │ │ │ ├── DataGridFixedColumnsView.axaml.cs │ │ │ │ ├── DataGridGroupingPageView.axaml │ │ │ │ ├── DataGridGroupingPageView.axaml.cs │ │ │ │ ├── DataGridLargeDataView.axaml │ │ │ │ ├── DataGridLargeDataView.axaml.cs │ │ │ │ ├── DataGridLiveDataPageView.axaml │ │ │ │ ├── DataGridLiveDataPageView.axaml.cs │ │ │ │ ├── DataGridMultipleSelectionPageView.axaml │ │ │ │ ├── DataGridMultipleSelectionPageView.axaml.cs │ │ │ │ ├── DataGridPageView.axaml │ │ │ │ ├── DataGridPageView.axaml.cs │ │ │ │ ├── DataGridRowAutoHeightView.axaml │ │ │ │ ├── DataGridRowAutoHeightView.axaml.cs │ │ │ │ ├── DataGridValidationView.axaml │ │ │ │ └── DataGridValidationView.axaml.cs │ │ │ ├── DesktopOnlyView.axaml │ │ │ ├── DesktopOnlyView.axaml.cs │ │ │ ├── DockManager/ │ │ │ │ ├── IdeLayoutPageView.axaml │ │ │ │ └── IdeLayoutPageView.axaml.cs │ │ │ ├── Editors/ │ │ │ │ ├── ColorEditorPageView.axaml │ │ │ │ ├── ColorEditorPageView.axaml.cs │ │ │ │ ├── ComboBoxEditorPageView.axaml │ │ │ │ ├── ComboBoxEditorPageView.axaml.cs │ │ │ │ ├── DateEditorPageView.axaml │ │ │ │ ├── DateEditorPageView.axaml.cs │ │ │ │ ├── EditorsGroupView.axaml │ │ │ │ ├── EditorsGroupView.axaml.cs │ │ │ │ ├── EditorsOverviewPageView.axaml │ │ │ │ ├── EditorsOverviewPageView.axaml.cs │ │ │ │ ├── EnumSourcePageView.axaml │ │ │ │ ├── EnumSourcePageView.axaml.cs │ │ │ │ ├── HyperlinkEditorPageView.axaml │ │ │ │ ├── HyperlinkEditorPageView.axaml.cs │ │ │ │ ├── MemoEditorPageView.axaml │ │ │ │ ├── MemoEditorPageView.axaml.cs │ │ │ │ ├── SegmentedEditorPageView.axaml │ │ │ │ ├── SegmentedEditorPageView.axaml.cs │ │ │ │ ├── SpinEditorPageView.axaml │ │ │ │ ├── SpinEditorPageView.axaml.cs │ │ │ │ ├── TextEditingPageView.axaml │ │ │ │ └── TextEditingPageView.axaml.cs │ │ │ ├── Export/ │ │ │ │ ├── DemoExportHelper.cs │ │ │ │ ├── ExportProgressControl.axaml │ │ │ │ └── ExportProgressControl.axaml.cs │ │ │ ├── Graphics3DControl/ │ │ │ │ ├── Graphics3DControlCameraView.axaml │ │ │ │ ├── Graphics3DControlCameraView.axaml.cs │ │ │ │ ├── Graphics3DControlHighlightingView.axaml │ │ │ │ ├── Graphics3DControlHighlightingView.axaml.cs │ │ │ │ ├── Graphics3DControlLightsView.axaml │ │ │ │ ├── Graphics3DControlLightsView.axaml.cs │ │ │ │ ├── Graphics3DControlLinesView.axaml │ │ │ │ ├── Graphics3DControlLinesView.axaml.cs │ │ │ │ ├── Graphics3DControlOverviewView.axaml │ │ │ │ ├── Graphics3DControlOverviewView.axaml.cs │ │ │ │ ├── Graphics3DControlPointsView.axaml │ │ │ │ ├── Graphics3DControlPointsView.axaml.cs │ │ │ │ ├── Graphics3DControlRobotArmView.axaml │ │ │ │ ├── Graphics3DControlRobotArmView.axaml.cs │ │ │ │ ├── Graphics3DControlSimpleMaterialsView.axaml │ │ │ │ ├── Graphics3DControlSimpleMaterialsView.axaml.cs │ │ │ │ ├── Graphics3DControlSkyboxView.axaml │ │ │ │ ├── Graphics3DControlSkyboxView.axaml.cs │ │ │ │ ├── Graphics3DControlStlView.axaml │ │ │ │ ├── Graphics3DControlStlView.axaml.cs │ │ │ │ ├── Graphics3DControlTexturedMaterialsView.axaml │ │ │ │ ├── Graphics3DControlTexturedMaterialsView.axaml.cs │ │ │ │ ├── Graphics3DControlTransformationView.axaml │ │ │ │ └── Graphics3DControlTransformationView.axaml.cs │ │ │ ├── MainView.axaml │ │ │ ├── MainView.axaml.cs │ │ │ ├── MainWindow.axaml │ │ │ ├── MainWindow.axaml.cs │ │ │ ├── PropertyGrid/ │ │ │ │ ├── PropertyGridDataEditorsView.axaml │ │ │ │ ├── PropertyGridDataEditorsView.axaml.cs │ │ │ │ ├── PropertyGridGroupView.axaml │ │ │ │ ├── PropertyGridGroupView.axaml.cs │ │ │ │ ├── PropertyGridTabItemsView.axaml │ │ │ │ ├── PropertyGridTabItemsView.axaml.cs │ │ │ │ └── Utils/ │ │ │ │ └── ContentControlPropertiesWrapper.cs │ │ │ ├── Ribbon/ │ │ │ │ ├── FontStyleGalleryItemForegroundConverter.cs │ │ │ │ ├── WordPadExampleView.axaml │ │ │ │ └── WordPadExampleView.axaml.cs │ │ │ ├── StandardControls/ │ │ │ │ ├── PrimitivesPageView.axaml │ │ │ │ ├── PrimitivesPageView.axaml.cs │ │ │ │ ├── ProgressBarPageView.axaml │ │ │ │ ├── ProgressBarPageView.axaml.cs │ │ │ │ ├── SliderPageView.axaml │ │ │ │ ├── SliderPageView.axaml.cs │ │ │ │ ├── StandardControlsGroupView.axaml │ │ │ │ ├── StandardControlsGroupView.axaml.cs │ │ │ │ ├── StandardControlsOverviewPageView.axaml │ │ │ │ └── StandardControlsOverviewPageView.axaml.cs │ │ │ ├── Tools/ │ │ │ │ ├── SvgIconsBrowserView.axaml │ │ │ │ ├── SvgIconsBrowserView.axaml.cs │ │ │ │ └── Templates/ │ │ │ │ ├── svgCodeExample.cs │ │ │ │ └── svgXamlExample.axaml │ │ │ ├── TreeList/ │ │ │ │ ├── FolderBrowserPageView.axaml │ │ │ │ ├── FolderBrowserPageView.axaml.cs │ │ │ │ ├── TreeListColumnBandsView.axaml │ │ │ │ ├── TreeListColumnBandsView.axaml.cs │ │ │ │ ├── TreeListDataEditorsPageView.axaml │ │ │ │ ├── TreeListDataEditorsPageView.axaml.cs │ │ │ │ ├── TreeListExportView.axaml │ │ │ │ ├── TreeListExportView.axaml.cs │ │ │ │ ├── TreeListFilteringPageView.axaml │ │ │ │ ├── TreeListFilteringPageView.axaml.cs │ │ │ │ ├── TreeListGroupView.axaml │ │ │ │ ├── TreeListGroupView.axaml.cs │ │ │ │ ├── TreeListMultipleSelectionPageView.axaml │ │ │ │ └── TreeListMultipleSelectionPageView.axaml.cs │ │ │ └── UseCases/ │ │ │ └── FinancialServices/ │ │ │ ├── MortgageCalculatorView.axaml │ │ │ └── MortgageCalculatorView.axaml.cs │ │ └── emxLicense.cs │ ├── DemoCenter.Android/ │ │ ├── DemoCenter.Android.csproj │ │ ├── MainActivity.cs │ │ ├── Properties/ │ │ │ └── AndroidManifest.xml │ │ └── Resources/ │ │ ├── AboutResources.txt │ │ ├── drawable/ │ │ │ └── splash_screen.xml │ │ ├── drawable-night-v31/ │ │ │ └── avalonia_anim.xml │ │ ├── drawable-v31/ │ │ │ └── avalonia_anim.xml │ │ ├── values/ │ │ │ ├── colors.xml │ │ │ └── styles.xml │ │ ├── values-night/ │ │ │ └── colors.xml │ │ └── values-v31/ │ │ └── styles.xml │ ├── DemoCenter.Desktop/ │ │ ├── AssemblyInfo.cs │ │ ├── DemoCenter.Desktop.csproj │ │ ├── Program.cs │ │ └── app.manifest │ ├── DemoCenter.Mobile.sln │ ├── DemoCenter.WASM.sln │ ├── DemoCenter.Web/ │ │ ├── DemoCenter.Web.csproj │ │ ├── Program.cs │ │ ├── Properties/ │ │ │ └── launchSettings.json │ │ ├── runtimeconfig.template.json │ │ └── wwwroot/ │ │ ├── app.css │ │ ├── index.html │ │ └── main.js │ ├── DemoCenter.iOS/ │ │ ├── AppDelegate.cs │ │ ├── DemoCenter.iOS.csproj │ │ ├── Entitlements.plist │ │ ├── Info.plist │ │ ├── Main.cs │ │ └── Resources/ │ │ └── LaunchScreen.xib │ └── DemoCenter.sln ├── Directory.Build.props ├── Directory.Packages.props ├── License.md ├── Tests/ │ ├── DemoCenter.Desktop.UI.Tests/ │ │ ├── AvaloniaApp.cs │ │ ├── AvaloniaUiTestFramework.cs │ │ ├── DemoCenter.Desktop.UI.Tests.csproj │ │ ├── DemoCenter.Desktop.UI.Tests.sln │ │ ├── ModulesShowTests.cs │ │ ├── NativeInputHelper.cs │ │ ├── TestMouseEventsHelper.cs │ │ ├── V11TestUtils.cs │ │ └── emxLicense.cs │ ├── Directory.Build.targets │ ├── Eremex.ruleset │ └── stylecop.json ├── docs/ │ ├── charts.md │ ├── commoncontrols.md │ ├── datagrid.md │ ├── docking.md │ ├── editors.md │ ├── graphics3dcontrol.md │ ├── heatmap.md │ ├── images/ │ │ ├── controls-dark.snag │ │ └── controls-light.snag │ ├── propertygrid.md │ ├── ribbon.md │ ├── toolbars.md │ └── treelist.md └── readme.md ================================================ FILE CONTENTS ================================================ ================================================ FILE: .github/workflows/deploy.yml ================================================ name: Deploy to GitHub Pages env: PROJECT_PATH: DemoCenter/DemoCenter.Web/DemoCenter.Web.csproj OUTPUT_PATH: DemoCenter/DemoCenter.Web/bin/Release_WASM/net9.0/publish/wwwroot on: workflow_dispatch: jobs: deploy-to-github-pages: runs-on: ubuntu-latest steps: - name: Checkout uses: actions/checkout@v4.1.1 - name: Setup .NET 9 uses: actions/setup-dotnet@v4 with: dotnet-version: 9.0.x - name: Install wasm-tools run: dotnet workload install wasm-tools-net9 wasm-tools-net8 - name: Publish .NET Project run: dotnet publish $PROJECT_PATH -f net9.0 -c Release_WASM --nologo -p:PublishTrimmed=false - name: Change base-tag in index.html run: sed -i 's###g' $OUTPUT_PATH/index.html - name: Add .nojekyll file run: touch $OUTPUT_PATH/.nojekyll - name: Commit wwwroot to GitHub Pages uses: JamesIves/github-pages-deploy-action@v4.5.0 with: github_token: ${{ secrets.GITHUB_TOKEN }} branch: gh-pages folder: ${{ env.OUTPUT_PATH }} single-commit: true ================================================ FILE: .github/workflows/publish.yml ================================================ name: Publish Demo on: workflow_dispatch: inputs: platform: description: 'Platform to publish' required: true default: 'all' type: choice options: - 'windows' - 'linux' - 'linux-rpi' - 'osx-arm64' - 'osx-x64' - 'all' jobs: windows: if: ${{ github.event.inputs.platform == 'windows' || github.event.inputs.platform == 'all' }} runs-on: windows-latest steps: - name: Checkout uses: actions/checkout@v4.1.1 - name: Make upload directory run: mkdir upload - name: Publish win-x64 run: dotnet publish ./DemoCenter/DemoCenter.Desktop/DemoCenter.Desktop.csproj -f net9.0 -r win-x64 -c Release --sc /p:PublishSingleFile=true /p:IncludeNativeLibrariesForSelfExtract=true -o ./publish/win64 - name: Zip win-x64 run: | $files = Get-ChildItem -Path ./publish/win64/* -Recurse -Exclude *.pdb Compress-Archive -Path $files.FullName -DestinationPath ./upload/EMX.Demo.Desktop.win-x64.zip - name: Upload a Build Artifact uses: actions/upload-artifact@v4.3.1 with: name: windows path: ./upload linux: if: ${{ github.event.inputs.platform == 'linux' || github.event.inputs.platform == 'all' }} runs-on: ubuntu-latest steps: - name: Checkout uses: actions/checkout@v4.1.1 - name: Make upload directory run: mkdir upload - name: Publish linux-x64 run: dotnet publish ./DemoCenter/DemoCenter.Desktop/DemoCenter.Desktop.csproj -f net9.0 -r linux-x64 -c Release --sc /p:PublishSingleFile=true /p:IncludeNativeLibrariesForSelfExtract=true -o ./publish/linux64 - name: Publish linux-x64 with files run: dotnet publish ./DemoCenter/DemoCenter.Desktop/DemoCenter.Desktop.csproj -f net9.0 -r linux-x64 -c Release -o ./publish/linux64Files - name: Rename app run: mv ./publish/linux64/DemoCenter.Desktop ./publish/linux64/DemoCenter.App - name: Copy library run: mv ./publish/linux64Files/libassimp.so ./publish/linux64/libassimp.so - name: Zip linux-x64 run: zip -j -r ./upload/EMX.Demo.Desktop.linux-x64.zip ./publish/linux64 -x "*.pdb" - name: Upload a Build Artifact uses: actions/upload-artifact@v4.3.1 with: name: linux path: ./upload linux-rpi: if: ${{ github.event.inputs.platform == 'linux-rpi' || github.event.inputs.platform == 'all' }} runs-on: ubuntu-latest steps: - name: Checkout uses: actions/checkout@v4.1.1 - name: Make upload directory run: mkdir upload - name: Publish linux-arm64 run: dotnet publish ./DemoCenter/DemoCenter.Desktop/DemoCenter.Desktop.csproj -f net9.0 -r linux-arm64 -c Release --sc /p:PublishSingleFile=true /p:IncludeNativeLibrariesForSelfExtract=true -o ./publish/linuxArm64 - name: Rename app run: mv ./publish/linuxArm64/DemoCenter.Desktop ./publish/linuxArm64/DemoCenter.App - name: Zip linux-x64 run: zip -j -r ./upload/EMX.Demo.Desktop.linux-arm64.zip ./publish/linuxArm64 -x "*.pdb" - name: Upload a Build Artifact uses: actions/upload-artifact@v4.3.1 with: name: linux-rpi path: ./upload osx-x64: if: ${{ github.event.inputs.platform == 'osx-x64' || github.event.inputs.platform == 'all' }} runs-on: ubuntu-latest steps: - name: Checkout uses: actions/checkout@v4.1.1 - name: Make upload directory run: mkdir upload - name: Publish linux-arm64 run: dotnet publish ./DemoCenter/DemoCenter.Desktop/DemoCenter.Desktop.csproj -f net9.0 -r osx-x64 -c Release --sc /p:PublishSingleFile=true /p:IncludeNativeLibrariesForSelfExtract=true -o ./publish/osx-x64 - name: Zip osx-x64 run: zip -j -r ./upload/EMX.Demo.Desktop.osx-x64.zip ./publish/osx-x64 -x "*.pdb" - name: Upload a Build Artifact uses: actions/upload-artifact@v4.3.1 with: name: osx-x64 path: ./upload osx-arm64: if: ${{ github.event.inputs.platform == 'osx-arm64' || github.event.inputs.platform == 'all' }} runs-on: ubuntu-latest steps: - name: Checkout uses: actions/checkout@v4.1.1 - name: Make upload directory run: mkdir upload - name: Publish osx-arm64 run: dotnet publish ./DemoCenter/DemoCenter.Desktop/DemoCenter.Desktop.csproj -f net9.0 -r osx-arm64 -c Release --sc /p:PublishSingleFile=true /p:IncludeNativeLibrariesForSelfExtract=true -o ./publish/osx-arm64 - name: Zip osx-arm64 run: zip -j -r ./upload/EMX.Demo.Desktop.osx-arm64.zip ./publish/osx-arm64 -x "*.pdb" - name: Upload a Build Artifact uses: actions/upload-artifact@v4.3.1 with: name: osx-arm64 path: ./upload ================================================ FILE: .github/workflows/release-tag.yml ================================================ name: Release Tag on: push: tags: - "v[0-9]+.[0-9]+.[0-9]+" workflow_dispatch: jobs: windows: runs-on: windows-latest steps: - name: Checkout uses: actions/checkout@v4 - name: Make upload directory run: mkdir upload - name: Publish win-x64 run: dotnet publish ./DemoCenter/DemoCenter.Desktop/DemoCenter.Desktop.csproj -f net9.0 -r win-x64 -c Release --sc /p:PublishSingleFile=true /p:IncludeNativeLibrariesForSelfExtract=true -o ./publish/win64 - name: Zip win-x64 run: | $files = Get-ChildItem -Path ./publish/win64/* -Recurse -Exclude *.pdb Compress-Archive -Path $files.FullName -DestinationPath ./upload/EMX.Demo.Desktop.win-x64.zip - name: Upload a Build Artifact uses: actions/upload-artifact@v4 with: name: windows path: ./upload linux: runs-on: ubuntu-latest steps: - name: Checkout uses: actions/checkout@v4 - name: Make upload directory run: mkdir upload - name: Publish linux-x64 run: dotnet publish ./DemoCenter/DemoCenter.Desktop/DemoCenter.Desktop.csproj -f net9.0 -r linux-x64 -c Release --sc /p:PublishSingleFile=true /p:IncludeNativeLibrariesForSelfExtract=true -o ./publish/linux64 - name: Publish linux-x64 with files run: dotnet publish ./DemoCenter/DemoCenter.Desktop/DemoCenter.Desktop.csproj -f net9.0 -r linux-x64 -c Release -o ./publish/linux64Files - name: Rename app run: mv ./publish/linux64/DemoCenter.Desktop ./publish/linux64/DemoCenter.App - name: Copy library run: mv ./publish/linux64Files/libassimp.so ./publish/linux64/libassimp.so - name: Zip linux-x64 run: zip -j -r ./upload/EMX.Demo.Desktop.linux-x64.zip ./publish/linux64 -x "*.pdb" - name: Upload a Build Artifact uses: actions/upload-artifact@v4 with: name: linux path: ./upload linux-rpi: runs-on: ubuntu-latest steps: - name: Checkout uses: actions/checkout@v4 - name: Make upload directory run: mkdir upload - name: Publish linux-arm64 run: dotnet publish ./DemoCenter/DemoCenter.Desktop/DemoCenter.Desktop.csproj -f net9.0 -r linux-arm64 -c Release --sc /p:PublishSingleFile=true /p:IncludeNativeLibrariesForSelfExtract=true -o ./publish/linuxArm64 - name: Rename app run: mv ./publish/linuxArm64/DemoCenter.Desktop ./publish/linuxArm64/DemoCenter.App - name: Zip linux-x64 run: zip -j -r ./upload/EMX.Demo.Desktop.linux-arm64.zip ./publish/linuxArm64 -x "*.pdb" - name: Upload a Build Artifact uses: actions/upload-artifact@v4.3.1 with: name: linux-rpi path: ./upload linux-orangepi: runs-on: ubuntu-latest steps: - name: Checkout uses: actions/checkout@v4 - name: Make upload directory run: mkdir upload - name: Publish linux-arm run: dotnet publish ./DemoCenter/DemoCenter.Desktop/DemoCenter.Desktop.csproj -f net9.0 -r linux-arm -c Release --sc /p:PublishSingleFile=true /p:IncludeNativeLibrariesForSelfExtract=true -o ./publish/linuxArm - name: Rename app run: mv ./publish/linuxArm/DemoCenter.Desktop ./publish/linuxArm/DemoCenter.App - name: Zip linux-arm run: zip -j -r ./upload/EMX.Demo.Desktop.linux-arm.zip ./publish/linuxArm -x "*.pdb" - name: Upload a Build Artifact uses: actions/upload-artifact@v4.3.1 with: name: linux-orangepi path: ./upload osx-x64: runs-on: ubuntu-latest steps: - name: Checkout uses: actions/checkout@v4 - name: Make upload directory run: mkdir upload - name: Publish linux-arm64 run: dotnet publish ./DemoCenter/DemoCenter.Desktop/DemoCenter.Desktop.csproj -f net9.0 -r osx-x64 -c Release --sc /p:PublishSingleFile=true /p:IncludeNativeLibrariesForSelfExtract=true -o ./publish/osx-x64 - name: Zip osx-x64 run: zip -j -r ./upload/EMX.Demo.Desktop.osx-x64.zip ./publish/osx-x64 -x "*.pdb" - name: Upload a Build Artifact uses: actions/upload-artifact@v4 with: name: osx-x64 path: ./upload osx-arm64: runs-on: ubuntu-latest steps: - name: Checkout uses: actions/checkout@v4 - name: Make upload directory run: mkdir upload - name: Publish osx-arm64 run: dotnet publish ./DemoCenter/DemoCenter.Desktop/DemoCenter.Desktop.csproj -f net9.0 -r osx-arm64 -c Release --sc /p:PublishSingleFile=true /p:IncludeNativeLibrariesForSelfExtract=true -o ./publish/osx-arm64 - name: Zip osx-arm64 run: zip -j -r ./upload/EMX.Demo.Desktop.osx-arm64.zip ./publish/osx-arm64 -x "*.pdb" - name: Upload a Build Artifact uses: actions/upload-artifact@v4 with: name: osx-arm64 path: ./upload draft-release: needs: [ windows, linux, linux-rpi, osx-x64, osx-arm64, linux-orangepi ] runs-on: ubuntu-latest steps: - name: Download windows Artifacts uses: actions/download-artifact@v4 with: name: windows - name: Download linux Artifacts uses: actions/download-artifact@v4 with: name: linux - name: Download linux-rpi Artifacts uses: actions/download-artifact@v4 with: name: linux-rpi - name: Download linux-orangepi Artifacts uses: actions/download-artifact@v4 with: name: linux-orangepi - name: Release uses: softprops/action-gh-release@v2 if: startsWith(github.ref, 'refs/tags/') || github.event_name == 'workflow_dispatch' with: generate_release_notes: true draft: true files: | *.zip ================================================ FILE: .github/workflows/test.yml ================================================ name: Test on: push: branches: [ "main", "action/publish" ] pull_request: branches: [ "main" ] workflow_dispatch: jobs: windows: runs-on: windows-latest steps: - name: Checkout uses: actions/checkout@v4.1.1 - name: EMXDemo Unit Test run: dotnet test ./Tests/DemoCenter.Desktop.UI.Tests/DemoCenter.Desktop.UI.Tests.csproj -f net9.0 ubuntu: runs-on: ubuntu-latest steps: - name: Checkout uses: actions/checkout@v4.1.1 - name: EMXDemo Unit Test run: dotnet test ./Tests/DemoCenter.Desktop.UI.Tests/DemoCenter.Desktop.UI.Tests.csproj -f net9.0 ================================================ FILE: .gitignore ================================================ #Ignore thumbnails created by Windows Thumbs.db #Ignore files built by Visual Studio *.obj *.exe *.pdb *.user *.aps *.pch *.vspscc *_i.c *_p.c *.ncb *.suo *.tlb *.tlh *.bak *.cache *.ilk *.log [Bb]in [Dd]ebug*/ *.lib *.sbr obj/ .cr/ [Rr]elease*/ _ReSharper*/ [Tt]est[Rr]esult* .vs/ #Nuget packages folder .idea ================================================ FILE: DemoCenter/DemoCenter/App.axaml ================================================ ================================================ FILE: DemoCenter/DemoCenter/App.axaml.cs ================================================ using Avalonia; using Avalonia.Controls.ApplicationLifetimes; using Avalonia.Markup.Xaml; using Avalonia.Styling; using System.Globalization; using System.Reflection; using DemoCenter.ViewModels; using DemoCenter.Views; using DemoCenter.ProductsData; using Eremex.AvaloniaUI.Controls.Common; namespace DemoCenter; public class App : Application { static string[] embeddedResources; public static bool IsWebApp { get; private set; } public static VersionInfo Version { get; } public static string[] EmbeddedResources => embeddedResources ??= Assembly.GetAssembly(typeof(App)).GetManifestResourceNames(); static App() { SetCultureInfo(); Version = new VersionInfo(Assembly.GetAssembly(typeof(MxWindow))); } void SetPaletteStyle(IStyle oldStyle, IStyle newStyle) { if (oldStyle != null && newStyle != null && !Styles.Contains(newStyle)) { if (Styles.Contains(oldStyle)) Styles[Styles.IndexOf(oldStyle)] = newStyle; else Styles.Add(newStyle); } } static void SetCultureInfo() { var cultureInfo = CultureInfo.GetCultureInfo("en-US"); Thread.CurrentThread.CurrentCulture = cultureInfo; Thread.CurrentThread.CurrentUICulture = cultureInfo; } public override void Initialize() { AvaloniaXamlLoader.Load(this); } public override void OnFrameworkInitializationCompleted() { if (ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop) { desktop.MainWindow = new MainWindow { DataContext = new MainViewModel(RequestedThemeVariant) }; } else if (ApplicationLifetime is ISingleViewApplicationLifetime singleViewPlatform) { IsWebApp = true; singleViewPlatform.MainView = new MainView { DataContext = new MainViewModel(RequestedThemeVariant) }; } base.OnFrameworkInitializationCompleted(); } } ================================================ FILE: DemoCenter/DemoCenter/AssemblyInfo.cs ================================================ using System.Reflection; using System.Runtime.CompilerServices; [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCulture("")] [assembly: InternalsVisibleTo("DemoCenter.Desktop.UI.Tests")] ================================================ FILE: DemoCenter/DemoCenter/DemoCenter.csproj ================================================  latest Debug;Release;Release_WASM True True Resources.resx CartesianCandlestickAggregationView.axaml Code MessageBoxPageView.axaml Code DataGridExportView.axaml DataGridExportPageView.axaml Graphics3DControlOverviewView.axaml Code Graphics3DControlSimpleMaterialView.axaml Code Graphics3DControlTexturedMaterialsView.axaml Code Graphics3DControlLinesView.axaml Code Graphics3DControlPointsView.axaml Code Graphics3DControlTransformationView.axaml Code Graphics3DControlSkyboxView.axaml Code PolarEmptyPointsView.axaml Code CartesianStackedAreaSeriesViewView.axaml Code CartesianFullStackedAreaSeriesViewView.axaml Code native Designer CartesianChartLogarithmicScalePageView.axaml Code DataGridDragDropPageView.axaml Code DataGridMultipleSelectionPageView.axaml DataGridLiveDataPageView.axaml DataGridFilteringView.axaml DataGridValidationView.axaml DataGridRowAutoHeightView.axaml TreeListColumnBandsView.axaml TreeListExportView.axaml TreeListMultipleSelectionPageView.axaml CartesianPointSeriesViewView.axaml Code CartesianLineSeriesViewView.axaml Code CartesianAreaSeriesViewView.axaml Code CartesianScatterLineSeriesViewView.axaml Code CartesianStepLineSeriesViewView.axaml Code CartesianStepAreaSeriesViewView.axaml Code CartesianRangeAreaSeriesViewView.axaml Code CartesianSideBySideBarSeriesViewView.axaml Code CartesianSideBySideRangeBarSeriesViewView.axaml Code PolarStripsAndConstantLinesView.axaml Code PolarPointSeriesViewView.axaml Code PolarLineSeriesViewView.axaml Code PolarAreaSeriesViewView.axaml Code PolarScatterLineSeriesViewView.axaml Code PolarRangeAreaSeriesViewView.axaml Code SmithPointSeriesViewView.axaml Code SmithLineSeriesViewView.axaml Code True True SvgIconsBrowserViewResources.resx PublicResXFileCodeGenerator Resources.Designer.cs ================================================ FILE: DemoCenter/DemoCenter/DemoData/ApparelProducts.cs ================================================ namespace DemoCenter.DemoData { public class ApparelProduct { public string Name { get; set; } public string Brand { get; set; } public string Category { get; set; } public string SubCategory { get; set; } public string Style { get; set; } public string Size { get; set; } public string Color { get; set; } public decimal Price { get; set; } public int Stock { get; set; } public DateTime ReleaseDate { get; set; } public bool IsNewArrival { get; set; } public bool IsBestSeller { get; set; } } public class ApparelProducts { private static readonly string[] ClothingBrands = { "Urban Wear", "Style Vista", "Thread Nation", "Cotton Bloom", "Denim Haven", "Silk Route", "Linen Legend", "Vogue Venture" }; private static readonly string[] FootwearBrands = { "Sole Superior", "Prestige Steps", "Elite Treads", "Urban Stride", "Lux Walk", "Aristo Feet", "Prime Pace", "Noble Heels" }; private static readonly string[] ClothingCategories = { "Men's T-Shirts", "Women's Dresses", "Jeans", "Jackets", "Sweaters", "Shirts", "Skirts", "Shorts", "Activewear", "Underwear" }; private static readonly string[] FootwearCategories = { "Sneakers", "Boots", "Sandals", "Loafers", "High Heels", "Athletic Shoes", "Oxfords", "Slip-ons", "Flip Flops", "Espadrilles" }; private static readonly string[] Styles = { "Casual", "Sport", "Formal", "Business", "Street", "Vintage", "Minimalist", "Grunge" }; private static readonly string[] Colors = { "Black", "White", "Navy", "Charcoal", "Beige", "Khaki", "Burgundy", "Olive", "Denim Blue", "Cream", "Camel", "Rust", "Terracotta", "Moss Green", "Blush Pink", "Lavender", "Mustard", "Teal", "Coral", "Eggplant" }; private static readonly string[] ProductNameTemplates = { "{0} {1}", "{0} {1} {2}", "{1} by {0}", "{0} - {1}" }; private static readonly string[] ProductNameModifiers = { "Classic", "Modern", "Essential", "Pro", "Basic", "Standard", "Premium", "Lite", "Air", "Comfort" }; public static IList GenerateData(int count) { var random = new Random(); var products = new List(); var startDate = DateTime.Now.AddYears(-1); for (int i = 0; i < count; i++) { bool isClothing = random.Next(2) == 0; var brand = isClothing ? ClothingBrands[random.Next(ClothingBrands.Length)] : FootwearBrands[random.Next(FootwearBrands.Length)]; var category = isClothing ? "Clothing" : "Footwear"; var subCategory = isClothing ? ClothingCategories[random.Next(ClothingCategories.Length)] : FootwearCategories[random.Next(FootwearCategories.Length)]; var isNewArrival = random.Next(10) == 0; var isBestSeller = random.Next(5) == 0; var product = new ApparelProduct { Name = GenerateProductName(brand, subCategory, i), Brand = brand, Category = category, SubCategory = subCategory, Style = Styles[random.Next(Styles.Length)], Color = Colors[random.Next(Colors.Length)], Size = GenerateSize(category, subCategory), Price = (decimal)Math.Round(15 + random.NextDouble() * 200, 2), Stock = random.Next(0, 500), ReleaseDate = isNewArrival ? DateTime.Now.AddDays(-random.Next(30)) : startDate.AddDays(random.Next(365)), IsNewArrival = isNewArrival, IsBestSeller = isBestSeller, }; products.Add(product); } return products; string GenerateSize(string category, string subCategory) { if (category == "Clothing") { return subCategory switch { "Men's T-Shirts" or "Shirts" => new[] { "S", "M", "L", "XL", "XXL" }[random.Next(5)], "Women's Dresses" or "Skirts" => new[] { "XS", "S", "M", "L", "XL" }[random.Next(5)], "Jeans" => $"{random.Next(26, 36)}W/{random.Next(30, 34)}L", _ => "One Size" }; } else { return subCategory switch { "High Heels" => (35 + random.Next(6)).ToString(), "Boots" => (36 + random.Next(7)).ToString(), _ => (38 + random.Next(8)).ToString() }; } } string GenerateProductName(string brand, string subCategory, int index) { string template = ProductNameTemplates[random.Next(ProductNameTemplates.Length)]; string modifier = ProductNameModifiers[random.Next(ProductNameModifiers.Length)]; return string.Format(template, brand, subCategory, modifier); } } } } ================================================ FILE: DemoCenter/DemoCenter/DemoData/CsvClasses/CarInfo.cs ================================================ using Avalonia.Media; using Avalonia.Media.Imaging; using Avalonia.Platform; namespace DemoCenter.DemoData; public class CarInfo { private IImage image; public int Id { get; init; } public string Trademark { get; init; } public decimal HP { get; init; } public decimal Liter { get; init; } public decimal Cyl { get; init; } public decimal TransmissionSpeedCount { get; init; } public string TransmissionType { get; init; } public decimal MPG { get; init; } public string Description { get; init; } public decimal Price { get; init; } public string Currency { get; init; } public bool IsInStock { get; init; } public string ImageName { get; init; } public IImage Image { get { if (image == null) { if (!string.IsNullOrEmpty(ImageName)) { var s = AssetLoader.Open(new Uri($"avares://DemoCenter/DemoData/csv/CarImages/{ImageName}", UriKind.RelativeOrAbsolute)); image = new Bitmap(s); } } return image; } } public CarInfo() { } public CarInfo(string trademark, CarInfo carInfo) { Trademark = trademark; HP = carInfo.HP; Liter = carInfo.Liter; Cyl = carInfo.Cyl; TransmissionSpeedCount = carInfo.TransmissionSpeedCount; TransmissionType = carInfo.TransmissionType; MPG = carInfo.MPG; Description = carInfo.Description.Replace(carInfo.Trademark, Trademark); Price = carInfo.Price; Currency = carInfo.Currency; IsInStock = carInfo.IsInStock; ImageName = carInfo.ImageName; } } ================================================ FILE: DemoCenter/DemoCenter/DemoData/CsvClasses/CsvClasses.cs ================================================ using System; using System.Linq; using System.Text; using System.Collections.Generic; using System.Text.RegularExpressions; namespace DemoCenter.DemoData { public class MechInfo { public string Name { get; init; } public double Weight { get; init; } public List Weapons { get; init; } public MechInfo(string name, int weight, List weapons) { Name = name; Weight = weight; Weapons = weapons; } } public class SpaceLaunchInfo { public DateTime Date { get; init; } public string MissionName { get; init; } public string LaunchSite { get; init; } public SpaceLaunchInfo(DateTime date, string missionName, string launchSite) { Date = date; MissionName = missionName; LaunchSite = launchSite; } } public class YachtInfo { public string Name { get; init; } public double Length { get; init; } public int NumberOfCabins { get; init; } public double MaxSpeed { get; init; } public decimal CruisingRange { get; init; } public decimal Price { get; init; } public int LaunchingYear { get; init; } public string Builder { get; init; } public string Designer { get; init; } public string Flag { get; init; } public string Location { get; init; } public YachtWebInfo Details { get; init; } public YachtInfo(string name, double length, int numberOfCabins, double maxSpeed, decimal cruisingRange, decimal price, int launchingYear, string builder, string designer, string flag, string location) { Name = name; Length = length; NumberOfCabins = numberOfCabins; MaxSpeed = maxSpeed; CruisingRange = cruisingRange; Price = price; LaunchingYear = launchingYear; Builder = builder; Designer = designer; Flag = flag; Location = location.Replace("''", ", "); Details = new YachtWebInfo(Name, Location, $"https://www.google.com/search?q=yacht+{Name.Replace(" ", "+")}"); } } public class YachtWebInfo { public string Header { get; init; } public string Link { get; init; } public YachtWebInfo(string name, string location, string link) { Header = $"{name}, {location}"; Link = link; } } } ================================================ FILE: DemoCenter/DemoCenter/DemoData/CsvClasses/CsvColumnData.cs ================================================ using System.Globalization; namespace DemoCenter.DemoData; public abstract class CsvColumn { public string Header { get; } public CsvColumn(string header) { Header = header; } public abstract void AddValue(string value); } public abstract class CsvColumn : CsvColumn { public List Data { get; } = new(); protected CsvColumn(string header) : base(header) { } } public class CsvDoubleColumn : CsvColumn { public CsvDoubleColumn(string header) : base(header) { } public override void AddValue(string value) => Data.Add(double.Parse(value.Trim(), CultureInfo.InvariantCulture)); } ================================================ FILE: DemoCenter/DemoCenter/DemoData/CsvClasses/StockInfo.cs ================================================ namespace DemoCenter.DemoData; public class StockInfo { public DateTime Date { get; } public double Close { get; } public double Open { get; } public double High { get; } public double Low { get; } public double Volume { get; } public StockInfo(DateTime date, double close, double open, double high, double low, double volume) { Date = date; Close = close; Open = open; High = high; Low = low; Volume = volume; } } ================================================ FILE: DemoCenter/DemoCenter/DemoData/CsvClasses/StockProduct.cs ================================================ using CommunityToolkit.Mvvm.ComponentModel; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace DemoCenter.DemoData.CsvClasses { public class StockProduct { public int Id { get; set; } public string Name { get; set; } public string Category { get; set; } public string Color { get; set; } public string Size { get; set; } public decimal Cost { get; set; } public int Quantity { get; set; } } } ================================================ FILE: DemoCenter/DemoCenter/DemoData/CsvSources.cs ================================================ using Avalonia.Platform; using System.Globalization; using System.Text.RegularExpressions; using Microsoft.VisualBasic.FileIO; using DemoCenter.DemoData.CsvClasses; namespace DemoCenter.DemoData { public static class CsvSources { static List cars; public static List Cars { get { cars ??= GetCars(); return cars; } } static List mechs; public static List Mechs { get { mechs ??= GetMechs(); return mechs; } } static List launches; public static List Launches { get { launches ??= GetLaunches(); return launches; } } static List yachtNames; public static List YachtNames { get { yachtNames ??= GetYachtNames(); return yachtNames; } } static List yachts; public static List Yachts { get { yachts ??= GetYachts(); return yachts; } } static List stockProducts; public static List StockProducts { get { stockProducts ??= GetStockProducts(); return stockProducts; } } static List logarithmic; public static List Logarithmic => logarithmic ??= GetLogarithmic(); static List stock; public static List Stock => stock ??= GetStock(); static List GetCars() { var culture = new CultureInfo("en-US"); return GetInfo(GetUriString("cars"), GetCarInfo); CarInfo GetCarInfo(string[] values) { return new CarInfo { Id = int.Parse(values[0], culture), Trademark = values[1], HP = decimal.Parse(values[2], culture), Liter = decimal.Parse(values[3], culture), Cyl = decimal.Parse(values[4], culture), TransmissionSpeedCount = decimal.Parse(values[5]), TransmissionType = values[6], MPG = decimal.Parse(values[7], culture), Description = values[8], Price = decimal.Parse(values[9], NumberStyles.Currency, culture), Currency = culture.NumberFormat.CurrencySymbol, IsInStock = bool.Parse(values[10]), ImageName = values[11] }; } } static List GetMechs() { var regex = new Regex(@"\d{1,}"); return GetInfo(GetUriString("mechs"), values => new MechInfo(values[0], int.Parse(regex.Match(values[1]).Value), new List() { values[2], values[3], values[4] })); } static List GetLaunches() { var provider = CultureInfo.InvariantCulture; return GetInfo(GetUriString("spacexlaunches"), values => { var launchDate = DateTime.ParseExact(values[0] + "," + values[1], "MMMM d, yyyy", provider); return new SpaceLaunchInfo(launchDate, values[2].TrimStart(), values[3].TrimStart()); }); } static List GetYachtNames() => GetInfo(GetUriString("yachtNames"), values => values[0]); static List GetYachts() { var provider = CultureInfo.InvariantCulture; return GetInfo(GetUriString("yachts"), values => { var price = 1000000m* decimal.Parse(values[5]) + 1000m * decimal.Parse(values[6]) + decimal.Parse(values[7]); return new YachtInfo(values[0], double.Parse(values[1]), int.Parse(values[2]), double.Parse(values[3]), decimal.Parse(values[4]), price, int.Parse(values[8]), values[9], values[10], values[11], values[12]); }); } static List GetLogarithmic() => GetColumnInfo(GetUriString("logarithmic")); static List GetStock() => GetInfo(GetUriString("Bitcoin Historical Data"), values => { var date = DateTime.Parse(values[0], CultureInfo.InvariantCulture); var close = double.Parse(values[1], CultureInfo.InvariantCulture); var open = double.Parse(values[2], CultureInfo.InvariantCulture); var high = double.Parse(values[3], CultureInfo.InvariantCulture); var low = double.Parse(values[4], CultureInfo.InvariantCulture); var volume = double.Parse(values[5].Substring(0, values[5].Length - 1), CultureInfo.InvariantCulture) * 1000; return new StockInfo(date, close, open, high, low, volume); }); static List GetInfo(string uriString, Func getInfo) { var result = new List(); var uri = new Uri(uriString); if (!AssetLoader.Exists(uri)) return result; using (var reader = new StreamReader(AssetLoader.Open(uri))) { reader.ReadLine(); using (var parser = new TextFieldParser(reader)) { parser.HasFieldsEnclosedInQuotes = true; parser.Delimiters = new[] { "," }; while (!parser.EndOfData) { string[] values = parser.ReadFields(); result.Add(getInfo(values)); } } } return result; } static List GetColumnInfo(string uriString) where T : CsvColumn { const char separator = ','; var result = new List(); var uri = new Uri(uriString); if (!AssetLoader.Exists(uri)) return result; using (var reader = new StreamReader(AssetLoader.Open(uri))) { string[] headers = reader.ReadLine()!.Split(separator); foreach (string header in headers) result.Add((T)Activator.CreateInstance(typeof(T), header.Trim())); using (var parser = new TextFieldParser(reader)) { parser.HasFieldsEnclosedInQuotes = false; parser.Delimiters = new[] { separator.ToString() }; while (!parser.EndOfData) { string[] values = parser.ReadFields(); if (values != null) { for(int i = 0; i < result.Count; i++) result[i].AddValue(values[i]); } } } } return result; } static List GetStockProducts() { return GetInfo(GetUriString("stockProducts"), GetStockProduct); StockProduct GetStockProduct(string[] values) { return new StockProduct() { Id = int.Parse(values[0]), Name = values[1], Color = values[2], Size = values[3], Category = values[4], Cost = decimal.Parse(values[5]), Quantity = int.Parse(values[6]), }; } } static string GetUriString(string path) => $"avares://DemoCenter/DemoData/csv/{path}.csv"; } } ================================================ FILE: DemoCenter/DemoCenter/DemoData/ElementsSources.cs ================================================ using Avalonia.Media; using DemoCenter.Helpers; using static System.Net.Mime.MediaTypeNames; namespace DemoCenter.DemoData { public class ElementInfo { public string Name { get; init; } public ElementCategory Category { get; init; } public IImage Icon { get; init; } public ElementInfo(string name, ElementCategory category, IImage icon) { Name = name; Category = category; Icon = icon; } } public enum ElementCategory { Active, Passive, IndependentSource, ControlledSource, Multipole } public static class ElementsSources { static List elements; public static List Elements { get { elements ??= GetElements(); return elements; } } static List GetElements() { return new List() { new ElementInfo("Arsenide-gallium transistor", ElementCategory.Active, Eremex.AvaloniaUI.Icons.Models.Aktivnye_komponenty___arsenid_gallievyj_polevoj_tranzistor), //"Group=Models, Icon=aktivnye komponenty - arsenid-gallievyj polevoj tranzistor"), new ElementInfo("N-Type bypolar transistor with base", ElementCategory.Active, Eremex.AvaloniaUI.Icons.Models.Aktivnye_komponenty___bipoljarnyj_tranzistor_n_tipa_s_podlozhkoj), new ElementInfo("N-Type bypolar transistor", ElementCategory.Active, Eremex.AvaloniaUI.Icons.Models.Aktivnye_komponenty___bipoljarnyj_tranzistor_n_tipa), new ElementInfo("P-Type bypolar transistor with base", ElementCategory.Active, Eremex.AvaloniaUI.Icons.Models.Aktivnye_komponenty___bipoljarnyj_tranzistor_p_tipa_s_podlozhkoj), new ElementInfo("P-Type bypolar transistor", ElementCategory.Active, Eremex.AvaloniaUI.Icons.Models.Aktivnye_komponenty___bipoljarnyj_tranzistor_p_tipa), new ElementInfo("MOS transistor (DN type)", ElementCategory.Active, Eremex.AvaloniaUI.Icons.Models.Aktivnye_komponenty___mop_tranzistor_DN_tipa), new ElementInfo("MOS transistor (DP type)", ElementCategory.Active, Eremex.AvaloniaUI.Icons.Models.Aktivnye_komponenty___mop_tranzistor_DP_tipa), new ElementInfo("MOS transistor (N type)", ElementCategory.Active, Eremex.AvaloniaUI.Icons.Models.Aktivnye_komponenty___mop_tranzistor_N_tipa), new ElementInfo("MOS transistor (P type)", ElementCategory.Active, Eremex.AvaloniaUI.Icons.Models.Aktivnye_komponenty___mop_tranzistor_P_tipa), new ElementInfo("Operational amplifier", ElementCategory.Active, Eremex.AvaloniaUI.Icons.Models.Aktivnye_komponenty___operacionnyj_usilitel), new ElementInfo("Field-effect transistor (N type)", ElementCategory.Active, Eremex.AvaloniaUI.Icons.Models.Aktivnye_komponenty___polevoj_tranzistor_n_tipa), new ElementInfo("Field-effect transistor (P type)", ElementCategory.Active, Eremex.AvaloniaUI.Icons.Models.Aktivnye_komponenty___polevoj_tranzistor_p_tipa), new ElementInfo("Functional voltage source", ElementCategory.IndependentSource, Eremex.AvaloniaUI.Icons.Models.Funkcionalnye_istochniki___funkcionalnyj_istochnik_naprjazhenija), new ElementInfo("Functional current source", ElementCategory.IndependentSource, Eremex.AvaloniaUI.Icons.Models.Funkcionalnye_istochniki___funkcionalnyj_istochnik_toka), new ElementInfo("Four-pole", ElementCategory.Multipole, Eremex.AvaloniaUI.Icons.Models.Mnogopolosniki___chetyrehpolosnik), new ElementInfo("Two-pole", ElementCategory.Multipole, Eremex.AvaloniaUI.Icons.Models.Mnogopolosniki___dvuhpolosnik), new ElementInfo("Six-pole", ElementCategory.Multipole, Eremex.AvaloniaUI.Icons.Models.Mnogopolosniki___shestipolosnik), new ElementInfo("Eight-pole", ElementCategory.Multipole,Eremex.AvaloniaUI.Icons.Models.Mnogopolosniki___vosmipolosnik), new ElementInfo("Battery", ElementCategory.IndependentSource, Eremex.AvaloniaUI.Icons.Models.Nezavisimye_istochniki___batareja), new ElementInfo("Voltage source", ElementCategory.IndependentSource, Eremex.AvaloniaUI.Icons.Models.Nezavisimye_istochniki___istochnik_naprjazhenija), new ElementInfo("Current source", ElementCategory.IndependentSource, Eremex.AvaloniaUI.Icons.Models.Nezavisimye_istochniki___istochnik_toka), new ElementInfo("Diod", ElementCategory.Passive, Eremex.AvaloniaUI.Icons.Models.Passivnye_elementy___diod), new ElementInfo("Long line", ElementCategory.Passive, Eremex.AvaloniaUI.Icons.Models.Passivnye_elementy___dlinnaja_linija), new ElementInfo("Transformator", ElementCategory.Passive, Eremex.AvaloniaUI.Icons.Models.Passivnye_elementy___dvuhobmotochnyj_transformator), new ElementInfo("Inductor", ElementCategory.Passive, Eremex.AvaloniaUI.Icons.Models.Passivnye_elementy___induktivnost), new ElementInfo("Capacitor", ElementCategory.Passive, Eremex.AvaloniaUI.Icons.Models.Passivnye_elementy___kondensator), new ElementInfo("Voltage-controlled switch", ElementCategory.Passive, Eremex.AvaloniaUI.Icons.Models.Passivnye_elementy___perekljuchatel_upravljaemyj_naprjazheniem), new ElementInfo("Current-controlled switch", ElementCategory.Passive, Eremex.AvaloniaUI.Icons.Models.Passivnye_elementy___perekljuchatel_upravljaemyj_tokom), new ElementInfo("Resistor", ElementCategory.Passive, Eremex.AvaloniaUI.Icons.Models.Passivnye_elementy___rezistor), new ElementInfo("Variable resistor", ElementCategory.Passive, Eremex.AvaloniaUI.Icons.Models.Passivnye_elementy___rezistor_potenciometr), new ElementInfo("Voltage-controlled voltage source", ElementCategory.ControlledSource, Eremex.AvaloniaUI.Icons.Models.Upravljaemye_istochniki___istochnik_naprjazhenija_upravljaemyj_naprjazheniem), new ElementInfo("Current-controlled voltage source", ElementCategory.ControlledSource, Eremex.AvaloniaUI.Icons.Models.Upravljaemye_istochniki___istochnik_naprjazhenija_upravljaemyj_tokom), new ElementInfo("Voltage-controlled current source", ElementCategory.ControlledSource, Eremex.AvaloniaUI.Icons.Models.Upravljaemye_istochniki___istochnik_toka_upravljaemyj_naprjazheniem), new ElementInfo("Current-controlled current source", ElementCategory.ControlledSource, Eremex.AvaloniaUI.Icons.Models.Upravljaemye_istochniki___istochnik_toka_upravljaemyj_tokom), }; } } } ================================================ FILE: DemoCenter/DemoCenter/DemoData/EmployeesData.cs ================================================ using System.Collections; using System.Collections.ObjectModel; using System.ComponentModel.DataAnnotations; using System.Dynamic; using System.Globalization; using System.Text; namespace DemoCenter.DemoData { public static class EmployeesData { public const string PhoneRegex = @"^(\+\d{1,2}\s?)?\(?\d{3}\)?[\s.-]?\d{3}[\s.-]?\d{4}$"; static List employeeNames = new List() { "Angelica Grace", "Janet Francis", "Lance Phillips", "Herbert Gilmore", "Jose Horn", "Alfred McFarland", "Gwen Chandler", "Julia Case", "Thomas Howell", "Liz McGill", "Pat Dudley", "Jodi Funk", "Taylor Monroe", "Vicki Stevenson", "Roman Bridges", "Bradley Maloney", "Craig MacDonald", "Cora Cameron", "Katherine Tyler", "Rachel Shah", "Earl Lee", "Merle Williamson", "Gene Morse", "Steven Dodd", "Julius Peck", "Trevor Chaney", "Lon Schneider", "Julio Hammond", "Rosario Kirby", "Janice Perry", "Lana Carey", "Terrell Wells", "Herbert Hardy", "Thomas Downs", "Audrey Shields", "Davis Buchanan", "Cassie Barron", "Kirsten Huff", "Gregg Wood", "Lily Alvarado", "Cruz Johns", "Michele Clark", "Jasper Ward" }; public static List EmployeeNames => employeeNames; static List cities = new List() { "New York", "Los Angeles", "Chicago", "Houston", "Phoenix", "Philadelphia", "San Antonio", "San Diego", "Dallas", "San Jose, Calif" }; private static Random random = new Random(); public static IReadOnlyList Positions { get; } = new List() { "Accountant", "Sales Representative", "Manager", "Project Manager", "Sales Manager", "HR Manager", "Operations Manager", "Account Manager", "Electrical Engineer", "Customer Service Engineer", "Software Engineer", "Engineer", "Program Manager", "Administrative Assistant", "Financial Analyst" }; public static IList GenerateEmployeeSales() { var sales = new ObservableCollection(); for (int i = 5; i > 0; i--) { foreach (var name in employeeNames) { var employee = new EmployeeSale() { Employee = name, Year = DateTime.Now.Year - i + 1 }; employee.Quarter1 = GetQuarterSalePercent(); employee.Quarter2 = GetQuarterSalePercent(); employee.Quarter3 = GetQuarterSalePercent(); employee.Quarter4 = GetQuarterSalePercent(); employee.Total = Math.Round((employee.Quarter1 + employee.Quarter2 + employee.Quarter3 + employee.Quarter4) / 4); sales.Add(employee); } } return sales; } private static decimal GetQuarterSale() { return random.Next(90000) + 10000; } private static decimal GetQuarterSalePercent() { return Math.Round(GetQuarterSale() / 1000); } public static IList GenerateEmployeeInfo() { var employees = new ObservableCollection(); foreach (var employeeName in employeeNames) { var name = employeeName.Split(' '); var employee = new EmployeeInfo() { FirstName = name[0], LastName = name[1] }; var age = 20 + random.Next(40); employee.BirthDate = new DateTime(DateTime.Now.Year - age, random.Next(12) + 1, random.Next(28) + 1); employee.HireDate = new DateTime(DateTime.Now.Year - random.Next(20) - 1, random.Next(12) + 1, random.Next(28) + 1); employee.Experience = Math.Max(age - 20 - random.Next(age - 20), DateTime.Now.Year - employee.HireDate.Year); employee.Position = Positions[random.Next(Positions.Count)]; employee.EmploymentType = (EmploymentType)random.Next(3); employee.Married = random.Next(3) != 0; employee.City = cities[random.Next(cities.Count)]; employee.Phone = GetPhoneNumber(); employees.Add(employee); } return employees; } public static IList GenerateValidationEmployeeInfo() { Random rnd = new(); var employees = GenerateEmployeeInfo(); GetRandomEmployee(rnd, employees).FirstName = string.Empty; GetRandomEmployee(rnd, employees).LastName = string.Empty; GetRandomEmployee(rnd, employees).FirstName = string.Empty; GetRandomEmployee(rnd, employees).LastName = string.Empty; GetRandomEmployee(rnd, employees).City = string.Empty; GetRandomEmployee(rnd, employees).City = string.Empty; GetRandomEmployee(rnd, employees).City = string.Empty; GetRandomEmployee(rnd, employees).Phone = "123 456"; GetRandomEmployee(rnd, employees).Phone = "(2994)345-235"; GetRandomEmployee(rnd, employees).Phone = "(574)786"; GetRandomEmployee(rnd, employees).BirthDate = DateTime.Now.AddDays(10); GetRandomEmployee(rnd, employees).HireDate = DateTime.Now.AddDays(4); var employee = GetRandomEmployee(rnd, employees); employee.HireDate = employee.BirthDate - TimeSpan.FromDays(10); employee.Experience = 0; return employees.Select(x => new EmployeeValidationInfo(x)).ToList(); EmployeeInfo GetRandomEmployee(Random rnd, IList employees) { return employees[rnd.Next(20)]; } } private static string GetPhoneNumber() { var stringBuilder = new StringBuilder(); for (int i = 0; i < 10; i++) { stringBuilder.Append(random.Next(10)); } var phone = stringBuilder.ToString(); return $"({phone.Substring(0, 3)}) {phone.Substring(3, 3)}-{phone.Substring(6, 4)}"; } public static IList GenerateComplexEmployeeSales() { var sales = new ObservableCollection(); foreach (var name in employeeNames.Order()) { IDictionary employeeSale = new ExpandoObject(); employeeSale["Employee"] = name; decimal total = 0; for (int i = 1; i < 4; i++) { var year = DateTime.Now.Year - i; decimal yearTotal = 0; for (int j = 0; j < 12; j++) { var sale = GetQuarterSale(); yearTotal += sale; var monthName = CultureInfo.InvariantCulture.DateTimeFormat.GetAbbreviatedMonthName(j + 1); var propertyName = $"{year}/Q{j / 3 + 1}/{monthName}"; employeeSale[propertyName] = sale; } employeeSale[$"{year}/Total"] = yearTotal; total += yearTotal; } employeeSale["Total"] = total; sales.Add(employeeSale); } return sales; } } public class EmployeeSale { public string Employee { get; set; } public int Year { get; set; } public decimal Quarter1 { get; set; } public decimal Quarter2 { get; set; } public decimal Quarter3 { get; set; } public decimal Quarter4 { get; set; } public decimal Total { get; set; } } public class EmployeeInfo { public string FirstName { get; set; } public string LastName { get; set; } public DateTime BirthDate { get; set; } public DateTime HireDate { get; set; } public int Experience { get; set; } public string Position { get; set; } public EmploymentType EmploymentType { get; set; } public bool Married { get; set; } public string City { get; set; } public string Phone { get; set; } } public class EmployeeValidationInfo { static readonly DateTime MinDate = new DateTime(1900, 1, 1); public EmployeeValidationInfo(EmployeeInfo employee) { FirstName = employee.FirstName; LastName = employee.LastName; BirthDate = employee.BirthDate; HireDate = employee.HireDate; Experience = employee.Experience; City = employee.City; Phone = employee.Phone; } [Required] public string FirstName { get; set; } [Required] public string LastName { get; set; } [CustomValidation(typeof(EmployeeValidationInfo), nameof(ValidateDate))] public DateTime BirthDate { get; set; } [CustomValidation(typeof(EmployeeValidationInfo), nameof(ValidateDate))] public DateTime HireDate { get; set; } [Required] public int Experience { get; set; } [Required] public string City { get; set; } [RegularExpression(EmployeesData.PhoneRegex, ErrorMessage = "The phone number is not valid")] public string Phone { get; set; } public static ValidationResult ValidateDate(DateTime date) { if(date > DateTime.Today) return new ValidationResult("The date cannot be in the future."); if (date < MinDate) return new ValidationResult($"The date cannot be less than {MinDate:d}"); return ValidationResult.Success; } } public enum EmploymentType { [Display(Name = "Full Time")] FullTime, [Display(Name = "Part Time")] PartTime, Contract } } ================================================ FILE: DemoCenter/DemoCenter/DemoData/Enums.cs ================================================ using DemoCenter.ViewModels; using Eremex.AvaloniaUI.Controls.Common; using System; using System.Collections.Generic; using System.ComponentModel; using System.ComponentModel.DataAnnotations; using System.Linq; using System.Text; using System.Threading.Tasks; namespace DemoCenter.DemoData { public enum GraphicPosition { [Image($"avares://Eremex.Avalonia.Icons/Graphics/Dimension.svg")] [Display(Description = "Set Graphics to Dimension")] Dimension, [Image($"avares://Eremex.Avalonia.Icons/Graphics/Maximum.svg")] [Display(Description = "Set Graphics to Maximum")] Maximum, [Image($"avares://Eremex.Avalonia.Icons/Graphics/Minimum.svg")] [Display(Description = "Set Graphics to Minimum")] Minimum, [Image($"avares://Eremex.Avalonia.Icons/Graphics/Point.svg")] [Display(Description = "Set Graphics to Next Point")] NextPoint, [Image($"avares://Eremex.Avalonia.Icons/Graphics/Peak.svg")] [Display(Description = "Set Graphics to Peak")] Peak, [Image($"avares://Eremex.Avalonia.Icons/Graphics/Recess.svg")] [Display(Description = "Set Graphics to Recess")] Recess, [Image($"avares://Eremex.Avalonia.Icons/Graphics/X.svg")] [Display(Description = "Set Graphics to X")] X, [Image($"avares://Eremex.Avalonia.Icons/Graphics/Y.svg")] [Display(Description = "Set Graphics to Y")] Y } public enum GraphicView { [Image($"avares://Eremex.Avalonia.Icons/3D/View Back.svg")] [Display(Description = "Back View")] Back, [Image($"avares://Eremex.Avalonia.Icons/3D/View Front.svg")] [Display(Description = "Front View")] Front, [Image($"avares://Eremex.Avalonia.Icons/3D/View Top.svg")] [Display(Description = "Top View")] Top, [Image($"avares://Eremex.Avalonia.Icons/3D/View Bottom.svg")] [Display(Description = "Bottom View")] Bottom } } ================================================ FILE: DemoCenter/DemoCenter/DemoData/InfrastructureData.cs ================================================ using System.Collections.ObjectModel; namespace DemoCenter.DemoData { public enum AssetType { DataCenter, ServerRack, VirtualizationHost, DatabaseServer, WebServer, StorageSystem, NetworkDevice, SecurityAppliance } public enum AssetStatus { Operational, Maintenance, Degraded, Offline, Decommissioned, Critical, Warning } public class InfrastructureItem { public string Name { get; set; } public AssetType AssetType { get; set; } public DateTime? LastMaintenance { get; set; } public bool IsOperational => Status == AssetStatus.Operational || Status == AssetStatus.Warning || Status == AssetStatus.Critical; public AssetStatus Status { get; set; } public float Utilization { get; set; } public decimal MaintenanceCost { get; set; } public decimal PowerConsumption { get; set; } public ObservableCollection Children { get; } = new(); public bool HasChildren => Children.Count > 0; } public class InfrastructureData { private static readonly AssetType[] serverTypes = { AssetType.VirtualizationHost, AssetType.DatabaseServer, AssetType.WebServer, AssetType.StorageSystem, AssetType.NetworkDevice, AssetType.SecurityAppliance }; private static readonly string[] DataCenterNames = { "Quantum Data Center", "Aether Data Center", "Stellar Data Center", "Nova Data Center", "Infinity Data Center" }; private static readonly string[] ServerNames = { "HyperCore", "VMHost", "CloudNode", "VirtualEngine", "Orchestrator", "DataForge", "QueryMaster", "StorageBrain", "ArchiveKeeper", "InfoStream", "WebFlux", "SiteStream", "PageServer", "APIGateway", "ContentHub","AppEngine", "ServiceNode", "RuntimeCore", "MicroHost", "WorkflowUnit", "StoragePod", "DataVault", "FileArray", "DiskCluster", "ArchiveBank","NetSwitch", "DataRouter", "TrafficHub", "PacketFlow", "ConnectionPoint", "Firewall", "SecurityShield", "ThreatGuard", "AccessControl", "CyberDefense","ComputeNode", "ServerUnit", "ProcessingCore", "ExecutionEngine", "TaskHandler" }; public static List GenerateData() { var items = new List(); var random = new Random(40); for (int i = 1; i <= 5; i++) { var dataCenter = CreateDataCenter(random, i); for (int j = 1; j <= random.Next(8, 13); j++) { var serverRack = CreateServerRack(random, j); for (int k = 1; k <= random.Next(6, 11); k++) { var serverComponent = CreateServer(random, k); serverRack.Children.Add(serverComponent); } dataCenter.Children.Add(serverRack); } items.Add(dataCenter); } return items; } private static InfrastructureItem CreateDataCenter(Random random, int index) { return new InfrastructureItem() { Name = DataCenterNames[index - 1], AssetType = AssetType.DataCenter, LastMaintenance = DateTime.Now.AddMonths(-random.Next(1, 6)), Status = GetRandomStatus(random, 0.8), Utilization = random.Next(60, 95) / 100f, MaintenanceCost = random.Next(50000, 200000), PowerConsumption = random.Next(200, 500), }; } private static InfrastructureItem CreateServerRack(Random random, int index) { return new InfrastructureItem { Name = $"Rack {index:00}", AssetType = AssetType.ServerRack, LastMaintenance = DateTime.Now.AddMonths(-random.Next(1, 12)), Status = GetRandomStatus(random, 0.7), Utilization = random.Next(70, 98) / 100f, MaintenanceCost = random.Next(5000, 15000), PowerConsumption = random.Next(5, 15), }; } private static InfrastructureItem CreateServer(Random random, int index) { var serverType = serverTypes[random.Next(serverTypes.Length)]; var server = new InfrastructureItem { Name = GetServerName(random, serverType), AssetType = serverType, LastMaintenance = DateTime.Now.AddMonths(-random.Next(1, 18)), Status = GetRandomStatus(random, 0.6), Utilization = random.Next(30, 95) / 100f, MaintenanceCost = GetServerMaintenanceCost(random, serverType), PowerConsumption = Math.Round((decimal)random.NextDouble() * 2 + 0.5m, 1) }; return server; } private static AssetStatus GetRandomStatus(Random random, double operationalChance) { var rand = random.NextDouble(); if (rand < operationalChance * 0.7) return AssetStatus.Operational; if (rand < operationalChance * 0.8) return AssetStatus.Warning; if (rand < operationalChance * 0.9) return AssetStatus.Maintenance; if (rand < operationalChance) return AssetStatus.Degraded; return AssetStatus.Offline; } private static string GetServerName(Random random, AssetType type) { return ServerNames[(int)type * 5 + random.Next(5)] + " Server"; } private static decimal GetServerMaintenanceCost(Random random, AssetType type) { return random.Next(20000, 80000) * (decimal)(random.NextDouble() * 0.15); } } } ================================================ FILE: DemoCenter/DemoCenter/DemoData/OrderData.cs ================================================ using System.Collections.ObjectModel; using System.ComponentModel.DataAnnotations; using System.Text; namespace DemoCenter.DemoData { public class OrderData { public static IList GenerateData(int count) { var random = new Random(); var data = new List(count); for (int i = 0; i < count; i++) { data.Add(new OrderData() { OrderId = i, Manager = EmployeesData.EmployeeNames[random.Next(EmployeesData.EmployeeNames.Count)], Count = random.Next(1000), Price = random.Next(1000), Date = DateTime.Today.AddDays(random.Next(200) - 100) }); } return data; } public int OrderId { get; private set; } public string Manager { get; set; } public int Count { get; set; } public decimal Price { get; set; } public decimal TotalPrice => Count * Price; public DateTime Date { get; set; } } } ================================================ FILE: DemoCenter/DemoCenter/DemoData/ProjectTasksData.cs ================================================ using CommunityToolkit.Mvvm.ComponentModel; using System.Collections.ObjectModel; using System.ComponentModel.DataAnnotations; namespace DemoCenter.DemoData { public enum TaskStatus { [Display(Name = "Not Started")] NotStarted, [Display(Name = "In Progress")] InProgress, [Display(Name = "Completed")] Completed } public partial class ProjectTask : ObservableObject { public ProjectTask(ProjectTask parent, string description, TaskStatus status, int estimateTime, int timeSpent, string assignee, DateTime dueDate) { Tasks = new(); Parent = parent; this.description = description; this.status = status; this.estimateTime = estimateTime; this.timeSpent = timeSpent; this.assignee = assignee; this.dueDate = dueDate; } public ProjectTask Parent { get; } [ObservableProperty] private bool highPriority; [ObservableProperty] private string description; [ObservableProperty] private TaskStatus status; [ObservableProperty] private string assignee; [ObservableProperty] private int estimateTime; [ObservableProperty] private int timeSpent; [ObservableProperty] private int progress; [ObservableProperty] private DateTime dueDate; public List Tasks { get; } public bool HasTasks => Tasks.Count > 0; partial void OnStatusChanged(TaskStatus value) => Parent?.UpdateStatus(); partial void OnEstimateTimeChanged(int value) => Parent?.UpdateEstimateTime(); partial void OnTimeSpentChanged(int value) => Parent?.UpdateTimeSpent(); private void UpdateStatus() { Status = Tasks.All(t => t.Status == TaskStatus.Completed) ? TaskStatus.Completed : Tasks.All(t => t.Status == TaskStatus.NotStarted) ? TaskStatus.NotStarted : TaskStatus.InProgress; } private void UpdateEstimateTime() => EstimateTime = Tasks.Sum(t => t.EstimateTime); private void UpdateTimeSpent() => TimeSpent = Tasks.Sum(t => t.TimeSpent); private void UpdateProgress() => Progress = Tasks.Sum(t => t.Progress) / Tasks.Count; internal void Update() { UpdateStatus(); UpdateEstimateTime(); UpdateTimeSpent(); UpdateProgress(); } } public class ProjectTasksGenerator { private static readonly Random random = new(); public static List Generate() { List tasks = new(); CreateProject(tasks, "'Trade Central' Web Site", 0, WebSiteTaskNames, new DateTime(2023, 11, 16)); CreateProject(tasks, "'World Wonders' Mobile App", WebSiteTaskNames.Length + 1, MobileAppTaskNames, new DateTime(2023, 11, 10)); CreateProject(tasks, "'Six Sigma' Mobile App", WebSiteTaskNames.Length + 1, MobileAppTaskNames, new DateTime(2023, 10, 20)); CreateProject(tasks, "'Profit First' Web Site", 0, WebSiteTaskNames,new DateTime(2023, 12, 11)); return tasks; } private static void CreateProject(List items, string description, int assigneeIndex, string[] taskNames, DateTime dueDate) { var project = new ProjectTask(null, description, TaskStatus.InProgress, 0, 0, AssigneeNames[assigneeIndex], dueDate); GenerateProjectTasks(project, assigneeIndex + 1, taskNames); items.Add(project); } private static void GenerateProjectTasks(ProjectTask project, int assigneeIndex, string[] taskNames) { int completedCount = taskNames.Length / 3, inProgressAndCompletedCount = completedCount + taskNames.Length / 2; for (int i = 0; i < taskNames.Length; i++) { var status = i <= completedCount ? TaskStatus.Completed : (i <= inProgressAndCompletedCount ? TaskStatus.InProgress : TaskStatus.NotStarted); var dueDate = project.DueDate - new TimeSpan((taskNames.Length - i) * 5, i, i, 0); var estimate = random.Next(10, 70); var timeSpent = status == TaskStatus.Completed ? random.Next(estimate - 5, estimate + 5) : random.Next(10, estimate); var task = new ProjectTask(project, taskNames[i], status, estimate, timeSpent, AssigneeNames[assigneeIndex + i], dueDate); task.Progress = status == TaskStatus.Completed ? 100 : (status == TaskStatus.InProgress ? random.Next(10, 80) : 0); task.HighPriority = random.Next(1, taskNames.Length) == i; project.Tasks.Add(task); } project.Update(); } private static readonly string[] WebSiteTaskNames = new[] { "Market research", "Define objectives and requirements", "Domain name registration", "Select a hosting provider", "Create a sitemap", "Wireframing and mockups", "Design UI/UX", "Front-end development", "Back-end development", "Content creation", "SEO (Search Engine Optimization)", "Mobile responsiveness", "Testing and quality assurance", "Security Assessment", "Launch and post-launch activities" }; private static readonly string[] MobileAppTaskNames = new[] { "Market research", "Define objectives and requirements", "Wireframing and mockups", "Design UI/UX", "Front-end development", "Back-end development", "API Integration", "Deployment", "Testing and quality assurance", "Security Assessment", "Launch and post-launch activities", }; private static readonly string[] AssigneeNames = new[] { "Ben Elliott", "Nelson Blackburn", "Clifford Hines", "Kaitlin Watts", "Lana Burnett", "Stanley Dorsey", "Tony Huffman", "Lisa Marquez", "Tim Robinson", "Jodie Bradley", "Casey Mccarthy", "Ralph Livingston", "Scott Reed", "Sarah Evans", "Jeremy Pearson", "Mattie Fowler", "Kylie Phillips", "Stefan Garrison", "Daniel Harvey", "Krish Joyce", "Kaitlyn Thomas", "Dan Berry", "John Oneal", "Nikolas Andrews", "Lisa Chan", "Molly Byrd", "Oliver Welsh", "Dillan Tanner" }; } } ================================================ FILE: DemoCenter/DemoCenter/DemoData/SalesData.cs ================================================ using System; namespace DemoCenter.DemoData { public class SalesData { static List cityNames = new List() { "New York", "Los Angeles", "Chicago", "Houston", "Phoenix", "Philadelphia", "San Francisco", "Las Vegas" }; public string Name { get; set; } public decimal Q1Absolute { get; set; } public decimal Q1Fraction { get; set; } public decimal Q2Absolute { get; set; } public decimal Q2Fraction { get; set; } public decimal Q3Absolute { get; set; } public decimal Q3Fraction { get; set; } public decimal Q4Absolute { get; set; } public decimal Q4Fraction { get; set; } public decimal Total { get; set; } public List Children { get; set; } public static IList GenerateData() { var data = new List(); var employeeNames = EmployeesData.EmployeeNames.ToList(); int employeesCount = employeeNames.Count / cityNames.Count; foreach (var cityName in cityNames) { var citySale = new SalesData() { Name = cityName, Children = new List() }; for (int i = 0; i < employeesCount; i++) { int employeeIndex = Random.Shared.Next(employeeNames.Count); var employeeSale = new SalesData() { Name = employeeNames[employeeIndex] }; employeeNames.RemoveAt(employeeIndex); employeeSale.Q1Absolute = GetAbsoluteQuarterSale(); employeeSale.Q1Fraction = GetEmployeeFractionQuarterSale(employeeSale.Q1Absolute); employeeSale.Q2Absolute = GetAbsoluteQuarterSale(); employeeSale.Q2Fraction = GetEmployeeFractionQuarterSale(employeeSale.Q2Absolute); employeeSale.Q3Absolute = GetAbsoluteQuarterSale(); employeeSale.Q3Fraction = GetEmployeeFractionQuarterSale(employeeSale.Q3Absolute); employeeSale.Q4Absolute = GetAbsoluteQuarterSale(); employeeSale.Q4Fraction = GetEmployeeFractionQuarterSale(employeeSale.Q4Absolute); employeeSale.Total = employeeSale.Q1Absolute + employeeSale.Q2Absolute + employeeSale.Q3Absolute + employeeSale.Q4Absolute; citySale.Children.Add(employeeSale); citySale.Q1Absolute += employeeSale.Q1Absolute; citySale.Q1Fraction += GetCityFractionQuarterSale(employeeSale.Q1Absolute, employeesCount); citySale.Q2Absolute += employeeSale.Q2Absolute; citySale.Q2Fraction += GetCityFractionQuarterSale(employeeSale.Q2Absolute, employeesCount); citySale.Q3Absolute += employeeSale.Q3Absolute; citySale.Q3Fraction += GetCityFractionQuarterSale(employeeSale.Q3Absolute, employeesCount); citySale.Q4Absolute += employeeSale.Q4Absolute; citySale.Q4Fraction += GetCityFractionQuarterSale(employeeSale.Q4Absolute, employeesCount); citySale.Total += employeeSale.Total; } data.Add(citySale); } return data; } static decimal GetAbsoluteQuarterSale() { return (decimal)Math.Round(Random.Shared.NextDouble() * 10000, 2); } static decimal GetEmployeeFractionQuarterSale(decimal employeeSale) { return (decimal)Math.Round(employeeSale / 100); } static decimal GetCityFractionQuarterSale(decimal employeeSale, int employeesCount) { return Math.Round(employeeSale / 100m / employeesCount); } } } ================================================ FILE: DemoCenter/DemoCenter/DemoData/csv/Bitcoin Historical Data.csv ================================================ "Date","Price","Open","High","Low","Vol.","Change %" "11/13/2024","92,553.2","87,971.2","93,226.6","86,168.4","242.94K","5.24%" "11/12/2024","87,941.3","88,665.0","89,929.6","85,122.2","288.68K","-0.82%" "11/11/2024","88,664.1","80,389.0","89,519.0","80,231.8","254.04K","10.29%" "11/10/2024","80,388.5","76,681.4","81,373.5","76,520.5","193.83K","4.81%" "11/09/2024","76,700.3","76,506.1","76,904.0","75,732.5","72.97K","0.24%" "11/08/2024","76,517.3","75,869.8","77,188.5","75,599.0","155.17K","0.85%" "11/07/2024","75,868.6","75,585.5","76,837.8","74,448.2","184.16K","0.37%" "11/06/2024","75,586.3","69,374.1","76,401.4","69,323.0","357.28K","8.96%" "11/05/2024","69,373.7","67,848.3","70,495.6","67,473.6","108.95K","2.25%" "11/04/2024","67,848.8","68,770.3","69,483.4","66,834.0","101.31K","-1.34%" "11/03/2024","68,769.6","69,334.8","69,383.6","67,514.2","83.16K","-0.80%" "11/02/2024","69,325.8","69,499.3","69,896.9","69,029.0","38.72K","-0.26%" "11/01/2024","69,507.2","70,278.7","71,598.4","68,846.0","130.46K","-1.10%" "10/31/2024","70,281.8","72,343.7","72,685.7","69,674.5","111.29K","-2.86%" "10/30/2024","72,347.8","72,732.5","72,907.4","71,460.0","99.05K","-0.53%" "10/29/2024","72,730.4","69,957.2","73,569.4","69,753.2","168.60K","3.97%" "10/28/2024","69,954.1","68,011.9","70,203.4","67,610.0","103.97K","2.87%" "10/27/2024","68,004.6","67,084.7","68,308.0","66,924.6","33.58K","1.37%" "10/26/2024","67,086.8","66,694.5","67,408.4","66,443.8","42.05K","0.58%" "10/25/2024","66,696.8","68,191.9","68,756.8","65,644.2","110.51K","-2.19%" "10/24/2024","68,191.5","66,659.2","68,831.8","66,510.6","82.78K","2.29%" "10/23/2024","66,663.7","67,428.6","67,441.1","65,246.7","84.99K","-1.13%" "10/22/2024","67,427.3","67,370.8","67,815.3","66,609.4","86.76K","0.08%" "10/21/2024","67,371.3","69,030.5","69,490.8","66,845.5","109.28K","-2.40%" "10/20/2024","69,030.5","68,373.3","69,386.4","67,443.9","44.92K","0.96%" "10/19/2024","68,372.0","68,426.4","68,688.8","68,025.5","33.29K","-0.07%" "10/18/2024","68,423.1","67,416.5","68,990.3","67,190.9","99.20K","1.49%" "10/17/2024","67,418.4","67,618.1","67,933.5","66,677.3","84.68K","-0.30%" "10/16/2024","67,617.9","67,075.1","68,389.4","66,766.6","98.30K","0.81%" "10/15/2024","67,077.5","66,084.1","67,821.9","64,850.6","136.72K","1.51%" "10/14/2024","66,081.7","62,870.7","66,476.6","62,463.7","122.09K","5.11%" "10/13/2024","62,870.9","63,205.4","63,284.6","62,054.2","42.26K","-0.53%" "10/12/2024","63,205.1","62,506.6","63,463.1","62,486.1","40.91K","1.13%" "10/11/2024","62,499.4","60,317.5","63,385.1","60,080.6","86.38K","3.62%" "10/10/2024","60,316.2","60,628.9","61,304.6","59,075.7","83.86K","-0.52%" "10/09/2024","60,628.8","62,157.0","62,537.0","60,355.5","68.79K","-2.46%" "10/08/2024","62,157.0","62,226.9","63,196.6","61,883.2","63.75K","-0.14%" "10/07/2024","62,245.6","62,819.8","64,449.3","62,175.8","86.27K","-0.91%" "10/06/2024","62,819.4","62,062.0","62,934.5","61,495.4","31.72K","1.22%" "10/05/2024","62,061.4","62,085.5","62,366.8","61,705.7","30.15K","-0.03%" "10/04/2024","62,081.0","60,751.4","62,471.7","60,469.3","72.71K","2.19%" "10/03/2024","60,751.2","60,642.0","61,468.9","59,904.4","82.43K","0.17%" "10/02/2024","60,645.7","60,834.2","62,339.8","60,002.7","98.94K","-0.31%" "10/01/2024","60,835.5","63,329.9","64,125.3","60,195.9","134.93K","-3.95%" "09/30/2024","63,339.2","65,607.0","65,607.0","62,901.1","101.70K","-3.46%" "09/29/2024","65,607.1","65,862.8","66,065.7","65,436.8","32.60K","-0.39%" "09/28/2024","65,866.5","65,775.6","66,232.5","65,438.1","35.00K","0.14%" "09/27/2024","65,776.3","65,168.8","66,440.7","64,839.2","80.55K","0.92%" "09/26/2024","65,175.7","63,157.2","65,770.9","62,693.3","96.06K","3.20%" "09/25/2024","63,156.5","64,262.9","64,788.4","62,952.8","62.72K","-1.71%" "09/24/2024","64,256.8","63,335.9","64,664.1","62,740.8","76.71K","1.46%" "09/23/2024","63,331.8","63,575.4","64,723.4","62,650.0","75.66K","-0.38%" "09/22/2024","63,572.7","63,351.2","63,998.2","62,394.6","48.86K","0.35%" "09/21/2024","63,348.1","63,201.2","63,526.3","62,778.6","33.20K","0.23%" "09/20/2024","63,201.2","62,942.4","64,085.1","62,367.1","90.65K","0.42%" "09/19/2024","62,938.6","61,754.8","63,849.6","61,596.5","120.17K","1.91%" "09/18/2024","61,757.6","60,308.5","61,757.6","59,210.7","105.57K","2.40%" "09/17/2024","60,309.1","58,213.1","61,309.0","57,630.2","106.30K","3.60%" "09/16/2024","58,213.1","59,126.2","59,204.3","57,527.8","87.60K","-1.56%" "09/15/2024","59,138.5","59,995.6","60,377.6","58,717.9","47.01K","-1.43%" "09/14/2024","59,995.4","60,514.8","60,609.4","59,494.3","44.47K","-0.85%" "09/13/2024","60,511.6","58,134.4","60,625.4","57,656.8","102.12K","4.09%" "09/12/2024","58,134.5","57,335.5","58,484.1","57,329.6","98.42K","1.39%" "09/11/2024","57,338.7","57,638.0","57,975.9","55,576.6","102.15K","-0.51%" "09/10/2024","57,635.0","57,045.6","58,019.9","56,415.3","77.65K","1.03%" "09/09/2024","57,049.6","54,868.0","57,956.7","54,595.4","105.33K","3.99%" "09/08/2024","54,861.3","54,161.4","55,292.7","53,642.4","51.99K","1.30%" "09/07/2024","54,156.5","53,965.0","54,819.2","53,754.3","58.11K","0.35%" "09/06/2024","53,966.8","56,179.7","56,969.1","52,644.6","155.84K","-3.94%" "09/05/2024","56,183.2","57,970.7","58,318.9","55,744.6","90.36K","-3.09%" "09/04/2024","57,973.4","57,490.4","58,508.8","55,732.1","108.44K","0.86%" "09/03/2024","57,479.8","59,133.7","59,799.7","57,436.9","74.77K","-2.80%" "09/02/2024","59,134.0","57,309.0","59,416.6","57,185.8","73.18K","3.17%" "09/01/2024","57,315.7","58,975.7","59,058.7","57,232.4","63.95K","-2.82%" "08/31/2024","58,978.6","59,120.4","59,447.0","58,761.1","30.86K","-0.24%" "08/30/2024","59,119.7","59,371.7","59,817.6","57,874.7","87.31K","-0.43%" "08/29/2024","59,373.5","59,027.3","61,150.6","58,807.1","87.19K","0.61%" "08/28/2024","59,016.0","59,425.6","60,198.4","57,912.1","109.47K","-0.73%" "08/27/2024","59,450.9","62,832.2","63,201.4","58,187.3","108.53K","-5.40%" "08/26/2024","62,846.2","64,240.7","64,472.5","62,841.1","68.89K","-2.22%" "08/25/2024","64,273.2","64,160.7","64,939.2","63,796.6","41.61K","0.18%" "08/24/2024","64,159.3","64,061.7","64,458.9","63,579.5","54.14K","0.17%" "08/23/2024","64,053.1","60,374.7","64,830.1","60,354.4","125.50K","6.10%" "08/22/2024","60,372.2","61,158.3","61,399.7","59,815.8","74.39K","-1.29%" "08/21/2024","61,158.1","59,010.0","61,812.0","58,831.1","91.31K","3.65%" "08/20/2024","59,005.8","59,470.3","61,331.6","58,612.0","69.77K","-0.78%" "08/19/2024","59,470.9","58,445.8","59,598.5","57,872.0","49.19K","1.75%" "08/18/2024","58,446.3","59,485.4","60,216.3","58,436.1","30.82K","-1.74%" "08/17/2024","59,483.1","58,877.8","59,659.5","58,825.5","18.51K","1.03%" "08/16/2024","58,877.2","57,545.1","59,817.3","57,129.1","64.01K","2.33%" "08/15/2024","57,534.6","58,710.1","59,831.4","56,275.7","81.47K","-2.00%" "08/14/2024","58,707.8","60,594.6","61,543.0","58,491.2","64.79K","-3.11%" "08/13/2024","60,595.2","59,350.2","61,537.0","58,492.4","62.92K","2.10%" "08/12/2024","59,350.0","58,711.7","60,606.2","57,689.0","79.31K","1.08%" "08/11/2024","58,713.3","60,929.8","61,677.3","58,388.7","41.06K","-3.64%" "08/10/2024","60,931.7","60,844.5","61,344.5","60,264.2","22.91K","0.13%" "08/09/2024","60,850.6","61,697.8","61,712.3","59,570.2","69.55K","-1.38%" "08/08/2024","61,699.7","55,112.8","62,563.5","54,786.9","109.77K","11.94%" "08/07/2024","55,120.9","56,049.9","57,669.6","54,598.5","94.52K","-1.67%" "08/06/2024","56,057.8","54,010.8","57,025.6","53,998.2","113.89K","3.85%" "08/05/2024","53,979.0","58,142.9","58,291.4","49,486.9","333.46K","-7.16%" "08/04/2024","58,141.8","60,700.2","61,086.5","57,346.9","72.71K","-4.21%" "08/03/2024","60,696.7","61,480.8","62,184.2","59,914.6","65.74K","-1.27%" "08/02/2024","61,478.7","65,351.8","65,567.1","61,242.3","93.89K","-5.96%" "08/01/2024","65,372.9","64,625.7","65,587.9","62,303.9","84.20K","1.16%" "07/31/2024","64,626.0","66,185.4","66,825.6","64,538.3","51.52K","-2.36%" "07/30/2024","66,184.9","66,796.1","66,998.3","65,328.7","54.43K","-0.92%" "07/29/2024","66,798.7","68,256.3","70,000.2","66,544.5","85.67K","-2.14%" "07/28/2024","68,256.3","67,888.9","68,291.9","67,067.8","26.17K","0.61%" "07/27/2024","67,843.1","67,910.8","69,387.6","66,776.8","67.99K","-0.10%" "07/26/2024","67,908.6","65,799.7","68,205.0","65,764.3","59.13K","3.21%" "07/25/2024","65,799.3","65,363.9","66,088.6","63,500.9","77.46K","0.66%" "07/24/2024","65,370.5","65,936.8","67,072.1","65,155.2","52.47K","-0.86%" "07/23/2024","65,937.8","67,550.4","67,750.2","65,512.9","69.58K","-2.39%" "07/22/2024","67,553.6","68,158.4","68,468.9","66,601.8","54.88K","-0.89%" "07/21/2024","68,158.7","67,147.8","68,352.9","65,825.6","47.19K","1.50%" "07/20/2024","67,148.5","66,677.0","67,586.4","66,257.4","32.94K","0.71%" "07/19/2024","66,677.4","63,981.2","67,390.4","63,326.1","82.87K","4.22%" "07/18/2024","63,980.5","64,090.4","65,102.0","63,253.5","51.27K","-0.17%" "07/17/2024","64,089.2","65,052.8","66,051.5","63,897.5","66.11K","-1.48%" "07/16/2024","65,049.7","64,749.2","65,319.5","62,430.8","93.63K","0.41%" "07/15/2024","64,782.4","60,794.7","64,869.5","60,678.8","96.02K","6.56%" "07/14/2024","60,794.9","59,207.9","61,326.9","59,207.9","47.48K","2.68%" "07/13/2024","59,209.8","57,897.4","59,826.5","57,770.6","34.28K","2.29%" "07/12/2024","57,885.1","57,338.3","58,520.9","56,575.7","56.84K","0.96%" "07/11/2024","57,337.3","57,745.9","59,404.4","57,095.0","66.40K","-0.71%" "07/10/2024","57,746.7","58,040.2","59,393.8","57,185.3","59.60K","-0.50%" "07/09/2024","58,039.4","56,721.3","58,234.0","56,306.3","64.25K","2.32%" "07/08/2024","56,724.7","55,850.2","58,115.8","54,320.0","102.91K","1.55%" "07/07/2024","55,861.1","58,240.2","58,394.6","55,756.3","41.12K","-4.12%" "07/06/2024","58,259.2","56,640.0","58,462.0","56,026.8","46.91K","2.86%" "07/05/2024","56,641.8","57,025.7","57,471.1","53,883.4","175.51K","-0.67%" "07/04/2024","57,026.3","60,201.4","60,463.0","56,812.7","116.38K","-5.27%" "07/03/2024","60,199.3","62,104.9","62,263.6","59,466.6","73.34K","-3.07%" "07/02/2024","62,103.3","62,888.3","63,257.0","61,797.6","46.52K","-1.25%" "07/01/2024","62,890.1","62,768.8","63,842.1","62,558.0","59.94K","0.22%" "06/30/2024","62,754.3","60,973.1","63,006.6","60,703.7","37.21K","2.92%" "06/29/2024","60,973.4","60,403.7","61,192.8","60,382.8","26.56K","0.94%" "06/28/2024","60,403.3","61,684.6","62,175.4","60,081.9","58.95K","-2.08%" "06/27/2024","61,685.3","60,848.3","62,351.2","60,629.4","48.79K","1.37%" "06/26/2024","60,849.4","61,809.9","62,469.4","60,715.1","54.95K","-1.55%" "06/25/2024","61,809.4","60,292.0","62,266.0","60,262.2","77.28K","2.52%" "06/24/2024","60,292.7","63,201.6","63,357.1","58,589.9","120.60K","-4.59%" "06/23/2024","63,196.2","64,261.0","64,518.9","63,195.3","19.94K","-1.66%" "06/22/2024","64,261.0","64,131.9","64,523.9","63,944.0","17.55K","0.21%" "06/21/2024","64,128.5","64,854.3","65,054.9","63,427.9","60.86K","-1.12%" "06/20/2024","64,854.3","64,982.1","66,474.2","64,566.7","56.24K","-0.19%" "06/19/2024","64,980.9","65,159.8","65,706.4","64,705.6","42.96K","-0.27%" "06/18/2024","65,159.9","66,495.7","66,571.2","64,098.4","93.72K","-2.01%" "06/17/2024","66,498.8","66,672.9","67,253.8","65,115.4","66.09K","-0.26%" "06/16/2024","66,674.7","66,223.0","66,951.4","66,038.1","20.74K","0.68%" "06/15/2024","66,223.0","66,034.1","66,446.4","65,895.1","24.05K","0.29%" "06/14/2024","66,034.8","66,775.2","67,347.7","65,076.5","65.18K","-1.11%" "06/13/2024","66,773.1","68,260.6","68,384.6","66,324.3","66.36K","-2.18%" "06/12/2024","68,260.1","67,320.9","69,990.8","66,911.5","85.55K","1.40%" "06/11/2024","67,319.8","69,537.9","69,573.3","66,197.8","96.70K","-3.19%" "06/10/2024","69,538.2","69,650.2","70,152.5","69,259.9","39.12K","-0.16%" "06/09/2024","69,650.6","69,310.5","69,847.8","69,136.7","20.99K","0.49%" "06/08/2024","69,310.1","69,347.0","69,572.1","69,222.4","23.03K","-0.05%" "06/07/2024","69,347.9","70,793.4","71,956.5","68,620.7","82.62K","-2.04%" "06/06/2024","70,791.5","71,083.6","71,616.1","70,178.7","49.79K","-0.41%" "06/05/2024","71,083.7","70,550.9","71,744.4","70,397.1","67.06K","0.76%" "06/04/2024","70,549.2","68,808.0","71,034.2","68,564.3","75.69K","2.53%" "06/03/2024","68,807.8","67,763.3","70,131.0","67,616.8","69.42K","1.53%" "06/02/2024","67,773.5","67,760.8","68,447.5","67,330.6","30.63K","0.02%" "06/01/2024","67,760.8","67,533.9","67,861.0","67,449.6","19.01K","0.34%" "05/31/2024","67,530.1","68,352.3","69,018.2","66,676.8","61.51K","-1.21%" "05/30/2024","68,354.7","67,631.3","69,504.7","67,138.4","66.84K","1.06%" "05/29/2024","67,635.8","68,366.2","68,897.6","67,143.2","52.13K","-1.07%" "05/28/2024","68,366.0","69,428.3","69,560.7","67,299.9","71.39K","-1.53%" "05/27/2024","69,428.7","68,514.6","70,638.3","68,275.2","49.07K","1.33%" "05/26/2024","68,514.8","69,287.2","69,494.0","68,294.5","24.58K","-1.11%" "05/25/2024","69,284.4","68,548.2","69,558.8","68,516.1","25.17K","1.07%" "05/24/2024","68,547.6","67,971.1","69,212.0","66,685.8","63.28K","0.84%" "05/23/2024","67,975.7","69,166.3","70,041.0","66,578.1","89.45K","-1.71%" "05/22/2024","69,155.4","70,141.0","70,593.4","69,024.3","65.08K","-1.40%" "05/21/2024","70,139.9","71,430.5","71,872.0","69,181.7","108.56K","-1.80%" "05/20/2024","71,422.7","66,278.3","71,482.8","66,076.5","112.66K","7.76%" "05/19/2024","66,279.1","66,919.0","67,662.5","65,937.3","36.19K","-0.95%" "05/18/2024","66,917.5","67,036.6","67,361.4","66,636.1","29.68K","-0.18%" "05/17/2024","67,036.8","65,231.1","67,420.7","65,121.7","63.09K","2.77%" "05/16/2024","65,231.0","66,219.6","66,643.9","64,623.3","72.55K","-1.50%" "05/15/2024","66,225.1","61,569.4","66,417.1","61,357.5","106.05K","7.56%" "05/14/2024","61,569.4","62,936.8","63,102.6","61,156.9","68.84K","-2.17%" "05/13/2024","62,937.2","61,480.5","63,443.2","60,779.0","70.55K","2.37%" "05/12/2024","61,480.0","60,826.6","61,847.7","60,647.1","27.40K","1.07%" "05/11/2024","60,826.6","60,796.8","61,487.5","60,499.3","27.50K","0.05%" "05/10/2024","60,796.9","63,074.3","63,454.3","60,251.8","79.33K","-3.61%" "05/09/2024","63,075.0","61,207.3","63,413.3","60,671.4","64.22K","3.05%" "05/08/2024","61,207.5","62,304.9","62,997.4","60,894.2","56.47K","-1.78%" "05/07/2024","62,317.7","63,163.1","64,361.0","62,294.1","59.74K","-1.34%" "05/06/2024","63,163.1","64,005.8","65,448.8","62,730.7","77.68K","-1.32%" "05/05/2024","64,006.4","63,897.7","64,587.2","62,923.9","40.51K","0.18%" "05/04/2024","63,888.3","62,887.1","64,466.0","62,599.1","53.03K","1.61%" "05/03/2024","62,877.5","59,104.3","63,298.4","58,830.8","100.46K","6.35%" "05/02/2024","59,121.3","58,334.9","59,548.0","56,989.8","98.06K","1.35%" "05/01/2024","58,331.2","60,665.0","60,827.5","56,643.5","171.55K","-3.85%" "04/30/2024","60,666.6","63,852.4","64,700.2","59,228.7","121.04K","-5.00%" "04/29/2024","63,860.1","63,113.7","64,193.1","61,837.2","67.26K","1.19%" "04/28/2024","63,109.7","63,457.9","64,346.1","62,827.8","36.65K","-0.55%" "04/27/2024","63,456.8","63,765.8","63,916.7","62,507.7","45.34K","-0.49%" "04/26/2024","63,766.4","64,497.1","64,771.3","63,354.9","61.60K","-1.13%" "04/25/2024","64,497.1","64,287.1","65,247.5","62,889.2","80.77K","0.33%" "04/24/2024","64,285.7","66,414.9","67,060.5","63,606.9","77.83K","-3.21%" "04/23/2024","66,415.0","66,829.5","67,180.0","65,848.3","52.42K","-0.62%" "04/22/2024","66,829.3","64,940.1","67,208.0","64,527.5","72.30K","2.91%" "04/21/2024","64,940.2","64,942.1","65,680.6","64,267.5","42.02K","-0.03%" "04/20/2024","64,961.1","63,817.6","65,375.6","63,131.7","49.33K","1.82%" "04/19/2024","63,799.1","63,480.5","65,441.2","59,693.3","150.34K","0.50%" "04/18/2024","63,481.4","61,278.9","64,092.4","60,822.3","97.38K","3.59%" "04/17/2024","61,278.9","63,802.3","64,451.5","59,820.8","118.92K","-3.96%" "04/16/2024","63,805.3","63,416.1","64,274.4","61,715.6","114.96K","0.62%" "04/15/2024","63,411.9","65,696.6","66,805.1","62,379.5","118.79K","-3.48%" "04/14/2024","65,697.4","63,909.5","65,758.2","62,174.7","134.40K","2.89%" "04/13/2024","63,849.9","67,137.4","67,921.0","61,065.5","149.48K","-4.92%" "04/12/2024","67,151.9","70,014.9","71,226.9","65,829.3","131.84K","-4.08%" "04/11/2024","70,011.6","70,620.4","71,249.2","69,586.1","72.51K","-0.86%" "04/10/2024","70,622.1","69,147.8","71,086.9","67,570.0","97.71K","2.13%" "04/09/2024","69,148.0","71,627.3","71,737.2","68,264.6","93.69K","-3.47%" "04/08/2024","71,630.1","69,358.0","72,710.8","69,110.5","105.78K","3.27%" "04/07/2024","69,360.4","68,897.3","70,285.8","68,849.4","46.99K","0.68%" "04/06/2024","68,890.6","67,830.5","69,632.0","67,467.2","41.48K","1.56%" "04/05/2024","67,830.6","68,498.7","68,692.2","66,023.3","88.97K","-0.97%" "04/04/2024","68,496.5","65,968.4","69,238.8","65,096.3","100.30K","3.84%" "04/03/2024","65,963.0","65,443.6","66,844.8","64,559.0","88.46K","0.80%" "04/02/2024","65,439.2","69,662.7","69,673.0","64,628.4","152.87K","-6.07%" "04/01/2024","69,664.4","71,329.3","71,329.3","68,175.9","94.05K","-2.34%" "03/31/2024","71,332.0","69,608.5","71,367.5","69,576.6","42.45K","2.47%" "03/30/2024","69,611.5","69,872.3","70,321.2","69,564.9","29.87K","-0.37%" "03/29/2024","69,871.7","70,766.7","70,907.0","69,090.9","58.99K","-1.26%" "03/28/2024","70,762.1","69,449.4","71,542.5","68,956.9","72.49K","1.90%" "03/27/2024","69,442.4","69,999.2","71,670.8","68,428.6","112.88K","-0.80%" "03/26/2024","69,999.3","69,896.3","71,490.7","69,366.4","90.98K","0.15%" "03/25/2024","69,892.0","67,216.4","71,118.8","66,395.0","124.72K","3.99%" "03/24/2024","67,211.9","64,036.5","67,587.8","63,812.9","65.59K","4.96%" "03/23/2024","64,037.8","63,785.6","65,972.4","63,074.9","35.11K","0.40%" "03/22/2024","63,785.5","65,501.5","66,633.3","62,328.3","72.43K","-2.62%" "03/21/2024","65,503.8","67,860.0","68,161.7","64,616.1","75.26K","-3.46%" "03/20/2024","67,854.0","62,046.8","68,029.5","60,850.9","133.53K","9.35%" "03/19/2024","62,050.0","67,594.1","68,099.6","61,560.6","148.08K","-8.20%" "03/18/2024","67,594.1","68,389.7","68,920.1","66,601.4","78.07K","-1.17%" "03/17/2024","68,391.2","65,314.2","68,857.7","64,605.5","66.07K","4.71%" "03/16/2024","65,314.2","69,456.5","70,037.0","64,971.0","75.82K","-5.97%" "03/15/2024","69,463.7","71,387.1","72,398.1","65,765.6","148.59K","-2.69%" "03/14/2024","71,387.5","73,066.7","73,740.9","68,717.2","109.43K","-2.30%" "03/13/2024","73,066.3","71,461.9","73,623.5","71,338.4","77.18K","2.23%" "03/12/2024","71,470.2","72,099.1","72,916.7","68,845.6","105.09K","-0.87%" "03/11/2024","72,099.1","68,964.7","72,771.5","67,452.8","114.72K","4.54%" "03/10/2024","68,964.8","68,360.7","69,905.3","68,165.0","53.49K","0.88%" "03/09/2024","68,366.5","68,178.5","68,576.9","67,923.9","30.71K","0.29%" "03/08/2024","68,172.0","66,854.4","69,904.0","66,170.7","112.67K","1.97%" "03/07/2024","66,855.3","66,074.6","67,985.5","65,602.6","77.47K","1.17%" "03/06/2024","66,080.4","63,794.7","67,604.9","62,848.7","117.91K","3.59%" "03/05/2024","63,792.6","68,273.1","69,063.1","60,138.2","207.60K","-6.56%" "03/04/2024","68,270.1","63,135.8","68,495.1","62,746.8","130.86K","8.13%" "03/03/2024","63,135.8","61,955.6","63,227.3","61,399.4","38.01K","1.84%" "03/02/2024","61,994.5","62,397.7","62,446.3","61,621.9","33.80K","-0.65%" "03/01/2024","62,397.7","61,157.3","63,147.3","60,790.9","74.96K","2.01%" "02/29/2024","61,169.3","62,467.1","63,653.4","60,512.5","119.29K","-2.08%" "02/28/2024","62,467.6","57,048.7","63,915.3","56,704.9","173.64K","9.48%" "02/27/2024","57,056.2","54,491.1","57,555.2","54,464.0","100.48K","4.70%" "02/26/2024","54,495.1","51,722.7","54,899.1","50,925.2","78.05K","5.36%" "02/25/2024","51,722.7","51,572.1","51,952.0","51,299.0","23.61K","0.29%" "02/24/2024","51,571.6","50,739.6","51,689.9","50,592.0","20.99K","1.64%" "02/23/2024","50,740.5","51,320.6","51,532.5","50,537.6","43.27K","-1.13%" "02/22/2024","51,320.4","51,850.2","52,015.8","50,947.3","50.27K","-1.04%" "02/21/2024","51,858.2","52,263.5","52,367.3","50,676.9","59.02K","-0.78%" "02/20/2024","52,263.5","51,783.1","52,936.8","50,801.8","68.10K","0.93%" "02/19/2024","51,783.6","52,119.6","52,484.8","51,694.2","36.73K","-0.64%" "02/18/2024","52,117.5","51,646.0","52,350.3","51,199.6","26.89K","0.91%" "02/17/2024","51,646.0","52,134.2","52,175.5","50,652.3","32.45K","-0.94%" "02/16/2024","52,134.2","51,901.4","52,556.7","51,612.6","52.86K","0.45%" "02/15/2024","51,901.3","51,805.2","52,819.4","51,327.5","74.72K","0.23%" "02/14/2024","51,782.4","49,708.6","52,010.7","49,263.8","80.35K","4.16%" "02/13/2024","49,716.0","49,941.0","50,326.6","48,398.3","78.51K","-0.45%" "02/12/2024","49,941.3","48,280.2","50,277.3","47,729.9","81.85K","3.45%" "02/11/2024","48,277.3","47,759.3","48,531.6","47,590.2","36.50K","1.09%" "02/10/2024","47,758.2","47,128.0","48,149.0","46,875.0","31.20K","1.34%" "02/09/2024","47,127.5","45,293.3","48,118.8","45,254.2","98.11K","4.05%" "02/08/2024","45,293.3","44,346.2","45,579.2","44,336.4","66.38K","2.15%" "02/07/2024","44,339.8","43,088.4","44,367.9","42,783.5","48.57K","2.91%" "02/06/2024","43,087.7","42,697.6","43,375.5","42,566.8","33.32K","0.91%" "02/05/2024","42,697.2","42,581.4","43,532.2","42,272.5","39.26K","0.27%" "02/04/2024","42,581.4","43,006.2","43,113.2","42,379.4","20.33K","-0.99%" "02/03/2024","43,005.7","43,194.7","43,370.4","42,882.0","14.57K","-0.44%" "02/02/2024","43,194.7","43,083.7","43,459.3","42,596.3","42.65K","0.26%" "02/01/2024","43,081.4","42,580.1","43,263.1","41,890.5","47.69K","1.18%" "01/31/2024","42,580.5","42,946.2","43,739.7","42,315.4","56.48K","-0.85%" "01/30/2024","42,946.2","43,303.3","43,817.9","42,702.9","55.13K","-0.82%" "01/29/2024","43,299.8","42,031.4","43,305.6","41,824.7","45.23K","3.02%" "01/28/2024","42,030.7","42,121.3","42,817.1","41,649.0","32.53K","-0.21%" "01/27/2024","42,120.9","41,811.5","42,191.8","41,413.0","20.46K","0.74%" "01/26/2024","41,811.3","39,942.0","42,214.8","39,831.2","69.47K","4.70%" "01/25/2024","39,935.7","40,085.1","40,285.8","39,546.3","46.30K","-0.37%" "01/24/2024","40,086.0","39,891.3","40,535.2","39,510.0","58.64K","0.49%" "01/23/2024","39,888.8","39,555.0","40,159.4","38,546.9","82.67K","0.84%" "01/22/2024","39,556.4","41,581.7","41,684.9","39,468.4","85.10K","-4.87%" "01/21/2024","41,583.2","41,695.4","41,878.0","41,504.5","16.11K","-0.27%" "01/20/2024","41,695.4","41,647.6","41,858.0","41,449.5","22.27K","0.11%" "01/19/2024","41,648.0","41,293.8","42,164.6","40,305.4","72.64K","0.86%" "01/18/2024","41,292.7","42,763.5","42,908.0","40,682.6","70.35K","-3.45%" "01/17/2024","42,768.7","43,139.1","43,192.3","42,211.8","50.44K","-0.87%" "01/16/2024","43,145.5","42,515.2","43,563.7","42,093.1","63.93K","1.49%" "01/15/2024","42,510.7","41,747.6","43,348.9","41,719.2","52.08K","1.83%" "01/14/2024","41,746.1","42,851.3","43,069.4","41,739.6","37.14K","-2.58%" "01/13/2024","42,851.3","42,836.7","43,248.6","42,443.3","48.18K","0.04%" "01/12/2024","42,835.9","46,348.1","46,503.2","41,857.9","136.92K","-7.58%" "01/11/2024","46,348.2","46,629.3","48,923.7","45,651.8","131.04K","-0.60%" "01/10/2024","46,629.3","46,112.0","47,654.3","44,403.6","131.48K","1.08%" "01/09/2024","46,129.0","46,959.2","47,880.1","45,333.9","100.09K","-1.77%" "01/08/2024","46,962.2","43,934.2","47,196.7","43,251.0","103.09K","6.91%" "01/07/2024","43,927.3","43,973.5","44,481.2","43,627.9","29.53K","-0.09%" "01/06/2024","43,967.9","44,156.6","44,203.2","43,424.0","24.26K","-0.43%" "01/05/2024","44,156.9","44,163.0","44,312.1","42,629.0","68.07K","0.00%" "01/04/2024","44,157.0","42,836.1","44,744.5","42,632.8","68.05K","3.08%" "01/03/2024","42,836.1","44,943.7","45,492.7","40,888.3","117.65K","-4.69%" "01/02/2024","44,943.7","44,182.9","45,885.4","44,166.0","97.84K","1.72%" "01/01/2024","44,183.4","42,272.5","44,187.0","42,196.7","36.30K","4.52%" "12/31/2023","42,272.5","42,141.6","42,878.8","41,971.4","35.58K","0.32%" "12/30/2023","42,136.7","42,074.7","42,592.2","41,527.3","35.18K","0.15%" "12/29/2023","42,072.4","42,581.1","43,108.0","41,459.0","60.98K","-1.19%" "12/28/2023","42,581.1","43,446.5","43,782.6","42,309.3","49.84K","-1.99%" "12/27/2023","43,446.5","42,514.3","43,676.7","42,115.3","50.10K","2.20%" "12/26/2023","42,513.3","43,579.9","43,594.9","41,796.6","56.03K","-2.44%" "12/25/2023","43,578.5","42,982.0","43,792.7","42,745.3","32.67K","1.39%" "12/24/2023","42,981.5","43,710.4","43,935.7","42,748.5","30.86K","-1.67%" "12/23/2023","43,710.4","43,968.9","43,994.6","43,325.7","21.29K","-0.59%" "12/22/2023","43,968.9","43,865.9","44,394.6","43,419.3","44.50K","0.23%" "12/21/2023","43,865.9","43,660.3","44,241.8","43,310.2","48.96K","0.47%" "12/20/2023","43,662.8","42,259.5","44,278.7","42,217.2","70.19K","3.32%" "12/19/2023","42,259.3","42,659.7","43,473.3","41,842.7","55.29K","-0.94%" "12/18/2023","42,659.7","41,369.1","42,728.0","40,554.0","61.58K","3.12%" "12/17/2023","41,368.7","42,271.7","42,413.2","41,276.9","35.46K","-2.14%" "12/16/2023","42,271.7","41,929.0","42,690.3","41,698.2","30.11K","0.82%" "12/15/2023","41,929.0","43,025.2","43,080.7","41,697.9","45.28K","-2.55%" "12/14/2023","43,025.9","42,886.3","43,392.7","41,591.2","59.15K","0.33%" "12/13/2023","42,884.5","41,487.0","43,417.5","40,649.3","63.11K","3.37%" "12/12/2023","41,487.0","41,256.1","42,070.9","40,691.5","57.04K","0.56%" "12/11/2023","41,256.1","43,791.0","43,806.3","40,277.1","105.19K","-5.79%" "12/10/2023","43,791.0","43,716.6","44,045.4","43,576.8","23.81K","0.17%" "12/09/2023","43,718.4","44,175.5","44,361.2","43,617.4","31.67K","-1.03%" "12/08/2023","44,175.5","43,288.3","44,697.6","43,108.4","58.44K","2.05%" "12/07/2023","43,289.7","43,774.4","44,046.4","42,860.5","63.09K","-1.11%" "12/06/2023","43,776.3","44,076.2","44,283.7","43,466.7","72.52K","-0.68%" "12/05/2023","44,076.2","41,989.6","44,424.1","41,424.9","96.84K","4.97%" "12/04/2023","41,987.8","39,968.6","42,394.4","39,968.6","104.21K","5.05%" "12/03/2023","39,970.2","39,456.8","40,178.9","39,280.3","35.27K","1.30%" "12/02/2023","39,458.4","38,688.2","39,673.4","38,646.5","37.09K","1.99%" "12/01/2023","38,688.2","37,712.9","38,950.8","37,618.3","62.50K","2.59%" "11/30/2023","37,712.9","37,857.6","38,144.4","37,509.2","33.53K","-0.38%" "11/29/2023","37,855.5","37,823.3","38,362.9","37,607.6","49.34K","0.09%" "11/28/2023","37,823.3","37,244.3","38,379.4","36,881.1","57.50K","1.54%" "11/27/2023","37,248.6","37,451.8","37,563.3","36,751.5","45.24K","-0.54%" "11/26/2023","37,451.8","37,786.4","37,819.1","37,166.3","29.20K","-0.89%" "11/25/2023","37,787.0","37,718.6","37,887.4","37,599.9","16.09K","0.18%" "11/24/2023","37,717.3","37,295.0","38,400.8","37,257.4","65.83K","1.14%" "11/23/2023","37,293.1","37,410.8","37,642.5","36,915.3","32.35K","-0.31%" "11/22/2023","37,410.8","35,797.5","37,862.5","35,695.6","64.81K","4.46%" "11/21/2023","35,813.6","37,452.7","37,631.2","35,799.2","71.07K","-4.38%" "11/20/2023","37,454.1","37,356.6","37,735.6","36,857.6","51.80K","0.27%" "11/19/2023","37,354.2","36,568.6","37,504.6","36,393.3","26.14K","2.15%" "11/18/2023","36,568.6","36,617.5","36,845.2","36,220.6","20.88K","-0.07%" "11/17/2023","36,595.4","36,161.8","36,690.6","35,875.2","51.37K","1.20%" "11/16/2023","36,161.2","37,873.9","37,907.6","35,561.6","66.92K","-4.52%" "11/15/2023","37,874.9","35,549.3","37,954.1","35,379.6","75.51K","6.54%" "11/14/2023","35,549.3","36,478.3","36,744.5","34,984.3","63.56K","-2.55%" "11/13/2023","36,478.3","37,067.8","37,404.6","36,358.4","44.55K","-1.58%" ================================================ FILE: DemoCenter/DemoCenter/DemoData/csv/CarImages/convert.bat ================================================ for /f %%f in ('dir /b *.png') do "C:\Program Files\ImageMagick-7.1.1-Q16\magick.exe" convert -quality 75 -colors 16 %%f %%f ================================================ FILE: DemoCenter/DemoCenter/DemoData/csv/cars.csv ================================================ ID,Trademark,HP,Liter,Cyl,Transmission speed count,Transmission type,MPG,Description,Price,IsInStock,PictureName 1,MarsRoverX,300,3,6,5,Automatic,20,"The MarsRoverX is a powerful off-road vehicle designed for exploring the rugged terrains of Mars. With its 300 horsepower engine and 3.0-liter cylinder capacity, it can easily traverse the harsh Martian landscape. The automatic transmission allows for smooth gear shifts, while achieving a fuel efficiency of 20 MPG. This Martian car is perfect for scientific missions and exploration.","$50,000 ",True,MarsRoverX.png 2,RedPlanetCruiser,250,2.5,4,6,Manual,25,"The RedPlanetCruiser is a sleek and stylish car built for high-speed travel on the Martian highways. It boasts a 250 horsepower engine with a 2.5-liter cylinder capacity, providing a thrilling driving experience. The manual transmission offers full control over gear shifts, making it ideal for Martians who enjoy a more hands-on driving experience. With a fuel efficiency of 25 MPG, this car combines performance and efficiency.","$45,000 ",True,RedPlanetCruiser.png 3,InterstellarExplorer,400,4,8,7,Automatic,18,"The InterstellarExplorer is a futuristic Martian car designed for long-distance space travel. Its powerful 400 horsepower engine and 4.0-liter cylinder capacity ensure smooth acceleration even in zero-gravity environments. The automatic transmission with seven-speed options allows for effortless gear changes. With a fuel efficiency of 18 MPG, this car can cover vast distances on minimal fuel consumption. Perfect for interplanetary adventurers seeking new frontiers.","$60,000 ",False,InterstellarExplorer.png 4,MarsOffroader,200,2,4,5,Manual,22,"The MarsOffroader is a rugged off-road vehicle built to conquer the challenging Martian terrain. It features a 200 horsepower engine with a 2.0-liter cylinder capacity, making it capable of tackling steep inclines and rocky surfaces. The manual transmission enables precise control over gear shifts, ensuring optimal performance in any off-road situation. With a fuel efficiency of 22 MPG, this car is a reliable companion for Martian explorers.","$35,000 ",True,MarsOffroader.png 5,AlienSpeedster,500,5,10,8,Automatic,15,"The AlienSpeedster is a high-performance sports car designed for Martians who crave adrenaline-fueled adventures. Its massive 500 horsepower engine and 5.0-liter cylinder capacity deliver unmatched acceleration and top speeds. The automatic transmission with eight-speed options guarantees lightning-fast gear changes. While fuel efficiency may not be its primary focus, the AlienSpeedster still manages a respectable 15 MPG. This car is a symbol of Martian luxury and speed.","$80,000 ",True,AlienSpeedster.png 6,MarsCruiser,350,3.5,6,6,Automatic,19,"The MarsCruiser is a versatile car that combines comfort, power, and style. With a 350 horsepower engine and a 3.5-liter cylinder capacity, it offers a smooth driving experience on Martian roads. The automatic transmission with six-speed options ensures effortless gear shifts. With a fuel efficiency of 19 MPG, this car strikes the perfect balance between performance and economy. Ideal for everyday commuting or weekend getaways on Mars.","$55,000 ",True,MarsCruiser.png 7,CyberRover,450,4.5,8,7,Automatic,17,"The CyberRover is an advanced Martian car equipped with cutting-edge technology. Its 450 horsepower engine and 4.5-liter cylinder capacity provide impressive power and performance. The automatic transmission with seven-speed options ensures seamless gear changes. With a fuel efficiency of 17 MPG, this car combines power with efficiency. Packed with futuristic features and sleek design, the CyberRover is a must-have for tech-savvy Martians.","$70,000 ",True,CyberRover.png 8,MarsUtilityTruck,300,3,6,6,Manual,21,"The MarsUtilityTruck is a versatile vehicle designed for various tasks on the Martian surface. Its 300 horsepower engine and 3.0-liter cylinder capacity offer sufficient power for hauling heavy loads or towing equipment. The manual transmission allows for precise gear shifts, ensuring optimal performance in different scenarios. With a fuel efficiency of 21 MPG, this truck is both practical and efficient for Martian work environments.","$40,000 ",False,MarsUtilityTruck.png 9,RedDustBuggy,150,1.5,4,4,Automatic,24,"The RedDustBuggy is a compact and agile car built for navigating the dusty Martian landscapes. Its 150 horsepower engine and 1.5-liter cylinder capacity provide ample power for zipping through narrow trails. The automatic transmission with four-speed options ensures effortless gear changes. With a fuel efficiency of 24 MPG, this car is perfect for Martian adventurers looking to explore the planet's hidden wonders.","$30,000 ",True,RedDustBuggy.png 10,SpaceHopper,250,2.5,4,5,Manual,23,"The SpaceHopper is a compact and nimble car designed for easy maneuverability in cramped Martian environments. Its 250 horsepower engine and 2.5-liter cylinder capacity offer sufficient power for urban commutes or interplanetary travel. The manual transmission provides full control over gear shifts, making it ideal for Martians who enjoy an engaging driving experience. With a fuel efficiency of 23 MPG, this car is practical and efficient for everyday use on Mars.","$35,000 ",True,SpaceHopper.png 11,MartianSprinter,400,4,8,6,Automatic,16,"The MartianSprinter is a high-performance car built for Martians who crave speed and luxury. Its powerful 400 horsepower engine and 4.0-liter cylinder capacity deliver exhilarating acceleration and top speeds. The automatic transmission with six-speed options ensures smooth gear changes. With a fuel efficiency of 16 MPG, this car combines performance with style. Perfect for Martians who want to make a statement on the Martian highways.","$65,000 ",True,MartianSprinter.png 12,AstroTrailblazer,200,2,4,5,Automatic,20,"The AstroTrailblazer is an all-terrain vehicle designed for exploring the uncharted regions of Mars. Its 200 horsepower engine and 2.0-liter cylinder capacity provide sufficient power for off-road adventures. The automatic transmission with five-speed options allows for seamless gear changes. With a fuel efficiency of 20 MPG, this car is a reliable companion for Martian explorers seeking new horizons.","$38,000 ",True,AstroTrailblazer.png 13,MarsInterceptor,550,5.5,10,8,Automatic,14,"The MarsInterceptor is a futuristic sports car that pushes the boundaries of Martian engineering. Its massive 550 horsepower engine and 5.5-liter cylinder capacity offer unmatched power and performance. The automatic transmission with eight-speed options guarantees lightning-fast gear changes. While fuel efficiency may not be its top priority, the MarsInterceptor still manages a respectable 14 MPG. This car is the epitome of Martian luxury and speed.","$90,000 ",True,MarsInterceptor.png 14,RedPlanetRacer,300,3,6,6,Automatic,18,"The RedPlanetRacer is a sleek and aerodynamic car built for high-speed racing on the Martian tracks. Its 300 horsepower engine and 3.0-liter cylinder capacity deliver adrenaline-fueled performance. The automatic transmission with six-speed options ensures smooth gear changes, allowing for optimal acceleration. With a fuel efficiency of 18 MPG, this car strikes the perfect balance between speed and efficiency. Perfect for Martians with a need for speed.","$50,000 ",False,RedPlanetRacer.png 15,MarsAdventureVan,180,1.8,4,4,Automatic,26,"The MarsAdventureVan is a versatile vehicle designed for Martian explorers who value comfort and practicality. Its 180 horsepower engine and 1.8-liter cylinder capacity provide sufficient power for long journeys. The automatic transmission with four-speed options ensures effortless gear shifts. With a fuel efficiency of 26 MPG, this van offers both comfort and efficiency for extended adventures on Mars.","$42,000 ",False,MarsAdventureVan.png ================================================ FILE: DemoCenter/DemoCenter/DemoData/csv/logarithmic.csv ================================================ Frequency, Left Avg, Test 1, Test 2, Test 3, Test 4, Test 5, Target Response 9.857, 101.33361020408161, 106.22230079608876, 106.01714852573393, 107.14047973658974, 92.45929500276931, 94.82882695922633, 95 10, 101.48741020408161, 106.34070079608877, 106.14614852573392, 107.26407973658975, 92.68669500276935, 94.99942695922631, 95 10.145, 101.68665020408162, 106.4939007960888, 106.3143485257339, 107.42247973658975, 92.97829500276931, 95.22422695922633, 95 10.293, 101.92321020408161, 106.67790079608876, 106.51734852573391, 107.60787973658974, 93.31789500276933, 95.49502695922634, 95 10.443, 102.1703702040816, 106.87010079608878, 106.7313485257339, 107.79627973658974, 93.6678950027693, 95.78622695922634, 95 10.595, 102.42065020408162, 107.0695007960888, 106.95194852573393, 107.98267973658973, 94.00949500276933, 96.08962695922635, 95 10.749, 102.65881020408162, 107.2645007960888, 107.1669485257339, 108.15467973658976, 94.31809500276934, 96.38982695922631, 95 10.905, 102.88501020408162, 107.4565007960888, 107.37534852573391, 108.31347973658974, 94.59389500276934, 96.6858269592263, 95 11.064, 103.09913020408162, 107.64550079608877, 107.57574852573391, 108.45967973658973, 94.83769500276931, 96.97702695922636, 95 11.225, 103.29897020408161, 107.8281007960888, 107.7643485257339, 108.59127973658975, 95.0514950027693, 97.25962695922631, 95 11.388, 103.48489020408162, 108.00210079608878, 107.93874852573391, 108.70867973658973, 95.24189500276931, 97.53302695922635, 95 11.554, 103.65813020408159, 108.16470079608878, 108.09894852573389, 108.81267973658971, 95.41769500276929, 97.79662695922629, 95 11.722, 103.81845020408161, 108.3125007960888, 108.2413485257339, 108.90247973658974, 95.58769500276931, 98.04822695922634, 95 11.892, 103.96777020408163, 108.44290079608881, 108.36634852573393, 108.97867973658977, 95.76329500276934, 98.28762695922633, 95 12.065, 104.10617020408162, 108.5521007960888, 108.4727485257339, 109.04107973658974, 95.95089500276931, 98.51402695922634, 95 12.241, 104.23629020408161, 108.64050079608877, 108.56134852573392, 109.09167973658971, 96.15849500276933, 98.72942695922633, 95 12.419, 104.3588902040816, 108.70710079608877, 108.6337485257339, 109.13107973658974, 96.3870950027693, 98.93542695922635, 95 12.599, 104.47489020408163, 108.75310079608882, 108.69154852573392, 109.16147973658973, 96.63469500276933, 99.13362695922633, 95 12.782, 104.58577020408158, 108.78190079608875, 108.73774852573392, 109.1856797365897, 96.8956950027693, 99.3278269592263, 95 12.968, 104.68981020408164, 108.79450079608883, 108.77234852573393, 109.20307973658974, 97.16009500276932, 99.51902695922634, 95 13.157, 104.78969020408161, 108.79730079608875, 108.8003485257339, 109.21667973658974, 97.42189500276932, 99.71222695922633, 95 13.348, 104.88493020408161, 108.79330079608879, 108.82214852573388, 109.22727973658972, 97.67389500276933, 99.90802695922635, 95 13.543, 104.9773302040816, 108.78770079608877, 108.84094852573388, 109.23547973658971, 97.91309500276931, 100.10942695922633, 95 13.74, 105.06641020408162, 108.78210079608881, 108.85634852573394, 109.24007973658975, 98.13769500276932, 100.31582695922636, 95 13.939, 105.1533702040816, 108.77870079608876, 108.86834852573388, 109.24047973658973, 98.35169500276932, 100.52762695922634, 95 14.142, 105.23805020408163, 108.77710079608882, 108.8759485257339, 109.23587973658975, 98.55909500276933, 100.74222695922636, 95 14.348, 105.31933020408162, 108.7747007960888, 108.8775485257339, 109.22247973658973, 98.76509500276934, 100.95682695922632, 95 14.557, 105.39785020408162, 108.77010079608876, 108.8723485257339, 109.20127973658974, 98.97549500276934, 101.17002695922635, 95 14.768, 105.47221020408162, 108.75970079608881, 108.85834852573389, 109.17027973658973, 99.19329500276935, 101.37942695922631, 95 14.983, 105.54173020408162, 108.74070079608875, 108.8355485257339, 109.13007973658974, 99.4180950027693, 101.58422695922634, 95 15.201, 105.60493020408163, 108.7115007960888, 108.80354852573389, 109.08087973658975, 99.6456950027693, 101.78302695922635, 95 15.422, 105.66005020408161, 108.67010079608879, 108.7621485257339, 109.02307973658971, 99.86889500276932, 101.97602695922633, 95 15.646, 105.70841020408162, 108.6189007960888, 108.71374852573389, 108.96027973658973, 100.0824950027693, 102.16662695922635, 95 15.874, 105.74865020408163, 108.55790079608882, 108.65794852573389, 108.89247973658975, 100.28029500276934, 102.35462695922634, 95 16.105, 105.78249020408161, 108.49010079608878, 108.59634852573389, 108.82147973658972, 100.46269500276931, 102.54182695922636, 95 16.339, 105.81185020408164, 108.41770079608882, 108.52934852573391, 108.74887973658976, 100.63389500276931, 102.72942695922633, 95 16.577, 105.83901020408162, 108.34130079608879, 108.45834852573391, 108.67607973658973, 100.80209500276932, 102.91722695922631, 95 16.818, 105.8660502040816, 108.26250079608879, 108.3825485257339, 108.6016797365897, 100.97789500276936, 103.10562695922631, 95 17.063, 105.89453020408162, 108.18030079608879, 108.30174852573388, 108.52747973658974, 101.16909500276934, 103.29402695922631, 95 17.311, 105.9248502040816, 108.09390079608876, 108.2165485257339, 108.45167973658972, 101.3800950027693, 103.48202695922636, 95 17.563, 105.9560502040816, 108.00190079608878, 108.12614852573391, 108.37447973658972, 101.60889500276933, 103.66882695922631, 95 17.818, 105.98637020408162, 107.90470079608879, 108.03094852573393, 108.29387973658974, 101.8478950027693, 103.85442695922633, 95 18.077, 106.01285020408162, 107.80190079608879, 107.9307485257339, 108.20867973658973, 102.08509500276934, 104.03782695922634, 95 18.34, 106.03349020408162, 107.69550079608878, 107.82574852573394, 108.11747973658971, 102.31089500276933, 104.21782695922634, 95 18.607, 106.0470102040816, 107.58750079608878, 107.71614852573389, 108.01907973658975, 102.51809500276933, 104.39422695922634, 95 18.877, 106.0530902040816, 107.48010079608879, 107.60234852573392, 107.91267973658974, 102.70589500276931, 104.56442695922631, 95 19.152, 106.05361020408164, 107.37550079608879, 107.48614852573392, 107.79767973658976, 102.88069500276931, 104.72802695922634, 95 19.431, 106.05061020408161, 107.27450079608879, 107.36834852573394, 107.67587973658972, 103.05069500276933, 104.88362695922633, 95 19.713, 106.04641020408162, 107.17750079608881, 107.25074852573393, 107.54827973658975, 103.2242950027693, 105.03122695922634, 95 20, 106.04229020408161, 107.08070079608878, 107.13534852573393, 107.41747973658973, 103.40629500276931, 105.17162695922634, 95 20.291, 106.03885020408161, 106.98230079608878, 107.02254852573391, 107.28687973658974, 103.59589500276927, 105.3066269592263, 94.999 20.586, 106.03277020408161, 106.87510079608877, 106.91114852573388, 107.15687973658974, 103.7860950027693, 105.43462695922632, 94.995 20.885, 106.02309020408161, 106.75510079608881, 106.80074852573392, 107.02927973658976, 103.97269500276929, 105.55762695922633, 94.99 21.189, 106.00829020408165, 106.61990079608881, 106.68974852573393, 106.90427973658976, 104.15209500276933, 105.67542695922634, 94.98 21.497, 105.9857702040816, 106.4673007960888, 106.57434852573392, 106.77927973658974, 104.3246950027693, 105.78322695922633, 94.97 21.81, 105.95965020408161, 106.30590079608882, 106.45554852573392, 106.65567973658972, 104.49809500276936, 105.88302695922633, 94.96 22.127, 105.93025020408163, 106.14190079608878, 106.33214852573391, 106.53027973658976, 104.67609500276936, 105.97082695922632, 94.95 22.449, 105.90061020408162, 105.98650079608878, 106.2053485257339, 106.40347973658972, 104.86029500276932, 106.04742695922631, 94.94 22.776, 105.87085020408162, 105.84590079608881, 106.07614852573388, 106.2750797365897, 105.04529500276931, 106.11182695922633, 94.93 23.107, 105.84165020408163, 105.72450079608882, 105.94674852573394, 106.14767973658977, 105.22109500276935, 106.16822695922633, 94.92 23.443, 105.80857020408162, 105.6165007960888, 105.8169485257339, 106.02067973658974, 105.37289500276931, 106.2158269592263, 94.91 23.784, 105.7705302040816, 105.51590079608876, 105.6891485257339, 105.89647973658974, 105.4940950027693, 106.25702695922631, 94.9 24.13, 105.72509020408162, 105.41390079608881, 105.5635485257339, 105.77527973658975, 105.58269500276931, 106.29002695922635, 94.899 24.481, 105.6738102040816, 105.30630079608879, 105.44114852573391, 105.65687973658974, 105.6498950027693, 106.3148269592263, 94.898 24.837, 105.61905020408162, 105.19290079608876, 105.32214852573392, 105.54147973658974, 105.71009500276935, 106.32862695922631, 94.897 25.198, 105.56605020408165, 105.07930079608883, 105.20794852573391, 105.43027973658977, 105.78009500276931, 106.33262695922633, 94.896 25.565, 105.5154902040816, 104.96930079608879, 105.09654852573394, 105.32207973658973, 105.86489500276932, 106.3246269592263, 94.895 25.937, 105.46941020408163, 104.8673007960888, 104.98854852573392, 105.21807973658976, 105.9642950027693, 106.3088269592263, 94.894 26.314, 105.4277302040816, 104.77490079608877, 104.88554852573391, 105.12107973658975, 106.06909500276929, 106.28802695922631, 94.893 26.697, 105.38749020408162, 104.69050079608878, 104.78754852573392, 105.02947973658972, 106.16649500276931, 106.26342695922632, 94.892 27.085, 105.34821020408162, 104.6127007960888, 104.69674852573394, 104.94567973658977, 106.24809500276933, 106.23782695922631, 94.891 27.479, 105.30909020408163, 104.54130079608878, 104.61414852573391, 104.86787973658976, 106.31109500276933, 106.21102695922634, 94.887 27.879, 105.26929020408161, 104.47430079608883, 104.5383485257339, 104.79467973658974, 106.35769500276929, 106.18142695922633, 94.882 28.284, 105.23121020408162, 104.41470079608878, 104.4717485257339, 104.72647973658975, 106.39329500276934, 106.1498269592263, 94.875 28.696, 105.19341020408163, 104.3605007960888, 104.41214852573391, 104.66067973658973, 106.41909500276934, 106.11462695922633, 94.868 29.113, 105.15809020408165, 104.31370079608882, 104.36054852573392, 104.59907973658974, 106.43829500276934, 106.07882695922632, 94.86 29.537, 105.1246502040816, 104.27230079608879, 104.3161485257339, 104.5422797365897, 106.44929500276933, 106.04322695922633, 94.849 29.966, 105.09341020408162, 104.23650079608878, 104.2775485257339, 104.49207973658976, 106.4520950027693, 106.00882695922634, 94.834 30.402, 105.06657020408161, 104.20750079608881, 104.2455485257339, 104.45227973658974, 106.44989500276931, 105.9776269592263, 94.816 30.844, 105.04421020408162, 104.18530079608882, 104.2195485257339, 104.42127973658975, 106.44549500276935, 105.94942695922632, 94.795 31.293, 105.02769020408161, 104.17110079608877, 104.20034852573393, 104.40067973658974, 106.4416950027693, 105.92462695922633, 94.774 31.748, 105.01773020408162, 104.16550079608879, 104.1889485257339, 104.39007973658974, 106.4404950027693, 105.90362695922633, 94.752 32.21, 105.01545020408162, 104.16870079608879, 104.18574852573391, 104.39067973658976, 106.44209500276929, 105.8900269592263, 94.728 32.678, 105.01777020408163, 104.1767007960888, 104.18834852573391, 104.39947973658974, 106.44229500276933, 105.88202695922632, 94.705 33.154, 105.02673020408164, 104.19190079608882, 104.19994852573393, 104.41807973658976, 106.44169500276934, 105.88202695922632, 94.682 33.636, 105.04081020408162, 104.21230079608881, 104.21934852573389, 104.44387973658971, 106.43929500276931, 105.88922695922633, 94.658 34.125, 105.06165020408162, 104.24090079608881, 104.2475485257339, 104.47747973658973, 106.43929500276933, 105.90302695922635, 94.63 34.621, 105.0901302040816, 104.27710079608879, 104.28394852573392, 104.51947973658973, 106.4460950027693, 105.92402695922634, 94.595 35.125, 105.1257302040816, 104.32050079608878, 104.3271485257339, 104.56687973658974, 106.4622950027693, 105.95182695922632, 94.553 35.636, 105.1700102040816, 104.37230079608884, 104.3789485257339, 104.62007973658976, 106.49049500276931, 105.9882269592263, 94.509 36.154, 105.2218102040816, 104.43090079608884, 104.43874852573389, 104.67747973658975, 106.52929500276927, 106.0326269592263, 94.47 36.68, 105.28061020408163, 104.49690079608882, 104.50494852573394, 104.74047973658978, 106.5758950027693, 106.08482695922635, 94.437 37.214, 105.34529020408164, 104.56890079608883, 104.5759485257339, 104.80927973658973, 106.62749500276931, 106.14482695922635, 94.413 37.755, 105.41401020408162, 104.64450079608879, 104.65054852573392, 104.88367973658974, 106.68089500276933, 106.21042695922633, 94.404 38.304, 105.48661020408163, 104.72390079608883, 104.73034852573389, 104.96327973658975, 106.7358950027693, 106.27962695922633, 94.397 38.861, 105.56297020408161, 104.80850079608878, 104.81534852573394, 105.04767973658973, 106.7930950027693, 106.3502269592263, 94.392 39.427, 105.64165020408161, 104.8965007960888, 104.9023485257339, 105.13647973658972, 106.85249500276929, 106.4204269592263, 94.392 40, 105.7224102040816, 104.9879007960888, 104.98994852573391, 105.22907973658972, 106.91509500276929, 106.49002695922631, 94.393 40.582, 105.80353020408161, 105.08050079608878, 105.07794852573389, 105.32207973658973, 106.97829500276933, 106.55882695922631, 94.397 41.172, 105.88453020408163, 105.17330079608882, 105.1663485257339, 105.41567973658974, 107.04049500276932, 106.62682695922632, 94.403 41.771, 105.9648902040816, 105.26670079608878, 105.25474852573392, 105.5108797365897, 107.09989500276929, 106.69222695922632, 94.41 42.379, 106.04353020408162, 105.3585007960888, 105.34174852573389, 105.60687973658975, 107.1556950027693, 106.7548269592263, 94.414 42.995, 106.12025020408161, 105.44850079608882, 105.42674852573391, 105.7026797365897, 107.20849500276934, 106.81482695922632, 94.418 43.62, 106.19281020408161, 105.53370079608881, 105.50894852573391, 105.79427973658973, 107.25749500276932, 106.86962695922632, 94.416 44.255, 106.26117020408162, 105.61490079608878, 105.58914852573393, 105.88107973658977, 107.30369500276932, 106.91702695922636, 94.404 44.898, 106.32517020408162, 105.69210079608882, 105.66514852573391, 105.96307973658972, 107.34769500276934, 106.95782695922631, 94.384 45.552, 106.38441020408163, 105.76550079608879, 105.73514852573393, 106.03967973658973, 107.38889500276932, 106.9928269592263, 94.361 46.214, 106.43685020408161, 105.83110079608878, 105.79774852573394, 106.10907973658973, 107.42449500276933, 107.02182695922633, 94.336 46.886, 106.48149020408161, 105.88730079608882, 105.85274852573389, 106.16987973658976, 107.45289500276931, 107.04462695922632, 94.307 47.568, 106.5180102040816, 105.93430079608882, 105.89934852573387, 106.22247973658972, 107.4740950027693, 107.05982695922631, 94.277 48.26, 106.54629020408163, 105.9737007960888, 105.93634852573392, 106.26627973658977, 107.48729500276933, 107.06782695922637, 94.25 48.962, 106.56661020408164, 106.00530079608882, 105.96474852573391, 106.30187973658977, 107.49249500276932, 107.06862695922632, 94.223 49.674, 106.5758502040816, 106.02510079608878, 105.98254852573392, 106.32507973658973, 107.48689500276929, 107.05962695922629, 94.196 50.397, 106.57625020408162, 106.03510079608883, 105.9923485257339, 106.33907973658974, 107.47309500276928, 107.04162695922632, 94.172 51.13, 106.56713020408161, 106.03610079608882, 105.99254852573392, 106.34327973658972, 107.44989500276932, 107.01382695922632, 94.146 51.874, 106.54861020408161, 106.02770079608878, 105.9821485257339, 106.33827973658974, 107.4178950027693, 106.97702695922631, 94.12 52.628, 106.52169020408162, 106.00970079608882, 105.96294852573394, 106.3244797365897, 107.37749500276934, 106.93382695922628, 94.092 53.394, 106.48501020408162, 105.98110079608881, 105.93434852573392, 106.30007973658977, 107.3274950027693, 106.88202695922632, 94.062 54.17, 106.44093020408161, 105.94410079608882, 105.89874852573392, 106.26747973658975, 107.26929500276928, 106.82502695922629, 94.025 54.958, 106.38949020408162, 105.89990079608879, 105.85554852573392, 106.22687973658972, 107.20289500276931, 106.76222695922633, 93.98 55.758, 106.33125020408161, 105.84950079608879, 105.80574852573389, 106.17827973658973, 107.1280950027693, 106.69462695922633, 93.931 56.569, 106.26649020408163, 105.79150079608883, 105.75114852573392, 106.12227973658972, 107.04569500276932, 106.62182695922633, 93.879 57.391, 106.19577020408163, 105.7271007960888, 105.69054852573394, 106.05967973658973, 106.95629500276932, 106.54522695922635, 93.832 58.226, 106.12017020408163, 105.65830079608884, 105.62454852573393, 105.99127973658975, 106.8618950027693, 106.46482695922631, 93.79 59.073, 106.03833020408163, 105.58330079608879, 105.55234852573392, 105.91627973658976, 106.76129500276932, 106.37842695922632, 93.752 59.932, 105.95273020408163, 105.50390079608883, 105.4765485257339, 105.83667973658973, 106.65709500276932, 106.28942695922632, 93.718 60.804, 105.86309020408162, 105.4197007960888, 105.39574852573391, 105.75327973658973, 106.54949500276932, 106.19722695922631, 93.684 61.688, 105.77093020408161, 105.33230079608877, 105.3115485257339, 105.66787973658974, 106.4402950027693, 106.10262695922633, 93.649 62.586, 105.6752902040816, 105.2411007960888, 105.22354852573392, 105.57807973658973, 106.32889500276929, 106.0048269592263, 93.615 63.496, 105.57885020408162, 105.14890079608877, 105.1345485257339, 105.48647973658974, 106.21849500276933, 105.90582695922633, 93.589 64.42, 105.4819702040816, 105.05650079608881, 105.04414852573393, 105.3940797365897, 106.10889500276932, 105.80622695922631, 93.569 65.357, 105.3858102040816, 104.96390079608878, 104.95394852573392, 105.30267973658971, 106.0012950027693, 105.70722695922632, 93.546 66.307, 105.28901020408162, 104.87090079608882, 104.86194852573388, 105.20927973658974, 105.89489500276935, 105.60802695922632, 93.52 67.272, 105.19497020408161, 104.7809007960888, 104.77274852573392, 105.11807973658973, 105.79249500276931, 105.51062695922631, 93.501 68.25, 105.10125020408161, 104.69210079608881, 104.6839485257339, 105.02667973658974, 105.68969500276931, 105.41382695922628, 93.482 69.243, 105.00985020408162, 104.60530079608881, 104.5969485257339, 104.93787973658971, 105.58949500276933, 105.31962695922635, 93.462 70.25, 104.91941020408163, 104.5189007960888, 104.50974852573391, 104.85107973658974, 105.4904950027693, 105.22682695922633, 93.429 71.272, 104.83181020408162, 104.4351007960888, 104.42594852573392, 104.76667973658972, 105.39389500276933, 105.13742695922632, 93.398 72.309, 104.74729020408161, 104.35430079608876, 104.34634852573389, 104.68447973658972, 105.30009500276931, 105.05122695922633, 93.363 73.36, 104.6647702040816, 104.2761007960888, 104.26794852573389, 104.60447973658972, 105.20809500276934, 104.96722695922634, 93.325 74.427, 104.5844502040816, 104.1995007960888, 104.1917485257339, 104.52727973658973, 105.11789500276929, 104.88582695922629, 93.286 75.51, 104.50741020408164, 104.12590079608881, 104.1193485257339, 104.45307973658976, 105.03149500276933, 104.80722695922628, 93.246 76.608, 104.4336102040816, 104.05590079608879, 104.05034852573391, 104.38167973658975, 104.94809500276932, 104.73202695922632, 93.206 77.723, 104.36197020408163, 103.98870079608878, 103.98414852573393, 104.31127973658974, 104.86689500276935, 104.6588269592263, 93.165 78.853, 104.29317020408162, 103.92470079608877, 103.91894852573391, 104.24487973658974, 104.78889500276934, 104.58842695922631, 93.118 80, 104.22661020408161, 103.86230079608879, 103.8549485257339, 104.18147973658975, 104.71389500276933, 104.52042695922631, 93.064 81.164, 104.1611702040816, 103.80130079608878, 103.79014852573388, 104.11907973658975, 104.64109500276933, 104.45422695922633, 93.008 82.344, 104.0979302040816, 103.74270079608883, 103.72814852573387, 104.05827973658972, 104.57029500276931, 104.39022695922631, 92.95 83.542, 104.03701020408161, 103.68630079608882, 103.66754852573389, 104.00047973658975, 104.50209500276931, 104.32862695922633, 92.892 84.757, 103.97717020408163, 103.6309007960888, 103.60694852573393, 103.94447973658977, 104.43549500276931, 104.2680269592263, 92.832 85.99, 103.9193302040816, 103.57690079608878, 103.54974852573392, 103.89007973658971, 104.37069500276934, 104.2092269592263, 92.765 87.241, 103.86337020408162, 103.5245007960888, 103.4961485257339, 103.83667973658976, 104.3076950027693, 104.15182695922633, 92.686 88.51, 103.8087302040816, 103.47390079608878, 103.4453485257339, 103.78427973658974, 104.24529500276928, 104.09482695922632, 92.588 89.797, 103.75565020408162, 103.42530079608883, 103.39714852573394, 103.73267973658974, 104.18429500276932, 104.0388269592263, 92.49 91.103, 103.70277020408162, 103.37570079608882, 103.34974852573392, 103.68247973658971, 104.12349500276933, 103.98242695922629, 92.388 92.428, 103.65137020408163, 103.32710079608879, 103.30334852573392, 103.63427973658975, 104.06429500276934, 103.92782695922631, 92.289 93.773, 103.59853020408161, 103.2777007960888, 103.25554852573393, 103.58407973658973, 104.00369500276932, 103.87162695922632, 92.188 95.137, 103.54709020408163, 103.22970079608878, 103.20874852573392, 103.53527973658974, 103.94469500276934, 103.81702695922634, 92.089 96.52, 103.4941702040816, 103.18050079608881, 103.15994852573388, 103.48627973658972, 103.88409500276933, 103.76002695922631, 91.991 97.924, 103.44205020408162, 103.13150079608882, 103.11114852573387, 103.43867973658975, 103.82469500276933, 103.70422695922635, 91.892 99.349, 103.38857020408163, 103.08150079608882, 103.0611485257339, 103.38947973658975, 103.76349500276936, 103.64722695922632, 91.806 100.794, 103.33585020408161, 103.03290079608878, 103.01254852573389, 103.34087973658974, 103.70289500276932, 103.59002695922631, 91.733 102.26, 103.2834102040816, 102.98510079608882, 102.9633485257339, 103.29287973658974, 103.6428950027693, 103.53282695922631, 91.662 103.747, 103.2287302040816, 102.9349007960888, 102.91154852573389, 103.24267973658972, 103.58109500276929, 103.47342695922633, 91.59 105.256, 103.1715702040816, 102.88170079608878, 102.8575485257339, 103.19027973658973, 103.5166950027693, 103.41162695922631, 91.515 106.787, 103.1130502040816, 102.8279007960888, 102.80174852573388, 103.13627973658977, 103.45109500276932, 103.3482269592263, 91.44 108.34, 103.05165020408162, 102.77110079608882, 102.74434852573391, 103.07907973658975, 103.38189500276933, 103.28182695922634, 91.364 109.916, 102.98765020408162, 102.71290079608877, 102.68414852573392, 103.01907973658976, 103.31009500276929, 103.2120269592263, 91.288 111.515, 102.91981020408161, 102.6503007960888, 102.62074852573392, 102.95527973658974, 103.23409500276932, 103.13862695922631, 91.216 113.137, 102.84777020408163, 102.58330079608879, 102.55314852573395, 102.88787973658972, 103.15329500276931, 103.06122695922633, 91.146 114.783, 102.7716902040816, 102.51290079608877, 102.48154852573391, 102.81607973658971, 103.06849500276932, 102.9794269592263, 91.078 116.452, 102.6910502040816, 102.43770079608878, 102.40574852573393, 102.73927973658972, 102.97969500276928, 102.89282695922633, 91.006 118.146, 102.60561020408161, 102.35790079608877, 102.32474852573391, 102.65867973658972, 102.88589500276932, 102.80082695922631, 90.923 119.865, 102.51369020408163, 102.2719007960888, 102.2365485257339, 102.57167973658974, 102.78589500276934, 102.70242695922633, 90.836 121.608, 102.41721020408161, 102.1819007960888, 102.14374852573391, 102.47987973658974, 102.6810950027693, 102.59942695922632, 90.736 123.377, 102.31485020408164, 102.08670079608882, 102.04434852573391, 102.38207973658973, 102.57129500276935, 102.48982695922632, 90.635 125.171, 102.20625020408161, 101.98430079608879, 101.93974852573392, 102.27827973658974, 102.4546950027693, 102.37422695922633, 90.535 126.992, 102.0896902040816, 101.8727007960888, 101.82874852573389, 102.16667973658971, 102.32969500276931, 102.25062695922634, 90.432 128.839, 101.96589020408163, 101.75250079608884, 101.7111485257339, 102.04827973658976, 102.1972950027693, 102.12022695922633, 90.331 130.713, 101.83425020408163, 101.62370079608883, 101.5859485257339, 101.92267973658974, 102.05669500276935, 101.98222695922632, 90.235 132.615, 101.69461020408161, 101.48610079608882, 101.45334852573392, 101.78907973658973, 101.90789500276931, 101.83662695922631, 90.144 134.543, 101.54781020408163, 101.34210079608879, 101.31294852573392, 101.64787973658976, 101.75169500276932, 101.68442695922634, 90.059 136.5, 101.39209020408161, 101.19010079608877, 101.1633485257339, 101.49747973658977, 101.58649500276933, 101.52302695922636, 89.976 138.486, 101.22953020408161, 101.03230079608879, 101.00634852573391, 101.33947973658972, 101.41469500276928, 101.35482695922632, 89.905 140.5, 101.05881020408161, 100.8667007960888, 100.84074852573391, 101.17327973658973, 101.23529500276933, 101.17802695922632, 89.849 142.544, 100.88009020408161, 100.69210079608882, 100.66674852573391, 100.99907973658972, 101.04889500276931, 100.99362695922633, 89.8 144.617, 100.6926102040816, 100.50830079608879, 100.4845485257339, 100.81527973658974, 100.85429500276932, 100.80062695922628, 89.744 146.721, 100.49773020408163, 100.31670079608884, 100.29474852573392, 100.62347973658973, 100.65289500276933, 100.60082695922631, 89.676 148.855, 100.29409020408161, 100.11630079608881, 100.09594852573389, 100.42247973658974, 100.44289500276932, 100.39282695922634, 89.61 151.02, 100.08189020408162, 99.90710079608881, 99.8877485257339, 100.21287973658973, 100.22469500276931, 100.17702695922635, 89.548 153.217, 99.85993020408162, 99.68790079608878, 99.66894852573391, 99.99407973658974, 99.99669500276933, 99.9520269592263, 89.487 155.445, 99.6298502040816, 99.46070079608877, 99.44234852573389, 99.76727973658974, 99.7604950027693, 99.71842695922636, 89.428 157.706, 99.3919702040816, 99.22570079608877, 99.20814852573389, 99.53307973658974, 99.51609500276933, 99.47682695922632, 89.373 160, 99.1454102040816, 98.98130079608877, 98.96534852573392, 99.29067973658972, 99.26349500276929, 99.22622695922634, 89.322 162.327, 98.89069020408161, 98.72850079608882, 98.71434852573388, 99.0400797365897, 99.0028950027693, 98.96762695922631, 89.273 164.688, 98.6272502040816, 98.46650079608881, 98.45374852573391, 98.78047973658971, 98.73509500276933, 98.70042695922632, 89.224 167.084, 98.35705020408162, 98.1977007960888, 98.18714852573389, 98.51227973658975, 98.46109500276931, 98.42702695922635, 89.18 169.514, 98.07993020408162, 97.92270079608878, 97.9139485257339, 98.23607973658972, 98.18089500276935, 98.14602695922633, 89.14 171.98, 97.79641020408164, 97.6409007960888, 97.63334852573391, 97.95427973658974, 97.89489500276935, 97.85862695922634, 89.104 174.481, 97.50849020408164, 97.35370079608884, 97.34734852573393, 97.66907973658974, 97.6048950027693, 97.56742695922634, 89.067 177.019, 97.21661020408162, 97.0631007960888, 97.0567485257339, 97.37967973658974, 97.31169500276934, 97.2718269592263, 89.028 179.594, 96.92153020408162, 96.76950079608883, 96.76374852573389, 97.08667973658979, 97.01509500276933, 96.97262695922632, 88.997 182.206, 96.6243302040816, 96.47390079608877, 96.46914852573391, 96.79087973658972, 96.71649500276934, 96.67122695922632, 88.972 184.856, 96.3254902040816, 96.1759007960888, 96.1717485257339, 96.49407973658973, 96.4164950027693, 96.36922695922632, 88.949 187.545, 96.0270102040816, 95.8781007960888, 95.8737485257339, 96.19807973658973, 96.11729500276931, 96.06782695922632, 88.92 190.273, 95.73185020408161, 95.58390079608878, 95.57974852573389, 95.90367973658977, 95.8216950027693, 95.7702269592263, 88.89 193.041, 95.4410902040816, 95.29470079608878, 95.2903485257339, 95.61307973658974, 95.53009500276933, 95.47722695922631, 88.863 195.849, 95.1592102040816, 95.0149007960888, 95.01014852573388, 95.33167973658973, 95.2470950027693, 95.19222695922633, 88.836 198.697, 94.88737020408162, 94.74530079608878, 94.73974852573393, 95.06167973658974, 94.97349500276933, 94.91662695922635, 88.815 201.587, 94.6282102040816, 94.48950079608878, 94.48314852573392, 94.80487973658973, 94.7118950027693, 94.65162695922632, 88.796 204.52, 94.38485020408162, 94.25130079608881, 94.2439485257339, 94.56387973658975, 94.4658950027693, 94.39922695922634, 88.779 207.494, 94.15685020408162, 94.02810079608884, 94.0207485257339, 94.33927973658976, 94.2352950027693, 94.16082695922631, 88.771 210.512, 93.9440902040816, 93.8193007960888, 93.81214852573389, 94.13247973658976, 94.0204950027693, 93.93602695922631, 88.762 213.574, 93.74609020408163, 93.62410079608881, 93.61794852573391, 93.94087973658975, 93.82149500276935, 93.72602695922632, 88.753 216.681, 93.56469020408163, 93.44410079608878, 93.43974852573393, 93.76547973658975, 93.64049500276934, 93.53362695922632, 88.754 219.833, 93.39893020408162, 93.27870079608881, 93.2763485257339, 93.60547973658977, 93.47529500276933, 93.35882695922636, 88.762 223.03, 93.24869020408161, 93.1279007960888, 93.12674852573394, 93.46047973658975, 93.32689500276933, 93.20142695922632, 88.771 226.274, 93.11405020408162, 92.99170079608882, 92.9919485257339, 93.33027973658974, 93.19429500276931, 93.06202695922633, 88.79 229.565, 92.99705020408162, 92.87330079608878, 92.8747485257339, 93.21687973658976, 93.07809500276935, 92.94222695922633, 88.813 232.905, 92.89613020408163, 92.77170079608878, 92.77394852573393, 93.11827973658974, 92.97729500276931, 92.83942695922632, 88.838 236.292, 92.81181020408162, 92.68710079608881, 92.69034852573391, 93.03587973658973, 92.89209500276932, 92.75362695922631, 88.869 239.729, 92.7438102040816, 92.6189007960888, 92.6225485257339, 92.97047973658972, 92.82289500276933, 92.68422695922631, 88.906 243.216, 92.69169020408161, 92.56790079608878, 92.57134852573391, 92.92047973658971, 92.76869500276932, 92.6300269592263, 88.941 246.754, 92.65393020408162, 92.53170079608881, 92.53474852573387, 92.88507973658972, 92.72829500276933, 92.58982695922631, 88.967 250.343, 92.63077020408161, 92.51070079608878, 92.51394852573394, 92.86467973658974, 92.70109500276932, 92.56342695922633, 88.988 253.984, 92.62097020408164, 92.50370079608882, 92.50694852573395, 92.85807973658976, 92.6870950027693, 92.54902695922635, 89.004 257.678, 92.62181020408163, 92.50750079608882, 92.51094852573392, 92.86227973658971, 92.6824950027693, 92.54582695922635, 89.013 261.426, 92.63169020408161, 92.52010079608877, 92.52414852573392, 92.8758797365897, 92.68689500276932, 92.55142695922632, 89.02 265.229, 92.64925020408161, 92.5405007960888, 92.54574852573391, 92.89687973658972, 92.6986950027693, 92.56442695922637, 89.029 269.087, 92.67197020408162, 92.5657007960888, 92.57274852573389, 92.92347973658974, 92.71569500276931, 92.58222695922632, 89.046 273.001, 92.69909020408161, 92.59570079608879, 92.60334852573389, 92.95467973658974, 92.7372950027693, 92.6044269592263, 89.071 276.972, 92.7289302040816, 92.62870079608878, 92.63574852573392, 92.98867973658976, 92.7620950027693, 92.62942695922631, 89.096 281, 92.7616902040816, 92.66450079608877, 92.6713485257339, 93.02527973658972, 92.79009500276932, 92.65722695922632, 89.12 285.088, 92.79489020408163, 92.7005007960888, 92.70834852573391, 93.06187973658974, 92.81809500276931, 92.68562695922633, 89.136 289.234, 92.82837020408161, 92.73710079608878, 92.7451485257339, 93.09847973658978, 92.84689500276932, 92.71422695922632, 89.153 293.441, 92.86073020408165, 92.77290079608883, 92.78054852573393, 93.13467973658973, 92.87469500276933, 92.74082695922633, 89.17 297.709, 92.89265020408163, 92.8083007960888, 92.81534852573394, 93.17007973658976, 92.90289500276928, 92.76662695922634, 89.186 302.04, 92.92253020408164, 92.84150079608882, 92.84754852573393, 93.20347973658973, 92.92989500276933, 92.79022695922633, 89.201 306.433, 92.95073020408162, 92.87290079608881, 92.8775485257339, 93.23547973658977, 92.95629500276932, 92.81142695922632, 89.221 310.89, 92.97869020408162, 92.90330079608881, 92.90614852573387, 93.26687973658971, 92.98349500276933, 92.83362695922631, 89.241 315.412, 93.00629020408161, 92.93210079608883, 92.93454852573387, 93.29787973658975, 93.01129500276932, 92.8556269592263, 89.252 320, 93.03389020408162, 92.96070079608879, 92.96334852573389, 93.32807973658976, 93.0390950027693, 92.87822695922631, 89.26 324.655, 93.06233020408162, 92.98890079608883, 92.9939485257339, 93.35887973658974, 93.06709500276928, 92.90282695922632, 89.268 329.377, 93.09037020408161, 93.0165007960888, 93.02394852573393, 93.38987973658972, 93.09369500276934, 92.92782695922632, 89.281 334.168, 93.11949020408161, 93.0455007960888, 93.0557485257339, 93.42227973658972, 93.11989500276935, 92.95402695922634, 89.298 339.028, 93.14845020408161, 93.0753007960888, 93.08794852573392, 93.45507973658972, 93.14449500276929, 92.9794269592263, 89.316 343.959, 93.17721020408162, 93.10510079608882, 93.1207485257339, 93.48867973658973, 93.16729500276931, 93.00422695922633, 89.333 348.962, 93.20569020408162, 93.13670079608879, 93.1533485257339, 93.52287973658976, 93.18789500276931, 93.02762695922631, 89.35 354.038, 93.2330902040816, 93.16810079608878, 93.1865485257339, 93.55707973658973, 93.20649500276933, 93.04722695922631, 89.37 359.188, 93.26330573979592, 93.19675793894595, 93.21850254359106, 93.5892493794469, 93.23392714562647, 93.07809169136917, 89.389 364.412, 93.29858127551019, 93.23069008180306, 93.25528156144821, 93.62779402230402, 93.26690928848359, 93.11223142351201, 89.42 369.713, 93.34119181122449, 93.27149722466024, 93.29863557930534, 93.67516366516116, 93.30872893134077, 93.15193365565491, 89.45 375.09, 93.39212234693875, 93.31877936751738, 93.3491145971625, 93.73325830801829, 93.36022357419785, 93.19923588779773, 89.48 380.546, 93.45342538265305, 93.37431151037454, 93.40928111501962, 93.80240295087548, 93.42430571705502, 93.25682561994061, 89.517 386.081, 93.52753341836734, 93.43916865323168, 93.48027263287678, 93.88572259373261, 93.50408785991216, 93.32841535208347, 89.553 391.697, 93.61610395408164, 93.51471329608881, 93.56361415073394, 93.98376723658973, 93.60223250276931, 93.41619258422634, 89.593 397.394, 93.7204144897959, 93.60065793894596, 93.65758066859105, 94.09863687944689, 93.72285214562645, 93.52234481636917, 89.638 403.175, 93.84280502551016, 93.70161508180306, 93.7643221864482, 94.23089402230403, 93.86830928848357, 93.64888454851203, 89.688 409.039, 93.98423056122446, 93.81807222466026, 93.88276370430535, 94.38002616516115, 94.04239143134075, 93.79789928065489, 89.736 414.989, 94.14673609693875, 93.95382936751737, 94.01423022216248, 94.5483833080183, 94.24643607419792, 93.97080151279773, 89.781 421.025, 94.33210663265307, 94.11353651037454, 94.16089674001962, 94.73401545087545, 94.48108071705506, 94.17100374494062, 89.826 427.149, 94.54203466836734, 94.30196865323168, 94.32346325787677, 94.9387975937326, 94.7458628599122, 94.40008097708346, 89.871 433.362, 94.77596770408162, 94.51887579608884, 94.5021547757339, 95.16045473658976, 95.04102000276932, 94.65733320922631, 89.916 439.665, 95.0308982397959, 94.75852043894595, 94.69153379359106, 95.39799937944689, 95.36511464562649, 94.94132294136917, 89.957 446.06, 95.3003387755102, 95.01661508180308, 94.8848128114482, 95.64579402230405, 95.7114092884836, 95.24306267351204, 89.997 452.548, 95.5101387755102, 95.25161508180307, 95.0528128114482, 95.86379402230403, 95.9454092884836, 95.43706267351203, 90.034 459.131, 95.7033387755102, 95.48361508180312, 95.1998128114482, 96.06879402230405, 96.15940928848363, 95.60506267351204, 90.069 465.809, 95.86453877551018, 95.70161508180307, 95.31281281144821, 96.24279402230401, 96.3334092884836, 95.73206267351203, 90.102 472.584, 95.97733877551019, 95.89361508180308, 95.3758128114482, 96.36979402230402, 96.44440928848358, 95.80306267351203, 90.131 479.458, 96.02573877551019, 96.04861508180309, 95.37581281144818, 96.42879402230403, 96.47140928848361, 95.80406267351205, 90.157 486.432, 95.9955387755102, 96.14861508180307, 95.30181281144819, 96.40479402230405, 96.39840928848359, 95.72406267351202, 90.179 493.507, 95.8773387755102, 96.17961508180309, 95.14381281144819, 96.28679402230404, 96.2184092884836, 95.55806267351204, 90.204 500.686, 95.66933877551018, 96.12961508180308, 94.9018128114482, 96.07279402230401, 95.93640928848362, 95.30606267351203, 90.23 507.968, 95.37793877551019, 95.9956150818031, 94.5818128114482, 95.76979402230404, 95.56540928848361, 94.97706267351205, 90.258 515.357, 95.0185387755102, 95.78461508180311, 94.20181281144818, 95.39179402230403, 95.12540928848364, 94.58906267351205, 90.29 522.853, 94.61093877551019, 95.50961508180309, 93.78481281144822, 94.95679402230404, 94.64040928848364, 94.16306267351202, 90.327 530.458, 94.1769387755102, 95.1866150818031, 93.35681281144821, 94.48779402230403, 94.1344092884836, 93.71906267351204, 90.367 538.174, 93.73753877551017, 94.83461508180308, 92.93281281144819, 94.01279402230402, 93.62940928848361, 93.27806267351203, 90.404 546.002, 93.30873877551018, 94.46961508180307, 92.5298128114482, 93.54979402230403, 93.14140928848362, 92.85306267351201, 90.445 553.943, 92.9015387755102, 94.10661508180307, 92.1568128114482, 93.11079402230403, 92.68140928848364, 92.45206267351203, 90.488 562.001, 92.52433877551019, 93.75461508180307, 91.8178128114482, 92.70579402230403, 92.2634092884836, 92.08006267351202, 90.535 570.175, 92.1869387755102, 93.4216150818031, 91.52281281144819, 92.34679402230402, 91.89640928848364, 91.74706267351205, 90.595 578.469, 91.8969387755102, 93.11861508180311, 91.2828128114482, 92.03779402230404, 91.58540928848362, 91.46006267351203, 90.665 586.883, 91.66133877551019, 92.85461508180309, 91.10481281144818, 91.78679402230405, 91.3354092884836, 91.22506267351203, 90.737 595.419, 91.4837387755102, 92.6406150818031, 90.99381281144821, 91.59579402230403, 91.14440928848359, 91.04406267351203, 90.819 604.08, 91.3637387755102, 92.48161508180311, 90.9458128114482, 91.46379402230403, 91.00840928848362, 90.91906267351203, 90.908 612.866, 91.29573877551017, 92.37661508180307, 90.94881281144819, 91.38779402230404, 90.9214092884836, 90.84406267351201, 90.986 621.78, 91.27153877551021, 92.32161508180309, 90.98881281144821, 91.35879402230401, 90.87540928848364, 90.81306267351204, 91.026 630.824, 91.27953877551018, 92.30861508180308, 91.05381281144818, 91.36279402230403, 90.85740928848364, 90.81506267351202, 91.061 640, 91.30913877551019, 92.32261508180308, 91.1328128114482, 91.38879402230403, 90.86440928848363, 90.83706267351205, 91.118 649.309, 91.35393877551019, 92.35161508180312, 91.22081281144818, 91.43079402230401, 90.88940928848359, 90.87706267351203, 91.175 658.753, 91.4081387755102, 92.38461508180309, 91.31881281144821, 91.48179402230402, 90.92740928848362, 90.92806267351203, 91.233 668.335, 91.4675387755102, 92.4126150818031, 91.4278128114482, 91.53979402230405, 90.97240928848362, 90.98506267351203, 91.278 678.056, 91.52893877551021, 92.43161508180309, 91.5488128114482, 91.59979402230404, 91.02140928848364, 91.04306267351204, 91.316 687.919, 91.5851387755102, 92.43461508180312, 91.6778128114482, 91.65579402230404, 91.0634092884836, 91.09406267351201, 91.349 697.925, 91.62973877551019, 92.42161508180308, 91.80881281144818, 91.69879402230401, 91.08940928848361, 91.13006267351201, 91.373 708.077, 91.65753877551019, 92.39561508180311, 91.93781281144818, 91.72279402230403, 91.0914092884836, 91.14006267351205, 91.382 718.376, 91.66273877551018, 92.35861508180308, 92.05881281144819, 91.71579402230402, 91.06140928848363, 91.11906267351203, 91.38 728.825, 91.6411387755102, 92.31261508180312, 92.1618128114482, 91.67379402230405, 90.9944092884836, 91.06306267351202, 91.364 739.426, 91.5923387755102, 92.25461508180307, 92.2388128114482, 91.59779402230403, 90.89440928848363, 90.97606267351203, 91.34 750.181, 91.51913877551019, 92.17861508180309, 92.28781281144822, 91.49079402230404, 90.7674092884836, 90.87106267351203, 91.313 761.093, 91.42593877551018, 92.07961508180308, 92.30681281144821, 91.36179402230401, 90.62240928848361, 90.75906267351202, 91.286 772.163, 91.3211387755102, 91.96461508180309, 92.3008128114482, 91.22079402230403, 90.47040928848364, 90.64906267351202, 91.26 783.394, 91.21013877551019, 91.84061508180311, 92.27781281144821, 91.07279402230402, 90.3174092884836, 90.54206267351204, 91.231 794.789, 91.0947387755102, 91.7136150818031, 92.2378128114482, 90.92279402230405, 90.16440928848364, 90.43506267351204, 91.197 806.349, 90.9739387755102, 91.58661508180312, 92.18281281144822, 90.76879402230402, 90.0134092884836, 90.31806267351202, 91.155 818.078, 90.8423387755102, 91.45661508180312, 92.1078128114482, 90.60379402230403, 89.8594092884836, 90.18406267351203, 91.1 829.977, 90.69333877551018, 91.30861508180311, 92.01381281144819, 90.42579402230402, 89.69340928848362, 90.02506267351202, 91.033 842.05, 90.53373877551019, 91.13761508180309, 91.9158128114482, 90.25179402230401, 89.51940928848362, 89.84406267351201, 90.96 854.298, 90.38693877551017, 90.97961508180308, 91.82081281144818, 90.10779402230403, 89.35740928848364, 89.66906267351203, 90.883 866.724, 90.2775387755102, 90.86161508180312, 91.7378128114482, 90.01379402230403, 89.23740928848362, 89.53706267351204, 90.803 879.33, 90.2187387755102, 90.80161508180308, 91.6718128114482, 89.97879402230404, 89.1764092884836, 89.46506267351205, 90.722 892.12, 90.21373877551018, 90.8056150818031, 91.62481281144821, 90.00279402230404, 89.1764092884836, 89.45906267351202, 90.647 905.097, 90.24733877551019, 90.8556150818031, 91.58181281144819, 90.07079402230401, 89.2284092884836, 89.50006267351203, 90.577 918.262, 90.28913877551018, 90.91561508180308, 91.51781281144821, 90.15179402230402, 89.30640928848362, 89.55406267351202, 90.509 931.618, 90.3097387755102, 90.94761508180312, 91.4158128114482, 90.20979402230401, 89.3794092884836, 89.59606267351205, 90.444 945.169, 90.2867387755102, 90.9236150818031, 91.27681281144821, 90.22179402230402, 89.41140928848363, 89.60006267351203, 90.393 958.917, 90.21693877551019, 90.8386150818031, 91.1248128114482, 90.19079402230402, 89.3874092884836, 89.54306267351204, 90.356 972.864, 90.1315387755102, 90.7396150818031, 90.9928128114482, 90.14479402230401, 89.32940928848359, 89.45106267351204, 90.341 987.015, 90.05453877551018, 90.6526150818031, 90.90081281144819, 90.10279402230404, 89.2594092884836, 89.35706267351202, 90.341 1001.371, 90.00873877551018, 90.59161508180307, 90.88081281144821, 90.08979402230403, 89.1994092884836, 89.28206267351203, 90.343 1015.937, 90.0165387755102, 90.56361508180312, 90.9598128114482, 90.13379402230403, 89.17040928848361, 89.25506267351203, 90.351 1030.714, 90.08953877551019, 90.57461508180309, 91.1438128114482, 90.24079402230403, 89.1904092884836, 89.29806267351204, 90.37 1045.706, 90.2263387755102, 90.63761508180309, 91.3978128114482, 90.39879402230403, 89.27540928848359, 89.42206267351204, 90.395 1060.916, 90.4091387755102, 90.75661508180309, 91.6758128114482, 90.58379402230403, 89.41240928848362, 89.61706267351204, 90.437 1076.347, 90.6025387755102, 90.9196150818031, 91.92481281144819, 90.75679402230404, 89.5624092884836, 89.84906267351204, 90.502 1092.003, 90.76813877551021, 91.1016150818031, 92.10481281144818, 90.88879402230403, 89.68740928848364, 90.05806267351203, 90.583 1107.887, 90.88093877551019, 91.26761508180309, 92.19781281144819, 90.96679402230404, 89.76440928848362, 90.20806267351205, 90.681 1124.001, 90.93253877551017, 91.38861508180307, 92.22181281144819, 90.98879402230403, 89.78240928848359, 90.28106267351203, 90.794 1140.35, 90.95533877551019, 91.47361508180309, 92.2448128114482, 90.98879402230402, 89.76640928848362, 90.30306267351203, 90.916 1156.937, 91.03253877551019, 91.5876150818031, 92.38481281144821, 91.05079402230403, 89.79540928848358, 90.34406267351203, 91.049 1173.765, 91.2623387755102, 91.81961508180312, 92.7498128114482, 91.26279402230405, 89.9704092884836, 90.50906267351205, 91.191 1190.838, 91.6813387755102, 92.20161508180311, 93.36281281144821, 91.66079402230403, 90.32940928848362, 90.85206267351205, 91.373 1208.159, 92.2447387755102, 92.70761508180308, 94.15681281144819, 92.20279402230403, 90.8254092884836, 91.33106267351204, 91.561 1225.732, 92.85153877551019, 93.2496150818031, 94.99881281144822, 92.79979402230403, 91.35740928848362, 91.85206267351204, 91.731 1243.561, 93.37873877551019, 93.70961508180308, 95.73681281144822, 93.33779402230401, 91.80840928848359, 92.30106267351205, 91.904 1261.649, 93.7243387755102, 93.98661508180308, 96.24981281144821, 93.71979402230403, 92.08440928848361, 92.58106267351204, 92.087 1280, 93.8449387755102, 94.04461508180312, 96.48581281144818, 93.90579402230405, 92.14040928848364, 92.64806267351203, 92.279 1298.618, 93.76153877551019, 93.91461508180309, 96.47481281144819, 93.90579402230402, 91.9944092884836, 92.51806267351203, 92.482 1317.507, 93.5521387755102, 93.68361508180307, 96.3118128114482, 93.78079402230405, 91.72240928848363, 92.26206267351203, 92.69 1336.67, 93.3225387755102, 93.45461508180311, 96.11681281144818, 93.62779402230403, 91.43240928848358, 91.98106267351203, 92.881 1356.113, 93.1393387755102, 93.28061508180308, 95.96881281144822, 93.50979402230404, 91.1914092884836, 91.74606267351201, 93.042 1375.838, 93.0209387755102, 93.1736150818031, 95.8938128114482, 93.44279402230403, 91.01940928848363, 91.57506267351202, 93.191 1395.85, 92.9639387755102, 93.12961508180311, 95.88281281144819, 93.42779402230403, 90.91840928848362, 91.46106267351203, 93.347 1416.153, 92.96113877551018, 93.14061508180312, 95.91381281144818, 93.46479402230402, 90.88540928848359, 91.40106267351202, 93.488 1436.751, 93.00113877551021, 93.20061508180311, 95.9628128114482, 93.55179402230405, 90.90740928848362, 91.38306267351203, 93.615 1457.649, 93.0767387755102, 93.30761508180308, 96.0168128114482, 93.69179402230404, 90.97040928848361, 91.39706267351204, 93.718 1478.851, 93.18393877551019, 93.45861508180312, 96.07981281144819, 93.87679402230401, 91.06540928848361, 91.43906267351204, 93.789 1500.362, 93.3207387755102, 93.6466150818031, 96.16181281144819, 94.09679402230404, 91.18440928848364, 91.51406267351203, 93.835 1522.185, 93.49153877551021, 93.86961508180312, 96.2728128114482, 94.34479402230403, 91.3324092884836, 91.63806267351205, 93.866 1544.326, 93.7045387755102, 94.1286150818031, 96.41881281144822, 94.61679402230405, 91.53240928848362, 91.82606267351204, 93.891 1566.789, 93.93213877551018, 94.38661508180309, 96.55581281144822, 94.88279402230401, 91.7854092884836, 92.05006267351203, 93.92 1589.578, 94.11433877551019, 94.5846150818031, 96.60281281144822, 95.09879402230405, 92.0344092884836, 92.25106267351205, 93.955 1612.699, 94.2571387755102, 94.73061508180311, 96.55881281144818, 95.26579402230402, 92.27840928848363, 92.45206267351202, 93.996 1636.156, 94.3641387755102, 94.83261508180308, 96.42881281144818, 95.37879402230402, 92.5224092884836, 92.65806267351203, 94.07300000000001 1659.955, 94.46033877551021, 94.92161508180311, 96.24581281144822, 95.46079402230404, 92.78840928848359, 92.88506267351204, 94.182 1684.099, 94.58193877551018, 95.03761508180307, 96.0698128114482, 95.54379402230404, 93.10240928848359, 93.15606267351203, 94.313 1708.595, 94.76353877551018, 95.21161508180307, 95.9558128114482, 95.65879402230402, 93.49640928848362, 93.49506267351205, 94.449 1733.447, 95.0177387755102, 95.44861508180311, 95.9248128114482, 95.81979402230404, 93.98140928848359, 93.91406267351205, 94.594 1758.661, 95.35273877551019, 95.7516150818031, 95.98781281144818, 96.03679402230404, 94.57140928848361, 94.41606267351204, 94.766 1784.241, 95.7245387755102, 96.05961508180312, 96.08881281144821, 96.27379402230403, 95.23740928848363, 94.96306267351204, 94.962 1810.193, 96.07413877551019, 96.31761508180307, 96.15581281144819, 96.48779402230403, 95.90740928848362, 95.50206267351203, 95.17 1836.523, 96.39933877551019, 96.52461508180309, 96.19081281144818, 96.67479402230401, 96.56540928848361, 96.04106267351202, 95.383 1863.236, 96.7111387755102, 96.70061508180311, 96.20881281144818, 96.83879402230403, 97.2254092884836, 96.58206267351204, 95.593 1890.337, 97.02573877551019, 96.87061508180311, 96.23481281144818, 96.99779402230403, 97.9004092884836, 97.12506267351203, 95.797 1917.833, 97.3505387755102, 97.04861508180312, 96.28781281144819, 97.16679402230403, 98.58740928848363, 97.66206267351203, 95.997 1945.729, 97.6919387755102, 97.24761508180308, 96.38081281144821, 97.35779402230403, 99.28240928848362, 98.19106267351202, 96.199 1974.03, 98.04933877551021, 97.46461508180312, 96.5208128114482, 97.57279402230401, 99.97040928848361, 98.71806267351204, 96.408 2002.743, 98.41373877551021, 97.6886150818031, 96.7058128114482, 97.80179402230405, 100.63140928848361, 99.24106267351203, 96.581 2031.873, 98.77093877551019, 97.91161508180309, 96.9258128114482, 98.02879402230403, 101.23440928848359, 99.75406267351204, 96.722 2061.428, 99.1077387755102, 98.12661508180308, 97.1688128114482, 98.23879402230405, 101.7514092884836, 100.25306267351202, 96.84 2091.412, 99.4123387755102, 98.33361508180309, 97.4098128114482, 98.42379402230404, 102.17340928848358, 100.72106267351205, 96.961 2121.832, 99.6775387755102, 98.52961508180309, 97.6298128114482, 98.57779402230403, 102.50640928848364, 101.14406267351202, 97.099 2152.695, 99.9025387755102, 98.71361508180307, 97.81481281144819, 98.70479402230403, 102.76040928848361, 101.51906267351204, 97.256 2184.006, 100.09253877551019, 98.8876150818031, 97.95581281144818, 98.80979402230402, 102.9534092884836, 101.85606267351203, 97.345 2215.774, 100.25613877551021, 99.05461508180309, 98.0528128114482, 98.90679402230401, 103.10140928848364, 102.16506267351204, 97.43 2248.003, 100.4033387755102, 99.22061508180307, 98.11581281144821, 98.99879402230404, 103.22340928848364, 102.45806267351203, 97.607 2280.701, 100.5433387755102, 99.39361508180308, 98.1568128114482, 99.09179402230403, 103.3284092884836, 102.74606267351201, 97.85 2313.874, 100.68393877551019, 99.5796150818031, 98.19181281144822, 99.18679402230401, 103.4264092884836, 103.03506267351204, 98.109 2347.53, 100.83113877551018, 99.78461508180308, 98.23281281144821, 99.28779402230401, 103.52140928848362, 103.32906267351203, 98.354 2381.676, 100.9851387755102, 100.00561508180311, 98.27981281144821, 99.39879402230403, 103.61640928848362, 103.62506267351205, 98.564 2416.318, 101.14773877551019, 100.2396150818031, 98.32881281144819, 99.52779402230405, 103.7184092884836, 103.92406267351203, 98.735 2451.464, 101.3199387755102, 100.48761508180309, 98.3778128114482, 99.68479402230403, 103.82740928848364, 104.22206267351203, 98.865 2487.122, 101.4957387755102, 100.74561508180312, 98.41781281144819, 99.87079402230401, 103.93540928848358, 104.50906267351203, 98.966 2523.298, 101.66013877551019, 100.99861508180312, 98.4348128114482, 100.08179402230404, 104.0244092884836, 104.76106267351203, 99.036 2560, 101.79713877551018, 101.23361508180308, 98.4168128114482, 100.30479402230402, 104.0774092884836, 104.95306267351204, 99.149 2597.236, 101.89673877551017, 101.43761508180307, 98.3668128114482, 100.52679402230402, 104.08440928848358, 105.06806267351203, 99.3 2635.014, 101.9519387755102, 101.59261508180309, 98.29681281144819, 100.73179402230404, 104.04340928848363, 105.09506267351203, 99.489 2673.341, 101.94733877551019, 101.67561508180312, 98.1978128114482, 100.89179402230401, 103.9414092884836, 105.03006267351203, 99.684 2712.226, 101.88813877551019, 101.7016150818031, 98.06781281144818, 101.00179402230403, 103.77940928848359, 104.89006267351205, 99.856 2751.676, 101.79413877551019, 101.68461508180307, 97.9348128114482, 101.07279402230402, 103.57640928848359, 104.70206267351203, 99.987 2791.7, 101.66293877551018, 101.62361508180308, 97.79381281144819, 101.09179402230401, 103.33140928848363, 104.47406267351204, 100.061 2832.306, 101.48953877551018, 101.52561508180307, 97.6298128114482, 101.05279402230403, 103.03540928848363, 104.20406267351203, 100.07300000000001 2873.503, 101.2659387755102, 101.38961508180311, 97.43181281144818, 100.94379402230403, 102.68340928848362, 103.88106267351203, 100.035 2915.299, 100.98633877551018, 101.2176150818031, 97.1838128114482, 100.76479402230402, 102.2714092884836, 103.49406267351202, 99.961 2957.703, 100.6581387755102, 101.02761508180308, 96.8848128114482, 100.53179402230404, 101.80440928848358, 103.04206267351205, 99.849 3000.724, 100.30233877551021, 100.83761508180314, 96.57181281144821, 100.26479402230405, 101.3014092884836, 102.53606267351205, 99.707 3044.37, 99.92673877551019, 100.64661508180308, 96.26281281144819, 99.96779402230402, 100.76940928848359, 101.98706267351201, 99.56700000000001 3088.652, 99.55313877551019, 100.47461508180312, 95.9818128114482, 99.65779402230403, 100.23040928848361, 101.42106267351205, 99.459 3133.577, 99.2035387755102, 100.3276150818031, 95.76081281144819, 99.35579402230401, 99.70640928848358, 100.86706267351205, 99.388 3179.156, 98.8689387755102, 100.18361508180311, 95.5868128114482, 99.04579402230402, 99.19740928848358, 100.33106267351204, 99.36 3225.398, 98.5283387755102, 100.02361508180309, 95.41681281144821, 98.71879402230402, 98.68040928848359, 99.80206267351204, 99.367 3272.312, 98.1623387755102, 99.83961508180309, 95.20781281144818, 98.36079402230405, 98.13440928848362, 99.26906267351202, 99.397 3319.909, 97.7685387755102, 99.63561508180307, 94.93981281144819, 97.99179402230403, 97.54940928848363, 98.72606267351203, 99.406 3368.198, 97.35953877551019, 99.42661508180308, 94.6238128114482, 97.63779402230404, 96.93540928848361, 98.17406267351205, 99.383 3417.19, 96.96693877551019, 99.2346150818031, 94.30581281144822, 97.33679402230402, 96.3264092884836, 97.63106267351202, 99.343 3466.894, 96.62873877551019, 99.07461508180309, 94.0498128114482, 97.11779402230404, 95.7764092884836, 97.12506267351203, 99.298 3517.321, 96.37373877551019, 98.94961508180309, 93.90281281144821, 96.99579402230403, 95.33540928848363, 96.68506267351204, 99.274 3568.482, 96.2189387755102, 98.85261508180312, 93.88881281144822, 96.96979402230403, 95.04440928848359, 96.33906267351202, 99.284 3620.387, 96.15913877551021, 98.7656150818031, 93.99481281144821, 97.02179402230405, 94.91440928848363, 96.09906267351204, 99.326 3673.046, 96.17113877551019, 98.66661508180312, 94.1828128114482, 97.12379402230403, 94.92540928848359, 95.95706267351204, 99.389 3726.472, 96.2283387755102, 98.53961508180312, 94.4108128114482, 97.24879402230401, 95.04540928848361, 95.89706267351205, 99.447 3780.675, 96.30573877551019, 98.3726150818031, 94.64981281144819, 97.37279402230402, 95.23840928848361, 95.89506267351203, 99.46000000000001 3835.666, 96.3881387755102, 98.16761508180309, 94.88281281144822, 97.48379402230401, 95.47440928848363, 95.93206267351204, 99.408 3891.457, 96.47213877551019, 97.9386150818031, 95.11281281144818, 97.58079402230402, 95.7354092884836, 95.99306267351201, 99.293 3948.06, 96.55813877551019, 97.70261508180309, 95.34681281144819, 97.66479402230402, 96.00640928848364, 96.07006267351204, 99.123 4005.486, 96.6475387755102, 97.4786150818031, 95.58881281144821, 97.73679402230403, 96.2794092884836, 96.15406267351202, 98.907 4063.747, 96.7395387755102, 97.27961508180307, 95.8398128114482, 97.79779402230405, 96.54240928848363, 96.23806267351203, 98.637 4122.855, 96.8261387755102, 97.1066150818031, 96.08681281144821, 97.84179402230403, 96.7804092884836, 96.31506267351203, 98.328 4182.824, 96.89233877551018, 96.95361508180308, 96.30681281144818, 97.85579402230401, 96.97140928848363, 96.37406267351203, 98.035 4243.664, 96.9203387755102, 96.8046150818031, 96.4768128114482, 97.82179402230405, 97.0964092884836, 96.40206267351205, 97.786 4305.39, 96.89573877551018, 96.64461508180308, 96.5788128114482, 97.72679402230402, 97.14140928848362, 96.38706267351203, 97.589 4368.013, 96.81013877551018, 96.46061508180308, 96.60381281144821, 97.56279402230403, 97.1024092884836, 96.32106267351203, 97.446 4431.547, 96.66173877551019, 96.24161508180308, 96.54881281144819, 97.33179402230402, 96.98440928848359, 96.20206267351202, 97.359 4496.006, 96.45553877551019, 95.98661508180311, 96.42481281144819, 97.03579402230403, 96.79840928848358, 96.03206267351203, 97.336 4561.401, 96.20493877551019, 95.70361508180308, 96.2458128114482, 96.69279402230403, 96.56440928848359, 95.81806267351202, 97.376 4627.749, 95.93313877551017, 95.41461508180308, 96.0328128114482, 96.33579402230401, 96.30540928848362, 95.57706267351202, 97.472 4695.061, 95.66973877551018, 95.1506150818031, 95.8138128114482, 95.99579402230401, 96.0524092884836, 95.33606267351203, 97.615 4763.352, 95.4477387755102, 94.9466150818031, 95.6148128114482, 95.71079402230403, 95.83640928848361, 95.13006267351203, 97.786 4832.636, 95.2917387755102, 94.8266150818031, 95.45581281144821, 95.50879402230403, 95.68140928848364, 94.98606267351205, 97.976 4902.929, 95.2081387755102, 94.79561508180312, 95.34881281144821, 95.39379402230402, 95.5904092884836, 94.91206267351204, 98.15 4974.244, 95.19533877551021, 94.8486150818031, 95.29781281144821, 95.35779402230403, 95.5634092884836, 94.90906267351204, 98.30799999999999 5046.596, 95.2441387755102, 94.96961508180307, 95.2988128114482, 95.39279402230402, 95.59040928848363, 94.96906267351203, 98.452 5120, 95.3407387755102, 95.1406150818031, 95.3478128114482, 95.47179402230404, 95.66340928848365, 95.08006267351203, 98.576 5194.472, 95.4811387755102, 95.34861508180312, 95.44981281144821, 95.59579402230402, 95.77740928848361, 95.23406267351201, 98.667 5270.027, 95.6669387755102, 95.59161508180311, 95.6088128114482, 95.76579402230404, 95.93540928848363, 95.43306267351203, 98.713 5346.682, 95.89713877551019, 95.86461508180311, 95.82081281144819, 95.98279402230405, 96.14240928848359, 95.67506267351202, 98.721 5424.451, 96.16093877551017, 96.1566150818031, 96.0688128114482, 96.23779402230403, 96.38840928848359, 95.95306267351205, 98.705 5503.352, 96.4443387755102, 96.4536150818031, 96.3308128114482, 96.51879402230404, 96.66240928848362, 96.25606267351202, 98.682 5583.4, 96.72213877551022, 96.7286150818031, 96.5768128114482, 96.80079402230405, 96.94240928848362, 96.56206267351203, 98.645 5664.612, 96.96953877551019, 96.95961508180308, 96.7808128114482, 97.05479402230402, 97.20340928848363, 96.84906267351205, 98.56 5747.006, 97.1725387755102, 97.13561508180311, 96.9258128114482, 97.26179402230403, 97.43140928848362, 97.10806267351205, 98.403 5830.598, 97.3287387755102, 97.26061508180311, 97.0098128114482, 97.41279402230404, 97.62340928848363, 97.33706267351204, 98.16499999999999 5915.406, 97.44913877551019, 97.34561508180309, 97.04881281144822, 97.51479402230402, 97.78740928848362, 97.54906267351203, 97.848 6001.447, 97.55073877551021, 97.4096150818031, 97.06981281144822, 97.58079402230403, 97.93540928848363, 97.75806267351201, 97.453 6088.74, 97.6517387755102, 97.4706150818031, 97.09881281144818, 97.62679402230403, 98.08340928848362, 97.97906267351205, 96.995 6177.303, 97.7625387755102, 97.53861508180307, 97.1528128114482, 97.66479402230405, 98.24140928848362, 98.21506267351202, 96.49 6267.154, 97.90193877551019, 97.63161508180308, 97.25881281144818, 97.72079402230402, 98.42240928848359, 98.47606267351203, 95.994 6358.312, 98.08393877551018, 97.76261508180309, 97.4388128114482, 97.81379402230402, 98.63840928848359, 98.76606267351204, 95.544 6450.796, 98.3191387755102, 97.94361508180307, 97.70881281144821, 97.95879402230403, 98.89640928848362, 99.08806267351204, 95.164 6544.625, 98.60833877551019, 98.17161508180311, 98.07981281144819, 98.15879402230402, 99.1994092884836, 99.43206267351204, 94.86 6639.819, 98.94133877551019, 98.44161508180309, 98.55581281144822, 98.40279402230405, 99.53140928848359, 99.77506267351202, 94.615 6736.397, 99.3043387755102, 98.74261508180312, 99.1378128114482, 98.67579402230403, 99.87540928848362, 100.09006267351204, 94.422 6834.38, 99.6791387755102, 99.06161508180311, 99.81781281144818, 98.95479402230403, 100.21040928848363, 100.35106267351203, 94.267 6933.788, 100.0445387755102, 99.3806150818031, 100.57481281144821, 99.21679402230403, 100.51040928848361, 100.54006267351205, 94.15 7034.643, 100.3773387755102, 99.67661508180308, 101.3738128114482, 99.44179402230401, 100.75140928848359, 100.64306267351202, 94.07300000000001 7136.964, 100.65773877551018, 99.9316150818031, 102.16681281144821, 99.61579402230402, 100.91740928848361, 100.65706267351203, 94.021 7240.773, 100.8717387755102, 100.12861508180309, 102.89781281144819, 99.73479402230403, 101.00440928848359, 100.59306267351205, 94.001 7346.093, 101.01853877551021, 100.2656150818031, 103.5148128114482, 99.80979402230403, 101.02940928848363, 100.47306267351203, 94.021 7452.944, 101.1097387755102, 100.3476150818031, 103.9848128114482, 99.86179402230403, 101.02240928848363, 100.33206267351204, 94.074 7561.35, 101.16893877551018, 100.39761508180307, 104.29681281144822, 99.92179402230401, 101.02140928848361, 100.20706267351203, 94.142 7671.332, 101.22813877551019, 100.44861508180311, 104.46781281144821, 100.02379402230405, 101.06440928848362, 100.13606267351203, 94.214 7782.914, 101.3297387755102, 100.54461508180309, 104.5428128114482, 100.20879402230402, 101.19340928848361, 100.15906267351203, 94.263 7896.119, 101.5179387755102, 100.73361508180312, 104.58381281144818, 100.51979402230401, 101.44140928848361, 100.31106267351203, 94.283 8010.971, 101.8265387755102, 101.0536150818031, 104.6568128114482, 100.98479402230403, 101.8234092884836, 100.61406267351204, 94.362 8127.493, 102.2745387755102, 101.5286150818031, 104.82081281144819, 101.61679402230403, 102.33840928848362, 101.06806267351205, 94.457 8245.71, 102.85913877551017, 102.15561508180308, 105.12181281144818, 102.40079402230403, 102.9654092884836, 101.65206267351202, 94.511 8365.647, 103.5303387755102, 102.8756150818031, 105.57481281144821, 103.26379402230403, 103.63540928848361, 102.30206267351205, 94.506 8487.328, 104.1719387755102, 103.5446150818031, 106.1398128114482, 104.04979402230404, 104.22940928848362, 102.89606267351203, 94.509 8610.779, 104.6171387755102, 103.95661508180311, 106.7058128114482, 104.54679402230403, 104.6064092884836, 103.27006267351203, 94.474 8736.026, 104.6957387755102, 103.90961508180311, 107.11481281144819, 104.54979402230404, 104.64240928848363, 103.26206267351205, 94.396 8863.094, 104.27873877551019, 103.26361508180312, 107.21081281144819, 103.91079402230403, 104.25640928848364, 102.75206267351203, 94.18299999999999 8992.011, 103.3131387755102, 101.98061508180311, 106.8858128114482, 102.57179402230403, 103.4264092884836, 101.70106267351204, 93.80799999999999 9122.803, 101.83853877551019, 100.15361508180308, 106.10681281144821, 100.57979402230401, 102.18840928848363, 100.16406267351203, 93.379 9255.497, 99.98093877551018, 97.98861508180312, 104.9198128114482, 98.06879402230405, 100.62740928848359, 98.30006267351203, 92.877 9390.121, 97.92813877551018, 95.75861508180307, 103.42281281144821, 95.24279402230403, 98.86340928848361, 96.35306267351203, 92.222 9526.704, 95.89513877551022, 93.7296150818031, 101.73281281144821, 92.39279402230403, 97.03140928848364, 94.58906267351205, 91.439 9665.273, 94.08033877551019, 92.09661508180311, 99.95781281144819, 89.86079402230403, 95.26140928848359, 93.22506267351203, 90.576 9805.858, 92.61753877551021, 90.9546150818031, 98.15681281144819, 87.92079402230405, 93.68040928848362, 92.37506267351202, 89.717 9948.487, 91.5757387755102, 90.31761508180313, 96.36381281144821, 86.73879402230403, 92.4104092884836, 92.04806267351205, 88.939 10093.191, 90.96493877551019, 90.13561508180307, 94.6258128114482, 86.36279402230404, 91.54140928848359, 92.15906267351205, 88.358 10240, 90.7495387755102, 90.32061508180308, 93.0398128114482, 86.69679402230403, 91.1184092884836, 92.57206267351202, 88.044 10388.944, 90.86473877551018, 90.77561508180307, 91.7228128114482, 87.55279402230403, 91.1234092884836, 93.14906267351202, 87.931 10540.055, 91.24513877551018, 91.43161508180307, 90.78181281144819, 88.71979402230403, 91.49940928848363, 93.79306267351203, 88.092 10693.364, 91.84233877551019, 92.25361508180308, 90.2848128114482, 90.02079402230402, 92.16940928848359, 94.48306267351202, 88.46 10848.902, 92.6401387755102, 93.23761508180311, 90.2588128114482, 91.39179402230403, 93.06140928848359, 95.25106267351205, 88.962 11006.703, 93.65713877551019, 94.4046150818031, 90.70181281144819, 92.90379402230401, 94.12440928848359, 96.15106267351204, 89.679 11166.799, 94.89893877551017, 95.76361508180311, 91.58681281144818, 94.62079402230403, 95.3174092884836, 97.20606267351202, 90.673 11329.224, 96.3347387755102, 97.2926150818031, 92.87381281144822, 96.53079402230405, 96.59040928848363, 98.38606267351203, 91.911 11494.011, 97.88153877551017, 98.9306150818031, 94.5038128114482, 98.54979402230401, 97.8304092884836, 99.59306267351204, 93.109 11661.196, 99.4013387755102, 100.55661508180309, 96.3888128114482, 100.50079402230405, 98.87040928848363, 100.69006267351203, 94.131 11830.812, 100.73073877551019, 102.00461508180308, 98.37581281144821, 102.16079402230403, 99.57240928848364, 101.54006267351204, 94.92699999999999 12002.895, 101.7235387755102, 103.10661508180311, 100.24981281144818, 103.34579402230403, 99.87040928848359, 102.04506267351204, 95.44200000000001 12177.481, 102.2895387755102, 103.7356150818031, 101.7888128114482, 103.95079402230402, 99.7964092884836, 102.17606267351204, 95.734 12354.606, 102.41853877551019, 103.8376150818031, 102.8398128114482, 103.96879402230401, 99.4774092884836, 101.96906267351203, 95.737 12534.308, 102.1813387755102, 103.45261508180312, 103.3658128114482, 103.50179402230404, 99.0764092884836, 101.51006267351204, 95.355 12716.624, 101.70133877551021, 102.70261508180312, 103.44081281144821, 102.71079402230404, 98.73240928848361, 100.92006267351204, 94.74 12901.592, 101.12633877551019, 101.76261508180309, 103.21381281144821, 101.77179402230405, 98.54840928848361, 100.33506267351203, 93.95 13089.25, 100.58593877551019, 100.81461508180308, 102.85781281144818, 100.83379402230403, 98.54840928848358, 99.87506267351205, 93.091 13279.637, 100.14493877551017, 99.9786150818031, 102.48881281144818, 99.95979402230404, 98.67940928848358, 99.61806267351201, 92.181 13472.794, 99.78753877551021, 99.2626150818031, 102.1088128114482, 99.10679402230404, 98.87540928848362, 99.58406267351204, 91.201 13668.76, 99.4257387755102, 98.56961508180311, 101.61881281144818, 98.17079402230405, 99.06240928848362, 99.70706267351201, 90.2 13867.577, 98.91993877551019, 97.71361508180307, 100.8938128114482, 97.00579402230404, 99.13940928848363, 99.84706267351201, 89.261 14069.285, 98.1019387755102, 96.46061508180308, 99.83181281144822, 95.43179402230403, 98.9774092884836, 99.80806267351203, 88.511 14273.928, 96.84873877551021, 94.5626150818031, 98.3978128114482, 93.49179402230402, 98.41840928848362, 99.37306267351204, 88.068 14481.547, 95.2557387755102, 92.3186150818031, 96.6878128114482, 91.68479402230403, 97.26240928848364, 98.32506267351204, 88.045 14692.186, 93.44533877551021, 90.31061508180312, 94.9338128114482, 90.38479402230402, 95.20540928848362, 96.39206267351204, 88.403 14905.889, 91.56573877551018, 88.93861508180308, 93.40481281144818, 89.86279402230403, 92.4214092884836, 93.20106267351204, 89.133 15122.7, 90.1003387755102, 88.5256150818031, 92.31181281144819, 90.22279402230404, 89.63540928848363, 89.80606267351203, 90.117 15342.664, 89.23473877551021, 89.11761508180312, 91.7698128114482, 91.29679402230404, 87.31440928848359, 86.67506267351204, 91.114 15565.829, 89.0237387755102, 90.45461508180308, 91.7988128114482, 92.74579402230403, 85.86440928848363, 84.25506267351203, 92.089 15792.239, 89.39773877551018, 92.14861508180309, 92.33881281144818, 94.25779402230401, 85.35340928848359, 82.89006267351203, 93.086 16021.942, 90.0937387755102, 93.84661508180311, 93.19381281144818, 95.45979402230402, 85.24540928848363, 82.72306267351205, 94.035 16254.987, 90.9017387755102, 95.10761508180312, 94.11881281144818, 96.21979402230403, 85.4334092884836, 83.62906267351204, 94.866 16491.421, 91.8323387755102, 95.99761508180308, 94.9498128114482, 96.79979402230404, 86.04140928848364, 85.37306267351204, 95.54 16731.294, 92.79813877551021, 96.71461508180309, 95.66281281144822, 97.34679402230404, 86.7054092884836, 87.56106267351205, 96.152 16974.657, 93.6935387755102, 97.31461508180311, 96.2668128114482, 97.85279402230401, 87.60540928848363, 89.42806267351202, 96.818 17221.559, 94.62133877551018, 97.76961508180307, 96.7548128114482, 98.25179402230404, 89.04340928848359, 91.28706267351203, 97.266 17472.052, 95.5077387755102, 98.02461508180309, 97.0868128114482, 98.45679402230402, 90.90340928848363, 93.06706267351203, 97.402 17726.189, 96.1929387755102, 98.0296150818031, 97.21681281144821, 98.39779402230404, 92.84340928848358, 94.47706267351204, 96.977 17984.022, 96.56253877551018, 97.77061508180307, 97.13181281144819, 98.08279402230403, 94.54540928848363, 95.28206267351203, 96.436 18245.606, 96.48993877551018, 97.28261508180312, 96.80781281144819, 97.55579402230403, 95.31640928848363, 95.48706267351203, 95.601 18510.994, 96.06493877551017, 96.65661508180307, 96.2468128114482, 96.87979402230403, 95.32140928848361, 95.22006267351202, 94.276 18780.243, 95.40733877551018, 95.9296150818031, 95.5238128114482, 96.12779402230403, 94.8654092884836, 94.59006267351204, 92.197 19053.408, 94.60373877551021, 95.11761508180312, 94.76481281144821, 95.32679402230401, 94.11340928848362, 93.69606267351203, 89.78 19330.546, 93.6635387755102, 94.1846150818031, 94.03981281144821, 94.39079402230404, 93.10740928848362, 92.59506267351203, 86.892 19611.715, 92.52993877551019, 93.03461508180307, 93.28881281144818, 93.17979402230402, 91.83540928848363, 91.31106267351204, 83.226 19896.974, 91.1273387755102, 91.58461508180308, 92.33781281144822, 91.59779402230403, 90.29140928848359, 89.82506267351205, 79.495 20186.382, 89.33973877551018, 89.73161508180307, 90.9528128114482, 89.59079402230402, 88.39540928848363, 88.02806267351203, 79.495 20480, 87.03913877551018, 87.39661508180309, 88.9188128114482, 87.11879402230402, 85.99840928848359, 85.76306267351204, 79.495 20777.888, 84.0733387755102, 84.45261508180307, 86.0538128114482, 84.16079402230405, 82.88640928848362, 82.81306267351205, 79.495 21080.11, 80.82813877551017, 81.30361508180307, 82.72381281144818, 81.05879402230401, 79.4784092884836, 79.57606267351203, 79.495 21386.727, 77.58013877551019, 78.21761508180312, 79.26481281144818, 78.08179402230404, 76.03540928848362, 76.30106267351205, 79.495 21697.804, 74.69193877551018, 75.53461508180307, 76.09981281144822, 75.51179402230404, 72.94840928848363, 73.36506267351201, 79.495 ================================================ FILE: DemoCenter/DemoCenter/DemoData/csv/mechs.csv ================================================ Mech,Weight,Weapons Atlas,100 tons,AC/20,LRM-20,Medium Laser Mad Cat,75 tons,Ultra AC/5,ER PPC,LRM-10 Timber Wolf,75 tons,ER PPC,Large Laser,SRM-6 Daishi,100 tons,Gauss Rifle,ER PPC,LRM-15 Hellbringer,65 tons,ER Large Laser,ER Medium Laser,Streak SRM-6 Summoner,70 tons,ER Large Laser,LRM-20,Medium Pulse Laser Thor,70 tons,LRM-20,Large Laser,Medium Pulse Laser Warhawk,85 tons,Large Pulse Laser,ER PPC,Streak SRM-6 Dire Wolf,100 tons,ER PPC,LRM-20,Medium Pulse Laser Stormcrow,55 tons,ER Medium Laser,Streak SRM-2,Ultra AC/5 Black Hawk,55 tons,ER Large Laser,Streak SRM-6,Ultra AC/5 Ryoken,55 tons,LRM-20,ER Medium Laser,Medium Pulse Laser Vulture,65 tons,ER PPC,Large Pulse Laser,Streak SRM-6 Marauder,75 tons,ER Large Laser,LRM-15,Medium Pulse Laser Nova,35 tons,ER Medium Laser,Streak SRM-2,Ultra AC/5 Catapult,65 tons,ER PPC,LRM-15,Medium Pulse Laser Cauldron-Born,60 tons,ER Large Laser,LRM-15,Medium Pulse Laser Hunchback IIC,50 tons,ER PPC,LRM-10,Medium Pulse Laser Bushwacker,55 tons,ER Large Laser,Streak SRM-6,Ultra AC/5 Jenner IIC,35 tons,ER Medium Laser,Streak SRM-2,Ultra AC/5 ================================================ FILE: DemoCenter/DemoCenter/DemoData/csv/spacexlaunches.csv ================================================ Launch Date, Mission Name, Launch Site January 1, 2022, Starlink 3-10, Cape Canaveral Space Force Station January 15, 2022, Transporter-4, Cape Canaveral Space Force Station February 5, 2022, Starlink 3-11, Cape Canaveral Space Force Station February 20, 2022, Starlink 3-12, Cape Canaveral Space Force Station March 10, 2022, Starlink 3-13, Cape Canaveral Space Force Station March 25, 2022, Starlink 3-14, Cape Canaveral Space Force Station April 15, 2022, Starlink 3-15, Cape Canaveral Space Force Station April 30, 2022, Starlink 3-16, Cape Canaveral Space Force Station May 20, 2022, Starlink 3-17, Cape Canaveral Space Force Station June 5, 2022, Starlink 3-18, Cape Canaveral Space Force Station June 25, 2022, Starlink 3-19, Cape Canaveral Space Force Station July 10, 2022, Starlink 3-20, Cape Canaveral Space Force Station July 30, 2022, Starlink 3-21, Cape Canaveral Space Force Station August 15, 2022, Starlink 3-22, Cape Canaveral Space Force Station August 30, 2022, Starlink 3-23, Cape Canaveral Space Force Station September 20, 2022, Starlink 3-24, Cape Canaveral Space Force Station October 5, 2022, Starlink 3-25, Cape Canaveral Space Force Station October 25, 2022, Starlink 3-26, Cape Canaveral Space Force Station November 10, 2022, Starlink 3-27, Cape Canaveral Space Force Station November 30, 2022, Starlink 3-28, Cape Canaveral Space Force Station December 15, 2022, Starlink 3-29, Cape Canaveral Space Force Station December 30, 2022, Starlink 3-30, Cape Canaveral Space Force Station ================================================ FILE: DemoCenter/DemoCenter/DemoData/csv/stockProducts.csv ================================================ ProductId,Name,Color,Size,Category,Cost,Qnt 1,T-shirt,Red,M,Clothing,10.00,100 2,Jeans,Blue,L,Clothing,30.00,50 3,Jacket,Black,XL,Clothing,50.00,30 4,Dress,Green,S,Clothing,25.00,40 5,Skirt,Pink,M,Clothing,20.00,60 6,Sweater,Gray,L,Clothing,35.00,25 7,Shorts,Yellow,M,Clothing,15.00,70 8,Blouse,White,S,Clothing,18.00,80 9,Coat,Navy,L,Clothing,60.00,20 10,Hoodie,Black,XL,Clothing,40.00,35 11,Sneakers,Red,10,Footwear,55.00,45 12,Boots,Brown,9,Footwear,70.00,25 13,Sandals,Tan,8,Footwear,25.00,60 14,Flip Flops,Blue,11,Footwear,15.00,50 15,Loafers,Black,10,Footwear,65.00,30 16,Anorak,Olive,M,Clothing,45.00,20 17,Cardigan,Burgundy,L,Clothing,40.00,30 18,Jumpsuit,Black,S,Clothing,55.00,15 19,Tank Top,White,M,Clothing,12.00,85 20,Leggings,Gray,L,Clothing,25.00,75 21,Khakis,Beige,34,Clothing,35.00,40 22,Chinos,Olive,32,Clothing,38.00,25 23,V-neck T-shirt,Black,S,Clothing,22.00,65 24,Cargo Pants,Khaki,M,Clothing,28.00,50 25,Ballet Flats,Pink,8,Footwear,30.00,55 26,Cowboy Boots,Brown,9,Footwear,80.00,10 27,Raincoat,Yellow,L,Clothing,55.00,20 28,Windbreaker,Red,M,Clothing,42.00,30 29,High-Top Sneakers,White,10,Footwear,65.00,15 30,Dress Shoes,Black,11,Footwear,75.00,12 31,Baseball Cap,Gray,One Size,Accessories,15.00,50 32,Beanie,Black,One Size,Accessories,12.00,45 33,Scarf,Blue,One Size,Accessories,18.00,40 34,Belt,Brown,36,Accessories,20.00,60 35,Sunglasses,Black,One Size,Accessories,25.00,70 36,Gloves,Red,M,Accessories,15.00,35 37,Socks,Multicolor,10-12,Accessories,5.00,100 38,Running Shoes,Neon Green,9,Footwear,70.00,25 39,Work Boots,Black,10,Footwear,85.00,15 40,Slippers,Gray,L,Footwear,30.00,40 41,Tracksuit,Red,M,Clothing,60.00,20 42,Pajamas,Blue,L,Clothing,30.00,30 43,Swim Shorts,Black,M,Clothing,25.00,50 44,Sport Bra,Pink,M,Clothing,20.00,60 45,Tankini,Blue,M,Clothing,50.00,15 46,Evening Gown,Red,S,Clothing,100.00,10 47,Overalls,Denim,L,Clothing,45.00,20 48,Bow Tie,Black,One Size,Accessories,12.00,50 49,Cufflinks,Silver,One Size,Accessories,20.00,25 50,Fedora,Beige,One Size,Accessories,30.00,20 51,Puffer Jacket,Black,L,Clothing,65.00,15 52,Sports Bra,Black,M,Clothing,22.00,50 53,Wind Pants,Red,M,Clothing,38.00,30 54,Cargo Shorts,Camouflage,L,Clothing,24.00,40 55,Platform Shoes,Black,8,Footwear,45.00,25 56,Water Shoes,Blue,9,Footwear,30.00,60 57,Featherweight Vest,Yellow,M,Clothing,35.00,20 58,Executive Blazer,Gray,L,Clothing,95.00,10 59,Slip-On Sneakers,White,10,Footwear,60.00,15 60,Evening Dress,Blue,M,Clothing,75.00,12 61,Cycling Jersey,Black,L,Clothing,40.00,30 62,Hiking Boots,Brown,11,Footwear,90.00,8 63,Ballet Outfit,Pink,S,Clothing,55.00,20 64,Running Shorts,Gray,M,Clothing,28.00,50 65,Kitten Heels,Red,7,Footwear,35.00,30 66,Dressy Sandals,Gold,8,Footwear,45.00,25 67,Casual Trousers,Black,L,Clothing,50.00,15 68,Tight-Fitting Jeans,Dark Blue,32,Clothing,40.00,20 69,Leisure Shoes,White,9,Footwear,34.00,30 70,Boxy Crop Top,Coral,S,Clothing,20.00,50 ================================================ FILE: DemoCenter/DemoCenter/DemoData/csv/yachtNames.csv ================================================ Name Serenity Seeker Aquamarine Dream Ocean Odyssey Starlit Voyager Blissful Breeze Majestic Mariner Celestial Seas Pearl Serenade Nautical Nirvana Azure Horizon Enchanted Elegance Solstice Splendor Serendipity Shores Neptune's Haven Tranquil Tides Midnight Mirage Seabreeze Symphony Enigma Explorer Harmony Haven Radiant Rhapsody ================================================ FILE: DemoCenter/DemoCenter/DemoData/csv/yachts.csv ================================================ Yacht Name,Length (ft),Number of Cabins,Maximum Speed (knots),Cruising Range (nm),Price (USD),Year of Release,Builder,Designer,Flag,Location Ocean Dream,180,6,30,4000,25,000,000,2022,Benetti,Design Studio XYZ,USA,Fort Lauderdale''FL Sea Serenity,220,5,25,3500,45,000,000,2020,Feadship,Design Studio ABC,Monaco,Monaco Azure Explorer,295,6,28,3800,120,000,000,2019,Lürssen,Design Studio PQR,Spain,Barcelona Starlight,164,5,26,3600,32,000,000,2023,Heesen,Design Studio LMN,France,Antibes Pacific Queen,206,7,32,4200,65,000,000,2018,Amels,Design Studio RST,Bahamas,Nassau Horizon Seeker,171,4,24,3200,28,500,000,2021,Sanlorenzo,Design Studio UVW,USA,Miami''FL ================================================ FILE: DemoCenter/DemoCenter/Helpers/HeatmapHelper.cs ================================================ using System.Reflection; using System.Runtime.InteropServices; using Avalonia; using Avalonia.Media.Imaging; using Eremex.AvaloniaUI.Charts; namespace DemoCenter.Helpers; public static class HeatmapHelper { static double[,] ConvertToDoubles(byte[] data, PixelSize size) { var result = new double[size.Height, size.Width]; var x = 0; var y = size.Height - 1; for (int i = 0; i < data.Length; i++) { if (x == size.Width) { x = 0; y--; } result[y, x] = data[i]; x++; } return result; } public static string[] CreateArguments(int size) { var result = new string[size]; for (int i = 0; i < size; i++) result[i] = i.ToString(); return result; } public static HeatmapDataAdapter GetAdapter(string imageName) { var assembly = Assembly.GetAssembly(typeof(HeatmapHelper)); var resourceName = assembly!.GetManifestResourceNames().First(s => s.EndsWith($"{imageName}.png")); var stream = assembly.GetManifestResourceStream(resourceName)!; using var bitmap = WriteableBitmap.Decode(stream); var argumentsX = CreateArguments(bitmap.PixelSize.Width); var argumentsY = CreateArguments(bitmap.PixelSize.Height); var data = new byte[bitmap.PixelSize.Width * bitmap.PixelSize.Height]; using (var frameBuffer = bitmap.Lock()) { Marshal.Copy(frameBuffer.Address, data, 0, data.Length); } var values = ConvertToDoubles(data, bitmap.PixelSize); return new HeatmapDataAdapter(argumentsX, argumentsY, values); } } ================================================ FILE: DemoCenter/DemoCenter/Helpers/ThemedSyntaxHighlighter.cs ================================================ using System.Reflection; using System.Xml; using Avalonia.Markup.Xaml; using AvaloniaEdit.Highlighting; using AvaloniaEdit.Highlighting.Xshd; namespace DemoCenter.Helpers; public class ThemedSyntaxHighlighter : MarkupExtension { public ThemedSyntaxHighlighter(string highlightName) { string themeName = App.Current.GetValue(App.RequestedThemeVariantProperty).ToString(); string resourceName = $"DemoCenter.Resources.Highlighters.{highlightName}-{themeName}.xshd"; using(var stream = Assembly.GetExecutingAssembly() ?.GetManifestResourceStream(resourceName)) { HighlightingDefinition = HighlightingLoader.Load(new XmlTextReader(stream), null); } } public IHighlightingDefinition HighlightingDefinition { get; set; } public override object ProvideValue(IServiceProvider serviceProvider) { return this; } } ================================================ FILE: DemoCenter/DemoCenter/ProductsData/BarsGroupInfo.cs ================================================ using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using DemoCenter.ViewModels; using Eremex.AvaloniaUI.Controls.Common; namespace DemoCenter.ProductsData { public static class BarsGroupInfo { internal static List Create() { return new List() { //new PageInfo(name: "Overview", title: "Overview", //description: "Bars overview sample description", //viewModelGetter: () => new BarsOverviewPageViewModel()), new PageInfo(name: "IDE Layout", title: "IDE Layout", viewModelGetter: () => new IdeLayoutPageViewModel(), descriptionGetter: () => Resources.TheDockManagerComponentAllowsYouToImplemen, showInWeb: false), new PageInfo(name: "Toolbar & Menu", title: "Toolbar & Menu", viewModelGetter: () => new ToolbarAndMenuPageViewModel(), descriptionGetter: () => Resources.TheToolbarManagerComponentAllowsYouToImple), //new PageInfo(name: "Bar Items", title: "Bar Items", //description : "", //viewModelGetter: () => new BarItemsPageViewModel()), new PageInfo(name: "Context Menu", title: "Context Menu", viewModelGetter: () => new ContextMenuPageViewModel(), descriptionGetter: () => Resources.TheToolbarsMenuLibraryContainsAPopupMenuCo), }; } } } ================================================ FILE: DemoCenter/DemoCenter/ProductsData/CartesianChartGroupInfo.cs ================================================ using DemoCenter.ViewModels; namespace DemoCenter.ProductsData; public static class CartesianChartGroupInfo { internal static List Create() { return new List { new(name: "Real-Time Data", title: "Real-Time Data", viewModelGetter: () => new CartesianChartRealtimePageViewModel(), descriptionGetter: () => Resources.TheChartControlSupportsInstantDisplayOfRap, introduced: new VersionInfo(1, 0), updated: new VersionInfo(1, 2), showInWeb: false), new(name: "Large Data", title: "Large Data", viewModelGetter: () => new CartesianChartLargeDataPageViewModel(), descriptionGetter: () => Resources.TheChartControlSGraphicsRenderingIsOptimiz, introduced: new VersionInfo(1, 0), updated: new VersionInfo(1, 0), showInWeb: false), new(name: "Multiple Axes", title: "Multiple Axes", viewModelGetter: () => new CartesianChartAxesPageViewModel(), descriptionGetter: () => Resources.CartesianChartMultipleAxes, introduced: new VersionInfo(1, 0), updated: new VersionInfo(1, 3)), new(name: "Logarithmic Scale", title: "Logarithmic Scale", viewModelGetter: () => new CartesianChartLogarithmicScalePageViewModel(), descriptionGetter: () => Resources.ChartControlSupportsLogarithmicScalesForAn, introduced: new VersionInfo(1, 0), updated: new VersionInfo(1, 0)), new(name: "Strips and Constant Lines", title: "Strips and Constant Lines", viewModelGetter: () => new CartesianStripsAndConstantLinesViewModel(), descriptionGetter: () => Resources.ThisDemoShowsConstantLinesAndStripsUsedToH, introduced: new VersionInfo(1, 0)), new(name: "Point", title: "Point Series View", viewModelGetter: () => new CartesianPointSeriesViewViewModel(), descriptionGetter: () => Resources.ThisExampleDemonstratesThePointSeriesViewW, introduced: new VersionInfo(1, 0)), new(name: "Lollipop", title: "Lollipop Series View", viewModelGetter: () => new CartesianLollipopSeriesViewViewModel(), descriptionGetter: () => Resources.ChartsLollipop, introduced: new VersionInfo(1, 2)), new(name: "Line", title: "Line Series View", viewModelGetter: () => new CartesianLineSeriesViewViewModel(), descriptionGetter: () => Resources.TheLineSeriesViewShownInThisExampleAllowsY, introduced: new VersionInfo(1, 0)), new(name: "Area", title: "Area Series View", viewModelGetter: () => new CartesianAreaSeriesViewViewModel(), descriptionGetter: () => Resources.TheAreaSeriesViewAllowsYouDisplayFilledAre, introduced: new VersionInfo(1, 0)), new(name: "Stacked Area", title: "Stacked Area Series View", viewModelGetter: () => new CartesianStackedAreaSeriesViewViewModel(), descriptionGetter: () => Resources.StackedArea, introduced: new VersionInfo(1, 3)), new(name: "Full Stacked Area", title: "Full Stacked Area Series View", viewModelGetter: () => new CartesianFullStackedAreaSeriesViewViewModel(), descriptionGetter: () => Resources.FullStackedArea, introduced: new VersionInfo(1, 3)), new(name: "Scatter Line", title: "Scatter Line Series View", viewModelGetter: () => new CartesianScatterLineSeriesViewViewModel(), descriptionGetter: () => Resources.TheScatterLineSeriesViewIsUsefulWhenYouNee, introduced: new VersionInfo(1, 0)), new(name: "Step Line", title: "Step Line Series View", viewModelGetter: () => new CartesianStepLineSeriesViewViewModel(), descriptionGetter: () => Resources.ThisExampleDemonstratesTheStepLineSeriesVi, introduced: new VersionInfo(1, 0)), new(name: "Step Area", title: "Step Area Series View", viewModelGetter: () => new CartesianStepAreaSeriesViewViewModel(), descriptionGetter: () => Resources.TheStepAreaSeriesViewConnectsPointsWithHor, introduced: new VersionInfo(1, 0)), new(name: "Range Area", title: "Range Area Series View", viewModelGetter: () => new CartesianRangeAreaSeriesViewViewModel(), descriptionGetter: () => Resources.ADataSeriesInThisExampleContainsTwoYValues, introduced: new VersionInfo(1, 0)), new(name: "Side-by-Side Bar", title: "Side-by-Side Bar Series View", viewModelGetter: () => new CartesianSideBySideBarSeriesViewViewModel(), descriptionGetter: () => Resources.ThisExampleDemonstratesTheSideBySideBarSer, introduced: new VersionInfo(1, 0)), new(name: "Side-by-Side Range Bar", title: "Side-by-Side Range Bar Series View", viewModelGetter: () => new CartesianSideBySideRangeBarSeriesViewViewModel(), descriptionGetter: () => Resources.ADataSeriesInThisExampleContainsTwoYValues1, introduced: new VersionInfo(1, 0)), new(name: "Candlestick", title: "Candlestick Series View", viewModelGetter: () => new CartesianCandlestickSeriesViewViewModel(), descriptionGetter: () => Resources.TheCandlestickSeriesViewAllowsYouToCreateA, introduced: new VersionInfo(1, 1)), new(name: "Candlestick Aggregation", title: "Candlestick Aggregation", viewModelGetter: () => new CartesianCandlestickAggregationViewModel(), descriptionGetter: () => Resources.InThisDemoTheCandlestickSeriesViewUsesASpe, introduced: new VersionInfo(1, 1)), new(name: "Empty Points", title: "Empty Points", viewModelGetter: () => new CartesianEmptyPointsViewModel(), descriptionGetter: () => Resources.EmptyPoints, introduced: new VersionInfo(1, 3)) }; } } ================================================ FILE: DemoCenter/DemoCenter/ProductsData/CommonControlsGroupInfo.cs ================================================ using DemoCenter.ViewModels; using Eremex.AvaloniaUI.Controls.Common; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace DemoCenter.ProductsData { public static class CommonControlsGroupInfo { internal static List Create() { return new List() { new PageInfo(name: "TabControl", title: "TabControl", viewModelGetter: () => new TabControlPageViewModel(), descriptionGetter: () => Resources.EremexTabControlCanOrganizeTheContentsOfAB), new PageInfo(name: "MessageBox", title: "MessageBox", viewModelGetter: () => new MessageBoxPageViewModel(), descriptionGetter: () => Resources.TheMxMessageBoxDialogAllowsYouToDisplayMes, introduced: new VersionInfo(1, 1), showInWeb: false), new PageInfo(name: "SplitContainerControl", title: "SplitContainerControl", viewModelGetter: () => new SplitContainerControlPageViewModel(), descriptionGetter: () => Resources.SplitContainerControlAllowsYouToPlaceConte, updated: new VersionInfo(1,3)), }; } } } ================================================ FILE: DemoCenter/DemoCenter/ProductsData/DataGridGroupInfo.cs ================================================ using DemoCenter.ViewModels; using Eremex.AvaloniaUI.Controls.Common; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace DemoCenter.ProductsData { public static class DataGridGroupInfo { internal static List Create() { return new List() { new PageInfo(name: "Grouping", title: "Grouping", viewModelGetter: () => new DataGridGroupingPageViewModel(), descriptionGetter: () => Resources.TheDataGridSGroupingFeatureMakesItEasyToSu), new PageInfo(name: "Data Editors", title: "Data Editors", viewModelGetter: () => new DataGridDataEditorsViewModel(), descriptionGetter: () => Resources.YouCanEmbedAnyControlInDataGridCellsToPres), new PageInfo(name: "Data Validation", title: "Data Validation", viewModelGetter: () => new DataGridValidationViewModel(), descriptionGetter: () => Resources.TheDataValidationMechanismAllowsYouToCheck, introduced: new VersionInfo(1, 0)), new PageInfo(name: "Filter & Search", title: "Filter & Search", viewModelGetter: () => new DataGridFilteringViewModel(), descriptionGetter: () => Resources.DataGridSupportsBuiltInDataSearchAndFiltra, updated: new VersionInfo(1, 3)), new PageInfo(name: "Large Data", title: "Large Data", viewModelGetter: () => new DataGridLargeDataViewModel(), descriptionGetter: () => string.Format( Resources.RegardlessOfTheNumberOfColumnsAndRowsInThe), introduced: new VersionInfo(1, 0), updated: new VersionInfo(1, 1)), new PageInfo(name: "Row Auto Height", title: "Row Auto Height", viewModelGetter: () => new DataGridRowAutoHeightViewModel(), descriptionGetter: () => Resources.DataGridAdaptsRowHeightToFitCellContentsTe, introduced: new VersionInfo(1, 0)), new PageInfo(name: "Live Data", title: "Live Data", viewModelGetter: () => new DataGridLiveDataPageViewModel(), descriptionGetter: () => Resources.InThisDemoDataGridEmulatesTheWindowsTaskMa, introduced: new VersionInfo(1, 0)), new PageInfo(name: "Multiple Row Selection", title: "Multiple Row Selection", viewModelGetter: () => new DataGridMultipleSelectionPageViewModel(), descriptionGetter: () => Resources.DataGridSupportsMultipleRowSelectionModeWh, introduced: new VersionInfo(1, 1)), new PageInfo(name: "Fixed Columns", title: "Fixed Columns", viewModelGetter: () => new DataGridFixedColumnsViewModel(), descriptionGetter: () => Resources.DataGridFixedColumnsDescription, introduced: new VersionInfo(1, 3), showInWeb: true), new PageInfo(name: "Drag & Drop", title: "Drag & Drop", viewModelGetter: () => new DataGridDragDropPageViewModel(), descriptionGetter: () => string.Format( Resources.DataGridSupportsDragAndDropOperationsWithi, Environment.NewLine + Environment.NewLine, Environment.NewLine + Environment.NewLine), introduced: new VersionInfo(1, 1), showInWeb: false), new PageInfo(name: "Column Bands", title: "Column Bands", viewModelGetter: () => new DataGridColumnBandsViewModel(), descriptionGetter: () => Resources.DataGridColumnBandsDescription, introduced: new VersionInfo(1, 2), updated: new VersionInfo(1, 3)), new PageInfo(name: "Export", title: "Export", viewModelGetter: () => new DataGridExportViewModel(), descriptionGetter: () => Resources.DataGridExportDescription, introduced: new VersionInfo(1, 2), showInWeb: true) }; } } } ================================================ FILE: DemoCenter/DemoCenter/ProductsData/DeveloperToolsGroupInfo.cs ================================================ using DemoCenter.ViewModels; namespace DemoCenter.ProductsData; public class DeveloperToolsGroupInfo { internal static List Create() { return new List() { new PageInfo(name: "SVG Icons Browser", title: "Svg Icons Browser", viewModelGetter: () => new SvgIconsBrowserViewModel()) }; } } ================================================ FILE: DemoCenter/DemoCenter/ProductsData/EditorsGroupInfo.cs ================================================ using DemoCenter.ViewModels; using Eremex.AvaloniaUI.Controls.Common; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using DemoCenter.Views; namespace DemoCenter.ProductsData { public static class EditorsGroupInfo { internal static List Create() { return new List() { new PageInfo(name: "Overview", title: "Overview", viewModelGetter: () => new EditorsOverviewPageViewModel(), descriptionGetter: () => Resources.TheEremexControlsLibraryIncludesMultipleEd), new PageInfo(name: "Text Editing", title: "Button & Text Editors", viewModelGetter: () => new TextEditingPageViewModel(), descriptionGetter: () => Resources.TheEditorsLibraryIncludesTheTextEditorAndB), new PageInfo(name: "Spin Editor", title: "Spin Editor", viewModelGetter: () => new SpinEditorPageViewModel(), descriptionGetter: () => Resources.TheSpinEditorIsANumericValueEditorWithBuil), new PageInfo(name: "ComboBox Editor", title: "ComboBox Editor", viewModelGetter: () => new ComboBoxEditorPageViewModel(), descriptionGetter: () => Resources.TheComboBoxEditorFeaturesADropdownListOfIt), new PageInfo(name: "Segmented Editor", title: "Segmented Editor", viewModelGetter: () => new SegmentedEditorPageViewModel(), descriptionGetter: () => Resources.YouCanUseTheSegmentedEditorToPresentASetOf), new PageInfo(name: "Date Editor", title: "Date Editor", viewModelGetter: () => new DateEditorPageViewModel(), descriptionGetter: () => Resources.TheDateEditorFeaturesADropdownCalendarThat), new PageInfo(name: "Color Editor", title: "Color Editor", viewModelGetter: () => new ColorEditorPageViewModel(), descriptionGetter: () => Resources.TheColorEditorAndPopupColorEditorControlsA), new PageInfo(name: "Hyperlink Editor", title: "Hyperlink Editor", viewModelGetter: () => new HyperlinkEditorPageViewModel(), descriptionGetter: () => Resources.TheHyperlinkEditorDisplaysItsContentAsAHyp, introduced: new VersionInfo(1, 0)), new PageInfo(name: "Enum Source", title: "Enum Source", viewModelGetter: () => new EnumSourcePageViewModel(), descriptionGetter: () => Resources.YouCanCreateComboBoxAndSegmentedEditorsIte), new PageInfo(name: "Memo Editor", title: "Memo Editor", viewModelGetter: () => new MemoEditorPageViewModel(), descriptionGetter: () => Resources.UseMemoEditorToDisplayAndEditLargeTextInAP, introduced: new VersionInfo(1, 0)), }; } } } ================================================ FILE: DemoCenter/DemoCenter/ProductsData/Graphics3DControlGroupInfo.cs ================================================ using DemoCenter.ViewModels; namespace DemoCenter.ProductsData; public class Graphics3DControlGroupInfo { internal static List Create() { return new List { new (name: "Overview", title: "Overview", viewModelGetter: () => new Graphics3DControlOverviewViewModel(), descriptionGetter: () => Resources.Graphics3DControlAllowsYouToVisualizeAndIn, introduced: new VersionInfo(1, 1)), new (name: "Lines", title: "Line", viewModelGetter: () => new Graphics3DControlLinesViewModel(), descriptionGetter: () => Resources.ThisExampleDemonstratesAGraphics3DControlT, introduced: new VersionInfo(1, 1)), new (name: "Points", title: "Points", viewModelGetter: () => new Graphics3DControlPointsViewModel(), descriptionGetter: () => Resources.ThisExampleDemonstratesAGraphics3DControlT1, introduced: new VersionInfo(1, 1), updated: new VersionInfo(1, 2)), new (name: "Transformations", title: "Transformations", viewModelGetter: () => new Graphics3DControlTransformationViewModel(), descriptionGetter: () => Resources.ThisExampleDemonstratesDynamicTransformati, introduced: new VersionInfo(1, 1), updated: new VersionInfo(1, 2)), new (name: "STL Model", title: "STL Model", viewModelGetter: () => new Graphics3DControlStlViewModel(), descriptionGetter: () => Resources.STL, introduced: new VersionInfo(1, 1)), new (name: "Robot Arm", title: "Robot Arm", viewModelGetter: () => new Graphics3DControlRobotArmViewModel(), descriptionGetter: () => Resources.RobotArm, introduced: new VersionInfo(1, 3)), new (name: "Simple Materials", title: "Simple Materials", viewModelGetter: () => new Graphics3DControlSimpleMaterialsViewModel(), descriptionGetter: () => Resources.ThisExampleDemonstratesAGraphics3DControlD1, introduced: new VersionInfo(1, 1), updated: new VersionInfo(1, 2)), new (name: "Textured Materials", title: "Textured Materials", viewModelGetter: () => new Graphics3DControlTexturedMaterialsViewModel(), descriptionGetter: () => Resources.InThisExampleAGraphics3DControlDisplaysA3D, introduced: new VersionInfo(1, 1)), new (name: "Camera", title: "Camera", viewModelGetter: () => new Graphics3DControlCameraViewModel(), descriptionGetter: () => Resources.ThisExampleDemonstratesTheIsometricAndPers, introduced: new VersionInfo(1, 1)), new (name: "Skybox", title: "Skybox", viewModelGetter: () => new Graphics3DControlSkyboxViewModel(), descriptionGetter: () => Resources.Skybox, introduced: new VersionInfo(1, 2)), new (name: "Lights", title: "Lights", viewModelGetter: () => new Graphics3DControlLightsViewModel(), descriptionGetter: () => Resources.Lights, introduced: new VersionInfo(1, 2)), new (name: "Highlighting and Selection", title: "Highlighting and Selection", viewModelGetter: () => new Graphics3DControlHighlightingViewModel(), descriptionGetter: () => Resources.HighlightingAndSelection3D, introduced: new VersionInfo(1, 2)), }; } } ================================================ FILE: DemoCenter/DemoCenter/ProductsData/GroupInfo.cs ================================================ using DemoCenter.ViewModels; namespace DemoCenter.ProductsData; public class GroupInfo : ProductInfoBase { public List Pages { get; } public override bool HasChildren => Pages.Count > 0; public override VersionInfo Introduced { get; } public override VersionInfo? Updated { get; } public GroupInfo(string name, string title, Func viewModelGetter, Func descriptionGetter, List pages, bool showInWeb = true) : base(name, title, viewModelGetter, descriptionGetter, showInWeb) { Pages = pages; Introduced = pages.Min(info => info.Introduced); var maxUpdated = pages.Max(info => info.Updated); var maxIntroduced = pages.Max(info => info.Introduced); Updated = VersionInfo.Max(maxIntroduced, maxUpdated); } } ================================================ FILE: DemoCenter/DemoCenter/ProductsData/HeatmapGroupInfo.cs ================================================ using DemoCenter.ViewModels; namespace DemoCenter.ProductsData; public static class HeatmapGroupInfo { internal static List Create() { return new List { new (name: "Color Providers", title: "Color Providers", viewModelGetter: () => new HeatmapColorProvidersViewModel(), descriptionGetter: () => Resources.AHeatmapRendersA2DimensionalArrayOfValuesA, introduced: new VersionInfo(1, 1)), new(name: "Real-Time Data", title: "Real-Time Data", viewModelGetter: () => new HeatmapRealTimeViewModel(), descriptionGetter: () => Resources.InThisExampleTheHeatmapControlUsesCustomCo, introduced: new VersionInfo(1, 1), updated: new VersionInfo(1, 2), showInWeb: false), }; } } ================================================ FILE: DemoCenter/DemoCenter/ProductsData/PageInfo.cs ================================================ using DemoCenter.ViewModels; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace DemoCenter.ProductsData; public class PageInfo : ProductInfoBase { public override VersionInfo Introduced { get; } public override VersionInfo? Updated { get; } public override bool HasChildren => false; public PageInfo(string name, string title, Func viewModelGetter, Func descriptionGetter = null, VersionInfo? introduced = null, VersionInfo? updated = null, bool showInWeb = true) : base(name, title, viewModelGetter, descriptionGetter, showInWeb) { Updated = updated; Introduced = introduced ?? new VersionInfo(0, 0); } } ================================================ FILE: DemoCenter/DemoCenter/ProductsData/PolarChartGroupInfo.cs ================================================ using DemoCenter.ViewModels; namespace DemoCenter.ProductsData; public static class PolarChartGroupInfo { internal static List Create() { return new List { new (name: "Strips and Constant Lines", title: "Strips and Constant Lines", viewModelGetter: () => new PolarStripsAndConstantLinesViewModel(), descriptionGetter: () => Resources.InAPolarChartEachDataPointIsDeterminedByAn, introduced: new VersionInfo(1, 0)), new (name: "Point", title: "Point Series View", viewModelGetter: () => new PolarPointSeriesViewViewModel(), descriptionGetter: () => Resources.ThisExampleDemonstratesThePointSeriesViewW1, introduced: new VersionInfo(1, 0)), new (name: "Line", title: "Line Series View", viewModelGetter: () => new PolarLineSeriesViewViewModel(), descriptionGetter: () => Resources.TheLineSeriesViewShownInThisExampleAllowsY1, introduced: new VersionInfo(1, 0)), new (name: "Area", title: "Area Series View", viewModelGetter: () => new PolarAreaSeriesViewViewModel(), descriptionGetter: () => Resources.TheAreaSeriesViewAllowsYouDisplayFilledAre1, introduced: new VersionInfo(1, 0)), new (name: "Scatter Line", title: "Scatter Line Series View", viewModelGetter: () => new PolarScatterLineSeriesViewViewModel(), descriptionGetter: () => Resources.TheScatterLineSeriesViewIsUsefulWhenYouNee1, introduced: new VersionInfo(1, 0)), new (name: "Range Area", title: "Range Area Series View", viewModelGetter: () => new PolarRangeAreaSeriesViewViewModel(), descriptionGetter: () => Resources.ADataSeriesInThisExampleContainsTwoYValues2, introduced: new VersionInfo(1, 0)), new(name: "Empty Points", title: "Empty Points", viewModelGetter: () => new PolarEmptyPointsViewModel(), descriptionGetter: () => Resources.EmptyPoints, introduced: new VersionInfo(1, 3)) }; } } ================================================ FILE: DemoCenter/DemoCenter/ProductsData/ProductInfoBase.cs ================================================ using System.Reflection; using DemoCenter.ViewModels; namespace DemoCenter.ProductsData; public abstract class ProductInfoBase { public string Name { get; } public string Title { get; } public Func DescriptionGetter { get; set; } public string Description => DescriptionGetter?.Invoke(); public Func ViewModelGetter { get; } public bool ShowInWeb { get; } public bool IsNew => Introduced.Matches(App.Version) && !IsUpdated; public bool IsUpdated => Updated?.Matches(App.Version) is true; public bool IsWebApp => App.IsWebApp; public abstract VersionInfo Introduced { get; } public abstract VersionInfo? Updated { get; } public abstract bool HasChildren { get; } protected ProductInfoBase(string name, string title, Func viewModelGetter, Func descriptionGetter, bool showInWeb) { Name = name; Title = title; DescriptionGetter = descriptionGetter; ViewModelGetter = viewModelGetter; ShowInWeb = showInWeb; } } public readonly struct VersionInfo : IComparable { public static VersionInfo Max(VersionInfo v1, VersionInfo? v2) { if (v2.HasValue) { int compare = v1.CompareTo(v2.Value); if (compare < 0) return v2.Value; } return v1; } public int Major { get; } = 0; public int Minor { get; } = 0; public VersionInfo(int major, int minor) { Major = major; Minor = minor; } public VersionInfo(Assembly assembly) { if (assembly.GetCustomAttributes(typeof(AssemblyFileVersionAttribute), true).SingleOrDefault() is AssemblyFileVersionAttribute attribute) { var parts = attribute.Version.Split('.', StringSplitOptions.RemoveEmptyEntries | StringSplitOptions.TrimEntries); if (parts.Length > 0 && int.TryParse(parts[0], out var major)) Major = major; if (parts.Length > 1 && int.TryParse(parts[1], out var minor)) Minor = minor; } } public bool Matches(VersionInfo version) => version.Major == Major && version.Minor == Minor; public int CompareTo(VersionInfo other) { int result = Major.CompareTo(other.Major); return result == 0 ? Minor.CompareTo(other.Minor) : result; } } ================================================ FILE: DemoCenter/DemoCenter/ProductsData/Products.cs ================================================ using DemoCenter.ViewModels; namespace DemoCenter.ProductsData; public static class Products { static List products; static List CreateProducts() => new() { new GroupInfo("Data Grid", "Data Grid", () => new DataGridPageViewModel(), () => "Data Grid description", DataGridGroupInfo.Create()), new GroupInfo("Tree List", "Tree List", () => new TreeListGroupViewModel(), () => "Tree List description", TreeListGroupInfo.Create()), new GroupInfo("Ribbon", "Ribbon", () => new RibbonGroupViewModel(), () => "Ribbon description", RibbonGroupInfo.Create()), new GroupInfo("Graphics3D Control", "Graphics3D Control", () => new Graphics3DControlViewModel(), () => "Graphics3D Control description", Graphics3DControlGroupInfo.Create(), false), new GroupInfo("Cartesian Chart", "Cartesian Chart", () => new ChartsPageViewModel(), () => "Cartesian Chart description", CartesianChartGroupInfo.Create()), new GroupInfo("Polar Chart", "Polar Chart", () => new ChartsPageViewModel(), () => "Polar Chart description", PolarChartGroupInfo.Create()), new GroupInfo("Smith Chart", "Smith Chart", () => new ChartsPageViewModel(), () => "Smith Chart description", SmithChartGroupInfo.Create()), new GroupInfo("Heatmap", "Heatmap", () => new ChartsPageViewModel(), () => "Heatmap description", HeatmapGroupInfo.Create()), new GroupInfo("Bars and Docking", "Bars and Docking", () => new BarsGroupViewModel(), () => "Bars and Docking description", BarsGroupInfo.Create()), new GroupInfo("Editors", "Editors", () => new EditorsGroupViewModel(), () => "Editors description", EditorsGroupInfo.Create()), new GroupInfo("Property Grid", "Property Grid", () => new PropertyGridGroupViewModel(), () => "Property Grid description", PropertyGridGroupInfo.Create()), new GroupInfo("Common Controls", "Common Controls", () => new CommonControlsGroupViewModel(), () => "Common Controls description", CommonControlsGroupInfo.Create()), new GroupInfo("Standard Controls", "Standard Controls", () => new StandardControlsGroupViewModel(), () => "Standard Controls description", StandardControlsGroupInfo.Create()), new GroupInfo("Samples", "Samples", () => new UseCasesGroupViewModel(), () => "Use Cases by Industry description", UseCasesGroupInfo.Create()), new GroupInfo("Tools", "Tools", () => new DeveloperToolsGroupViewModel(), () => "Developer Tools", DeveloperToolsGroupInfo.Create()), }; public static List GetOrCreate() => products ??= CreateProducts(); public static void Reset() { products = null; } } ================================================ FILE: DemoCenter/DemoCenter/ProductsData/PropertyGridGroupInfo.cs ================================================ using DemoCenter.ViewModels; using Eremex.AvaloniaUI.Controls.Common; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace DemoCenter.ProductsData { public static class PropertyGridGroupInfo { internal static List Create() { return new List() { new PageInfo(name: "Data Editors", title: "Data Editors", viewModelGetter: () => new PropertyGridDataEditorsViewModel(), descriptionGetter: () => Resources.PropertyGridAutomaticallyDetectsTheTypeOfB), new PageInfo(name: "Tab Items", title: "Tab Items", viewModelGetter: () => new PropertyGridTabItemsViewModel(), descriptionGetter: () => Resources.PropertyGridTabRowsAllowYouToGroupASetOfFi) }; } } } ================================================ FILE: DemoCenter/DemoCenter/ProductsData/RibbonGroupInfo.cs ================================================ using DemoCenter.ViewModels; namespace DemoCenter.ProductsData { public static class RibbonGroupInfo { internal static List Create() { return new List() { new PageInfo(name: "WordPad Example", title: "WordPad Example", viewModelGetter: () => new WordPadExampleViewModel(), descriptionGetter: () => string.Format( Resources.RibbonControlAllowsYouToIntegrateMicrosoft, Environment.NewLine + Environment.NewLine, Environment.NewLine+ Environment.NewLine), introduced: new VersionInfo(1, 1), updated: null, showInWeb: false) }; } } } ================================================ FILE: DemoCenter/DemoCenter/ProductsData/SmithChartGroupInfo.cs ================================================ using DemoCenter.ViewModels; namespace DemoCenter.ProductsData; public static class SmithChartGroupInfo { internal static List Create() { return new List { new (name: "Point", title: "Point Series View", viewModelGetter: () => new SmithPointSeriesViewViewModel(), descriptionGetter: () => Resources.ThisExampleDemonstratesThePointSeriesViewW2, introduced: new VersionInfo(1, 0)), new (name: "Scatter Line", title: "Scatter Line Series View", viewModelGetter: () => new SmithLineSeriesViewViewModel(), descriptionGetter: () => Resources.TheScatterLineSeriesViewIsUsefulWhenYouNee2, introduced: new VersionInfo(1, 0)) }; } } ================================================ FILE: DemoCenter/DemoCenter/ProductsData/StandardControlsGroupInfo.cs ================================================ using DemoCenter.ViewModels; using Eremex.AvaloniaUI.Controls.Common; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace DemoCenter.ProductsData { public static class StandardControlsGroupInfo { internal static List Create() { return new List() { new PageInfo(name: "Overview", title: "Overview", viewModelGetter: () => new StandardControlsOverviewPageViewModel()), new PageInfo(name: "Primitives", title: "Primitives", viewModelGetter: () => new PrimitivesPageViewModel()), new PageInfo(name: "ProgressBar", title: "ProgressBar", viewModelGetter: () => new ProgressBarPageViewModel()), new PageInfo(name: "Slider", title: "Slider", viewModelGetter: () => new SliderPageViewModel()), }; } } } ================================================ FILE: DemoCenter/DemoCenter/ProductsData/TreeListGroupInfo.cs ================================================ using DemoCenter.ViewModels; using Eremex.AvaloniaUI.Controls.Common; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace DemoCenter.ProductsData { public static class TreeListGroupInfo { internal static List Create() { return new List() { new PageInfo(name: "Filter & Search", title: "Filter & Search", viewModelGetter: () => new TreeListFilteringPageViewModel(), descriptionGetter: () => Resources.TheTreeListSAutoFilterRowDisplayedAtTheTop, showInWeb: false, updated: new VersionInfo(1, 3)), new PageInfo(name: "Data Editors", title: "Data Editors", viewModelGetter: () => new TreeListDataEditorsPageViewModel(), descriptionGetter: () => Resources.EremexEditorsAreUsedInTreeListCellsByDefau, showInWeb: false), new PageInfo(name: "Folder Browser", title: "Folder Browser", viewModelGetter: () => new FolderBrowserPageViewModel(), descriptionGetter: () => Resources.YouCanBindTreeListToAHierarchicalDataSourc), new PageInfo(name: "Multiple Node Selection", title: "Multiple Node Selection", viewModelGetter: () => new TreeListMultipleSelectionPageViewModel(), descriptionGetter: () => Resources.TheTreeListAndTreeViewControlsSupportMulti, introduced: new VersionInfo(1, 0)), new PageInfo(name: "Column Bands", title: "Column Bands", viewModelGetter: () => new TreeListColumnBandsViewModel(), descriptionGetter: () => Resources.TreeListColumnBandsDescription, introduced: new VersionInfo(1, 2)), new PageInfo(name: "Export", title: "Export", viewModelGetter: () => new TreeListExportViewModel(), descriptionGetter: () => Resources.TreeListExportDescription, introduced: new VersionInfo(1, 2)) }; } } } ================================================ FILE: DemoCenter/DemoCenter/ProductsData/UseCasesGroupInfo.cs ================================================ using DemoCenter.ViewModels; namespace DemoCenter.ProductsData; public static class UseCasesGroupInfo { internal static List Create() { return new List { new (name: "Mortgage calculator", title: "Mortgage Calculator", descriptionGetter : () => Resources.UseCasesGroupInfo_Desc, viewModelGetter: () => new MortgageCalculatorViewModel(), updated: new VersionInfo(1, 3)) }; } } ================================================ FILE: DemoCenter/DemoCenter/Resources/Colors.Dark.axaml ================================================  #85C46C #C191FF #85C46C #BDBDBD #BDBDBD #85C46C #C9A26D #C9A26D #C9A26D #6C95EB #BDBDBD #6C95EB #6C95EB #39CC8F #248700 #6C95EB #6C95EB #6C95EB #6C95EB #6C95EB #6C95EB #6C95EB #6C95EB #6C95EB #6C95EB #6C95EB #6C95EB #C191FF #39CC8F #6C95EB #6C95EB #6C95EB ================================================ FILE: DemoCenter/DemoCenter/Resources/Colors.Light.axaml ================================================  #00855F #6B2FBA #00855F #000000 #000000 #248700 #8C6C41 #8C6C41 #8C6C41 #0F54D6 #383838 #0F54D6 #0F54D6 #00855F #248700 #0F54D6 #0F54D6 #0F54D6 #0F54D6 #0F54D6 #0F54D6 #0F54D6 #0F54D6 #0F54D6 #0F54D6 #0F54D6 #0F54D6 #6B2FBA #00855F #0F54D6 #0F54D6 #0F54D6 ================================================ FILE: DemoCenter/DemoCenter/Resources/Highlighters/Axaml-Highlight-Dark.xshd ================================================ <!-- --> < > "[clr\-namespace|using] " " " { } ' ' [a-zA-Z:\.]{1,}[,=] clr\-namespace:.{1,} using:.{1,} xmlns= xmlns:[a-z0-9A-Z]{1,} [a-z0-9A-z]{1,}: \.[a-z0-9A-Z]{1,} [a-z0-9A-Z]{1,} :|=|/ & [\w\d\#]+ ; & [\w\d\#]* #missing ; ================================================ FILE: DemoCenter/DemoCenter/Resources/Highlighters/Axaml-Highlight-Light.xshd ================================================ <!-- --> < > "[clr\-namespace|using] " " " { } ' ' [a-zA-Z:\.]{1,}[,=] clr\-namespace:.{1,} using:.{1,} xmlns= xmlns:[a-z0-9A-Z]{1,} [a-z0-9A-z]{1,}: \.[a-z0-9A-Z]{1,} [a-z0-9A-Z]{1,} :|=|/ & [\w\d\#]+ ; & [\w\d\#]* #missing ; ================================================ FILE: DemoCenter/DemoCenter/Resources/Highlighters/CSharp-Highlight-Dark.xshd ================================================ TODO FIXME HACK UNDONE \# (define|undef|if|elif|else|endif|line)\b // (region|endregion|error|warning|pragma)\b // /\* \*/ " " ' ' @" " \$" " @[\w\d_]+ this base as is new sizeof typeof stackalloc true false else if switch case default do for foreach in while lock break continue goto return yield partial global where select group by into from ascending descending orderby let join on equals var dynamic await try throw catch finally checked unchecked fixed unsafe bool byte char decimal double enum float int long sbyte short struct uint ushort ulong class interface delegate object string void explicit implicit operator params ref out abstract const event extern override readonly sealed static virtual volatile async public protected private internal namespace using get set add remove null value nameof \b [\d\w_]+ # an identifier (?=\s*\() # followed by ( \b0[xX][0-9a-fA-F]+ # hex number | ( \b\d+(\.[0-9]+)? #number with optional floating point | \.[0-9]+ #or just starting with floating point ) ([eE][+-]?[0-9]+)? # optional exponent [?,.;()\[\]{}+\-/%*<>^+~!|&]+ ================================================ FILE: DemoCenter/DemoCenter/Resources/Highlighters/CSharp-Highlight-Light.xshd ================================================ TODO FIXME HACK UNDONE \# (define|undef|if|elif|else|endif|line)\b // (region|endregion|error|warning|pragma)\b // /\* \*/ " " ' ' @" " \$" " @[\w\d_]+ this base as is new sizeof typeof stackalloc true false else if switch case default do for foreach in while lock break continue goto return yield partial global where select group by into from ascending descending orderby let join on equals var dynamic await try throw catch finally checked unchecked fixed unsafe bool byte char decimal double enum float int long sbyte short struct uint ushort ulong class interface delegate object string void explicit implicit operator params ref out abstract const event extern override readonly sealed static virtual volatile async public protected private internal namespace using get set add remove null value nameof \b [\d\w_]+ # an identifier (?=\s*\() # followed by ( \b0[xX][0-9a-fA-F]+ # hex number | ( \b\d+(\.[0-9]+)? #number with optional floating point | \.[0-9]+ #or just starting with floating point ) ([eE][+-]?[0-9]+)? # optional exponent [?,.;()\[\]{}+\-/%*<>^+~!|&]+ ================================================ FILE: DemoCenter/DemoCenter/Resources/SearchPanel.axaml ================================================  ================================================ FILE: DemoCenter/DemoCenter/Resources/SharedResources.axaml ================================================  16 0,8,0,0 0,0,0,8 0,4,0,0 4,0,0,0 8,0,0,0 6 0 8,0,8,0 4 3,6,3,6 8,8,8,8 8,0,8,8 0,4,0,4 0,0,0,4 0,4,0,0 8,4,0,4 8,0,0,4 8,4,0,0 ================================================ FILE: DemoCenter/DemoCenter/Resources/SharedStyles.axaml ================================================  ================================================ FILE: DemoCenter/DemoCenter/Resources/SvgIconsBrowserViewResources.Designer.cs ================================================ //------------------------------------------------------------------------------ // // This code was generated by a tool. // Runtime Version:4.0.30319.42000 // // Changes to this file may cause incorrect behavior and will be lost if // the code is regenerated. // //------------------------------------------------------------------------------ namespace DemoCenter.Views.Resources { using System; /// /// A strongly-typed resource class, for looking up localized strings, etc. /// // This class was auto-generated by the StronglyTypedResourceBuilder // class via a tool like ResGen or Visual Studio. // To add or remove a member, edit your .ResX file then rerun ResGen // with the /str option, or rebuild your VS project. [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0")] [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] public class SvgIconsBrowserViewResources { private static global::System.Resources.ResourceManager resourceMan; private static global::System.Globalization.CultureInfo resourceCulture; [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] internal SvgIconsBrowserViewResources() { } /// /// Returns the cached ResourceManager instance used by this class. /// [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] public static global::System.Resources.ResourceManager ResourceManager { get { if (object.ReferenceEquals(resourceMan, null)) { global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("DemoCenter.Resources.SvgIconsBrowserViewResources", typeof(SvgIconsBrowserViewResources).Assembly); resourceMan = temp; } return resourceMan; } } /// /// Overrides the current thread's CurrentUICulture property for all /// resource lookups using this strongly typed resource class. /// [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] public static global::System.Globalization.CultureInfo Culture { get { return resourceCulture; } set { resourceCulture = value; } } /// /// Looks up a localized string similar to Categories. /// public static string CategoriesCaption { get { return ResourceManager.GetString("CategoriesCaption", resourceCulture); } } } } ================================================ FILE: DemoCenter/DemoCenter/Resources/SvgIconsBrowserViewResources.resx ================================================  text/microsoft-resx 1.3 System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Categories ================================================ FILE: DemoCenter/DemoCenter/Resources.Designer.cs ================================================ //------------------------------------------------------------------------------ // // This code was generated by a tool. // Runtime Version:4.0.30319.42000 // // Changes to this file may cause incorrect behavior and will be lost if // the code is regenerated. // //------------------------------------------------------------------------------ namespace DemoCenter { using System; /// /// A strongly-typed resource class, for looking up localized strings, etc. /// // This class was auto-generated by the StronglyTypedResourceBuilder // class via a tool like ResGen or Visual Studio. // To add or remove a member, edit your .ResX file then rerun ResGen // with the /str option, or rebuild your VS project. [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0")] [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] public class Resources { private static global::System.Resources.ResourceManager resourceMan; private static global::System.Globalization.CultureInfo resourceCulture; [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] internal Resources() { } /// /// Returns the cached ResourceManager instance used by this class. /// [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] public static global::System.Resources.ResourceManager ResourceManager { get { if (object.ReferenceEquals(resourceMan, null)) { global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("DemoCenter.Resources", typeof(Resources).Assembly); resourceMan = temp; } return resourceMan; } } /// /// Overrides the current thread's CurrentUICulture property for all /// resource lookups using this strongly typed resource class. /// [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] public static global::System.Globalization.CultureInfo Culture { get { return resourceCulture; } set { resourceCulture = value; } } /// /// Looks up a localized string similar to A data series in this example contains two Y-values for each data point. The Range Area view fills the area between these Y-values.. /// public static string ADataSeriesInThisExampleContainsTwoYValues { get { return ResourceManager.GetString("ADataSeriesInThisExampleContainsTwoYValues", resourceCulture); } } /// /// Looks up a localized string similar to A data series in this example contains two Y-values for each data point. The Side-by-side Range Bar view draws rectangular bars between these Y-values.. /// public static string ADataSeriesInThisExampleContainsTwoYValues1 { get { return ResourceManager.GetString("ADataSeriesInThisExampleContainsTwoYValues1", resourceCulture); } } /// /// Looks up a localized string similar to A data series in this example contains two Y-values for each data point. The Range Area view fills the area between these Y-values.. /// public static string ADataSeriesInThisExampleContainsTwoYValues2 { get { return ResourceManager.GetString("ADataSeriesInThisExampleContainsTwoYValues2", resourceCulture); } } /// /// Looks up a localized string similar to A heatmap renders a 2-dimensional array of values as a color-encoded matrix. Each data point's color corresponds to the data point's value. This example demonstrates the Heatmap control which allows you to create heatmaps from your data. Click a color gradient on the right to apply this color encoding to the heatmap. /// ///Image source: Webb Space Telescope, https://webbtelescope.org/. /// public static string AHeatmapRendersA2DimensionalArrayOfValuesA { get { return ResourceManager.GetString("AHeatmapRendersA2DimensionalArrayOfValuesA", resourceCulture); } } /// /// Looks up a localized string similar to This example demonstrates multiple axes in the CartesianChart control, along with the options to customize axis layout, position, labels, gridlines, and more. ///• Multiple Axes — The chart control allows you to create multiple X and Y axes and bind each data series to its own axes. ///• Axis Position — You can display specific X or Y axes opposite their default locations: X axes at the top, and Y axes at the right. ///• Swap Axes — With a single property, you can transpose the axes, so the Y axes are displayed [rest of string was truncated]";. /// public static string CartesianChartMultipleAxes { get { return ResourceManager.GetString("CartesianChartMultipleAxes", resourceCulture); } } /// /// Looks up a localized string similar to Chart Control supports logarithmic scales for any of its numeric axes. Log base 10 is default. You can specify a custom log base to change data scaling.. /// public static string ChartControlSupportsLogarithmicScalesForAn { get { return ResourceManager.GetString("ChartControlSupportsLogarithmicScalesForAn", resourceCulture); } } /// /// Looks up a localized string similar to The Lollipop series view is a sleek, space-efficient alternative to traditional bar charts. ///Instead of bulky bars, it uses thin lines topped with markers to visualize data points. You can use default markers or specify custom markers in SVG format. The Orientation setting allows you to specify the direction of the lollipop lines (horizontal or vertical).. /// public static string ChartsLollipop { get { return ResourceManager.GetString("ChartsLollipop", resourceCulture); } } /// /// Looks up a localized string similar to Data Grid adapts row height to fit cell contents. Text columns can display data in a single or multiple lines. Assign a TextEditor in-place editor (or its descendant) to a column, and enable text wrapping to display text in multiple lines.. /// public static string DataGridAdaptsRowHeightToFitCellContentsTe { get { return ResourceManager.GetString("DataGridAdaptsRowHeightToFitCellContentsTe", resourceCulture); } } /// /// Looks up a localized string similar to Column bands allow you to visually combine columns together by displaying shared headers above them. Both band and column headers can include text, images, or custom content. This demo showcases the following features: /// • Band Generation from a Source — You can populate column bands from a band source defined in a View Model. /// • Hierarchical Bands — The control allows you to create hierarchical bands with an unlimited number of nesting levels. /// • Fixed Columns Support — Bands can work with fixed columns. [rest of string was truncated]";. /// public static string DataGridColumnBandsDescription { get { return ResourceManager.GetString("DataGridColumnBandsDescription", resourceCulture); } } /// /// Looks up a localized string similar to This example demonstrates the Data Grid control's export functionality. Data Grid can export data to XLSX (Microsoft Excel) and PDF formats, while preserving data shaping options, including row grouping, sorting, and cell formatting.. /// public static string DataGridExportDescription { get { return ResourceManager.GetString("DataGridExportDescription", resourceCulture); } } /// /// Looks up a localized string similar to To keep essential data in view during horizontal scrolling, you can fix (pin) columns to the left or right edge. Once fixed, these columns remain stationary while other data scrolls. Enable the built-in 'Fixed' column menu to allow users to fix columns at runtime.. /// public static string DataGridFixedColumnsDescription { get { return ResourceManager.GetString("DataGridFixedColumnsDescription", resourceCulture); } } /// /// Looks up a localized string similar to The Data Grid offers multiple ways to filter and search for data: /// • Column Filter Menus: Hover over a column header and click the filter button to open a menu. You can apply filters to one or multiple columns simultaneously. /// • Auto Filter Row: This dedicated row at the top allows you to type filter values directly into any column. The grid instantly displays only the records that match your input. /// • Search Panel: Search for text across all columns. The Search Panel can be set to remain visible or ac [rest of string was truncated]";. /// public static string DataGridSupportsBuiltInDataSearchAndFiltra { get { return ResourceManager.GetString("DataGridSupportsBuiltInDataSearchAndFiltra", resourceCulture); } } /// /// Looks up a localized string similar to Data Grid supports drag-and-drop operations within the control and to external controls (for instance, Tree List or another Data Grid).This example demonstrates drag-and-drop functionality within and between Data Grids. The AllowDragDrop option activates the drag-and-drop feature. {0}The AllowDragDropSortedRows option must be enabled to allow drag-and-drop operations for sorted/grouped Data Grids. When data is sorted or grouped, a drag-and-drop operation modifies values of a dragged row in sort columns. {1} [rest of string was truncated]";. /// public static string DataGridSupportsDragAndDropOperationsWithi { get { return ResourceManager.GetString("DataGridSupportsDragAndDropOperationsWithi", resourceCulture); } } /// /// Looks up a localized string similar to DataGrid supports multiple row selection mode, which allows you and your user to select (highlight) multiple rows at one time. Users can select multiple rows with the mouse and keyboard. Click rows while holding the CTRL and/or SHIFT key down for row selection.. /// public static string DataGridSupportsMultipleRowSelectionModeWh { get { return ResourceManager.GetString("DataGridSupportsMultipleRowSelectionModeWh", resourceCulture); } } /// /// Looks up a localized string similar to This demo shows how a chart control handles incomplete datasets with the help of "empty points". These points allow you to create visible gaps in the series where values are missing. To specify an empty point, set its value to double.NaN, double.PositiveInfinity, or double.NegativeInfinity.. /// public static string EmptyPoints { get { return ResourceManager.GetString("EmptyPoints", resourceCulture); } } /// /// Looks up a localized string similar to Eremex editors are used in Tree List cells by default to display and edit cell values of common data types (Boolean, integer, enumerations, etc.). This demo shows implicitly assigned in-place editors, and demonstrates how you can explicitly specify an editor for a Tree List column.. /// public static string EremexEditorsAreUsedInTreeListCellsByDefau { get { return ResourceManager.GetString("EremexEditorsAreUsedInTreeListCellsByDefau", resourceCulture); } } /// /// Looks up a localized string similar to Eremex Tab Control can organize the contents of a bound item source into a tabbed UI. It supports tab re-ordering, multiple tab layout modes, and built-in buttons to add and close tabs.. /// public static string EremexTabControlCanOrganizeTheContentsOfAB { get { return ResourceManager.GetString("EremexTabControlCanOrganizeTheContentsOfAB", resourceCulture); } } /// /// Looks up a localized string similar to Exporting.... /// public static string ExportProgressMessage { get { return ResourceManager.GetString("ExportProgressMessage", resourceCulture); } } /// /// Looks up a localized string similar to Do you want to open the exported file?. /// public static string ExportProgressPromptMessage { get { return ResourceManager.GetString("ExportProgressPromptMessage", resourceCulture); } } /// /// Looks up a localized string similar to Export. /// public static string ExportProgressTitle { get { return ResourceManager.GetString("ExportProgressTitle", resourceCulture); } } /// /// Looks up a localized string similar to The Full Stacked Area series view (100% Stacked Area) shows proportional relationships between all data series. Each series is rendered as a filled area stacked on the previous one, with its thickness representing its percentage contribution to the total. The top line always indicates 100%.. /// public static string FullStackedArea { get { return ResourceManager.GetString("FullStackedArea", resourceCulture); } } /// /// Looks up a localized string similar to Graphics3DControl allows you to visualize and interact with 3D models. Use the Properties pane on the right to customize the control's basic rendering and behavior settings.. /// public static string Graphics3DControlAllowsYouToVisualizeAndIn { get { return ResourceManager.GetString("Graphics3DControlAllowsYouToVisualizeAndIn", resourceCulture); } } /// /// Looks up a localized string similar to Graphics3DControl supports model and mesh highlighting and selection. Highlighting draws a colored border around models or meshes when you hover over them with the mouse. With the selection feature, a colored border is painted around models or meshes when you click them. Use the HighlightMode and SelectionMode properties to choose whether highlighting/selection applies to models or meshes. The ShowHints property controls hint visibility for models and meshes.. /// public static string HighlightingAndSelection3D { get { return ResourceManager.GetString("HighlightingAndSelection3D", resourceCulture); } } /// /// Looks up a localized string similar to In a Polar Chart each data point is determined by an angle and a distance. This example demonstrates constant lines and strips used to highlight specific values and value ranges. Angle ranges and distance ranges are set in code of this demo. Left-click within a diagram to create custom constant lines for angles. Right-click to create custom constant lines for distances.. /// public static string InAPolarChartEachDataPointIsDeterminedByAn { get { return ResourceManager.GetString("InAPolarChartEachDataPointIsDeterminedByAn", resourceCulture); } } /// /// Looks up a localized string similar to In this demo, Data Grid emulates the Windows Task Manager by showing frequently updated fake processes. Data Grid supports automatic data updates if a bound item source implements the INotifyPropertyChanged interface. In this example, change notifications are supported for the underlying business object using the ObservableObject class (implements the INotifyPropertyChanged interface) and ObservableProperty attributes defined in the CommunityToolkit.Mvvm library.. /// public static string InThisDemoDataGridEmulatesTheWindowsTaskMa { get { return ResourceManager.GetString("InThisDemoDataGridEmulatesTheWindowsTaskMa", resourceCulture); } } /// /// Looks up a localized string similar to In this demo, the Candlestick series view uses a special data adapter (SummaryCandlestickDataAdapter) that accepts raw tick data and builds candlesticks from it. ///Raw ticks are single price values of an asset, taken at specific points in time. The data adapter aggregates the raw prices into candlesticks according to a specified time (measure) unit. ///For instance, data can be aggregated to 1 second, 1 minute, 1 hour, 1 day, 1 week, etc. or to multiples of the selected time unit such as 5 seconds, 15 minutes, [rest of string was truncated]";. /// public static string InThisDemoTheCandlestickSeriesViewUsesASpe { get { return ResourceManager.GetString("InThisDemoTheCandlestickSeriesViewUsesASpe", resourceCulture); } } /// /// Looks up a localized string similar to In this example, a Graphics3DControl displays a 3D model with a textured material. Use the Materials pane on the right to choose the texture.. /// public static string InThisExampleAGraphics3DControlDisplaysA3D { get { return ResourceManager.GetString("InThisExampleAGraphics3DControlDisplaysA3D", resourceCulture); } } /// /// Looks up a localized string similar to In this example the Heatmap control uses custom color encoding to visualize the intensity of a sample signal changing in real time. A chart control at the top displays the amplitude of this signal. The controls update seamlessly as the underlying data changes using a timer.. /// public static string InThisExampleTheHeatmapControlUsesCustomCo { get { return ResourceManager.GetString("InThisExampleTheHeatmapControlUsesCustomCo", resourceCulture); } } /// /// Looks up a localized string similar to Graphics3DControl allows you to specify custom light sources for 3D scenes. Supported light types include: Point, Directional, Camera Point, and Camera Directional. Custom lights automatically disable the default light.. /// public static string Lights { get { return ResourceManager.GetString("Lights", resourceCulture); } } /// /// Looks up a localized string similar to Property Grid automatically detects the type of bound fields, and uses appropriate Eremex data editors to display and edit cell values. You can explicitly assign editors to specific fields to override the default behavior and customize editor settings.. /// public static string PropertyGridAutomaticallyDetectsTheTypeOfB { get { return ResourceManager.GetString("PropertyGridAutomaticallyDetectsTheTypeOfB", resourceCulture); } } /// /// Looks up a localized string similar to Property Grid tab rows allow you to group a set of fields into a tabbed UI. Each tab item in a row displays its own set of bound fields.. /// public static string PropertyGridTabRowsAllowYouToGroupASetOfFi { get { return ResourceManager.GetString("PropertyGridTabRowsAllowYouToGroupASetOfFi", resourceCulture); } } /// /// Looks up a localized string similar to Regardless of the number of columns and rows in the control, Data Grid remains responsive as you scroll the control horizontally or vertically, or sort/group its data. The built-in data virtualization mechanism updates only cells within the viewport to maintain high-performance scrolling. /// public static string RegardlessOfTheNumberOfColumnsAndRowsInThe { get { return ResourceManager.GetString("RegardlessOfTheNumberOfColumnsAndRowsInThe", resourceCulture); } } /// /// Looks up a localized string similar to RibbonControl allows you to integrate Microsoft Office-inspired navigation menus into your Avalonia UI applications. The control comes with two views: Classic (three item rows) and Simplified (one item row). The dropdown button at the control's bottom right corner opens a selector between these views. {0}RibbonControl supports multiple item types: large and small buttons, check buttons, sub-menus, in-place editors, inline and dropdown galleries, groups of buttons, and more. You can create as many pages with [rest of string was truncated]";. /// public static string RibbonControlAllowsYouToIntegrateMicrosoft { get { return ResourceManager.GetString("RibbonControlAllowsYouToIntegrateMicrosoft", resourceCulture); } } /// /// Looks up a localized string similar to This demo showcases a 3D robotic arm loaded from an FBX file. Using the interactive panel on the right, you can manipulate each joint (from the base to the claw) by applying transformations to nested 3D models. Model by Ryan King Art https://sketchfab.com/ryankingart.. /// public static string RobotArm { get { return ResourceManager.GetString("RobotArm", resourceCulture); } } /// /// Looks up a localized string similar to Graphics3DControl supports the skybox feature, which provides a background for 3D scenes. The skybox is a large cube surrounding the entire scene, with six textured faces (front, back, left, right, top, and bottom). These textures are mapped to the cube's inner sides, creating the illusion of a distant sky, horizon, or backdrop.. /// public static string Skybox { get { return ResourceManager.GetString("Skybox", resourceCulture); } } /// /// Looks up a localized string similar to Split Container Control allows you to place content onto two panels, and separate the panels with a splitter that a user can drag to resize the panels. With the panel collapse feature enabled, the user can click the splitter to collapse and restore a panel.. /// public static string SplitContainerControlAllowsYouToPlaceConte { get { return ResourceManager.GetString("SplitContainerControlAllowsYouToPlaceConte", resourceCulture); } } /// /// Looks up a localized string similar to The Stacked Area series view shows absolute relationships between all data series. Each series is rendered as a filled area stacked on the previous one, with its thickness representing its absolute value. The top line shows the cumulative total of all series.. /// public static string StackedArea { get { return ResourceManager.GetString("StackedArea", resourceCulture); } } /// /// Looks up a localized string similar to This demo showcases a 3D model of a circuit board rendered in the Graphics3DControl. The example shows how you can import a complex model from an STL file using the Assimp library. The loaded geometry is used to initialize meshes, vertices and materials in the Graphics3DControl.. /// public static string STL { get { return ResourceManager.GetString("STL", resourceCulture); } } /// /// Looks up a localized string similar to The Area series view allows you display filled areas. This view is helpful when you need to visually compare two or more data series.. /// public static string TheAreaSeriesViewAllowsYouDisplayFilledAre { get { return ResourceManager.GetString("TheAreaSeriesViewAllowsYouDisplayFilledAre", resourceCulture); } } /// /// Looks up a localized string similar to The Area series view allows you display filled areas between a chart and point Zero. This view is helpful when you need to visually compare two or more data series.. /// public static string TheAreaSeriesViewAllowsYouDisplayFilledAre1 { get { return ResourceManager.GetString("TheAreaSeriesViewAllowsYouDisplayFilledAre1", resourceCulture); } } /// /// Looks up a localized string similar to The Candlestick series view allows you to create a financial chart that describes price movements of an asset. For each time period, the chart displays a data set that contains Open, Close, High and Low values. /// ///Stock data: https://www.investing.com/. /// public static string TheCandlestickSeriesViewAllowsYouToCreateA { get { return ResourceManager.GetString("TheCandlestickSeriesViewAllowsYouToCreateA", resourceCulture); } } /// /// Looks up a localized string similar to The Chart Control's graphics rendering is optimized to display large data. The control provides high performance even when series contain millions of points. /// public static string TheChartControlSGraphicsRenderingIsOptimiz { get { return ResourceManager.GetString("TheChartControlSGraphicsRenderingIsOptimiz", resourceCulture); } } /// /// Looks up a localized string similar to The Chart Control supports instant display of rapidly changing real-time data. This example shows how to use a special data adapter to implement a moving viewport.. /// public static string TheChartControlSupportsInstantDisplayOfRap { get { return ResourceManager.GetString("TheChartControlSupportsInstantDisplayOfRap", resourceCulture); } } /// /// Looks up a localized string similar to The Color Editor and Popup Color Editor controls allow a user to select a color. The controls support three color palettes: default (customizable in code), standard (fixed colors), and custom (customizable by users). The built-in Color Picker helps the user add custom colors from a color space, or specify color values in the RGB and HSB formats.. /// public static string TheColorEditorAndPopupColorEditorControlsA { get { return ResourceManager.GetString("TheColorEditorAndPopupColorEditorControlsA", resourceCulture); } } /// /// Looks up a localized string similar to The ComboBox Editor features a dropdown list of items from which a user can select one or more items. The editor can display a list of strings, a list of business objects, or enumeration values. In multi-select mode, item check boxes allow the user to select multiple items at a time.. /// public static string TheComboBoxEditorFeaturesADropdownListOfIt { get { return ResourceManager.GetString("TheComboBoxEditorFeaturesADropdownListOfIt", resourceCulture); } } /// /// Looks up a localized string similar to The Data Grid's grouping feature makes it easy to summarize information for users. They can group data by an unlimited number of columns by dragging columns onto the Group Panel.. /// public static string TheDataGridSGroupingFeatureMakesItEasyToSu { get { return ResourceManager.GetString("TheDataGridSGroupingFeatureMakesItEasyToSu", resourceCulture); } } /// /// Looks up a localized string similar to The data validation mechanism allows you to check cell values and show errors in cells that contain invalid data. You can use DataAnnotation attributes and IDataErrorInfo/INotifyDataErrorInfo interface to validate data at the ItemsSource level. Toggle the 'Show ItemsSource Errors' checkbox in this demo to see data validation errors from DataAnnotation attributes. Data Grid also allows you to use the ValidateCellValue event to implement custom rules to validate user input.. /// public static string TheDataValidationMechanismAllowsYouToCheck { get { return ResourceManager.GetString("TheDataValidationMechanismAllowsYouToCheck", resourceCulture); } } /// /// Looks up a localized string similar to The Date Editor features a dropdown calendar that allows users to select a date. The calendar's navigation bar enables the user to browse through months and years. DateEditor uses a date-time mask to restrict user input to date-time values only, and to format the edit value according to the specified pattern.. /// public static string TheDateEditorFeaturesADropdownCalendarThat { get { return ResourceManager.GetString("TheDateEditorFeaturesADropdownCalendarThat", resourceCulture); } } /// /// Looks up a localized string similar to The Dock Manager component allows you to implement the classic docking UI found in popular IDEs. You can create tool panels that support dock, auto-hide, and float operations. Special Document containers are designed to display the main content of your window. You can create multiple Documents and organize them into a tabbed UI.. /// public static string TheDockManagerComponentAllowsYouToImplemen { get { return ResourceManager.GetString("TheDockManagerComponentAllowsYouToImplemen", resourceCulture); } } /// /// Looks up a localized string similar to The Editors library includes the Text Editor and Button Editor controls that provide base text editing capabilities: data validation, watermarks (hints displayed when the editor is empty), and multiple options to control text selection and data edit operations. The Button Editor supports an unlimited number of built-in regular and check buttons, which can display text or images at the left or right edge of the edit box.. /// public static string TheEditorsLibraryIncludesTheTextEditorAndB { get { return ResourceManager.GetString("TheEditorsLibraryIncludesTheTextEditorAndB", resourceCulture); } } /// /// Looks up a localized string similar to The Eremex Controls library includes multiple editors that provide you with advanced data editing capabilities. The editors allow you to display and edit data of different data types (numeric, Boolean, date-time, enumerations, etc.). They support the data validation mechanism, styling, and embedding in container controls (Data Grid, Tree List, Property Grid, and Toolbars/Menus).. /// public static string TheEremexControlsLibraryIncludesMultipleEd { get { return ResourceManager.GetString("TheEremexControlsLibraryIncludesMultipleEd", resourceCulture); } } /// /// Looks up a localized string similar to The Hyperlink Editor displays its content as a hyperlink. The editor supports manual (default) and automatic hyperlink processing. A dedicated command or event allows you to manually handle hyperlink clicks. Enable automatic hyperlink navigation to allow the editor to automatically execute a link on a click.. /// public static string TheHyperlinkEditorDisplaysItsContentAsAHyp { get { return ResourceManager.GetString("TheHyperlinkEditorDisplaysItsContentAsAHyp", resourceCulture); } } /// /// Looks up a localized string similar to The Line series view shown in this example allows you to draw a chart by connecting points with lines.. /// public static string TheLineSeriesViewShownInThisExampleAllowsY { get { return ResourceManager.GetString("TheLineSeriesViewShownInThisExampleAllowsY", resourceCulture); } } /// /// Looks up a localized string similar to The Line series view shown in this example allows you to draw a chart by connecting points with lines.. /// public static string TheLineSeriesViewShownInThisExampleAllowsY1 { get { return ResourceManager.GetString("TheLineSeriesViewShownInThisExampleAllowsY1", resourceCulture); } } /// /// Looks up a localized string similar to The MxMessageBox dialog allows you to display messages and ask questions to users. The dialog supports the Eremex paint themes, and it looks consistent with other EMX Controls in your project. Use the visual elements on the right to customize and show a sample message box.. /// public static string TheMxMessageBoxDialogAllowsYouToDisplayMes { get { return ResourceManager.GetString("TheMxMessageBoxDialogAllowsYouToDisplayMes", resourceCulture); } } /// /// Looks up a localized string similar to The Scatter Line series view is useful when you need to connect points in the order in which they appear in the data series.. /// public static string TheScatterLineSeriesViewIsUsefulWhenYouNee { get { return ResourceManager.GetString("TheScatterLineSeriesViewIsUsefulWhenYouNee", resourceCulture); } } /// /// Looks up a localized string similar to The Scatter Line series view is useful when you need to connect points in the order in which they appear in the data series.. /// public static string TheScatterLineSeriesViewIsUsefulWhenYouNee1 { get { return ResourceManager.GetString("TheScatterLineSeriesViewIsUsefulWhenYouNee1", resourceCulture); } } /// /// Looks up a localized string similar to The Scatter Line series view is useful when you need to connect points in the order in which they appear in the data series.. /// public static string TheScatterLineSeriesViewIsUsefulWhenYouNee2 { get { return ResourceManager.GetString("TheScatterLineSeriesViewIsUsefulWhenYouNee2", resourceCulture); } } /// /// Looks up a localized string similar to The Spin Editor is a numeric value editor with built-in spin buttons used to increase and decrease a number by a specific value (increment). A user can increment and decrement the number by clicking these buttons, or by pressing the Up and Down Arrows on the keyboard. SpinEditor uses a numeric mask to restrict user input to numeric values only, and to format the edit value according to the specified pattern.. /// public static string TheSpinEditorIsANumericValueEditorWithBuil { get { return ResourceManager.GetString("TheSpinEditorIsANumericValueEditorWithBuil", resourceCulture); } } /// /// Looks up a localized string similar to The Step Area series view connects points with horizontal and vertical line segments, and fills the area between the lines and the X-axis with a specified color.. /// public static string TheStepAreaSeriesViewConnectsPointsWithHor { get { return ResourceManager.GetString("TheStepAreaSeriesViewConnectsPointsWithHor", resourceCulture); } } /// /// Looks up a localized string similar to The ToolbarManager component allows you to implement a classic toolbar and menu UI. You can dock toolbars not only at the edges of the window, but also at any specified position. Users can customize the toolbar layout using drag-and-drop operations. They can also display the Customization Window to access all (hidden and visible) toolbar items, and move the items using drag-and-drop operations.. /// public static string TheToolbarManagerComponentAllowsYouToImple { get { return ResourceManager.GetString("TheToolbarManagerComponentAllowsYouToImple", resourceCulture); } } /// /// Looks up a localized string similar to The Toolbars & Menu library contains a PopupMenu component that you can use to attach a context menu to any control. Eremex context menu style settings are consistent with all toolbar library components.. /// public static string TheToolbarsMenuLibraryContainsAPopupMenuCo { get { return ResourceManager.GetString("TheToolbarsMenuLibraryContainsAPopupMenuCo", resourceCulture); } } /// /// Looks up a localized string similar to The TreeList and TreeView controls support multiple node selection mode, which allows you and your user to select (highlight) multiple nodes at one time. Users can select multiple nodes with the mouse and keyboard. Click nodes while holding the CTRL and/or SHIFT key down for node selection.. /// public static string TheTreeListAndTreeViewControlsSupportMulti { get { return ResourceManager.GetString("TheTreeListAndTreeViewControlsSupportMulti", resourceCulture); } } /// /// Looks up a localized string similar to The Tree List control offers multiple ways to filter and search for data: /// • Column Filter Menus: Hover over a column header and click the filter button to open a menu. You can apply filters to one or multiple columns simultaneously. /// • Auto Filter Row: This dedicated row at the top allows you to type filter values directly into any column. The control instantly displays only the records that match your input. /// • Search Panel: Search for text across all columns. The Search Panel can be set to remain vis [rest of string was truncated]";. /// public static string TheTreeListSAutoFilterRowDisplayedAtTheTop { get { return ResourceManager.GetString("TheTreeListSAutoFilterRowDisplayedAtTheTop", resourceCulture); } } /// /// Looks up a localized string similar to This demo shows constant lines and strips used to highlight specific values and value ranges in the CartesianChart control. ///Right-click within the diagram to create a custom constant line for the X-axis.. /// public static string ThisDemoShowsConstantLinesAndStripsUsedToH { get { return ResourceManager.GetString("ThisDemoShowsConstantLinesAndStripsUsedToH", resourceCulture); } } /// /// Looks up a localized string similar to This example demonstrates a Graphics3DControl displaying a 3D model with a simple material. Use the Properties pane on the right to customize the material settings.. /// public static string ThisExampleDemonstratesAGraphics3DControlD1 { get { return ResourceManager.GetString("ThisExampleDemonstratesAGraphics3DControlD1", resourceCulture); } } /// /// Looks up a localized string similar to This example demonstrates a Graphics3DControl that renders a 3D model using lines.. /// public static string ThisExampleDemonstratesAGraphics3DControlT { get { return ResourceManager.GetString("ThisExampleDemonstratesAGraphics3DControlT", resourceCulture); } } /// /// Looks up a localized string similar to This example demonstrates a Graphics3DControl that renders a 3D model using points.. /// public static string ThisExampleDemonstratesAGraphics3DControlT1 { get { return ResourceManager.GetString("ThisExampleDemonstratesAGraphics3DControlT1", resourceCulture); } } /// /// Looks up a localized string similar to This example demonstrates dynamic transformations applied to 3D Models in a Graphics3DControl.. /// public static string ThisExampleDemonstratesDynamicTransformati { get { return ResourceManager.GetString("ThisExampleDemonstratesDynamicTransformati", resourceCulture); } } /// /// Looks up a localized string similar to This example demonstrates the isometric and perspective cameras supported by Graphics3DControl. Use the Camera pane on the right to choose camera mode and one of predefined camera views.. /// public static string ThisExampleDemonstratesTheIsometricAndPers { get { return ResourceManager.GetString("ThisExampleDemonstratesTheIsometricAndPers", resourceCulture); } } /// /// Looks up a localized string similar to This example demonstrates the Point series view, which allows you to plot individual points.. /// public static string ThisExampleDemonstratesThePointSeriesViewW { get { return ResourceManager.GetString("ThisExampleDemonstratesThePointSeriesViewW", resourceCulture); } } /// /// Looks up a localized string similar to This example demonstrates the Point series view, which allows you to plot individual points.. /// public static string ThisExampleDemonstratesThePointSeriesViewW1 { get { return ResourceManager.GetString("ThisExampleDemonstratesThePointSeriesViewW1", resourceCulture); } } /// /// Looks up a localized string similar to This example demonstrates the Point series view, which allows you to plot individual points on the Smith diagram.. /// public static string ThisExampleDemonstratesThePointSeriesViewW2 { get { return ResourceManager.GetString("ThisExampleDemonstratesThePointSeriesViewW2", resourceCulture); } } /// /// Looks up a localized string similar to This example demonstrates the Side-by-side Bar series view which visualizes data as a set of rectangular bars.. /// public static string ThisExampleDemonstratesTheSideBySideBarSer { get { return ResourceManager.GetString("ThisExampleDemonstratesTheSideBySideBarSer", resourceCulture); } } /// /// Looks up a localized string similar to This example demonstrates the Step Line series view, which connects points with horizontal and vertical line segments.. /// public static string ThisExampleDemonstratesTheStepLineSeriesVi { get { return ResourceManager.GetString("ThisExampleDemonstratesTheStepLineSeriesVi", resourceCulture); } } /// /// Looks up a localized string similar to Column bands allow you to visually combine columns together by displaying shared headers above them. Both band and column headers can include text, images, or custom content. The control allows you to create hierarchical bands with an unlimited number of nesting levels.. /// public static string TreeListColumnBandsDescription { get { return ResourceManager.GetString("TreeListColumnBandsDescription", resourceCulture); } } /// /// Looks up a localized string similar to TreeList can export data to XLSX (Microsoft Excel) and PDF formats. The Excel export feature is data-aware — it preserves the control's data shaping configuration (node hierarchy, data sorting, and value formatting) in the output XLSX document. The PDF rendering engine follows the WYSIWYG concept, which ensures the layout of TreeList elements is accurately reproduced in the output document.. /// public static string TreeListExportDescription { get { return ResourceManager.GetString("TreeListExportDescription", resourceCulture); } } /// /// Looks up a localized string similar to This demo emulates a dynamic mortgage calculator, built with the Data Grid and Cartersian Chart controls. Data Grid presents a detailed payment schedule as a table. The synchronized chart plots this data to show the relationship between principal and interest over the life of the loan.. /// public static string UseCasesGroupInfo_Desc { get { return ResourceManager.GetString("UseCasesGroupInfo_Desc", resourceCulture); } } /// /// Looks up a localized string similar to Use MemoEditor to display and edit large text in a popup window, with or without text wrapping enabled. The IsTextEditable property allows you to prevent text editing in the edit box. When the property is false, the edit box can display a special icon that indicates the presence of text in the popup.. /// public static string UseMemoEditorToDisplayAndEditLargeTextInAP { get { return ResourceManager.GetString("UseMemoEditorToDisplayAndEditLargeTextInAP", resourceCulture); } } /// /// Looks up a localized string similar to This demo is only available in Desktop mode. Download the . /// public static string WASMOnlyText1 { get { return ResourceManager.GetString("WASMOnlyText1", resourceCulture); } } /// /// Looks up a localized string similar to solution and run the DemoCenter.Desktop project to see this demo.. /// public static string WASMOnlyText2 { get { return ResourceManager.GetString("WASMOnlyText2", resourceCulture); } } /// /// Looks up a localized string similar to You can bind Tree List to a hierarchical data source, which returns child data through a collection property or special data selector. This demo shows how to create a selector that supplies the hierarchical structure of folders on your disk.. /// public static string YouCanBindTreeListToAHierarchicalDataSourc { get { return ResourceManager.GetString("YouCanBindTreeListToAHierarchicalDataSourc", resourceCulture); } } /// /// Looks up a localized string similar to You can create ComboBox and Segmented Editors' items from enumeration type values. Dedicated Data Annotation attributes applied to the enumeration values allow you to populate the controls' items with images, display text and tooltips.. /// public static string YouCanCreateComboBoxAndSegmentedEditorsIte { get { return ResourceManager.GetString("YouCanCreateComboBoxAndSegmentedEditorsIte", resourceCulture); } } /// /// Looks up a localized string similar to You can embed any control in Data Grid cells to present and edit cell data in the way you want. This demo demonstrates Eremex in-place editors: DateEditor, SpinEditor, and ComboBoxEditor. Data Grid boasts enhanced performance when you use Eremex editors in cells, particularly for large data sources.. /// public static string YouCanEmbedAnyControlInDataGridCellsToPres { get { return ResourceManager.GetString("YouCanEmbedAnyControlInDataGridCellsToPres", resourceCulture); } } /// /// Looks up a localized string similar to You can use the Segmented Editor to present a set of options as horizontally arranged segments. A user can click one of the segments to select a corresponding option, or CTRL-click on a selected segment to clear the selection. The editor allows you to populate segments from a list of strings, a list of business objects, or an enumeration type.. /// public static string YouCanUseTheSegmentedEditorToPresentASetOf { get { return ResourceManager.GetString("YouCanUseTheSegmentedEditorToPresentASetOf", resourceCulture); } } } } ================================================ FILE: DemoCenter/DemoCenter/Resources.resx ================================================ text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Eremex Tab Control can organize the contents of a bound item source into a tabbed UI. It supports tab re-ordering, multiple tab layout modes, and built-in buttons to add and close tabs. The MxMessageBox dialog allows you to display messages and ask questions to users. The dialog supports the Eremex paint themes, and it looks consistent with other EMX Controls in your project. Use the visual elements on the right to customize and show a sample message box. Split Container Control allows you to place content onto two panels, and separate the panels with a splitter that a user can drag to resize the panels. With the panel collapse feature enabled, the user can click the splitter to collapse and restore a panel. The Dock Manager component allows you to implement the classic docking UI found in popular IDEs. You can create tool panels that support dock, auto-hide, and float operations. Special Document containers are designed to display the main content of your window. You can create multiple Documents and organize them into a tabbed UI. The ToolbarManager component allows you to implement a classic toolbar and menu UI. You can dock toolbars not only at the edges of the window, but also at any specified position. Users can customize the toolbar layout using drag-and-drop operations. They can also display the Customization Window to access all (hidden and visible) toolbar items, and move the items using drag-and-drop operations. The Toolbars & Menu library contains a PopupMenu component that you can use to attach a context menu to any control. Eremex context menu style settings are consistent with all toolbar library components. The Chart Control supports instant display of rapidly changing real-time data. This example shows how to use a special data adapter to implement a moving viewport. The Chart Control's graphics rendering is optimized to display large data. The control provides high performance even when series contain millions of points This example demonstrates multiple axes in the CartesianChart control, along with the options to customize axis layout, position, labels, gridlines, and more. • Multiple Axes — The chart control allows you to create multiple X and Y axes and bind each data series to its own axes. • Axis Position — You can display specific X or Y axes opposite their default locations: X axes at the top, and Y axes at the right. • Swap Axes — With a single property, you can transpose the axes, so the Y axes are displayed horizontally and the X axes vertically. • Reverse Axis Direction — For individual axes, you can change the order of values from default (left-to-right and bottom-to-top) to reversed (right-to-left and top-to-bottom). • Scroll and Zoom Axes — You can click and drag with the mouse or use the mouse wheel over individual axes to scroll and zoom these axes, without affecting other axes. Chart Control supports logarithmic scales for any of its numeric axes. Log base 10 is default. You can specify a custom log base to change data scaling. This demo shows constant lines and strips used to highlight specific values and value ranges in the CartesianChart control. Right-click within the diagram to create a custom constant line for the X-axis. This example demonstrates the Point series view, which allows you to plot individual points. The Line series view shown in this example allows you to draw a chart by connecting points with lines. The Area series view allows you display filled areas. This view is helpful when you need to visually compare two or more data series. The Scatter Line series view is useful when you need to connect points in the order in which they appear in the data series. This example demonstrates the Step Line series view, which connects points with horizontal and vertical line segments. The Step Area series view connects points with horizontal and vertical line segments, and fills the area between the lines and the X-axis with a specified color. A data series in this example contains two Y-values for each data point. The Range Area view fills the area between these Y-values. This example demonstrates the Side-by-side Bar series view which visualizes data as a set of rectangular bars. A data series in this example contains two Y-values for each data point. The Side-by-side Range Bar view draws rectangular bars between these Y-values. The Candlestick series view allows you to create a financial chart that describes price movements of an asset. For each time period, the chart displays a data set that contains Open, Close, High and Low values. Stock data: https://www.investing.com/ In this demo, the Candlestick series view uses a special data adapter (SummaryCandlestickDataAdapter) that accepts raw tick data and builds candlesticks from it. Raw ticks are single price values of an asset, taken at specific points in time. The data adapter aggregates the raw prices into candlesticks according to a specified time (measure) unit. For instance, data can be aggregated to 1 second, 1 minute, 1 hour, 1 day, 1 week, etc. or to multiples of the selected time unit such as 5 seconds, 15 minutes, 2 days, etc. The Data Grid's grouping feature makes it easy to summarize information for users. They can group data by an unlimited number of columns by dragging columns onto the Group Panel. You can embed any control in Data Grid cells to present and edit cell data in the way you want. This demo demonstrates Eremex in-place editors: DateEditor, SpinEditor, and ComboBoxEditor. Data Grid boasts enhanced performance when you use Eremex editors in cells, particularly for large data sources. The data validation mechanism allows you to check cell values and show errors in cells that contain invalid data. You can use DataAnnotation attributes and IDataErrorInfo/INotifyDataErrorInfo interface to validate data at the ItemsSource level. Toggle the 'Show ItemsSource Errors' checkbox in this demo to see data validation errors from DataAnnotation attributes. Data Grid also allows you to use the ValidateCellValue event to implement custom rules to validate user input. The Data Grid offers multiple ways to filter and search for data: • Column Filter Menus: Hover over a column header and click the filter button to open a menu. You can apply filters to one or multiple columns simultaneously. • Auto Filter Row: This dedicated row at the top allows you to type filter values directly into any column. The grid instantly displays only the records that match your input. • Search Panel: Search for text across all columns. The Search Panel can be set to remain visible or activated with the Ctrl+F shortcut. Matching records are shown, and the text is highlighted within cells. • Filtering in Code: For advanced scenarios, you can create custom filter criteria and apply them programmatically using the control's API. Regardless of the number of columns and rows in the control, Data Grid remains responsive as you scroll the control horizontally or vertically, or sort/group its data. The built-in data virtualization mechanism updates only cells within the viewport to maintain high-performance scrolling Data Grid adapts row height to fit cell contents. Text columns can display data in a single or multiple lines. Assign a TextEditor in-place editor (or its descendant) to a column, and enable text wrapping to display text in multiple lines. In this demo, Data Grid emulates the Windows Task Manager by showing frequently updated fake processes. Data Grid supports automatic data updates if a bound item source implements the INotifyPropertyChanged interface. In this example, change notifications are supported for the underlying business object using the ObservableObject class (implements the INotifyPropertyChanged interface) and ObservableProperty attributes defined in the CommunityToolkit.Mvvm library. DataGrid supports multiple row selection mode, which allows you and your user to select (highlight) multiple rows at one time. Users can select multiple rows with the mouse and keyboard. Click rows while holding the CTRL and/or SHIFT key down for row selection. To keep essential data in view during horizontal scrolling, you can fix (pin) columns to the left or right edge. Once fixed, these columns remain stationary while other data scrolls. Enable the built-in 'Fixed' column menu to allow users to fix columns at runtime. Data Grid supports drag-and-drop operations within the control and to external controls (for instance, Tree List or another Data Grid).This example demonstrates drag-and-drop functionality within and between Data Grids. The AllowDragDrop option activates the drag-and-drop feature. {0}The AllowDragDropSortedRows option must be enabled to allow drag-and-drop operations for sorted/grouped Data Grids. When data is sorted or grouped, a drag-and-drop operation modifies values of a dragged row in sort columns. {1}In this example, the controls are bound to collections that contain the same business objects. This ensures automatic row movement during drag-and-drop operations from the source to the target grid. When you move a row from one grid to another, a corresponding item is moved between item sources of the two grid controls. Column bands allow you to visually combine columns together by displaying shared headers above them. Both band and column headers can include text, images, or custom content. This demo showcases the following features: • Band Generation from a Source — You can populate column bands from a band source defined in a View Model. • Hierarchical Bands — The control allows you to create hierarchical bands with an unlimited number of nesting levels. • Fixed Columns Support — Bands can work with fixed columns. When you pin (fix) a column, both the column and its band remain stationary during horizontal scrolling. The Eremex Controls library includes multiple editors that provide you with advanced data editing capabilities. The editors allow you to display and edit data of different data types (numeric, Boolean, date-time, enumerations, etc.). They support the data validation mechanism, styling, and embedding in container controls (Data Grid, Tree List, Property Grid, and Toolbars/Menus). The Editors library includes the Text Editor and Button Editor controls that provide base text editing capabilities: data validation, watermarks (hints displayed when the editor is empty), and multiple options to control text selection and data edit operations. The Button Editor supports an unlimited number of built-in regular and check buttons, which can display text or images at the left or right edge of the edit box. The Spin Editor is a numeric value editor with built-in spin buttons used to increase and decrease a number by a specific value (increment). A user can increment and decrement the number by clicking these buttons, or by pressing the Up and Down Arrows on the keyboard. SpinEditor uses a numeric mask to restrict user input to numeric values only, and to format the edit value according to the specified pattern. The ComboBox Editor features a dropdown list of items from which a user can select one or more items. The editor can display a list of strings, a list of business objects, or enumeration values. In multi-select mode, item check boxes allow the user to select multiple items at a time. You can use the Segmented Editor to present a set of options as horizontally arranged segments. A user can click one of the segments to select a corresponding option, or CTRL-click on a selected segment to clear the selection. The editor allows you to populate segments from a list of strings, a list of business objects, or an enumeration type. The Date Editor features a dropdown calendar that allows users to select a date. The calendar's navigation bar enables the user to browse through months and years. DateEditor uses a date-time mask to restrict user input to date-time values only, and to format the edit value according to the specified pattern. The Color Editor and Popup Color Editor controls allow a user to select a color. The controls support three color palettes: default (customizable in code), standard (fixed colors), and custom (customizable by users). The built-in Color Picker helps the user add custom colors from a color space, or specify color values in the RGB and HSB formats. The Hyperlink Editor displays its content as a hyperlink. The editor supports manual (default) and automatic hyperlink processing. A dedicated command or event allows you to manually handle hyperlink clicks. Enable automatic hyperlink navigation to allow the editor to automatically execute a link on a click. You can create ComboBox and Segmented Editors' items from enumeration type values. Dedicated Data Annotation attributes applied to the enumeration values allow you to populate the controls' items with images, display text and tooltips. Use MemoEditor to display and edit large text in a popup window, with or without text wrapping enabled. The IsTextEditable property allows you to prevent text editing in the edit box. When the property is false, the edit box can display a special icon that indicates the presence of text in the popup. Graphics3DControl allows you to visualize and interact with 3D models. Use the Properties pane on the right to customize the control's basic rendering and behavior settings. This example demonstrates a Graphics3DControl that renders a 3D model using lines. This example demonstrates a Graphics3DControl that renders a 3D model using points. This example demonstrates dynamic transformations applied to 3D Models in a Graphics3DControl. This example demonstrates a Graphics3DControl displaying a 3D model with a simple material. Use the Properties pane on the right to customize the material settings. In this example, a Graphics3DControl displays a 3D model with a textured material. Use the Materials pane on the right to choose the texture. This example demonstrates the isometric and perspective cameras supported by Graphics3DControl. Use the Camera pane on the right to choose camera mode and one of predefined camera views. A heatmap renders a 2-dimensional array of values as a color-encoded matrix. Each data point's color corresponds to the data point's value. This example demonstrates the Heatmap control which allows you to create heatmaps from your data. Click a color gradient on the right to apply this color encoding to the heatmap. Image source: Webb Space Telescope, https://webbtelescope.org/ In this example the Heatmap control uses custom color encoding to visualize the intensity of a sample signal changing in real time. A chart control at the top displays the amplitude of this signal. The controls update seamlessly as the underlying data changes using a timer. In a Polar Chart each data point is determined by an angle and a distance. This example demonstrates constant lines and strips used to highlight specific values and value ranges. Angle ranges and distance ranges are set in code of this demo. Left-click within a diagram to create custom constant lines for angles. Right-click to create custom constant lines for distances. This example demonstrates the Point series view, which allows you to plot individual points. The Line series view shown in this example allows you to draw a chart by connecting points with lines. The Area series view allows you display filled areas between a chart and point Zero. This view is helpful when you need to visually compare two or more data series. The Scatter Line series view is useful when you need to connect points in the order in which they appear in the data series. A data series in this example contains two Y-values for each data point. The Range Area view fills the area between these Y-values. Property Grid automatically detects the type of bound fields, and uses appropriate Eremex data editors to display and edit cell values. You can explicitly assign editors to specific fields to override the default behavior and customize editor settings. Property Grid tab rows allow you to group a set of fields into a tabbed UI. Each tab item in a row displays its own set of bound fields. RibbonControl allows you to integrate Microsoft Office-inspired navigation menus into your Avalonia UI applications. The control comes with two views: Classic (three item rows) and Simplified (one item row). The dropdown button at the control's bottom right corner opens a selector between these views. {0}RibbonControl supports multiple item types: large and small buttons, check buttons, sub-menus, in-place editors, inline and dropdown galleries, groups of buttons, and more. You can create as many pages with items as you need, and place items in the Quick Access Toolbar or the tab header area. {1}Press the ALT key to focus the Ribbon, and then use the keyboard to navigate between Ribbon elements and activate commands. This example demonstrates the Point series view, which allows you to plot individual points on the Smith diagram. The Scatter Line series view is useful when you need to connect points in the order in which they appear in the data series. The Tree List control offers multiple ways to filter and search for data: • Column Filter Menus: Hover over a column header and click the filter button to open a menu. You can apply filters to one or multiple columns simultaneously. • Auto Filter Row: This dedicated row at the top allows you to type filter values directly into any column. The control instantly displays only the records that match your input. • Search Panel: Search for text across all columns. The Search Panel can be set to remain visible or activated with the Ctrl+F shortcut. Matching records are shown, and the text is highlighted within cells. • Filtering in Code: For advanced scenarios, you can create custom filter criteria and apply them programmatically using the control's API. Eremex editors are used in Tree List cells by default to display and edit cell values of common data types (Boolean, integer, enumerations, etc.). This demo shows implicitly assigned in-place editors, and demonstrates how you can explicitly specify an editor for a Tree List column. You can bind Tree List to a hierarchical data source, which returns child data through a collection property or special data selector. This demo shows how to create a selector that supplies the hierarchical structure of folders on your disk. The TreeList and TreeView controls support multiple node selection mode, which allows you and your user to select (highlight) multiple nodes at one time. Users can select multiple nodes with the mouse and keyboard. Click nodes while holding the CTRL and/or SHIFT key down for node selection. Column bands allow you to visually combine columns together by displaying shared headers above them. Both band and column headers can include text, images, or custom content. The control allows you to create hierarchical bands with an unlimited number of nesting levels. This demo is only available in Desktop mode. Download the solution and run the DemoCenter.Desktop project to see this demo. Graphics3DControl supports the skybox feature, which provides a background for 3D scenes. The skybox is a large cube surrounding the entire scene, with six textured faces (front, back, left, right, top, and bottom). These textures are mapped to the cube's inner sides, creating the illusion of a distant sky, horizon, or backdrop. Graphics3DControl allows you to specify custom light sources for 3D scenes. Supported light types include: Point, Directional, Camera Point, and Camera Directional. Custom lights automatically disable the default light. Graphics3DControl supports model and mesh highlighting and selection. Highlighting draws a colored border around models or meshes when you hover over them with the mouse. With the selection feature, a colored border is painted around models or meshes when you click them. Use the HighlightMode and SelectionMode properties to choose whether highlighting/selection applies to models or meshes. The ShowHints property controls hint visibility for models and meshes. The Lollipop series view is a sleek, space-efficient alternative to traditional bar charts. Instead of bulky bars, it uses thin lines topped with markers to visualize data points. You can use default markers or specify custom markers in SVG format. The Orientation setting allows you to specify the direction of the lollipop lines (horizontal or vertical). This example demonstrates the Data Grid control's export functionality. Data Grid can export data to XLSX (Microsoft Excel) and PDF formats, while preserving data shaping options, including row grouping, sorting, and cell formatting. Export Exporting... Do you want to open the exported file? TreeList can export data to XLSX (Microsoft Excel) and PDF formats. The Excel export feature is data-aware — it preserves the control's data shaping configuration (node hierarchy, data sorting, and value formatting) in the output XLSX document. The PDF rendering engine follows the WYSIWYG concept, which ensures the layout of TreeList elements is accurately reproduced in the output document. This demo emulates a dynamic mortgage calculator, built with the Data Grid and Cartersian Chart controls. Data Grid presents a detailed payment schedule as a table. The synchronized chart plots this data to show the relationship between principal and interest over the life of the loan. This demo shows how a chart control handles incomplete datasets with the help of "empty points". These points allow you to create visible gaps in the series where values are missing. To specify an empty point, set its value to double.NaN, double.PositiveInfinity, or double.NegativeInfinity. The Stacked Area series view shows absolute relationships between all data series. Each series is rendered as a filled area stacked on the previous one, with its thickness representing its absolute value. The top line shows the cumulative total of all series. The Full Stacked Area series view (100% Stacked Area) shows proportional relationships between all data series. Each series is rendered as a filled area stacked on the previous one, with its thickness representing its percentage contribution to the total. The top line always indicates 100%. This demo showcases a 3D robotic arm loaded from an FBX file. Using the interactive panel on the right, you can manipulate each joint (from the base to the claw) by applying transformations to nested 3D models. Model by Ryan King Art https://sketchfab.com/ryankingart. This demo showcases a 3D model of a circuit board rendered in the Graphics3DControl. The example shows how you can import a complex model from an STL file using the Assimp library. The loaded geometry is used to initialize meshes, vertices and materials in the Graphics3DControl. ================================================ FILE: DemoCenter/DemoCenter/Resources.ru.resx ================================================ text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 MXTabControl позволяет организовать содержимое связанного источника элементов в виде интерфейса с вкладками. Он поддерживает возможность перестановки вкладок, различные варианты их отображения, а также встроенные кнопки для добавления и закрытия вкладок. MxMessageBox — диалоговое окно, которое позволяет показывать сообщения и задавать вопросы пользователям. Оно поддерживает темы оформления Eremex и гармонично сочетается с другими элементами управления EMX в вашем проекте. С помощью элементов управления справа вы можете настроить диалоговое окно и затем показать его. Split Container Control состоит из разделенных сплиттером двух панелей, на которых вы можете размещать другие контролы. Пользователь может перетаскивать сплиттер, чтобы изменять размер панелей. Если функция сворачивания панелей активна, можно щелкнуть по сплиттеру, чтобы свернуть или развернуть нужную панель. Компонент Dock Manager позволяет реализовать классический интерфейс Докинга, аналогичный тому, что используется в популярных средах разработки (IDE). С его помощью можно создавать панели инструментов, которые можно закреплять, переводить в режим свободного перемещения (плавающий режим) или настроить на автоматическое скрытие. Для отображения основного содержимого окна предусмотрены специальные контейнеры документов. Вы можете добавлять несколько документов и организовывать их в виде интерфейса с вкладками. Компонент ToolbarManager позволяет создать классические панели инструментов и меню. Панели инструментов можно закреплять не только по краям, но и в любом месте родительского контейнера. Пользователи могут изменять расположение элементов на панели инструментов с помощью перетаскивания. Также доступно окно настройки, где можно управлять всеми элементами панели инструментов (как скрытыми, так и видимыми) и перемещать их с помощью перетаскивания. Библиотека Toolbars&Menus содержит компонент PopupMenu, с помощью которого можно добавить контекстное меню к любому элементу управления. Дизайн контекстного меню выполнен в едином стиле и гармонично сочетается с другими компонентами библиотеки EMX Controls. Chart Control позволяет мгновенно отображать данные, которые быстро меняются в реальном времени. В данном примере показано, как с помощью специального адаптера данных можно реализовать движущееся окно просмотра. Механизм отрисовки в элементе управления Chart Control оптимизирован для обработки больших объемов данных. Он обеспечивает высокую производительность и плавное отображение, даже если серии содержат миллионы точек. Этот пример демонстрирует использование нескольких осей в элементе управления CartesianChart, а также возможности настройки макета осей, их положения, меток, линий сетки и других параметров. • Несколько осей — Элемент управления CartesianChart позволяет создавать несколько осей X и Y и привязывать каждую серию данных к собственным осям. • Положение оси — Вы можете отображать определённые оси X или Y напротив их стандартных расположений: оси X вверху, а оси Y справа. • Обмен осей — С помощью одного свойства вы можете транспонировать оси, чтобы оси Y отображались горизонтально, а оси X — вертикально. • Обратное направление оси — Для отдельных осей вы можете изменить порядок значений со стандартного (слева направо и снизу вверх) на обратный (справа налево и сверху вниз). • Прокрутка и масштабирование осей — Вы можете щёлкнуть и перетащить мышью или использовать колёсико мыши над отдельными осями для прокрутки и масштабирования этих осей, не затрагивая другие оси. Элемент управления Chart Control позволяет использовать логарифмические шкалы для любых числовых осей. По умолчанию применяется логарифм по основанию 10. Вы также можете задать собственное основание логарифма, чтобы изменить масштабирование данных. Этот пример показывает, как использовать постоянные линии и полосы для выделения определенных значений и диапазонов в элементе управления CartesianChart. Чтобы добавить постоянную линию для оси X, щелкните правой кнопкой мыши в области диаграммы. Этот пример показывает, как работает представление данных Point Series View, позволяющее отображать данные в виде точек. В этом примере демонстрируется представление данных Line Series View, которое позволяет построить график, где точки данных соединены линиями. Представление данных Area Series View позволяет заполнять области между графиками и осью X. Это представление полезно, когда вам нужно визуально сравнить две или более серии данных. Представление данных Scatter Line Series View позволяет соединить точки в том порядке, в котором они расположены в серии данных. Этот пример демонстрирует представление данных Step Line Series View, в котором точки соединены горизонтальными и вертикальными отрезками. В этом примере демонстрируется представление данных Step Area Series View. Оно позволяет соединить точки горизонтальными и вертикальными отрезками, а также залить области между графиками и осью X определенным цветом. Серия данных в этом примере содержит по два значения Y для каждой точки. Представление Range Area используется, чтобы заполнить области между этими значениями Y. Этот пример показывает, как работает представление данных Side-by-side Bar Series View. С помощью его вы можете отображать данные в виде столбцов, расположенных рядом друг с другом на оси X. В этом примере серия данных содержит по два значения Y для каждой точки. Представление данных Side-by-side Range Bar отображает столбцы, которые строятся между этими значениями Y. Представление данных Candlestick Series View позволяет строить финансовые диаграммы, отображающие изменения цен на актив. Для каждого временного интервала диаграмма показывает набор данных, включающий значения Open (открытие), Close (закрытие), High (максимум) и Low (минимум). Данные акций: https://www.investing.com/ В настоящем примере представление данных Candlestick Series View использует специальный адаптер данных (SummaryCandlestickDataAdapter). Этот адаптер принимает сырые тиковые данные — отдельные значения цены актива, зафиксированные в определенные моменты времени, — и преобразует их в свечи. Адаптер агрегирует сырые данные в свечи в соответствии с заданным временным интервалом. Например, данные могут быть сгруппированы в интервалы 1 секунда, 1 минута, 1 час, 1 день, 1 неделя и т.д., а также в кратные интервалы, такие как 5 секунд, 15 минут, 2 дня и т.д. В этом примере показана функция группировки данных в контроле Data Grid. Она позволяет объединять строки по значениям выбранных столбцов. Пользователи могут группировать данные по любому количеству столбцов, перетаскивая их на панель группировки. Вы можете добавлять любые UI-контролы в ячейки контрола Data Grid, чтобы отображать и редактировать данные в ячейках так, как вам удобно. Этот пример демонстрирует встраиваемые редакторы Eremex: DateEditor, SpinEditor и ComboBoxEditor. Data Grid обеспечивает высокую производительность при использовании редакторов Eremex, особенно при работе с большими объемами данных. Механизм валидации данных позволяет проверять значения ячеек и отображать ошибки в ячейках, содержащих недопустимые данные. Вы можете использовать атрибуты DataAnnotation и интерфейсы IDataErrorInfo/INotifyDataErrorInfo для проверки данных на уровне источника данных (ItemsSource). В этом примере включите флажок 'Show ItemsSource Errors', чтобы увидеть ошибки валидации, основанные на атрибутах DataAnnotation. Data Grid также поддерживает событие ValidateCellValue, которое позволяет реализовать пользовательские правила проверки ввода. Data Grid предоставляет несколько способов фильтрации и поиска данных: • Фильтры столбцов: Наведите курсор на заголовок столбца и нажмите кнопку фильтра, чтобы открыть меню. Вы можете применять фильтры к одному или нескольким столбцам одновременно. • Строка автоматического фильтра: Эта специальная строка вверху позволяет вводить значения фильтра непосредственно в любой столбец. Data Grid отобразит только записи, соответствующие вашему вводу. • Панель поиска: Выполняется поиск текста по всем столбцам. Панель поиска можно настроить на постоянное отображение или активировать с помощью сочетания клавиш Ctrl+F. Отобразятся подходящие записи, а текст подсветится внутри ячеек. • Фильтрация в коде: Для сложных сценариев вы можете создавать пользовательские условия фильтрации и применять их программно с помощью API элемента управления. Независимо от количества столбцов и строк, Data Grid сохраняет высокую отзывчивость при горизонтальной и вертикальной прокрутке, а также при сортировке и группировке данных. Встроенный механизм виртуализации данных обновляет только те ячейки, которые находятся в видимой области, что обеспечивает плавную и быструю прокрутку. Data Grid может автоматически изменять высоту строк в зависимости от содержимого ячеек. Текстовые столбцы могут отображать данные в одну или несколько строк. Чтобы включить многострочное отображение текста, назначьте столбцу встроенный редактор TextEditor (или его наследника) и активируйте функцию переноса текста. В этом примере Data Grid имитирует Диспетчер задач Windows, отображая часто обновляемые фиктивные процессы. Data Grid поддерживает автоматическое обновление данных, если связанный источник данных реализует интерфейс INotifyPropertyChanged. В данном примере уведомления об изменениях реализованы для базового бизнес-объекта с использованием класса ObservableObject (который реализует интерфейс INotifyPropertyChanged) и атрибутов ObservableProperty из библиотеки CommunityToolkit.Mvvm. Data Grid поддерживает режим множественного выбора строк, позволяющий выделять несколько строк одновременно. Пользователи могут выбирать строки с помощью мыши и клавиатуры. Для выделения строк щелкните по ним мышью, удерживая клавиши CTRL и/или SHIFT. Чтобы важные данные были постоянно видны при горизонтальной прокрутке, вы можете зафиксировать (закрепить) колонки к левому или правому краю. После "фиксации" эти колонки остаются неподвижными, в то время как другие данные будут скролироваться. Включите встроенное меню «Зафиксировать» для колонок, чтобы пользователи могли закреплять колонки во время работы приложения. Data Grid поддерживает операции перетаскивания как внутри себя, так и на внешние контролы (например, Tree List или другой Data Grid). Этот пример демонстрирует функциональность перетаскивания внутри и между контролами Data Grid. Опция AllowDragDrop активирует функцию перетаскивания. {0} Опция AllowDragDropSortedRows должна быть включена, чтобы разрешить перетаскивание в отсортированных или сгруппированных контролах Data Grid. Если данные отсортированы или сгруппированы, операция перетаскивания изменяет значения перетаскиваемой строки в столбцах, используемых для сортировки. {1} В этом примере контролы привязаны к коллекциям, содержащим одинаковые бизнес-объекты. Это позволяет автоматически перемещать строки при перетаскивании из исходного грида в целевой. Когда вы перемещаете строку из одного грида в другой, соответствующий элемент данных перемещается между источниками данных двух гридов. Бэнды (группы колонок) помогают визуально объединить колонки, отображая над ними общие заголовки. Заголовки бэндов и столбцов могут содержать текст, изображения или пользовательский контент. В этом примере демонстрируются следующие возможности: • Создание бэндов из источника — Вы можете генерировать бэнды из источника, определенного в модели представления. • Иерархические бэнды — Контрол позволяет создавать иерархические бэнды с неограниченным числом уровней вложенности. • Поддержка фиксированных колонок — Когда вы закрепляете (фиксируете) колонку, и колонка и её бэнд остаются неподвижными при горизонтальной прокрутке. Библиотека контролов Eremex включает несколько редакторов, которые предлагают расширенные возможности для редактирования данных. Эти редакторы позволяют отображать и изменять данные различных типов, такие как числовые, логические, дата-время, перечисления и другие. Они поддерживают механизм валидации, стилизацию и возможность встраивания в контейнеры, такие как Data Grid, Tree List, Property Grid, Ribbon, а также Toolbars&Menus. Библиотека редакторов включает элементы управления Text Editor и Button Editor, которые предоставляют базовые функции для редактирования текста: проверку данных (валидацию), водяные знаки (подсказки, которые отображаются, если редактор пуст), а также различные опции для управления выбором текста и операциями редактирования. Button Editor поддерживает неограниченное количество встроенных кнопок, как обычных, так и переключаемых, которые могут отображать текст или изображение и располагаться справа или слева. Spin Editor — это редактор числовых значений, оснащенный кнопками вверх и вниз, которые позволяют увеличивать или уменьшать число на заданное значение (инкремент). Пользователь может изменять значение, нажимая эти кнопки или используя клавиши со стрелками вверх и вниз на клавиатуре. Spin Editor использует числовую маску, чтобы ограничить ввод только числовыми значениями и отформатировать редактируемое значение в соответствии с указанным шаблоном. Редактор ComboBox Editor предоставляет выпадающий список элементов, из которых пользователь может выбрать один или несколько вариантов. Редактор может отображать список строк, список бизнес-объектов или значения перечисления. В режиме множественного выбора флажки рядом с элементами позволяют пользователю выбирать несколько элементов одновременно. Вы можете использовать Segmented Editor для отображения набора опций в виде горизонтально расположенных сегментов. Пользователь может щелкнуть по одному из сегментов, чтобы выбрать соответствующую опцию, или нажать CTRL + щелчок на выбранном сегменте, чтобы снять выделение. Редактор позволяет создавать сегменты из списка строк, списка бизнес-объектов или значений перечисления. Редактор Date Editor предоставляет выпадающий календарь, который позволяет пользователям выбирать дату. Панель навигации календаря дает возможность перемещаться между месяцами и годами. Date Editor использует маску даты и времени, чтобы ограничить ввод пользователя только допустимыми значениями даты и времени, а также отформатировать редактируемое значение в соответствии с заданным шаблоном. Элементы управления Color Editor и Popup Color Editor позволяют пользователю выбирать цвет. Они поддерживают три цветовые палитры: по умолчанию (которую можно настроить в коде), стандартную (с фиксированными цветами) и пользовательскую (которую может настраивать сам пользователь). Встроенный Color Picker помогает пользователю добавлять пользовательские цвета из цветового пространства или задавать значения цвета в форматах RGB и HSB. Редактор Hyperlink Editor отображает содержимое в виде гиперссылки. Он поддерживает ручную (по умолчанию) и автоматическую обработку гиперссылок. Специальная команда или событие позволяет обрабатывать клики по гиперссылкам. Вы можете включить автоматическую навигацию, чтобы редактор автоматически переходил по ссылке при клике. Вы можете создавать элементы для контролов ComboBox и Segmented Editor на основе значений типа перечисления. С помощью специальных атрибутов Data Annotation, примененных к значениям перечисления, можно задать изображения, текст и подсказки для этих элементов. Используйте редактор MemoEditor для отображения и редактирования больших текстов в выпадающем окне, с возможностью включения или отключения переноса текста. Свойство IsTextEditable позволяет запретить редактирование текста в поле ввода. Если свойство установлено в значение false, поле ввода может отображать специальный значок, указывающий на наличие текста в выпадающем окне. Graphics3DControl позволяет отображать и взаимодействовать с 3D-моделями. С помощью панели свойств справа вы можете настроить основные параметры рендеринга и поведения контрола. Этот пример показывает, как использовать контрол Graphics3DControl для отображения 3D-модели с помощью линий. Этот пример показывает, как использовать контрол Graphics3DControl для отображения 3D-модели с помощью точек. Этот пример демонстрирует динамические преобразования, применяемые к 3D-моделям в элементе управления Graphics3DControl. Этот пример показывает, как отобразить 3D-модель с простым материалом в контроле Graphics3DControl. С помощью панели свойств справа вы можете настроить параметры материала. Этот пример демонстрирует, как отобразить 3D-модель с текстурированным материалом в контроле Graphics3DControl. С помощью панели материалов справа вы можете выбрать текстуру. Этот пример показывает, как работают изометрические и перспективные камеры в контроле Graphics3DControl. С помощью панели справа вы можете выбрать режим камеры и один из предустановленных видов. Тепловая карта визуализирует двумерный массив значений в виде цветовой матрицы, где цвет каждой точки соответствует ее значению. Этот пример демонстрирует контрол Heatmap, позволяющий создавать тепловые карты на основе ваших данных. Щелкните по цветовому градиенту справа, чтобы применить это цветовое кодирование к тепловой карте. Источник изображения: Webb Space Telescope, https://webbtelescope.org/ В этом примере контрол Heatmap применяет пользовательское цветовое кодирование для отображения интенсивности сигнала, который изменяется в реальном времени. График в верхней части окна показывает амплитуду этого сигнала. Элементы управления плавно обновляются по мере изменения данных с использованием таймера. В полярной диаграмме каждая точка данных определяется углом и расстоянием. Этот пример показывает, как используются постоянные линии и полосы для выделения конкретных значений и диапазонов. Диапазоны углов и расстояний задаются в коде этого примера. Щелкните левой кнопкой мыши внутри диаграммы, чтобы создать пользовательские постоянные линии для углов. Щелкните правой кнопкой мыши, чтобы создать пользовательские постоянные линии для расстояний. Этот пример показывает, как работает представление данных Point Series View, позволяющее отображать данные в виде точек. В этом примере демонстрируется представление данных Line Series View, которое позволяет построить график, где точки данных соединены линиями. Представление данных Area Series View позволяет заполнять области между графиками и осью X. Это представление полезно, когда вам нужно визуально сравнить две или более серии данных. Представление данных Scatter Line Series View позволяет соединить точки в том порядке, в котором они расположены в серии данных. Серия данных в этом примере содержит по два значения Y для каждой точки. Представление Range Area используется, чтобы заполнить области между этими значениями Y. Контрол Property Grid автоматически определяет тип связанных полей и использует соответствующие редакторы Eremex для отображения и редактирования значений ячеек. Вы можете явно назначить редакторы для конкретных полей, чтобы переопределить поведение по умолчанию и настроить параметры редактора. Строки-вкладки в контроле Property Grid позволяют организовать набор полей в интерфейс с вкладками (Tabbed UI). Каждая вкладка может отображать свой собственный набор полей. Контрол RibbonControl позволяет добавлять навигационные меню в стиле Microsoft Office в ваши приложения на Avalonia UI. Элемент управления поддерживает два режима отображения: Классический (три строки элементов) и Упрощенный (одна строка элементов). Нажатие на кнопку в правом нижнем углу контрола открывает список, с помощью которого пользователь может выбрать один из этих двух режимов. {0}RibbonControl поддерживает различные типы элементов: большие и маленькие кнопки, переключаемые кнопки, подменю, встроенные редакторы, встроенные и выпадающие галереи, группы кнопок и многое другое. Вы можете создать любое количество страниц с элементами и разместить элементы на панели быстрого доступа или в области заголовков вкладок. {1}Нажмите клавишу ALT, чтобы перевести фокус на RibbonControl, а затем используйте клавиатуру для навигации между элементами риббона и активации команд. Этот пример показывает, как работает представление данных Point Series View, позволяющее отображать данные в виде точек на диаграмме Смита. Этот пример показывает, как работает представление данных Scatter Line Series View. Оно позволяет соединить точки в том порядке, в котором они расположены в серии данных. Tree List предоставляет несколько способов фильтрации и поиска данных: • Фильтры столбцов: Наведите курсор на заголовок столбца и нажмите кнопку фильтра, чтобы открыть меню. Вы можете применять фильтры к одному или нескольким столбцам одновременно. • Строка автоматического фильтра: Эта специальная строка вверху позволяет вводить значения фильтра непосредственно в любой столбец. Tree List отобразит только записи, соответствующие вашему вводу. • Панель поиска: Выполняется поиск текста по всем столбцам. Панель поиска можно настроить на постоянное отображение или активировать с помощью сочетания клавиш Ctrl+F. Отобразятся подходящие записи, а текст подсветится внутри ячеек. • Фильтрация в коде: Для сложных сценариев вы можете создавать пользовательские условия фильтрации и применять их программно с помощью API элемента управления. Редакторы Eremex по умолчанию применяются в ячейках Tree List для отображения и редактирования значений ячеек стандартных типов данных (логические, целые числа, перечисления и т.д.). Этот пример демонстрирует неявно назначенные встроенные редакторы, а также показывает, как можно явно указать редактор для столбца. Вы можете привязать Tree List к иерархическому источнику данных, который возвращает дочерние элементы через свойство коллекции или специальный селектор. Этот пример демонстрирует, как создать селектор, который предоставляет иерархическую структуру папок на вашем диске. Контролы TreeList и TreeView поддерживают режим множественного выбора строк, позволяющий выделять несколько строк одновременно. Пользователи могут осуществлять множественный выбор с помощью мыши и клавиатуры. Для выбора строк удерживайте клавиши CTRL и/или SHIFT и нажмите на строки кнопкой мыши. Бэнды (группы колонок) помогают визуально объединить колонки, отображая над ними общие заголовки. Заголовки бэндов и столбцов могут содержать текст, изображения или пользовательский контент. Вы можете создавать иерархические бэнды с неограниченным числом уровней вложенности. Этот демо модуль доступен только в режиме для ПК. Скачайте приложение и запустите проект DemoCenter.Desktop Graphics3DControl поддерживает функцию Skybox, которая обеспечивает фон для 3D-сцен. Skybox представляет собой большой куб, окружающий всю сцену, с шестью текстурированными гранями (передняя, задняя, левая, правая, верхняя и нижняя). Эти текстуры накладываются на внутренние стороны куба, создавая иллюзию далекого неба, горизонта или фона. Graphics3DControl позволяет задавать пользовательские источники света для 3D-сцен. Поддерживаемые типы освещения: точечный (Point), направленный (Directional), точечный от камеры (Camera Point) и направленный от камеры (Camera Directional). При использовании пользовательского освещения стандартный источник света автоматически отключается. Graphics3DControl поддерживает подсветку и выделение моделей и мешей. Подсветка рисует цветную рамку вокруг моделей или мешей при наведении на них курсора мыши. Функция выделения окрашивает рамку вокруг моделей или мешей при клике на них. Используйте свойства HighlightMode и SelectionMode, чтобы выбрать, применяется ли подсветка/выделение к моделям или мешам. Свойство ShowHints управляет отображением подсказок для моделей и мешей. Представление серии "Леденцы" — это элегантная и компактная альтернатива традиционным гистограммам. Вместо громоздких столбцов оно использует тонкие линии с маркерами на концах для визуализации точек данных. Вы можете использовать стандартные маркеры или указать собственные маркеры в формате SVG. Настройка "Ориентация" позволяет задать направление линий "леденцов" (горизонтальное или вертикальное). Данный пример демонстрирует функциональность экспорта Data Grid. Data Grid может экспортировать данные в форматы XLSX (Microsoft Excel) и PDF, сохраняя при этом настройки группировки строк, сортировки данных и форматирование ячеек. Экспорт Выполняется экспорт... Вы хотите открыть экспортированный файл? Компонент TreeList позволяет экспортировать данные в форматы XLSX (Microsoft Excel) и PDF. Функция экспорта в Excel сохраняет иерархию узлов, сортировку данных и форматирование значений в результирующем XLSX документе. Механизм рендеринга PDF следует концепции WYSIWYG, что гарантирует точное воспроизведение компоновки элементов TreeList в результирующем документе. Это демо-приложение эмулирует ипотечный калькулятор, созданный с помощью элементов управления Data Grid (таблица данных) и Cartesian Chart (декартов график). Data Grid представляет детальный график платежей в виде таблицы. Синхронизированный график отображает эти данные, показывая соотношение основного долга и процентов в течение всего срока кредита. Диаграмма поддерживает работу с неполными наборами данных. Используйте "пустые точки", чтобы создать видимые разрывы в серии там, где значения отсутствуют. Чтобы задать пустую точку, установите её значение как double.NaN, double.PositiveInfinity или double.NegativeInfinity. Вид серии "Область с накоплением" показывает абсолютные соотношения между всеми рядами данных. Каждый ряд отображается в виде залитой области, наложенной на предыдущую, где её толщина представляет абсолютное значение. Верхняя линия показывает совокупную сумму всех рядов. Вид серии "Область с полным накоплением" (100% область с накоплением) показывает пропорциональные соотношения между всеми рядами данных. Каждый ряд отображается в виде залитой области, наложенной на предыдущую, где её толщина представляет процентный вклад в общую сумму. Верхняя линия всегда указывает на 100%. В этой демонстрации представлен 3D-манипулятор, загруженный из файла FBX. С помощью интерактивной панели справа вы можете управлять каждым шарниром (от основания до захватного механизма), применяя преобразования к вложенным 3D-моделям. Модель от Ryan King Art https://sketchfab.com/ryankingart. Эта демонстрация представляет 3D-модель печатной платы, отображаемую в элементе управления Graphics3DControl. В примере показано, как можно импортировать сложную модель из файла STL с помощью библиотеки Assimp. Загруженная геометрия используется для инициализации сеток, вершин и материалов в Graphics3DControl. ================================================ FILE: DemoCenter/DemoCenter/Resources.zh-Hans.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Eremex Tab Control 可以将绑定项源的内容组织成选项卡式用户界面。它支持选项卡重新排序、多种选项卡布局模式以及用于添加和关闭选项卡的内置按钮。 MxMessageBox 对话框允许您向用户显示消息并提问。该对话框支持 Eremex 绘制主题,并且与项目中的其他 EMX 控件保持一致。使用右侧的可视元素自定义并显示示例消息框。 Split Container Control 允许您将内容放置在两个面板上,并通过用户可拖动的分隔条来调整面板大小。启用面板折叠功能后,用户可以单击分隔条以折叠和恢复面板。 Dock Manager 组件允许您实现流行 IDE 中的经典停靠用户界面。您可以创建支持停靠、自动隐藏和浮动操作的工具面板。特殊的文档容器设计用于显示窗口的主要内容。您可以创建多个文档并将其组织成选项卡式用户界面。 ToolbarManager 组件允许您实现经典的工具栏和菜单用户界面。您不仅可以将工具栏停靠在窗口边缘,还可以停靠在任何指定位置。用户可以使用拖放操作自定义工具栏布局。他们还可以显示自定义窗口以访问所有(隐藏和可见的)工具栏项,并使用拖放操作移动这些项。 工具栏和菜单库包含一个 PopupMenu 组件,您可以使用它将上下文菜单附加到任何控件。Eremex 上下文菜单样式设置与所有工具栏库组件一致。 Chart Control 支持即时显示快速变化的实时数据。此示例展示了如何使用特殊的数据适配器实现移动视口。 Chart Control 的图形渲染经过优化,可以显示大量数据。即使系列包含数百万个点,控件仍能提供高性能。 这个示例演示了 CartesianChart 控件中的多重坐标轴功能,以及自定义坐标轴布局、位置、标签、网格线等选项。 • 多重坐标轴 — CartesianChart 控件允许创建多个 X 轴和 Y 轴,并将每个数据序列绑定到各自的坐标轴。 • 坐标轴位置 — 您可以将特定的 X 轴或 Y 轴显示在默认位置的另一侧:X 轴位于顶部,Y 轴位于右侧。 • 交换坐标轴 — 通过单个属性即可交换坐标轴,使 Y 轴水平显示,X 轴垂直显示。 • 反转坐标轴方向 — 对于单个坐标轴,您可以将数值顺序从默认的(从左到右、从下到上)改为反转方向(从右到左、从上到下)。 • 滚动和缩放坐标轴 — 您可以通过鼠标点击拖拽或在单个坐标轴上使用鼠标滚轮来滚动和缩放这些轴,而不会影响其他坐标轴。 Chart Control 支持对其任何数值轴使用对数刻度。默认情况下使用以 10 为底的对数。您可以指定自定义对数底数以更改数据缩放比例。 此演示展示了用于在 CartesianChart 控件中突出显示特定值和值范围的常量和带状区域。右键单击图表以创建 X 轴的自定义常量线。 此示例展示了点系列视图,它允许您绘制单个点。 此示例中展示的线系列视图允许您通过连接点来绘制图表。 区域系列视图允许您显示填充区域。当您需要直观地比较两个或多个数据系列时,此视图非常有用。 散点线系列视图在您需要按数据系列中出现的顺序连接点时非常有用。 此示例展示了阶梯线系列视图,它通过水平和垂直线段连接点。 阶梯区域系列视图通过水平和垂直线段连接点,并使用指定颜色填充线与 X 轴之间的区域。 此示例中的数据系列包含每个数据点的两个 Y 值。范围区域视图填充这些 Y 值之间的区域。 此示例展示了并排条形系列视图,它将数据可视化为一组矩形条。 此示例中的数据系列包含每个数据点的两个 Y 值。并排范围条形视图在这些 Y 值之间绘制矩形条。 蜡烛图系列视图允许您创建描述资产价格变动的金融图表。对于每个时间段,图表显示包含开盘价、收盘价、最高价和最低价的数据集。 股票数据:https://www.investing.com/ 在此演示中,蜡烛图系列视图使用特殊的数据适配器(SummaryCandlestickDataAdapter),它接受原始价格数据并从中构建蜡烛图。 原始价格是资产在特定时间点的单个价格值。数据适配器根据指定的时间单位将原始价格聚合为蜡烛图。 例如,数据可以聚合为 1 秒、1 分钟、1 小时、1 天、1 周等,或聚合为选定时间单位的倍数,例如 5 秒、15 分钟、2 天等。 Data Grid 的分组功能使用户可以轻松汇总信息。他们可以通过将列拖到分组面板上来按无限数量的列对数据进行分组。 您可以在 Data Grid 单元格中嵌入任何控件,以按您希望的方式呈现和编辑单元格数据。此演示展示了 Eremex 的内置编辑器:DateEditor、SpinEditor 和 ComboBoxEditor。当您在单元格中使用 Eremex 编辑器时,Data Grid 的性能会显著提高,尤其是在处理大型数据源时。 数据验证机制允许您检查单元格值并显示包含无效数据的单元格中的错误。您可以使用 DataAnnotation 属性和 IDataErrorInfo/INotifyDataErrorInfo 接口在 ItemsSource 级别验证数据。在此演示中切换“显示 ItemsSource 错误”复选框以查看来自 DataAnnotation 属性的数据验证错误。Data Grid 还允许您使用 ValidateCellValue 事件来实现自定义规则以验证用户输入。 Data Grid 提供了多种过滤和搜索数据的方法: • 列过滤菜单: 将鼠标悬停在列标题上,然后单击过滤按钮以打开菜单。您可以同时对一个或多个列应用过滤器。 • 自动过滤行: 顶部的这一专用行允许您直接将过滤值输入到任何列中。网格会立即显示仅与您输入的内容匹配的记录。 • 搜索面板: 在所有列中搜索文本。搜索面板可以设置为始终可见,或通过 Ctrl+F 快捷键激活。匹配的记录会被显示,并且文本在单元格内高亮显示。 • 代码中的过滤: 对于高级场景,您可以创建自定义过滤条件,并使用控件的 API 以编程方式应用它们。 无论控件中有多少列和行,Data Grid 在水平或垂直滚动或排序/分组数据时仍能保持响应。内置的数据虚拟化机制仅更新视口内的单元格,以保持高性能滚动。 Data Grid 会调整行高以适应单元格内容。文本列可以以单行或多行显示数据。为列分配 TextEditor 内置编辑器(或其派生类),并启用文本换行以多行显示文本。 在此演示中,Data Grid 通过显示频繁更新的模拟进程来模拟 Windows 任务管理器。如果绑定项源实现了 INotifyPropertyChanged 接口,Data Grid 支持自动数据更新。在此示例中,使用 ObservableObject 类(实现 INotifyPropertyChanged 接口)和 CommunityToolkit.Mvvm 库中定义的 ObservableProperty 属性支持对基础业务对象的更改通知。 DataGrid 支持多行选择模式,允许您和用户一次选择(突出显示)多行。用户可以使用鼠标和键盘选择多行。按住 CTRL 和/或 SHIFT 键单击行以选择行。 要在水平滚动期间保留基本数据,您可以将列固定(固定)到左侧或右侧边缘。一旦固定,这些列将保持静止,而其他数据则滚动。启用内置的“固定”列菜单以允许用户在运行时修复列。 Data Grid 支持在控件内部和外部控件(例如 Tree List 或另一个 Data Grid)之间进行拖放操作。此示例展示了在 Data Grid 内部和之间的拖放功能。AllowDragDrop 选项激活拖放功能。{0}必须启用 AllowDragDropSortedRows 选项以允许对已排序/分组的 Data Grid 进行拖放操作。当数据已排序或分组时,拖放操作会修改拖动行在排序列中的值。{1}在此示例中,控件绑定到包含相同业务对象的集合。这确保了在从源网格到目标网格的拖放操作期间自动移动行。当您将一行从一个网格移动到另一个网格时,相应的项会在两个网格控件的项源之间移动。 列带允许您通过在列上方显示共享标题,将列以可视方式组合在一起。列带和列标题均可包含文本、图像或自定义内容。此演示展示了以下功能: • 从源生成列带 — 您可以从视图模型中定义的列带源填充列带。 • 分层列带 — 该控件允许您创建具有无限嵌套级别的分层列带。 • 固定列支持 — 列带可以与固定列配合使用。当您固定列时,该列及其列带在水平滚动期间将保持静止。 Eremex 控件库包括多个编辑器,为您提供高级数据编辑功能。这些编辑器允许您显示和编辑不同数据类型(数字、布尔值、日期时间、枚举等)的数据。它们支持数据验证机制、样式设置以及嵌入到容器控件(Data Grid、Tree List、Property Grid 和工具栏/菜单)中。 编辑器库包括 Text Editor 和 Button Editor 控件,它们提供基本的文本编辑功能:数据验证、水印(编辑器为空时显示的提示)以及控制文本选择和数据编辑操作的多个选项。Button Editor 支持无限数量的内置常规按钮和复选框按钮,它们可以在编辑框的左侧或右侧显示文本或图像。 Spin Editor 是一个数值编辑器,带有用于按特定值(增量)增加和减少数字的内置旋转按钮。用户可以通过单击这些按钮或按键盘上的上下箭头来增加和减少数字。SpinEditor 使用数字掩码将用户输入限制为仅数字值,并根据指定的模式格式化编辑值。 ComboBox Editor 具有一个下拉列表,用户可以从列表中选择一个或多个项目。编辑器可以显示字符串列表、业务对象列表或枚举值。在多选模式下,项目复选框允许用户一次选择多个项目。 您可以使用 Segmented Editor 将一组选项呈现为水平排列的段。用户可以单击其中一个段以选择相应的选项,或按住 CTRL 键单击选定的段以清除选择。编辑器允许您从字符串列表、业务对象列表或枚举类型填充段。 Date Editor 具有一个下拉日历,允许用户选择日期。日历的导航栏使用户可以浏览月份和年份。DateEditor 使用日期时间掩码将用户输入限制为仅日期时间值,并根据指定的模式格式化编辑值。 Color Editor 和 Popup Color Editor 控件允许用户选择颜色。这些控件支持三种调色板:默认(可在代码中自定义)、标准(固定颜色)和自定义(用户可自定义)。内置的颜色选择器帮助用户从颜色空间添加自定义颜色,或以 RGB 和 HSB 格式指定颜色值。 Hyperlink Editor 将其内容显示为超链接。编辑器支持手动(默认)和自动超链接处理。专用命令或事件允许您手动处理超链接点击。启用自动超链接导航以允许编辑器在点击时自动执行链接。 您可以从枚举类型值创建 ComboBox 和 Segmented Editors 的项目。应用于枚举值的专用 Data Annotation 属性允许您使用图像、显示文本和工具提示填充控件的项目。 使用 MemoEditor 在弹出窗口中显示和编辑大文本,无论是否启用文本换行。IsTextEditable 属性允许您防止在编辑框中编辑文本。当该属性为 false 时,编辑框可以显示一个特殊图标,指示弹出窗口中存在文本。 Graphics3DControl 允许您可视化和与 3D 模型交互。使用右侧的属性窗格自定义控件的基本渲染和行为设置。 此示例展示了一个使用线条渲染 3D 模型的 Graphics3DControl。 此示例展示了一个使用点渲染 3D 模型的 Graphics3DControl。 此示例展示了应用于 Graphics3DControl 中 3D 模型的动态变换。 此示例展示了一个显示具有简单材质的 3D 模型的 Graphics3DControl。使用右侧的属性窗格自定义材质设置。 在此示例中,Graphics3DControl 显示具有纹理材质的 3D 模型。使用右侧的材质窗格选择纹理。 此示例展示了 Graphics3DControl 支持的等距和透视相机。使用右侧的相机窗格选择相机模式和预定义的相机视图之一。 热力图将二维数组的值渲染为颜色编码的矩阵。每个数据点的颜色对应于数据点的值。此示例展示了热力图控件,它允许您从数据创建热力图。单击右侧的颜色渐变以将此颜色编码应用于热力图。 图片来源:韦伯太空望远镜,https://webbtelescope.org/ 在此示例中,热力图控件使用自定义颜色编码来实时可视化样本信号的强度变化。顶部的图表控件显示此信号的振幅。控件在底层数据变化时通过计时器无缝更新。 在极坐标图中,每个数据点由角度和距离确定。此示例展示了用于突出显示特定值和值范围的常量和带状区域。角度范围和距离范围在此演示的代码中设置。在图表内左键单击以创建角度的自定义常量线。右键单击以创建距离的自定义常量线。 此示例展示了点系列视图,它允许您绘制单个点。 此示例中展示的线系列视图允许您通过连接点来绘制图表。 区域系列视图允许您显示图表与零点之间的填充区域。当您需要直观地比较两个或多个数据系列时,此视图非常有用。 散点线系列视图在您需要按数据系列中出现的顺序连接点时非常有用。 此示例中的数据系列包含每个数据点的两个 Y 值。范围区域视图填充这些 Y 值之间的区域。 属性网格自动检测绑定字段的类型,并使用适当的 Eremex 数据编辑器来显示和编辑单元格值。您可以显式地为特定字段分配编辑器,以覆盖默认行为并自定义编辑器设置。 属性网格的选项卡行允许您将一组字段分组到选项卡式用户界面中。每行中的选项卡项显示其自己的一组绑定字段。 RibbonControl 允许您将受 Microsoft Office 启发的导航菜单集成到您的 Avalonia UI 应用程序中。该控件提供两种视图:经典视图(三行项目)和简化视图(一行项目)。控件右下角的下拉按钮打开一个选择器以在这些视图之间切换。{0}RibbonControl 支持多种项目类型:大按钮和小按钮、复选框按钮、子菜单、内置编辑器、内联和下拉画廊、按钮组等。您可以根据需要创建任意数量的页面,并将项目放置在快速访问工具栏或选项卡标题区域。{1}按下 ALT 键以聚焦到功能区,然后使用键盘在功能区元素之间导航并激活命令。 此示例展示了点系列视图,它允许您在史密斯图上绘制单个点。 散点线系列视图在您需要按数据系列中出现的顺序连接点时非常有用。 Tree List 控件提供了多种过滤和搜索数据的方法: • 列过滤菜单: 将鼠标悬停在列标题上,然后单击过滤按钮以打开菜单。您可以同时对一个或多个列应用过滤器。 • 自动过滤行: 顶部的专用行允许您直接将过滤值输入到任何列中。控件会立即显示仅与您输入内容匹配的记录。 • 搜索面板: 在所有列中搜索文本。搜索面板可以设置为始终可见,或通过 Ctrl+F 快捷键激活。匹配的记录会被显示,且文本在单元格内高亮显示。 • 代码过滤: 对于高级场景,您可以创建自定义过滤条件,并使用控件的 API 以编程方式应用它们。 默认情况下,Eremex 编辑器用于树列表单元格中以显示和编辑常见数据类型(布尔值、整数、枚举等)的单元格值。此演示展示了隐式分配的内置编辑器,并演示了如何显式指定树列表列的编辑器。 您可以将树列表绑定到分层数据源,该数据源通过集合属性或特殊数据选择器返回子数据。此演示展示了如何创建一个选择器,以提供磁盘上文件夹的分层结构。 树列表和树视图控件支持多节点选择模式,允许您和用户一次选择(突出显示)多个节点。用户可以使用鼠标和键盘选择多个节点。按住 CTRL 和/或 SHIFT 键单击节点以选择节点。 列带功能允许您通过在列上方显示共享标题,将多列以可视化的方式组合在一起。列标题和列带标题均可包含文本、图像或自定义内容。该控件允许您创建具有无限嵌套级别的分层列带。 此演示仅适用于桌面模式。下载应用程序。 解决方案并运行 DemoCenter.Desktop 项目以查看此演示。 Graphics3DControl支持天空盒(Skybox)功能,为3D场景提供背景。天空盒是一个包围整个场景的巨大立方体,具有六个纹理面(前、后、左、右、顶和底)。这些纹理被映射到立方体的内侧,营造出遥远的天空、地平线或背景的视觉效果。 Graphics3DControl 允许为3D场景指定自定义光源。支持的光源类型包括:点光源(Point)、平行光(Directional)、相机点光源(Camera Point)和相机平行光(Camera Directional)。使用自定义光源时,默认光源会自动关闭。 Graphics3DControl 支持模型和网格的高亮与选中功能。高亮功能会在鼠标悬停在模型或网格上时,为其绘制彩色边框。选中功能则在点击模型或网格时为其添加彩色边框。通过 HighlightMode 和 SelectionMode 属性,可选择高亮/选中是应用于模型还是网格。ShowHints 属性控制模型和网格的提示信息是否可见。 棒棒糖系列视图是一种时尚、节省空间的传统条形图替代方案。它不使用笨重的条形,而是采用顶端带有标记的细线来可视化数据点。您可以使用默认标记,或以SVG格式指定自定义标记。通过“方向”设置,您可以指定棒棒糖线条的方向(水平或垂直)。 此示例演示了 Data Grid 控件的导出功能。Data Grid 可以将数据导出为 XLSX (Microsoft Excel) 和 PDF 格式,同时保留数据整形选项,包括行分组、排序和单元格格式。 导出 正在导出... 您想打开导出的文件吗? 树状列表(TreeList)支持将数据导出为XLSX(Microsoft Excel)和PDF格式。其Excel导出功能具备数据感知特性——可在输出的XLSX文档中保留控件的数据整形配置(节点层级结构、数据排序和数值格式化)。PDF渲染引擎遵循WYSIWYG(所见即所得)原则,确保树状列表元素在输出文档中的布局能够被精确还原。 本演示应用模拟了一个抵押贷款计算器,它使用 Data Grid(数据网格)和 Cartesian Chart(直角坐标图表)控件构建。数据网格以表格形式呈现详细的还款计划。同步的图表会将此数据绘制出来,显示在贷款期限内本金和利息之间的关系。 本演示展示了图表控件如何借助"空点"处理不完整的数据集。这些点允许您在值缺失的位置创建系列中的可见间隙。要将某个点指定为空点,请将其值设置为 double.NaN、double.PositiveInfinity 或 double.NegativeInfinity。 堆叠面积图系列视图展示所有数据系列之间的绝对关系。每个系列以填充区域的形式层叠在前一个系列之上,其厚度表示该系列的绝对值。顶部的线条显示所有系列的总和。 百分比堆叠面积图系列视图(100% 堆叠面积图)展示所有数据系列之间的比例关系。每个系列以填充区域的形式层叠在前一个系列之上,其厚度表示该系列占总体的百分比。顶部线条始终显示为100%。 本演示展示了一个从FBX文件加载的3D机械臂。通过右侧的交互面板,您可以对嵌套的3D模型应用变换,从而操控每个关节(从底座到机械爪)。模型由 Ryan King Art 设计 https://sketchfab.com/ryankingart。 本演示展示了在Graphics3DControl中渲染的电路板3D模型。该示例展示了如何使用Assimp库从STL文件导入复杂模型。加载的几何数据用于初始化Graphics3DControl中的网格、顶点和材质。 ================================================ FILE: DemoCenter/DemoCenter/ViewLocator.cs ================================================ using System; using Avalonia.Controls; using Avalonia.Controls.Templates; using Avalonia.Media; using Eremex.AvaloniaUI.Controls.Common; namespace DemoCenter; public class ViewLocator : IDataTemplate { public Control Build(object data) { if (data is null) return null; var name = data.GetType().FullName!.Replace("ViewModel", "View"); var type = Type.GetType(name); if (type != null) { return (Control)Activator.CreateInstance(type)!; } return new TextBlock { Text = name + " not found!", Foreground = new SolidColorBrush(Colors.Red), HorizontalAlignment = Avalonia.Layout.HorizontalAlignment.Center, VerticalAlignment = Avalonia.Layout.VerticalAlignment.Center}; } public bool Match(object data) { return data is ViewModelBase; } } ================================================ FILE: DemoCenter/DemoCenter/ViewModels/Bars/BarItemsPageViewModel.cs ================================================ using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using Avalonia; using CommunityToolkit.Mvvm.ComponentModel; using Eremex.AvaloniaUI.Controls.Common; namespace DemoCenter.ViewModels { public partial class BarItemsPageViewModel : PageViewModelBase { public BarItemsPageViewModel() { } static List glyphSizes; public static List GlyphSizes { get { if (glyphSizes == null) glyphSizes = new List { new Size(48, 48), new Size(32, 32), new Size(20, 20), new Size(16, 16) }; return glyphSizes; } } } } ================================================ FILE: DemoCenter/DemoCenter/ViewModels/Bars/BarsGroupViewModel.cs ================================================ using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using CommunityToolkit.Mvvm.ComponentModel; using Eremex.AvaloniaUI.Controls.Common; namespace DemoCenter.ViewModels { public partial class BarsGroupViewModel : PageViewModelBase { public BarsGroupViewModel() { } } } ================================================ FILE: DemoCenter/DemoCenter/ViewModels/Bars/BarsOverviewPageViewModel.cs ================================================ using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using CommunityToolkit.Mvvm.ComponentModel; using Eremex.AvaloniaUI.Controls.Common; namespace DemoCenter.ViewModels { public partial class BarsOverviewPageViewModel : PageViewModelBase { public BarsOverviewPageViewModel() { } } } ================================================ FILE: DemoCenter/DemoCenter/ViewModels/Bars/ContextMenuPageViewModel.cs ================================================ using System; using System.Collections; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Linq; using CommunityToolkit.Mvvm.ComponentModel; using CommunityToolkit.Mvvm.Input; using DemoCenter.DemoData; namespace DemoCenter.ViewModels { public partial class ContextMenuPageViewModel : PageViewModelBase { [ObservableProperty] ObservableCollection mechs; [ObservableProperty] bool orderByAscending; [ObservableProperty] bool orderByDescending; [ObservableProperty] DateTime dateTime; private Random random = new Random(); public ContextMenuPageViewModel() { ReloadMechs(); DateTime = DateTime.Now; } [RelayCommand] public void Reload() => ReloadMechs(); [RelayCommand] public void ClearAllButTheFirst() => Mechs = new ObservableCollection { Mechs.First() }; void ReloadMechs(int count = 4) { var result = new ObservableCollection(); var mechsCount = CsvSources.Mechs.Count; do { var item = CsvSources.Mechs[random.Next(0, mechsCount)]; if(!result.Contains(item)) result.Add(item); } while (result.Count < count); Mechs = result; if (OrderByAscending) CreateAscendingMechs(); else if (OrderByDescending) CreateDescendingMechs(); } partial void OnOrderByAscendingChanged(bool value) { if (value) { CreateAscendingMechs(); OrderByDescending = false; } } partial void OnOrderByDescendingChanged(bool value) { if (value) { CreateDescendingMechs(); OrderByAscending = false; } } private void CreateAscendingMechs() => Mechs = new ObservableCollection(Mechs.OrderBy(x => x.Name)); private void CreateDescendingMechs() => Mechs = new ObservableCollection(Mechs.OrderByDescending(x => x.Name)); } } ================================================ FILE: DemoCenter/DemoCenter/ViewModels/Bars/ToolbarAndMenuPageViewModel.cs ================================================ using Avalonia.Threading; using CommunityToolkit.Mvvm.ComponentModel; using CommunityToolkit.Mvvm.Input; namespace DemoCenter.ViewModels { public partial class ToolbarAndMenuPageViewModel : PageViewModelBase { [ObservableProperty] string message; [ObservableProperty] private bool isSyncing; [ObservableProperty] private string syncText = "Sync Completed"; [ObservableProperty] private double syncProgress = 100; [ObservableProperty] private string text = "Text Editor (please type here)"; [ObservableProperty] private bool autoSyncEnabled = true; public ToolbarAndMenuPageViewModel() { Message = GetType().FullName; timer = new() { Interval = TimeSpan.FromMilliseconds(10) }; timer.Tick += TimerOnTick; } private void TimerOnTick(object sender, EventArgs e) { SyncProgress = Math.Min(100, SyncProgress + 1); if(SyncProgress == 100) { IsSyncing = false; } } [RelayCommand] public void ToggleSync(object par) { IsSyncing = !IsSyncing; } partial void OnTextChanged(string value) { if(AutoSyncEnabled) { IsSyncing = true; } } partial void OnIsSyncingChanged(bool value) { if(IsSyncing) { SyncText = "Syncing..."; StartSynchronization(); } else { if(SyncProgress == 100) { SyncText = "Sync Completed"; } else { SyncText = "Click the circle to sync the document"; } StopSynchronization(); } } private readonly DispatcherTimer timer; private void StartSynchronization() { SyncProgress = 0; timer.Start(); } private void StopSynchronization() { timer.Stop(); } partial void OnAutoSyncEnabledChanged(bool value) { if (value) { IsSyncing = true; } } } } ================================================ FILE: DemoCenter/DemoCenter/ViewModels/Charts/CartesianAreaSeriesViewViewModel.cs ================================================ using System.Collections.ObjectModel; using Avalonia.Media; using CommunityToolkit.Mvvm.ComponentModel; using Eremex.AvaloniaUI.Charts; namespace DemoCenter.ViewModels; public partial class CartesianAreaSeriesViewViewModel : ChartsPageViewModel { static double Sin(double argument) => Math.Sin(argument); static double Cos(double argument) => Math.Cos(argument); const int ItemsCount = 100; const double Step = 4 * Math.PI / ItemsCount; [ObservableProperty] ObservableCollection series = new() { new SeriesViewModel { Color = Color.FromArgb(255, 189, 20, 54), DataAdapter = new FormulaDataAdapter(0, Step, ItemsCount, Sin)}, new SeriesViewModel { Color = Color.FromArgb(255, 0, 120, 122), DataAdapter = new FormulaDataAdapter(0, Step, ItemsCount, Cos)}, }; } ================================================ FILE: DemoCenter/DemoCenter/ViewModels/Charts/CartesianCandlestickAggregationViewModel.cs ================================================ using CommunityToolkit.Mvvm.ComponentModel; using CommunityToolkit.Mvvm.Input; using Eremex.AvaloniaUI.Charts; namespace DemoCenter.ViewModels; public partial class CartesianCandlestickAggregationViewModel : ChartsPageViewModel { const double MinPrice = 5.0; const double StartPrice = 24.0; const int ItemsCount = 30 * 24 * 60; [ObservableProperty] SummaryCandlestickDataAdapter stockData; [ObservableProperty] DateTimeUnit measureUnit = DateTimeUnit.Hour; [ObservableProperty] int measureUnitFactor = 1; public CartesianCandlestickAggregationViewModel() { var random = new Random(3); var arguments = new List(ItemsCount); var values = new List(ItemsCount); var now = DateTime.Now; double prevValue = StartPrice; for (int i = 0; i < ItemsCount; i++) { double value = prevValue + (random.NextDouble() - 0.5) / 8d; if (value <= MinPrice) value = 2 * MinPrice - value; arguments.Add(now.AddMinutes(i - ItemsCount)); values.Add(value); prevValue = value; } stockData = new SummaryCandlestickDataAdapter(arguments, values) { MeasureUnit = MeasureUnit, MeasureUnitFactor = MeasureUnitFactor }; } [RelayCommand] void SetMeasureUnit(DateTimeUnitItem unit) { MeasureUnit = unit.Unit; MeasureUnitFactor = unit.Factor; StockData.MeasureUnit = unit.Unit; StockData.MeasureUnitFactor = unit.Factor; } } public class DateTimeUnitItem { public DateTimeUnit Unit { get; set; } public int Factor { get; set; } } ================================================ FILE: DemoCenter/DemoCenter/ViewModels/Charts/CartesianCandlestickSeriesViewViewModel.cs ================================================ using CommunityToolkit.Mvvm.ComponentModel; using DemoCenter.DemoData; using Eremex.AvaloniaUI.Charts; namespace DemoCenter.ViewModels; public partial class CartesianCandlestickSeriesViewViewModel : ChartsPageViewModel { [ObservableProperty] CandlestickDataAdapter stockData; [ObservableProperty] SortedDateTimeDataAdapter volumeData; public CartesianCandlestickSeriesViewViewModel() { var data = CsvSources.Stock; var arguments = new List(data.Count); var open = new List(data.Count); var high = new List(data.Count); var low = new List(data.Count); var close = new List(data.Count); var volume = new List(data.Count); for (var i = data.Count - 1; i >= 0; i--) { arguments.Add(data[i].Date); open.Add(data[i].Open); high.Add(data[i].High); low.Add(data[i].Low); close.Add(data[i].Close); volume.Add(data[i].Volume); } StockData = new CandlestickDataAdapter(arguments, open, high, low, close); volumeData = new SortedDateTimeDataAdapter(arguments, volume); } } ================================================ FILE: DemoCenter/DemoCenter/ViewModels/Charts/CartesianChartAxesPageViewModel.cs ================================================ using System.Collections.ObjectModel; using Avalonia.Media; using CommunityToolkit.Mvvm.ComponentModel; using Eremex.AvaloniaUI.Charts; namespace DemoCenter.ViewModels; public partial class CartesianChartAxesPageViewModel : ChartsPageViewModel { static readonly Color Color1 = Color.FromArgb(255, 189, 20, 54); static readonly Color Color2 = Color.FromArgb(255, 0, 120, 122); static double Formula1(double argument) => Math.Pow(argument, 2); static double Formula2(double argument) => Math.Pow(argument, 1.7); [ObservableProperty] AxisViewModel selectedAxis; [ObservableProperty] ObservableCollection axesX = new() { new AxisViewModel { Key = "1", Title = "First Axis X", Color = Color1, ShowInterlacing = true, ShowMajorGridlines = true, ShowMinorGridlines = true }, new AxisViewModel { Key = "2", Title = "Second Axis X", Color = Color2, Position = AxisPosition.Far } }; [ObservableProperty] ObservableCollection axesY = new() { new AxisViewModel { Key = "1", Title = "First Axis Y", Color = Color1, ShowInterlacing = true, ShowMajorGridlines = true, ShowMinorGridlines = true, Reverse = true }, new AxisViewModel { Key = "2", Title = "Second Axis Y", Color = Color2, Position = AxisPosition.Far } }; [ObservableProperty] ObservableCollection series = new() { new SeriesViewModel { Color = Color1, AxisXKey = "1", AxisYKey = "1", DataAdapter = new FormulaDataAdapter(0, 1, 100, Formula1)}, new SeriesViewModel { Color = Color2, AxisXKey = "2", AxisYKey = "2", DataAdapter = new FormulaDataAdapter(0, 1, 200, Formula2)}, }; public IEnumerable Axes { get { foreach (var axis in AxesX) yield return axis; foreach (var axis in AxesY) yield return axis; } } public CartesianChartAxesPageViewModel() { SelectedAxis = AxesX.First(); } } ================================================ FILE: DemoCenter/DemoCenter/ViewModels/Charts/CartesianChartLargeDataPageViewModel.cs ================================================ using System.Collections.ObjectModel; using Avalonia.Media; using CommunityToolkit.Mvvm.ComponentModel; using Eremex.AvaloniaUI.Charts; namespace DemoCenter.ViewModels; public partial class CartesianChartLargeDataPageViewModel : ChartsPageViewModel { static double Formula(double argument, int index) => Math.Sin(argument) + Math.Sin(argument / 100.0) + 30 * Math.Sin(argument / 1000.0) + 1000 * (1 + 0.1 * index % 10) * Math.Sin(argument / 100000.0 + Math.PI / 6 * index); const int ItemsCount = 1_000_000; [ObservableProperty] ObservableCollection series = new() { new SeriesViewModel { Color = Color.FromArgb(255, 189, 20, 54), DataAdapter = new FormulaDataAdapter(0, 1, ItemsCount, arg => Formula(arg, 0))}, new SeriesViewModel { Color = Color.FromArgb(255, 0, 120, 122), DataAdapter = new FormulaDataAdapter(0, 1, ItemsCount, arg => Formula(arg, 1))}, }; } ================================================ FILE: DemoCenter/DemoCenter/ViewModels/Charts/CartesianChartLogarithmicScalePageViewModel.cs ================================================ using System.Collections.ObjectModel; using Avalonia.Media; using CommunityToolkit.Mvvm.ComponentModel; using DemoCenter.DemoData; using Eremex.AvaloniaUI.Charts; namespace DemoCenter.ViewModels; public partial class CartesianChartLogarithmicScalePageViewModel : ChartsPageViewModel { static readonly Color[] colors = new[] { Color.FromArgb(255, 168, 207, 213), Color.FromArgb(255, 163, 201, 207), Color.FromArgb(255, 138, 193, 201), Color.FromArgb(255, 107, 178, 188), Color.FromArgb(255, 103, 171, 181), Color.FromArgb(255, 31, 114, 115), Color.FromArgb(255, 0, 95, 96) }; const double LogBase = 10; [ObservableProperty] LogarithmicAxisViewModel axisX = new() { LogarithmicBase = LogBase }; [ObservableProperty] bool logarithmicX = true; [ObservableProperty] CustomLabelFormatter frequencyFormatter = new(o => $"{o} Hz"); [ObservableProperty] ObservableCollection series = new(); public CartesianChartLogarithmicScalePageViewModel() { var data = CsvSources.Logarithmic; for (int i = 0; i < 7; i++) series.Add(new SeriesViewModel { Color = colors[i], DataAdapter = CreateDataAdapter(data, i + 1) }); } SortedNumericDataAdapter CreateDataAdapter(List data, int valueIndex) { var result = new SortedNumericDataAdapter(); for (int i = 0; i < data[0].Data.Count; i++) result.Add(data[0].Data[i], data[valueIndex].Data[i]); return result; } partial void OnLogarithmicXChanged(bool value) => AxisX.LogarithmicBase = value ? LogBase : null; } ================================================ FILE: DemoCenter/DemoCenter/ViewModels/Charts/CartesianChartRealtimePageViewModel.cs ================================================ using System.Collections.ObjectModel; using Avalonia.Media; using Avalonia.Threading; using CommunityToolkit.Mvvm.ComponentModel; using DemoCenter.ViewModels.DataAdapters; namespace DemoCenter.ViewModels; public partial class CartesianChartRealtimePageViewModel : ChartsPageViewModel { static readonly Color[] colors = new[] { Color.FromArgb(255, 204, 55, 28), Color.FromArgb(255, 255, 106, 0), Color.FromArgb(255, 0, 148, 255), Color.FromArgb(255, 119, 133, 255), Color.FromArgb(255, 0, 127, 128), Color.FromArgb(255, 91, 171, 171) }; readonly DispatcherTimer timer = new(DispatcherPriority.Background); readonly RealtimeDataGenerator generator = new(6, 500, 35); [ObservableProperty] ObservableCollection series = new(); public CartesianChartRealtimePageViewModel() { generator.GenerateInitialData(); timer.Tick += (_, _) => generator.UpdateAdapters(); timer.Interval = TimeSpan.FromMilliseconds(2); for (int i = 0; i < generator.Adapters.Length; i++) series.Add(new SeriesViewModel { Color = colors[i], DataAdapter = generator.Adapters[i] }); } public void Start() { generator.Start(); timer.Start(); } public void Stop() { generator.Stop(); timer.Stop(); } } ================================================ FILE: DemoCenter/DemoCenter/ViewModels/Charts/CartesianEmptyPointsViewModel.cs ================================================ using Avalonia.Media; using CommunityToolkit.Mvvm.ComponentModel; using Eremex.AvaloniaUI.Charts; namespace DemoCenter.ViewModels; public partial class CartesianEmptyPointsViewModel : ChartsPageViewModel { const int PointsCount = 100; static bool IsEmpty(double v) => v is > 30 and < 40 or > 60 and < 70; [ObservableProperty] List views; [ObservableProperty] SeriesViewBase selectedView; [ObservableProperty] ISeriesDataAdapter dataAdapter; public CartesianEmptyPointsViewModel() { var color = Color.FromArgb(255, 189, 20, 54); var color2 = Color.FromArgb(255, 0, 120, 122); var simpleAdapter = new FormulaDataAdapter(0, 1, PointsCount, d => IsEmpty(d) ? double.NaN : Math.Sin(d / 10)); views = [ new("Line", simpleAdapter, new CartesianLineSeriesView { Color = color, ShowMarkers = true }), new("Area", simpleAdapter, new CartesianAreaSeriesView { Color = color, ShowMarkers = true }), new("Scatter Line", CreateScatterData(), new CartesianScatterLineSeriesView { Color = color, ShowMarkers = true }), new("Step Line", simpleAdapter, new CartesianStepLineSeriesView { Color = color, ShowMarkers = true }), new("Step Area", simpleAdapter, new CartesianStepAreaSeriesView { Color = color, ShowMarkers = true }), new("Range Area", CreateRangeData(), new CartesianRangeAreaSeriesView { Color = Color.FromArgb(255, 67, 201, 39), Color1 = color, Color2 = color2, ShowMarkers1 = true, ShowMarkers2 = true }) ]; selectedView = views[0].View; dataAdapter = views[0].DataAdapter; } ScatterDataAdapter CreateScatterData() { var scatterData = new List<(double, double)>(PointsCount); for (int i = 0; i < PointsCount; i++) { double factor = 0.1 * i; double v = IsEmpty(i) ? double.NaN : factor * Math.Sin(factor); scatterData.Add((factor * Math.Cos(factor), v)); } return new ScatterDataAdapter(scatterData); } TimeSpanRangeDataAdapter CreateRangeData() { var rangeData = new List<(TimeSpan, double, double)>(PointsCount); for (double i = 0; i < PointsCount; i++) { double v = IsEmpty(i) ? double.NaN : Math.Sin(i / 10); rangeData.Add((TimeSpan.FromSeconds(i), v, v - 1)); } return new TimeSpanRangeDataAdapter(rangeData); } } ================================================ FILE: DemoCenter/DemoCenter/ViewModels/Charts/CartesianFullStackedAreaSeriesViewViewModel.cs ================================================ using System.Collections.ObjectModel; using Avalonia.Media; using CommunityToolkit.Mvvm.ComponentModel; using Eremex.AvaloniaUI.Charts; namespace DemoCenter.ViewModels; public partial class CartesianFullStackedAreaSeriesViewViewModel : ChartsPageViewModel { [ObservableProperty] ObservableCollection series = new() { new SeriesViewModel { Color = Color.FromUInt32(0xFF9B59B6), DataAdapter = new SortedNumericDataAdapter()}, new SeriesViewModel { Color = Color.FromUInt32(0xFFE74C3C), DataAdapter = new SortedNumericDataAdapter()}, new SeriesViewModel { Color = Color.FromUInt32(0xFFF39C12), DataAdapter = new SortedNumericDataAdapter()} }; public CartesianFullStackedAreaSeriesViewViewModel() { const int pointCount = 15; const int step = 1; var random = new Random(); for (int i = 0; i < pointCount; i++) { ((SortedNumericDataAdapter)series[0].DataAdapter).Add(i * step, 20 + 10 * Math.Cos(i * 0.1) + random.NextDouble() * 5); ((SortedNumericDataAdapter)series[1].DataAdapter).Add(i * step, 15 + 8 * Math.Sin(i * 0.6) + random.NextDouble() * 4); ((SortedNumericDataAdapter)series[2].DataAdapter).Add(i * step, 8 + 8 * Math.Cos(i * 0.1) + random.NextDouble() * 4); } } } ================================================ FILE: DemoCenter/DemoCenter/ViewModels/Charts/CartesianLineSeriesViewViewModel.cs ================================================ using System.Collections.ObjectModel; using Avalonia.Media; using CommunityToolkit.Mvvm.ComponentModel; using Eremex.AvaloniaUI.Charts; namespace DemoCenter.ViewModels; public partial class CartesianLineSeriesViewViewModel : ChartsPageViewModel { static double Sin(double argument) => Math.Sin(argument); static double Cos(double argument) => Math.Cos(argument); const int ItemsCount = 100; const double Step = 4 * Math.PI / ItemsCount; [ObservableProperty] ObservableCollection series = new() { new SeriesViewModel { Color = Color.FromArgb(255, 189, 20, 54), DataAdapter = new FormulaDataAdapter(0, Step, ItemsCount, Sin)}, new SeriesViewModel { Color = Color.FromArgb(255, 0, 120, 122), DataAdapter = new FormulaDataAdapter(0, Step, ItemsCount, Cos)}, }; } ================================================ FILE: DemoCenter/DemoCenter/ViewModels/Charts/CartesianLollipopSeriesViewViewModel.cs ================================================ using CommunityToolkit.Mvvm.ComponentModel; using Eremex.AvaloniaUI.Charts; namespace DemoCenter.ViewModels; public partial class CartesianLollipopSeriesViewViewModel : ChartsPageViewModel { [ObservableProperty] SortedNumericDataAdapter dataAdapter = new(); [ObservableProperty] CartesianLollipopOrientation lineOrientation = CartesianLollipopOrientation.Vertical; [ObservableProperty] double lineThickness = 1; [ObservableProperty] double markerSize = 12; public CartesianLollipopSeriesViewViewModel() { const int step = 30; for (int i = -step; i < step; i++) { double x = 0.5 * Math.PI * i / step; double y = Math.Sin(x); DataAdapter.Add(x, y); } } } ================================================ FILE: DemoCenter/DemoCenter/ViewModels/Charts/CartesianPointSeriesViewViewModel.cs ================================================ using System.Collections.ObjectModel; using Avalonia.Media; using CommunityToolkit.Mvvm.ComponentModel; using DemoCenter.ViewModels.DataAdapters; namespace DemoCenter.ViewModels; public partial class CartesianPointSeriesViewViewModel : ChartsPageViewModel { [ObservableProperty] private ObservableCollection series = new() { new SeriesViewModel { Color = Color.FromArgb(64, 189, 20, 54), DataAdapter = new ClusterDataAdapter(2000, -1000, 2000, -1000, 10000) }, new SeriesViewModel { Color = Color.FromArgb(64, 0, 120, 122), DataAdapter = new ClusterDataAdapter(1000, -2000, 1000, -2000, 10000) } }; } ================================================ FILE: DemoCenter/DemoCenter/ViewModels/Charts/CartesianRangeAreaSeriesViewViewModel.cs ================================================ using System.Collections.ObjectModel; using Avalonia.Media; using CommunityToolkit.Mvvm.ComponentModel; using Eremex.AvaloniaUI.Charts; namespace DemoCenter.ViewModels; public partial class CartesianRangeAreaSeriesViewViewModel : ChartsPageViewModel { readonly Random random = new(); [ObservableProperty] Color color = Color.FromArgb(255, 67, 201, 39); [ObservableProperty] Color color1 = Color.FromArgb(255, 189, 20, 54); [ObservableProperty] Color color2 = Color.FromArgb(255, 0, 120, 122); [ObservableProperty] NumericRangeDataAdapter dataAdapter = new(); public CartesianRangeAreaSeriesViewViewModel() { for (int i = 0; i < 20; i++) { double argument = i; double value1 = random.NextDouble() + 1.5; double value2 = random.NextDouble() + 0.5; if (i is > 6 and < 13) DataAdapter.Add(argument, value2, value1); else DataAdapter.Add(argument, value1, value2); } } } ================================================ FILE: DemoCenter/DemoCenter/ViewModels/Charts/CartesianScatterLineSeriesViewViewModel.cs ================================================ using Avalonia.Media; using CommunityToolkit.Mvvm.ComponentModel; using Eremex.AvaloniaUI.Charts; namespace DemoCenter.ViewModels; public partial class CartesianScatterLineSeriesViewViewModel : ChartsPageViewModel { const int ItemsCount = 500; [ObservableProperty] SeriesViewModel series; public CartesianScatterLineSeriesViewViewModel() { var data = new List<(double, double)>(ItemsCount); for (int i = 0; i < ItemsCount; i++) { double factor = 0.1 * i; data.Add((factor * Math.Cos(factor), factor * Math.Sin(factor))); } Series = new() { Color = Color.FromArgb(255, 189, 20, 54), DataAdapter = new ScatterDataAdapter(data) }; } } ================================================ FILE: DemoCenter/DemoCenter/ViewModels/Charts/CartesianSideBySideBarSeriesViewViewModel.cs ================================================ using System.Collections.ObjectModel; using Avalonia.Media; using CommunityToolkit.Mvvm.ComponentModel; using Eremex.AvaloniaUI.Charts; namespace DemoCenter.ViewModels; public partial class CartesianSideBySideBarSeriesViewViewModel : ChartsPageViewModel { [ObservableProperty] private ObservableCollection series = new(); public CartesianSideBySideBarSeriesViewViewModel() { var random = new Random(4); var start = DateTime.Now.AddMonths(-1); SortedDateTimeDataAdapter adapter1 = new(); SortedDateTimeDataAdapter adapter2 = new(); for (int i = 0; i < 12; i++) { var argument = start.AddDays(i); adapter1.Add(argument, random.NextDouble() * 100 - 30); adapter2.Add(argument, random.NextDouble() * 100 - 30); } series.Add(new SeriesViewModel { Color = Color.FromArgb(180, 189, 20, 54), DataAdapter = adapter1 }); series.Add(new SeriesViewModel { Color = Color.FromArgb(180, 0, 120, 122), DataAdapter = adapter2 }); } } ================================================ FILE: DemoCenter/DemoCenter/ViewModels/Charts/CartesianSideBySideRangeBarSeriesViewViewModel.cs ================================================ using System.Collections.ObjectModel; using Avalonia.Media; using CommunityToolkit.Mvvm.ComponentModel; using Eremex.AvaloniaUI.Charts; namespace DemoCenter.ViewModels; public partial class CartesianSideBySideRangeBarSeriesViewViewModel : ChartsPageViewModel { [ObservableProperty] private ObservableCollection series = new(); public CartesianSideBySideRangeBarSeriesViewViewModel() { var random = new Random(10); NumericRangeDataAdapter adapter1 = new(); NumericRangeDataAdapter adapter2 = new(); for (int i = 0; i < 12; i++) { adapter1.Add(i, random.NextDouble() * 100, random.NextDouble() * 100); adapter2.Add(i, random.NextDouble() * 100, random.NextDouble() * 100); } series.Add(new SeriesViewModel { Color = Color.FromArgb(180, 189, 20, 54), DataAdapter = adapter1 }); series.Add(new SeriesViewModel { Color = Color.FromArgb(180, 0, 120, 122), DataAdapter = adapter2 }); } } ================================================ FILE: DemoCenter/DemoCenter/ViewModels/Charts/CartesianStackedAreaSeriesViewViewModel.cs ================================================ using System.Collections.ObjectModel; using Avalonia.Media; using CommunityToolkit.Mvvm.ComponentModel; using Eremex.AvaloniaUI.Charts; namespace DemoCenter.ViewModels; public partial class CartesianStackedAreaSeriesViewViewModel : ChartsPageViewModel { [ObservableProperty] ObservableCollection series = new() { new SeriesViewModel { Color = Color.FromUInt32(0xFF9B59B6), DataAdapter = new SortedNumericDataAdapter()}, new SeriesViewModel { Color = Color.FromUInt32(0xFFE74C3C), DataAdapter = new SortedNumericDataAdapter()}, new SeriesViewModel { Color = Color.FromUInt32(0xFFF39C12), DataAdapter = new SortedNumericDataAdapter()} }; public CartesianStackedAreaSeriesViewViewModel() { const int pointCount = 15; const int step = 1; var random = new Random(); for (int i = 0; i < pointCount; i++) { ((SortedNumericDataAdapter)series[0].DataAdapter).Add(i * step, 20 + 10 * Math.Cos(i * 0.1) + random.NextDouble() * 5); ((SortedNumericDataAdapter)series[1].DataAdapter).Add(i * step, 15 + 8 * Math.Sin(i * 0.6) + random.NextDouble() * 4); ((SortedNumericDataAdapter)series[2].DataAdapter).Add(i * step, 8 + 8 * Math.Cos(i * 0.1) + random.NextDouble() * 4); } } } ================================================ FILE: DemoCenter/DemoCenter/ViewModels/Charts/CartesianStepAreaSeriesViewViewModel.cs ================================================ using System.Collections.ObjectModel; using Avalonia.Media; using CommunityToolkit.Mvvm.ComponentModel; using Eremex.AvaloniaUI.Charts; namespace DemoCenter.ViewModels; public partial class CartesianStepAreaSeriesViewViewModel : ChartsPageViewModel { static Random Random = new(1); static double Formula1(double argument) => Random.NextDouble() * 20 + 10; static double Formula2(double argument) => Random.NextDouble() * 20; const int ItemsCount = 10; [ObservableProperty] ObservableCollection series = new() { new SeriesViewModel { Color = Color.FromArgb(255, 189, 20, 54), DataAdapter = new FormulaDataAdapter(0, 1, ItemsCount, Formula1)}, new SeriesViewModel { Color = Color.FromArgb(255, 0, 120, 122), DataAdapter = new FormulaDataAdapter(0, 1, ItemsCount, Formula2)}, }; public CartesianStepAreaSeriesViewViewModel() { Random = new Random(1); } } ================================================ FILE: DemoCenter/DemoCenter/ViewModels/Charts/CartesianStepLineSeriesViewViewModel.cs ================================================ using System.Collections.ObjectModel; using Avalonia.Media; using CommunityToolkit.Mvvm.ComponentModel; using Eremex.AvaloniaUI.Charts; namespace DemoCenter.ViewModels; public partial class CartesianStepLineSeriesViewViewModel : ChartsPageViewModel { static Random Random = new(1); static double Formula1(double argument) => Random.NextDouble() * 20; static double Formula2(double argument) => Random.NextDouble() * 20 - 10; const int ItemsCount = 10; [ObservableProperty] ObservableCollection series = new() { new SeriesViewModel { Color = Color.FromArgb(255, 189, 20, 54), DataAdapter = new FormulaDataAdapter(0, 1, ItemsCount, Formula1)}, new SeriesViewModel { Color = Color.FromArgb(255, 0, 120, 122), DataAdapter = new FormulaDataAdapter(0, 1, ItemsCount, Formula2)}, }; public CartesianStepLineSeriesViewViewModel() { Random = new Random(1); } } ================================================ FILE: DemoCenter/DemoCenter/ViewModels/Charts/CartesianStripsAndConstantLinesViewModel.cs ================================================ using System.Collections.ObjectModel; using Avalonia.Media; using CommunityToolkit.Mvvm.ComponentModel; using Eremex.AvaloniaUI.Charts; namespace DemoCenter.ViewModels; public partial class CartesianStripsAndConstantLinesViewModel : ChartsPageViewModel { [ObservableProperty] SeriesViewModel series = new() { Color = Color.FromArgb(255, 0, 120, 122), DataAdapter = CreateAdapter() }; [ObservableProperty] ObservableCollection constantLines = new(); static ISeriesDataAdapter CreateAdapter() { const int pointsCount = 250; var random = new Random(0); var arguments = new List(pointsCount); var values = new List(pointsCount); double startTemperature = 30; for (int i = 0; i < pointsCount; i++) { arguments.Add(TimeSpan.FromSeconds(i)); double temperature = startTemperature + (random.NextDouble() - 0.5) * 10; if (temperature > 90) temperature -= 20; if (temperature < 20) temperature += 10; values.Add(temperature); startTemperature = temperature; } return new SortedTimeSpanDataAdapter(arguments, values); } } ================================================ FILE: DemoCenter/DemoCenter/ViewModels/Charts/ChartElementViewModels/AxisViewModel.cs ================================================ using Avalonia.Media; using CommunityToolkit.Mvvm.ComponentModel; using Eremex.AvaloniaUI.Charts; namespace DemoCenter.ViewModels; public partial class AxisViewModel : ObservableObject { [ObservableProperty] AxisPosition position; [ObservableProperty] string title; [ObservableProperty] string key; [ObservableProperty] bool showTitle = true; [ObservableProperty] bool showLabels = true; [ObservableProperty] bool showInterlacing; [ObservableProperty] bool? showMajorGridlines = false; [ObservableProperty] bool? showMinorGridlines = false; [ObservableProperty] int minorCount = 3; [ObservableProperty] Color color; [ObservableProperty] bool reverse; public override string ToString() => Title; } ================================================ FILE: DemoCenter/DemoCenter/ViewModels/Charts/ChartElementViewModels/ConstantLineViewModel.cs ================================================ using CommunityToolkit.Mvvm.ComponentModel; namespace DemoCenter.ViewModels; public partial class ConstantLineViewModel : ObservableObject { [ObservableProperty] string title; [ObservableProperty] object axisValue; } ================================================ FILE: DemoCenter/DemoCenter/ViewModels/Charts/ChartElementViewModels/CustomLabelFormatter.cs ================================================ using Eremex.AvaloniaUI.Charts; namespace DemoCenter.ViewModels; public class CustomLabelFormatter : IAxisLabelFormatter { readonly Func formatFunc; public CustomLabelFormatter(Func formatFunc) { this.formatFunc = formatFunc; } public string Format(object value) => formatFunc(value); } ================================================ FILE: DemoCenter/DemoCenter/ViewModels/Charts/ChartElementViewModels/LogarithmicAxisViewModel.cs ================================================ using CommunityToolkit.Mvvm.ComponentModel; namespace DemoCenter.ViewModels; public partial class LogarithmicAxisViewModel : ObservableObject { [ObservableProperty] double? logarithmicBase; } ================================================ FILE: DemoCenter/DemoCenter/ViewModels/Charts/ChartElementViewModels/SeriesViewModel.cs ================================================ using Avalonia.Media; using CommunityToolkit.Mvvm.ComponentModel; using Eremex.AvaloniaUI.Charts; namespace DemoCenter.ViewModels; public partial class SeriesViewModel : ObservableObject { [ObservableProperty] string axisXKey; [ObservableProperty] string axisYKey; [ObservableProperty] Color color; [ObservableProperty] ISeriesDataAdapter dataAdapter; } ================================================ FILE: DemoCenter/DemoCenter/ViewModels/Charts/ChartElementViewModels/ViewViewModel.cs ================================================ using CommunityToolkit.Mvvm.ComponentModel; using Eremex.AvaloniaUI.Charts; using Eremex.AvaloniaUI.Controls.Common; namespace DemoCenter.ViewModels; public partial class ViewViewModel : ViewModelBase { [ObservableProperty] string name; [ObservableProperty] SeriesViewBase view; [ObservableProperty] ISeriesDataAdapter dataAdapter; public ViewViewModel(string name, ISeriesDataAdapter adapter, SeriesViewBase view) { Name = name; View = view; DataAdapter = adapter; } } ================================================ FILE: DemoCenter/DemoCenter/ViewModels/Charts/ChartsPageViewModel.cs ================================================ namespace DemoCenter.ViewModels; public partial class ChartsPageViewModel : PageViewModelBase { public ChartsPageViewModel() { } } ================================================ FILE: DemoCenter/DemoCenter/ViewModels/Charts/Data/ClusterDataAdapter.cs ================================================ using Eremex.AvaloniaUI.Charts; namespace DemoCenter.ViewModels.DataAdapters; public class ClusterDataAdapter : ISeriesDataAdapter { readonly int count; readonly List arguments; readonly List values; public int ItemCount => count; public bool IsDataSorted => false; public event SeriesDataAdapterDataChangedEventHandler DataChanged; public ClusterDataAdapter(int xMinus, int xPlus, int yMinus, int yPlus, int count) { this.count = count; arguments = new List(count); values = new List(count); var random = new Random(0); int deltaX = xMinus - xPlus; int deltaY = yMinus - yPlus; double centerX = 0.5 * xMinus + 0.5 * xPlus; double centerY = 0.5 * yMinus + 0.5 * yPlus; for (int i = 0; i < count; i++) { double half = 0.5 * i + 1; double ratio = Math.Max(2.1, count / half); int xOffset = (int)(deltaX / ratio); int yOffset = (int)(deltaY / ratio); double delta = xMinus - xOffset - centerX; int rx, ry; do { rx = random.Next(xPlus + xOffset, xMinus - xOffset); ry = random.Next(yPlus + yOffset, yMinus - yOffset); } while (delta * delta < Math.Pow(centerX - rx, 2) + Math.Pow(centerY - ry, 2)); arguments.Add(rx); values.Add(ry); }; } public Dictionary GetScaleTypes() => new() { { AxisType.Argument, ScaleType.Numeric }, { AxisType.Value, ScaleType.Numeric } }; protected virtual void OnDataChanged(ISeriesDataAdapter adapter, SeriesDataAdapterDataChangedEventArgs e) => DataChanged?.Invoke(adapter, e); public double GetNumericalValue(int index, SeriesDataMemberType dataMember) => dataMember switch { SeriesDataMemberType.Argument => arguments[index], SeriesDataMemberType.Value => values[index], _ => throw new ArgumentOutOfRangeException(nameof(dataMember), dataMember, null) }; public DateTime GetDateTimeValue(int index, SeriesDataMemberType dataMember) => throw new NotImplementedException(); public TimeSpan GetTimeSpanValue(int index, SeriesDataMemberType dataMember) => throw new NotImplementedException(); public string GetQualitativeValue(int index, SeriesDataMemberType dataMember) => throw new NotImplementedException(); public string GetUnderlyingData(int index) => null; } ================================================ FILE: DemoCenter/DemoCenter/ViewModels/Charts/Data/RealtimeDataGenerator.cs ================================================ using Eremex.AvaloniaUI.Charts; namespace DemoCenter.ViewModels.DataAdapters; public class RealtimeDataGenerator { readonly Random random = new(1); readonly object sync = new(); readonly int interval; readonly int pointsCount; readonly List<(TimeSpan, double)>[] buffers; readonly SortedTimeSpanDataAdapter[] adapters; readonly double[] yAdditions; bool enabled; Thread generatingThread; int AdaptersCount => adapters.Length; public SortedTimeSpanDataAdapter[] Adapters => adapters; public RealtimeDataGenerator(int adaptersCount, int pointsCount, int interval) { this.interval = interval; this.pointsCount = pointsCount; adapters = new SortedTimeSpanDataAdapter[adaptersCount]; buffers = new List<(TimeSpan, double)>[adaptersCount]; yAdditions = new double[adaptersCount]; for (int i = 0; i < AdaptersCount; i++) { adapters[i] = new SortedTimeSpanDataAdapter(); buffers[i] = new List<(TimeSpan, double)>(); } } (TimeSpan, double) CreatePoint(int index, TimeSpan timeStamp) { double arg = timeStamp.TotalMilliseconds; yAdditions[index] += random.Next(10, 20) * Math.Sign(random.NextDouble() - 0.5); if (yAdditions[index] < -30) yAdditions[index] += 10; if (yAdditions[index] > 30) yAdditions[index] -= 10; double indication = 5 * Math.Sin((index + 1) * Math.Cos(arg)) + 100 * index + (random.NextDouble() - 0.5) * 5 + yAdditions[index]; return (timeStamp, indication); } void GeneratingLoop() { var timeStamp = TimeSpan.FromMilliseconds(pointsCount * interval); var addition = TimeSpan.FromMilliseconds(interval); while (enabled) { Thread.Sleep((int)addition.TotalMilliseconds); timeStamp += addition; for (int i = 0; i < AdaptersCount; i++) { var point = CreatePoint(i, timeStamp); lock (sync) { buffers[i].Add(point); } } } } public void GenerateInitialData() { for (int i = 0; i < pointsCount - 1; i++) { var argument = TimeSpan.FromMilliseconds(i * interval); for (int j = 0; j < AdaptersCount; j++) adapters[j].Add(CreatePoint(j, argument)); } } public void Start() { generatingThread ??= new Thread(GeneratingLoop); enabled = true; generatingThread.Start(); } public void Stop() { enabled = false; generatingThread?.Join(); generatingThread = null; } public void UpdateAdapters() { lock (sync) { for (int i = 0; i < AdaptersCount; i++) { adapters[i].AddRange(buffers[i]); adapters[i].RemoveFromStart(buffers[i].Count); buffers[i].Clear(); } } } } ================================================ FILE: DemoCenter/DemoCenter/ViewModels/Charts/Data/SmithSampleDataAdapter.cs ================================================ using Avalonia; using Eremex.AvaloniaUI.Charts; namespace DemoCenter.ViewModels.DataAdapters; public class SmithSampleDataAdapter : ScatterDataAdapter { static List<(double, double)> CreatePoints() => new() { new(4.0927416947323625, 5.039470338092902), new(3.92510559125759, 5.038444841265609), new(2.9609480516938445, 4.388962584752334), new(2.5546535427921997, 4.000471294814654), new(1.964717762258852, 3.3997119638438367), new(1.664097447415818, 3.0249308991544144), new(1.443557453328536, 2.7954983980116954), new(1.2681152405414577, 2.502502932413702), new(1.1100296667507819, 2.1847040378971396), new(0.9392207784153547, 1.854062392922539), new(0.846089195699504, 1.7082233596053027), new(0.7705257398312417, 1.5529513803851396), new(0.6719552097724123, 1.352344942921545), new(0.5877645431815587, 1.180666264709727), new(0.5111203186726802, 1.0322050014852482), new(0.46301028834485936, 0.921361441133213), new(0.38351079156636886, 0.7998918714458432), new(0.3478144093933388, 0.7194480222678319), new(0.3248983102732522, 0.6642728279656329), new(0.2816305674430336, 0.5855939023590193), new(0.25584555266104975, 0.5226929043338495), new(0.23529646617441882, 0.4683983374673091), new(0.21602243403906227, 0.42985460828467703), new(0.21230948367795713, 0.3827462979735884), new(0.20497820337091424, 0.33847337013198103), new(0.18900574934462128, 0.2970955634833308), new(0.18394916472084608, 0.26015163253654855), new(0.17845441391224548, 0.2172719442948981), new(0.17224167022622433, 0.18135577409329476), new(0.17029203319744238, 0.12565543452267378), new(0.16657050817062716, 0.07287521161882622), new(0.17101775870369532, -0.011101043410171247), new(0.1629916144256333, -0.0741315546761855), new(0.1697711624181565, -0.12260488128437728), new(0.19961866302746403, -0.20896384612510208), new(0.19924677434147384, -0.24065671934610092), new(0.20464883477630527, -0.28036502928504925), new(0.21632626503829122, -0.3322953198300484), new(0.21360546678353406, -0.46906870241922927), new(0.19844543817776145, -0.5815443598287293), new(0.20704405829292036, -0.6257752253896222), new(0.23047251687560255, -0.7000964320154291), new(0.2614096427695895, -0.7866609226726707), new(0.28998891117547276, -0.8641624707525366), new(0.30051700092548717, -0.9691090162228121), new(0.32157358472227837, -1.0192188232132002), new(0.3601509245920335, -1.0971208063694364), new(0.4081488865392029, -1.2087206939785746), new(0.45908678614089393, -1.2926720229648234), new(0.5053734699314155, -1.3879021297922591), new(0.5761497281206099, -1.5099000218570713), new(0.6974549985645953, -1.670380473622166), new(0.8148891027221786, -1.7734593809369144), new(1.0435229738246268, -1.8847248777424928), new(1.1975740297463773, -1.929533901723999), new(1.5721806813354386, -1.9939896392916607), new(1.8170907463573003, -1.9977084642445946) }; public SmithSampleDataAdapter() : base(CreatePoints()) { } } ================================================ FILE: DemoCenter/DemoCenter/ViewModels/Charts/HeatmapColorProvidersViewModel.cs ================================================ using Avalonia; using Avalonia.Media; using Avalonia.Media.Imaging; using AvaloniaEdit.Utils; using CommunityToolkit.Mvvm.ComponentModel; using DemoCenter.Helpers; using Eremex.AvaloniaUI.Charts; using Eremex.AvaloniaUI.Charts.Native; namespace DemoCenter.ViewModels; public partial class HeatmapColorProvidersViewModel : ChartsPageViewModel { [ObservableProperty] HeatmapDataAdapter dataAdapter = HeatmapHelper.GetAdapter("hlsp_jwst-ero_jwst_miri_carina_f1130w_v1_i2d"); [ObservableProperty] HeatmapColorProviderItem selectedColorProvider; public string MiddleX => DataAdapter.XArguments[DataAdapter.XArguments.Count / 2]; public string MiddleY => DataAdapter.YArguments[DataAdapter.YArguments.Count / 2]; public List ColorProviders { get; } = new() { new("Hot Spot", new HeatmapRangeStop[] { new() { Value = 0.0, Color = Color.FromRgb(0, 0, 0) }, new() { Value = 0.6, Color = Color.FromRgb(160, 160, 160) }, new() { Value = 0.65, Color = Color.FromRgb(238, 137, 17) }, new() { Value = 0.8, Color = Color.FromRgb(242, 36, 0) }, new() { Value = 1.0, Color = Color.FromRgb(160, 20, 0) } }), new("Rainbow", new HeatmapRangeStop[] { new() { Value = 0.0, Color = Color.FromRgb(0, 8, 73) }, new() { Value = 0.2, Color = Color.FromRgb(0, 118, 212) }, new() { Value = 0.4, Color = Color.FromRgb(64, 171, 57) }, new() { Value = 0.6, Color = Color.FromRgb(241, 197, 9) }, new() { Value = 0.8, Color = Color.FromRgb(247, 38, 63) }, new() { Value = 1.0, Color = Color.FromRgb(250, 226, 202) } }), new(), new("Green", new HeatmapRangeStop[] { new() { Value = 0.0, Color = Colors.Black }, new() { Value = 1.0, Color = Colors.Lime } }), new("Hot Metal", new HeatmapRangeStop[] { new() { Value = 0.0, Color = Color.FromRgb(0, 0, 12) }, new() { Value = 0.2, Color = Color.FromRgb(74, 25, 144) }, new() { Value = 0.4, Color = Color.FromRgb(187, 38, 143) }, new() { Value = 0.6, Color = Color.FromRgb(230, 77, 12) }, new() { Value = 0.8, Color = Color.FromRgb(248, 218, 12) }, new() { Value = 1.0, Color = Color.FromRgb(248, 251, 245) } }), new("Cold Spot", new HeatmapRangeStop[] { new() { Value = 0.0, Color = Color.FromRgb(1, 33, 184) }, new() { Value = 0.2, Color = Color.FromRgb(46, 168, 220) }, new() { Value = 0.25, Color = Color.FromRgb(155, 155, 155) }, new() { Value = 1.0, Color = Color.FromRgb(0, 0, 0) } }) }; public HeatmapColorProvidersViewModel() { SelectedColorProvider = ColorProviders[4]; } } public partial class HeatmapColorProviderItem : ObservableObject { public string Name { get; } public IHeatmapColorProvider ColorProvider { get; } public IImage PreviewImage { get; } public HeatmapColorProviderItem() { Name = "Gray"; ColorProvider = new HeatmapGrayscaleColorProvider(); PreviewImage = UpdatePreview(); } public HeatmapColorProviderItem(string name, IEnumerable rangeStops) { Name = name; var provider = new HeatmapRangeColorProvider { IsNormalizedValues = true }; provider.AddRange(rangeStops); ColorProvider = provider; PreviewImage = UpdatePreview(); } IImage UpdatePreview() { const int width = 200; const int height = 8; var bitmap = new RenderTargetBitmap(new PixelSize(width, height), new Vector(96, 96)); using var context = bitmap.CreateDrawingContext(); var range = new MinMaxValues(0, width); for (int i = 0; i < width; i++) { var brush = new SolidColorBrush(ColorProvider.GetColor(i, range)); context.FillRectangle(brush, new Rect(i, 0, i + 1, height)); } return bitmap; } } ================================================ FILE: DemoCenter/DemoCenter/ViewModels/Charts/HeatmapRealTimeViewModel.cs ================================================ using Avalonia.Threading; using CommunityToolkit.Mvvm.ComponentModel; using Eremex.AvaloniaUI.Charts; namespace DemoCenter.ViewModels; public partial class HeatmapRealTimeViewModel : ChartsPageViewModel { const int BandSize = 1000; const int TimeSize = 500; const int StartFrequency = 2000; const int TimeInterval = 20; const double Amplitude = -50; const int ListingSize = BandSize / 20; static double Interpolate(double y1, double y2, double mu) { double mu2 = (1 - Math.Cos(mu * Math.PI)) * 0.5; return y1 * (1 - mu2) + y2 * mu2; } static string ToYLabel(DateTime dateTime) => dateTime.ToString("HH:mm:ss.ffff"); readonly DispatcherTimer timer = new(DispatcherPriority.Background); readonly double[,] values = new double[TimeSize, BandSize]; readonly double[] signalValues = new double[BandSize]; readonly double[] bands = new[] { 0, 0.3, 0, 0, 0.2, 0, 0, 0.9, 0, 0, 0.3, 0, 0.01, 0, 0 }; readonly Random random = new(0); readonly Dictionary xArgumentsIndices = new(); List yArguments = new(TimeSize); public string[] xArguments = new string[BandSize]; [ObservableProperty] HeatmapDataAdapter waterfallAdapter; [ObservableProperty] QualitativeDataAdapter signalAdapter; [ObservableProperty] string mainFrequency; [ObservableProperty] string bandLeftFrequency; [ObservableProperty] string bandRightFrequency; public HeatmapRealTimeViewModel() { for (int i = 0; i < xArguments.Length; i++) { string value = $"{((StartFrequency + i) * 0.001):#.###}k"; xArguments[i] = value; xArgumentsIndices.Add(value, i); } mainFrequency = xArguments[xArguments.Length / 2]; bandLeftFrequency = xArguments[xArguments.Length / 2 - ListingSize]; bandRightFrequency = xArguments[xArguments.Length / 2 + ListingSize]; for (int i = 0; i < TimeSize; i++) { for (int j = 0; j < BandSize; j++) values[i, j] = Amplitude; } var now = DateTime.Now; for (int i = 0; i < TimeSize; i++) yArguments.Add(ToYLabel(now.AddMilliseconds((i - TimeSize) * TimeInterval))); GenerateData(); waterfallAdapter = new HeatmapDataAdapter(xArguments, yArguments, values); signalAdapter = new QualitativeDataAdapter(xArguments, signalValues); timer.Tick += UpdateAdapter; timer.Interval = TimeSpan.FromMilliseconds(TimeInterval); } void UpdateAdapter(object sender, EventArgs e) { GenerateData(); WaterfallAdapter.UpdateValues(values); yArguments.Add(ToYLabel(DateTime.Now)); yArguments.RemoveAt(0); WaterfallAdapter.UpdateYArguments(yArguments); SignalAdapter.Clear(); for (int i = 0; i < BandSize; i++) SignalAdapter.Add(xArguments[i], signalValues[i]); } void GenerateData() { for (int i = 0; i < bands.Length; i++) bands[i] = Math.Max(0, Math.Min(1, bands[i] + (random.NextDouble() - 0.5) * 0.05)); Array.Copy(values, BandSize, values, 0, values.Length - BandSize); for (int i = 0; i < signalValues.Length; i++) { double relativePosition = (double)i * (bands.Length - 1) / signalValues.Length; double value = Interpolate(bands[(int)relativePosition], bands[(int)relativePosition + 1], relativePosition - Math.Floor(relativePosition)); value = Math.Round((1 - Math.Min(1, Math.Max(0, value + (random.NextDouble() - 0.5) * 0.05))) * Amplitude); signalValues[i] = value; values[TimeSize - 1, i] = value; } } public void Start() => timer.Start(); public void Stop() => timer.Stop(); public void UpdateFrequency(string value) { int index = Math.Min(Math.Max(ListingSize, xArgumentsIndices[value]), BandSize - ListingSize - 1); MainFrequency = xArguments[index]; BandLeftFrequency = xArguments[index - ListingSize]; BandRightFrequency = xArguments[index + ListingSize]; } } ================================================ FILE: DemoCenter/DemoCenter/ViewModels/Charts/PolarAreaSeriesViewViewModel.cs ================================================ using System.Collections.ObjectModel; using Avalonia.Media; using CommunityToolkit.Mvvm.ComponentModel; using Eremex.AvaloniaUI.Charts; namespace DemoCenter.ViewModels; public partial class PolarAreaSeriesViewViewModel : ChartsPageViewModel { static double Cos(double argument) => Math.Cos(4 * Math.PI * argument / 180) + 1; const int ItemsCount = 180; const double Step = 360d / ItemsCount; [ObservableProperty] ObservableCollection series = new() { new SeriesViewModel { Color = Color.FromArgb(255, 189, 20, 54), DataAdapter = new FormulaDataAdapter(0, Step, ItemsCount + 1, Cos)}, }; } ================================================ FILE: DemoCenter/DemoCenter/ViewModels/Charts/PolarEmptyPointsViewModel.cs ================================================ using Avalonia.Media; using CommunityToolkit.Mvvm.ComponentModel; using Eremex.AvaloniaUI.Charts; namespace DemoCenter.ViewModels; public partial class PolarEmptyPointsViewModel : ChartsPageViewModel { [ObservableProperty] List views; [ObservableProperty] SeriesViewBase selectedView; [ObservableProperty] ISeriesDataAdapter dataAdapter; public PolarEmptyPointsViewModel() { var color = Color.FromArgb(255, 189, 20, 54); var color2 = Color.FromArgb(255, 0, 120, 122); var simpleAdapter = new FormulaDataAdapter(0, 2, 181, d => d is > 100 and < 170 or > 280 and < 350 ? double.NaN : Math.Cos(4 * Math.PI * d / 180) + 1); views = [ new("Line", simpleAdapter, new PolarLineSeriesView { Color = color, ShowMarkers = true }), new("Area", simpleAdapter, new PolarAreaSeriesView { Color = color, ShowMarkers = true }), new("Scatter Line", CreateScatterData(), new PolarScatterLineSeriesView { Color = color, ShowMarkers = true }), new("Range Area", CreateRangeData(), new PolarRangeAreaSeriesView { Color = Color.FromArgb(255, 67, 201, 39), Color1 = color, Color2 = color2, ShowMarkers1 = true, ShowMarkers2 = true }) ]; selectedView = views[0].View; dataAdapter = views[0].DataAdapter; } ScatterDataAdapter CreateScatterData() { var points = new List<(double, double)>(); points.AddRange(CreateFoliumPart(120, 180)); points.AddRange(CreateFoliumPart(0, 90)); points.AddRange(CreateFoliumPart(270, 330)); return new ScatterDataAdapter(points); IEnumerable<(double, double)> CreateFoliumPart(int minAngle, int maxAngle) { for (double i = minAngle; i <= maxAngle; i += 5) { double angleRad = i * Math.PI / 180; double sin = Math.Sin(angleRad); double cos = Math.Cos(angleRad); double r = 3.0 * sin * cos / (Math.Pow(sin, 3.0) + Math.Pow(cos, 3.0)); if (r is >= 0 and <= 3) yield return (i, i is > 30 and < 60 ? double.NaN : r); } } } NumericRangeDataAdapter CreateRangeData() { var rangeData = new List<(double, double, double)>(); for (double i = 0; i <= 360; i += 5) { bool isEmpty = i is > 60 and < 120 or > 240 and < 300; double value1 = isEmpty ? double.NaN : Math.Sin(Math.PI * i / 720); double value2 = isEmpty ? double.NaN : Math.Cos(Math.PI * i / 720); rangeData.Add((i, value1, value2)); } return new NumericRangeDataAdapter(rangeData); } } ================================================ FILE: DemoCenter/DemoCenter/ViewModels/Charts/PolarLineSeriesViewViewModel.cs ================================================ using System.Collections.ObjectModel; using Avalonia.Media; using CommunityToolkit.Mvvm.ComponentModel; using Eremex.AvaloniaUI.Charts; namespace DemoCenter.ViewModels; public partial class PolarLineSeriesViewViewModel : ChartsPageViewModel { static double Cos(double argument) => Math.Cos(4 * Math.PI * argument / 180); const int ItemsCount = 180; const double Step = 360d / ItemsCount; [ObservableProperty] ObservableCollection series = new() { new SeriesViewModel { Color = Color.FromArgb(255, 189, 20, 54), DataAdapter = new FormulaDataAdapter(0, Step, ItemsCount + 1, Cos)}, }; } ================================================ FILE: DemoCenter/DemoCenter/ViewModels/Charts/PolarPointSeriesViewViewModel.cs ================================================ using System.Collections.ObjectModel; using Avalonia.Media; using CommunityToolkit.Mvvm.ComponentModel; using Eremex.AvaloniaUI.Charts; namespace DemoCenter.ViewModels; public partial class PolarPointSeriesViewViewModel : ChartsPageViewModel { static double Cos(double argument) => Math.Cos(4 * Math.PI * argument / 180); const int ItemsCount = 180; const double Step = 360d / ItemsCount; [ObservableProperty] ObservableCollection series = new() { new SeriesViewModel { Color = Color.FromArgb(255, 189, 20, 54), DataAdapter = new FormulaDataAdapter(0, Step, ItemsCount, Cos)}, }; } ================================================ FILE: DemoCenter/DemoCenter/ViewModels/Charts/PolarRangeAreaSeriesViewViewModel.cs ================================================ using Avalonia.Media; using CommunityToolkit.Mvvm.ComponentModel; using Eremex.AvaloniaUI.Charts; namespace DemoCenter.ViewModels; public partial class PolarRangeAreaSeriesViewViewModel : ChartsPageViewModel { [ObservableProperty] Color color = Color.FromArgb(255, 67, 201, 39); [ObservableProperty] Color color1 = Color.FromArgb(255, 189, 20, 54); [ObservableProperty] Color color2 = Color.FromArgb(255, 0, 120, 122); [ObservableProperty] NumericRangeDataAdapter dataAdapter = new(); public PolarRangeAreaSeriesViewViewModel() { for (int i = 0; i <= 360; i += 5) { double value1 = Math.Sin(Math.PI * i / 720); double value2 = Math.Cos(Math.PI * i / 720); DataAdapter.Add(i, value1, value2); } } } ================================================ FILE: DemoCenter/DemoCenter/ViewModels/Charts/PolarScatterLineSeriesViewViewModel.cs ================================================ using System.Collections.ObjectModel; using Avalonia.Media; using CommunityToolkit.Mvvm.ComponentModel; using Eremex.AvaloniaUI.Charts; namespace DemoCenter.ViewModels; public partial class PolarScatterLineSeriesViewViewModel : ChartsPageViewModel { static IEnumerable<(double, double)> CreateFoliumPart(int minAngle, int maxAngle) { for (int i = minAngle; i <= maxAngle; i += 5) { double angleRad = i * Math.PI / 180; double sin = Math.Sin(angleRad); double cos = Math.Cos(angleRad); double r = 3.0 * sin * cos / (Math.Pow(sin, 3.0) + Math.Pow(cos, 3.0)); if (r is >= 0 and <= 3) yield return (i, r); } } static ScatterDataAdapter CreateFolium() { var points = new List<(double, double)>(); points.AddRange(CreateFoliumPart(120, 180)); points.AddRange(CreateFoliumPart(0, 90)); points.AddRange(CreateFoliumPart(270, 330)); return new ScatterDataAdapter(points); } [ObservableProperty] ObservableCollection series = new() { new SeriesViewModel { Color = Color.FromArgb(255, 189, 20, 54), DataAdapter = CreateFolium() } }; } ================================================ FILE: DemoCenter/DemoCenter/ViewModels/Charts/PolarStripsAndConstantLinesViewModel.cs ================================================ using System.Collections.ObjectModel; using Avalonia.Media; using CommunityToolkit.Mvvm.ComponentModel; using CommunityToolkit.Mvvm.Input; using Eremex.AvaloniaUI.Charts; namespace DemoCenter.ViewModels; public partial class PolarStripsAndConstantLinesViewModel : ChartsPageViewModel { [ObservableProperty] SeriesViewModel series = new() { Color = Color.FromArgb(255, 189, 20, 54), DataAdapter = CreateAdapter() }; [ObservableProperty] ObservableCollection constantLinesX = new(); [ObservableProperty] ObservableCollection constantLinesY = new(); static ISeriesDataAdapter CreateAdapter() { var values = new List<(double, double)> { (0, 16), (5, 15.7), (10, 15), (16, 13), (20, 10), (22, 5), (26, 0), (28, -5), (29, 0), (30, -10), (32, -5), (34, 0), (39, 3), (44, 0), (45, -5), (48, -10), (50, -5), (52, 0), (55, 2), (58, 0), (60, -3), (62, -5), (65, -2), (68, 0), (70, 1), (72, 0), (76, -6), (80, -3), (85, -2), (88, -5), (91, -10), (98, -6), (100, -7), (102, -10), (104, -16), (106, -12), (110, -10), (114, -8), (118, -10), (120, -15), (125, -18), (127, -10), (130, -7), (137, -6), (138, -7), (140, -9), (146, -5), (150, -3), (154, -2), (160, -4), (165, -5), (170, -8), (180, -9) }; int count = values.Count; for (int i = count - 1; i >= 0; i--) values.Add((360 - values[i].Item1, values[i].Item2)); return new SortedNumericDataAdapter(values); } [RelayCommand] void ClearConstantLines() { ConstantLinesX.Clear(); ConstantLinesY.Clear(); } } ================================================ FILE: DemoCenter/DemoCenter/ViewModels/Charts/SmithLineSeriesViewViewModel.cs ================================================ using System.Collections.ObjectModel; using Avalonia.Media; using CommunityToolkit.Mvvm.ComponentModel; using DemoCenter.ViewModels.DataAdapters; using Eremex.AvaloniaUI.Charts; namespace DemoCenter.ViewModels; public partial class SmithLineSeriesViewViewModel : ChartsPageViewModel { [ObservableProperty] ObservableCollection series = new() { new SeriesViewModel { Color = Color.FromArgb(255, 189, 20, 54), DataAdapter = new SmithSampleDataAdapter()}, }; } ================================================ FILE: DemoCenter/DemoCenter/ViewModels/Charts/SmithPointSeriesViewViewModel.cs ================================================ using System.Collections.ObjectModel; using Avalonia.Media; using CommunityToolkit.Mvvm.ComponentModel; using DemoCenter.ViewModels.DataAdapters; using Eremex.AvaloniaUI.Charts; namespace DemoCenter.ViewModels; public partial class SmithPointSeriesViewViewModel : ChartsPageViewModel { [ObservableProperty] ObservableCollection series = new() { new SeriesViewModel { Color = Color.FromArgb(255, 189, 20, 54), DataAdapter = new SmithSampleDataAdapter()}, }; } ================================================ FILE: DemoCenter/DemoCenter/ViewModels/CommonControls/CommonControlsGroupViewModel.cs ================================================ using CommunityToolkit.Mvvm.ComponentModel; using Eremex.AvaloniaUI.Controls.Common; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace DemoCenter.ViewModels { public partial class CommonControlsGroupViewModel : PageViewModelBase { [ObservableProperty] string message; public CommonControlsGroupViewModel() { Message = GetType().FullName; } } } ================================================ FILE: DemoCenter/DemoCenter/ViewModels/CommonControls/MessageBoxPageViewModel.cs ================================================ using CommunityToolkit.Mvvm.ComponentModel; using Avalonia.Layout; using Eremex.AvaloniaUI.Controls; namespace DemoCenter.ViewModels { public partial class MessageBoxPageViewModel : PageViewModelBase { [ObservableProperty] private string title = "MxMessageBox Title"; [ObservableProperty] private string text = "MxMessageBox can display a text message, an icon and a set of standard buttons."; [ObservableProperty] private MessageBoxButtons buttons = MessageBoxButtons.OkCancel; [ObservableProperty] private MessageBoxIcon icon = MessageBoxIcon.Information; [ObservableProperty] private MessageBoxResult result = MessageBoxResult.Ok; [ObservableProperty] private HorizontalAlignment buttonAlignment = HorizontalAlignment.Right; } } ================================================ FILE: DemoCenter/DemoCenter/ViewModels/CommonControls/SplitContainerControlPageViewModel.cs ================================================ using CommunityToolkit.Mvvm.ComponentModel; using Eremex.AvaloniaUI.Controls.Common; using Eremex.AvaloniaUI.Controls.Editors; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using DemoCenter.DemoData; namespace DemoCenter.ViewModels { public partial class SplitContainerControlPageViewModel : PageViewModelBase { public IList Cars { get; } = CsvSources.Cars; } } ================================================ FILE: DemoCenter/DemoCenter/ViewModels/CommonControls/TabControlPageViewModel.cs ================================================ using CommunityToolkit.Mvvm.ComponentModel; using Eremex.AvaloniaUI.Controls.Common; using Eremex.AvaloniaUI.Controls.Editors; using System; using System.Collections; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Linq; using System.Text; using System.Threading.Tasks; using Avalonia.Controls; using CommunityToolkit.Mvvm.Input; using DemoCenter.DemoData; using Eremex.AvaloniaUI.Controls; namespace DemoCenter.ViewModels { public partial class TabControlPageViewModel : PageViewModelBase { private static readonly Random rnd = new(DateTime.Now.Millisecond); private int newCarCount; private readonly ObservableCollection cars = new(CsvSources.Cars); [ObservableProperty] private TabStripLayoutType layoutType = TabStripLayoutType.Stretch; [ObservableProperty] private Dock placement = Dock.Top; [ObservableProperty] private TabDragMode dragMode = TabDragMode.Reorder; [ObservableProperty] private TabHeaderOrientation headerOrientation; [ObservableProperty] private TabControlCloseButtonShowMode closeButtonShowMode = TabControlCloseButtonShowMode.None; [ObservableProperty] private TabControlNewButtonShowMode newButtonShowMode = TabControlNewButtonShowMode.None; [ObservableProperty] private CarInfo selectedCar; [ObservableProperty] private bool isTabPanelVisible = true; public IEnumerable Cars => cars; public IEnumerable CloseButtonShowModes { get; } = new[] { TabControlCloseButtonShowMode.None, TabControlCloseButtonShowMode.InActiveTab, TabControlCloseButtonShowMode.InAllTabs, TabControlCloseButtonShowMode.InHeaderPanel, TabControlCloseButtonShowMode.InAllTabs | TabControlCloseButtonShowMode.InHeaderPanel }; [RelayCommand] private void OnNew() { var randomCar = CsvSources.Cars[rnd.Next(CsvSources.Cars.Count - 1)]; var newCar = new CarInfo($"New Car ({++newCarCount})", randomCar); cars.Add(newCar); SelectedCar = newCar; } [RelayCommand] private void OnClose(object parameter) { if (parameter is CarInfo car) { cars.Remove(car); } } } } ================================================ FILE: DemoCenter/DemoCenter/ViewModels/DataGrid/DataGridColumnBandsViewModel.cs ================================================ using CommunityToolkit.Mvvm.ComponentModel; using DemoCenter.DemoData; using System.Collections; using System.Collections.ObjectModel; namespace DemoCenter.ViewModels; public partial class DataGridColumnBandsViewModel : PageViewModelBase { [ObservableProperty] IList sales; [ObservableProperty] IList bands; public DataGridColumnBandsViewModel() { Sales = EmployeesData.GenerateComplexEmployeeSales(); Bands = new ObservableCollection(); for (int i = 1; i < 4; i++) { var year = DateTime.Now.Year - i; var band = new BandInfo() { BandName = "" + year, Children = new List() }; for (int j = 0; j < 4; j++) { var quarterName = "Q" + (j + 1); band.Children.Add(new BandInfo() { BandName = year + "/" + quarterName, Header = quarterName }); } Bands.Add(band); } } } public class BandInfo { public string BandName { get; set; } public string Header { get; set; } public IList Children { get; set; } } ================================================ FILE: DemoCenter/DemoCenter/ViewModels/DataGrid/DataGridDataEditorsViewModel.cs ================================================ using CommunityToolkit.Mvvm.ComponentModel; using DemoCenter.DemoData; using Eremex.AvaloniaUI.Controls.Common; using System; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Linq; using System.Text; using System.Threading.Tasks; namespace DemoCenter.ViewModels { public partial class DataGridDataEditorsViewModel : PageViewModelBase { [ObservableProperty] IList employees; public DataGridDataEditorsViewModel() { Employees = EmployeesData.GenerateEmployeeInfo(); } } } ================================================ FILE: DemoCenter/DemoCenter/ViewModels/DataGrid/DataGridDragDropPageViewModel.cs ================================================ using CommunityToolkit.Mvvm.ComponentModel; using DemoCenter.DemoData; using DemoCenter.DemoData.CsvClasses; using System.Collections.ObjectModel; namespace DemoCenter.ViewModels { public partial class DataGridDragDropPageViewModel : PageViewModelBase { public DataGridDragDropPageViewModel() { ProductsInWarehouse = CsvSources.StockProducts.Take(50).ToList(); ProductsInStock = CsvSources.StockProducts.TakeLast(20).ToList(); } public List ProductsInStock { get; } public List ProductsInWarehouse { get; } } } ================================================ FILE: DemoCenter/DemoCenter/ViewModels/DataGrid/DataGridExportViewModel.cs ================================================ using CommunityToolkit.Mvvm.ComponentModel; using CommunityToolkit.Mvvm.Input; using DemoCenter.DemoData; using Eremex.DocumentProcessing.Exports; namespace DemoCenter.ViewModels { public enum ExportType { Xlsx, Pdf } public partial class DataGridExportViewModel : PageViewModelBase { public DataGridExportViewModel() { ApparelProducts = DemoData.ApparelProducts.GenerateData(10000); } #region xlsx export properties [ObservableProperty] private bool xlsExportColumnHeaders = true; [ObservableProperty] private bool xlsExportBandHeaders = true; #endregion #region page export properties [ObservableProperty] private bool pageExportColumnHeaders = true; [ObservableProperty] private bool pageExportBandHeaders = true; [ObservableProperty] private bool fitToPageWidth = true; [ObservableProperty] private bool landscape = true; #endregion public IList ApparelProducts { get; } public event Action RequestExport; public event Action RequestExportImage; [RelayCommand] private void Export(ExportType type) { RequestExport?.Invoke(type); } [RelayCommand] private void ExportImage(MxImageFormat format) { RequestExportImage?.Invoke(format); } } } ================================================ FILE: DemoCenter/DemoCenter/ViewModels/DataGrid/DataGridFilteringViewModel.cs ================================================ using CommunityToolkit.Mvvm.ComponentModel; using DemoCenter.DemoData; namespace DemoCenter.ViewModels { public partial class DataGridFilteringViewModel : PageViewModelBase { [ObservableProperty] IList employees; public DataGridFilteringViewModel() { Employees = EmployeesData.GenerateEmployeeInfo(); } } } ================================================ FILE: DemoCenter/DemoCenter/ViewModels/DataGrid/DataGridFixedColuimnsViewModel.cs ================================================ using CommunityToolkit.Mvvm.ComponentModel; using DemoCenter.DemoData; namespace DemoCenter.ViewModels { public partial class DataGridFixedColumnsViewModel : PageViewModelBase { [ObservableProperty] IList employees; [ObservableProperty] bool autoHideScrollbars = true; public DataGridFixedColumnsViewModel() { Employees = EmployeesData.GenerateEmployeeInfo(); } } } ================================================ FILE: DemoCenter/DemoCenter/ViewModels/DataGrid/DataGridGroupingPageViewModel.cs ================================================ using CommunityToolkit.Mvvm.ComponentModel; using DemoCenter.DemoData; namespace DemoCenter.ViewModels { public partial class DataGridGroupingPageViewModel : PageViewModelBase { [ObservableProperty] IList sales; public DataGridGroupingPageViewModel() { Sales = EmployeesData.GenerateEmployeeSales(); } } } ================================================ FILE: DemoCenter/DemoCenter/ViewModels/DataGrid/DataGridLargeDataPageViewModel.cs ================================================ using Avalonia.Controls.Platform; using CommunityToolkit.Mvvm.ComponentModel; using CommunityToolkit.Mvvm.Input; using DemoCenter.DemoData; using System; using System.Collections; using System.Data; using System.Reflection; namespace DemoCenter.ViewModels { public partial class DataGridLargeDataViewModel : PageViewModelBase { [ObservableProperty] IEnumerable items; [ObservableProperty] IEnumerable columns; [ObservableProperty] ItemsCount selectedItemsCount; [ObservableProperty] ItemsCount selectedColumnsCount; Random random = new Random(); public DataGridLargeDataViewModel() { SelectedItemsCount = ItemsCount.Medium; SelectedColumnsCount = ItemsCount.Small; Generate(); } [RelayCommand] void Generate() { Columns = Enumerable.Range(0, GetColumnsCount()).Select(x => GetColumn(x)).ToList(); Items = Enumerable.Range(0, GetItemsCount()).Select(x => new LargeDataItem() { Id = x }).ToList(); LargeDataColumn GetColumn(int index) { if (index == 0) return new LargeDataColumn("Id", "Id (0)", typeof(int)); int remainder = (index - 1) % 5; switch (remainder) { case 1: return new LargeDataColumn($"Numeric ({index})", typeof(int)); case 2: return new LargeDataColumn($"ComboBox ({index})", typeof(string)); case 3: return new LargeDataColumn($"DateTime ({index})", typeof(DateTime)); case 4: return new LargeDataColumn($"CheckBox ({index})", typeof(bool)); default: return new LargeDataColumn($"Text ({index})", typeof(string)); } } } int GetItemsCount() { switch (SelectedItemsCount) { case ItemsCount.Small: return 100000; case ItemsCount.Medium: return 500000; default: return 1000000; } } int GetColumnsCount() { switch (SelectedColumnsCount) { case ItemsCount.Small: return 100; case ItemsCount.Medium: return 500; default: return 1000; } } } public enum ItemsCount { Small, Medium, Large } public class LargeDataItem { public int Id { get; set; } } public class LargeDataColumn { public LargeDataColumn(string fieldName, Type dataType) { FieldName = fieldName; Header = fieldName; DataType = dataType; } public LargeDataColumn(string fieldName, string header, Type dataType) { FieldName = fieldName; Header = header; DataType = dataType; } public string FieldName { get; private set; } public string Header { get; private set; } public Type DataType { get; private set; } } } ================================================ FILE: DemoCenter/DemoCenter/ViewModels/DataGrid/DataGridLiveDataPageViewModel.cs ================================================ using Avalonia.Threading; using CommunityToolkit.Mvvm.ComponentModel; using System.Collections.ObjectModel; using System.Diagnostics; namespace DemoCenter.ViewModels { public partial class DataGridLiveDataPageViewModel : PageViewModelBase { static IReadOnlyList<(string name, int count)> ProcessList { get; } = new List<(string name, int count)>() { ("DemoCenter.Desktop", 1), ("Microsoft Edge", 5), ("Microsoft Visual Studio 2022", 3), ("Windows Explorer", 4), ("Google Chrome", 5), ("Notepad", 3), ("Paint", 2), ("Desktop Window Manager", 1), ("Task Manager", 1), ("Calculator", 1), ("Mail", 1), ("Media Player", 1), ("Cortana", 1), ("Settings", 1), ("Delta Design", 1), ("Telegram Desktop", 1), ("System", 1), ("System Interrupts", 1), ("Runtime Broker", 10), ("COM Surrogate", 5), ("CTF Loader", 1), ("AggregatorHost", 1), ("Client Server Runtime Process", 1), ("Registry", 1), ("Microsoft IME", 1), ("Host Process for Window Tasks", 1), ("Application Frame Host", 1), ("Console Window Host", 3), ("Antimalware Core Service", 1), ("Shell Infrastructure Host", 1), ("Windows Start-Up Application", 1), ("Windows Session Manager", 1), ("Secure System", 1), ("Credential Guard & Key Guard", 1), ("Local Security Authority Process", 1), ("svchost", 30) }; Random random = new Random(); DispatcherTimer dispatcherTimer; [ObservableProperty] IList processes; [ObservableProperty] double totalCpuLoad; [ObservableProperty] double totalMemoryLoad; [ObservableProperty] double totalDiskLoad; [ObservableProperty] double totalNetworkLoad; [ObservableProperty] double totalGpuLoad; public DataGridLiveDataPageViewModel() { var source = new List(); foreach (var process in ProcessList) { for (var i = 0; i < process.count; i++) source.Add(new ProcessInfo() { Name = process.name }); } Processes = new ObservableCollection(source.OrderBy(x => random.Next())); UpdateProcesses(); dispatcherTimer = new DispatcherTimer(); dispatcherTimer.Interval = TimeSpan.FromMilliseconds(250); dispatcherTimer.Tick += DispatcherTimer_Tick; } void UpdateProcesses() { UpdateValue(x => TotalCpuLoad = x, (p, x) => p.CpuLoad = x, 8, 40, 30); UpdateValue(x => TotalMemoryLoad = x, (p, x) => p.MemoryLoad = x, 20, 32 * 1024, 10 * 1024); UpdateValue(x => TotalDiskLoad = x, (p, x) => p.DiskLoad = x, 5, 10, 10); UpdateValue(x => TotalNetworkLoad = x, (p, x) => p.NetworkLoad = x, 5, 10, 1); UpdateValue(x => TotalGpuLoad = x, (p, x) => p.GpuLoad = x, 2, 10, 0); } public void RunUpdate() { dispatcherTimer.Start(); } public void StopUpdate() { dispatcherTimer.Stop(); } private void DispatcherTimer_Tick(object sender, EventArgs e) { UpdateProcesses(); } void UpdateValue(Action updateTotalValue, Action updateProcessValue, int activeProcessCount, double maxActiveValue, double otherValue) { var processes = Processes.ToList(); var sum = 0d; maxActiveValue = maxActiveValue * random.Next(3) / 3; for (int i = 0; i < activeProcessCount; i++) { var index = random.Next(processes.Count); var value = Math.Round(maxActiveValue * random.NextDouble(), 1); maxActiveValue -= value; updateProcessValue(processes[index], value); sum += value; processes.RemoveAt(index); } foreach (var process in processes) { var value = Math.Round(otherValue / Processes.Count * random.NextDouble(), 1); updateProcessValue(process, value); sum += value; } updateTotalValue(sum); } } public partial class ProcessInfo : ObservableObject { [ObservableProperty] string name; [ObservableProperty] double cpuLoad; [ObservableProperty] double memoryLoad; [ObservableProperty] double diskLoad; [ObservableProperty] double networkLoad; [ObservableProperty] double gpuLoad; } } ================================================ FILE: DemoCenter/DemoCenter/ViewModels/DataGrid/DataGridMultipleSelectionPageViewModel.cs ================================================ using CommunityToolkit.Mvvm.ComponentModel; using DemoCenter.DemoData; using System.Collections.ObjectModel; namespace DemoCenter.ViewModels { public partial class DataGridMultipleSelectionPageViewModel : PageViewModelBase { public DataGridMultipleSelectionPageViewModel() { Employees = EmployeesData.GenerateEmployeeInfo(); SelectedEmployees = new(Employees.Take(5)); } public ObservableCollection SelectedEmployees { get; } public IList Employees { get; } } } ================================================ FILE: DemoCenter/DemoCenter/ViewModels/DataGrid/DataGridPageViewModel.cs ================================================ namespace DemoCenter.ViewModels { public partial class DataGridPageViewModel : PageViewModelBase { public DataGridPageViewModel() { } } } ================================================ FILE: DemoCenter/DemoCenter/ViewModels/DataGrid/DataGridRowAutoHeightViewModel.cs ================================================ using CommunityToolkit.Mvvm.ComponentModel; using DemoCenter.DemoData; namespace DemoCenter.ViewModels { public partial class DataGridRowAutoHeightViewModel : PageViewModelBase { public IList Cars { get; } = CsvSources.Cars; } } ================================================ FILE: DemoCenter/DemoCenter/ViewModels/DataGrid/DataGridValidationViewModel.cs ================================================ using CommunityToolkit.Mvvm.ComponentModel; using DemoCenter.DemoData; namespace DemoCenter.ViewModels { public partial class DataGridValidationViewModel : PageViewModelBase { [ObservableProperty] IList employees; public DataGridValidationViewModel() { Employees = EmployeesData.GenerateValidationEmployeeInfo(); } } } ================================================ FILE: DemoCenter/DemoCenter/ViewModels/DesktopOnlyViewModel.cs ================================================ namespace DemoCenter.ViewModels; public partial class DesktopOnlyViewModel : PageViewModelBase { } ================================================ FILE: DemoCenter/DemoCenter/ViewModels/DockManager/IdeLayoutPageViewModel.cs ================================================ using System.Collections.ObjectModel; using System.ComponentModel; using System.ComponentModel.DataAnnotations; using System.Windows.Input; using CommunityToolkit.Mvvm.ComponentModel; using CommunityToolkit.Mvvm.Input; namespace DemoCenter.ViewModels { public partial class IdeLayoutPageViewModel : PageViewModelBase { [ObservableProperty] private object focusedSolutionItem; public IdeLayoutPageViewModel() { var embeddedFiles = App.EmbeddedResources.Where(x => x.EndsWith(".cs") || x.EndsWith(".axaml")); var projectNode = new SolutionProjectNode("AvaloniaApplication", string.Empty); foreach (var s in embeddedFiles) { var ext = GetExtension(s); var nameWithoutExtension = GetFileNameWithoutExtension(s, ext); var splitName = nameWithoutExtension.Split("."); string currentPath = string.Empty; for (var i = 0; i < splitName.Length; i++) { var last = i == splitName.Length - 1; var name = last ? splitName[i] + ext : splitName[i]; var parent = SolutionNodes.FirstOrDefault(x => x.Path == currentPath) ?? projectNode; currentPath = Path.Join(currentPath, name); var node = SolutionNodes.FirstOrDefault(x => x.Path == currentPath); if (node == null) { node = last ? new SolutionFile(name, currentPath, s) : new SolutionFolder(name, currentPath); node.ParentId = parent.Id; SolutionNodes.Add(node); } } } SolutionNodes.Add(projectNode); SolutionNodes.Add(new SolutionDependenciesNode { ParentId = projectNode.Id }); var focusedItem = SolutionNodes.OfType().First(); FocusedSolutionItem = focusedItem; Open(focusedItem); } public ObservableCollection SolutionNodes { get; } = new(); public ObservableCollection Documents { get; } = new(); public void Open(SolutionFile solutionFile) { var document = Documents.FirstOrDefault(x => x.Uri == solutionFile.Uri); if (document == null) { document = new IdeLayoutDocumentViewModel { Header = solutionFile.Filename, Uri = solutionFile.Uri }; document.CloseCommand = new RelayCommand(() => Documents.Remove(document)); Documents.Add(document); } document.IsActive = true; } private static string GetExtension(string filename) { return filename.EndsWith(".axaml.cs") ? ".axaml.cs" : Path.GetExtension(filename); } private static string GetFileNameWithoutExtension(string filename, string extension) { return filename.Replace(extension, ""); } } public class SolutionProjectNode : SolutionNodeBase { [Display(Name = "File Name")] public string Filename => $"{Name}.csproj"; public SolutionProjectNode(string name, string fullPath) : base(name, fullPath) { } } public class SolutionFolder : SolutionNodeBase { [Display(Name = "Folder Name")] public string FolderName => Name; [Display(Name = "Full Path")] public string FullPath => Path; public SolutionFolder(string name, string fullPath) : base(name, fullPath) { } } public enum BuildAction { Resource, [Display(Name="Avalonia XAML")] AvaloniaXaml, [Display(Name="C# Compiler")] CSharpCompiler, Content, None } public enum CopyToOutputDirectory { [Display(Name = "Do not copy")] DoNotCopy, [Display(Name = "Copy always")] CopyAlways, [Display(Name = "Copy if newer")] CopyIfNewer } public partial class SolutionFile : SolutionNodeBase { [ObservableProperty, Display(Name = "Build Action")] [property:Category("Advanced")] private BuildAction buildAction; [ObservableProperty, Display(Name = "Copy to Output Directory")] [property:Category("Advanced")] private CopyToOutputDirectory copyToOutputDirectory; [ObservableProperty, Display(Name = "Custom Tool")] [property:Category("Advanced")] private string customTool; [ObservableProperty, Display(Name = "Custom Tool Namespace")] [property:Category("Advanced")] private string customToolNamespace; public SolutionFile(string name, string fullPath, string uri) : base(name, fullPath) { if (fullPath.EndsWith(".cs")) { buildAction = BuildAction.CSharpCompiler; } else if (fullPath.EndsWith(".axaml")) { buildAction = BuildAction.AvaloniaXaml; } Uri = uri; } [Browsable(false)] public string Uri { get; } [Display(Name = "File Name")] public string Filename => Name; [Display(Name = "Full Path")] public string FullPath => Path; } public class SolutionDependenciesNode : SolutionNodeBase { public SolutionDependenciesNode() : base("Dependencies", string.Empty) { } } public abstract partial class SolutionNodeBase : ObservableObject { [ObservableProperty] [property:Browsable(false)] private bool isExpanded; protected SolutionNodeBase(string name, string fullPath) { Name = name; Path = fullPath; Id = Guid.NewGuid(); } [Browsable(false)] public object Id { get; } [Browsable(false)] public object ParentId { get; set; } [Browsable(false)] public string Name { get; } [Browsable(false)] public string Path { get; } } public partial class IdeLayoutDocumentViewModel : ObservableObject { [ObservableProperty] private string header; [ObservableProperty] private string uri; [ObservableProperty] private bool isActive; [ObservableProperty] private ICommand closeCommand; } } ================================================ FILE: DemoCenter/DemoCenter/ViewModels/Editors/ColorEditorPageViewModel.cs ================================================ using System; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Linq; using System.Text; using System.Threading.Tasks; using Avalonia.Media; using CommunityToolkit.Mvvm.ComponentModel; using Eremex.AvaloniaUI.Controls.Editors; namespace DemoCenter.ViewModels { public partial class ColorEditorPageViewModel : PageViewModelBase { [ObservableProperty] bool showStandardColors = true; [ObservableProperty] bool showCustomColors = true; [ObservableProperty] ColorsShowMode colorsShowMode = ColorsShowMode.StandardColors | ColorsShowMode.CustomColors; [ObservableProperty] ObservableCollection customColors1 = new ObservableCollection() { Color.FromRgb(0x7d, 0xd7, 0xab), Color.FromRgb(0xc5, 0x94, 0x88), Color.FromRgb(0x47, 0xfe, 0xff), Color.FromRgb(0xe9, 0xbf, 0x3f), }; [ObservableProperty] ObservableCollection customColors2 = new ObservableCollection() { Color.FromRgb(0x7d, 0x82, 0x82), Color.FromRgb(0xa1, 0x17, 0x2a), Color.FromRgb(0x58, 0xd9, 0xdb), Colors.Yellow, }; public ColorEditorPageViewModel() { } partial void OnShowStandardColorsChanged(bool value) { if(value) ColorsShowMode |= ColorsShowMode.StandardColors; else ColorsShowMode &= ~ColorsShowMode.StandardColors; } partial void OnShowCustomColorsChanged(bool value) { if (value) ColorsShowMode |= ColorsShowMode.CustomColors; else ColorsShowMode &= ~ColorsShowMode.CustomColors; } } } ================================================ FILE: DemoCenter/DemoCenter/ViewModels/Editors/ComboBoxEditorPageViewModel.cs ================================================ using System; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Linq; using System.Text; using CommunityToolkit.Mvvm.ComponentModel; using DemoCenter.DemoData; using Eremex.AvaloniaUI.Controls.Editors; namespace DemoCenter.ViewModels { public partial class ComboBoxEditorPageViewModel : PageViewModelBase { [ObservableProperty] string yachtValue = CsvSources.YachtNames[3]; [ObservableProperty] FilterCondition editableViewFilterCondition = FilterCondition.StartsWith; [ObservableProperty] List elements; [ObservableProperty] ElementInfo selectedElement; [ObservableProperty] IList mechs; [ObservableProperty] ObservableCollection selectedMechs; [ObservableProperty] string[] separators = new[] { ";", ".", "...", "|" }; [ObservableProperty] string selectedSeparator; public ComboBoxEditorPageViewModel() { Elements = ElementsSources.Elements; SelectedElement = Elements[9]; Mechs = CsvSources.Mechs; SelectedMechs = new ObservableCollection() { Mechs[1], Mechs[5], Mechs[6], Mechs[9] }; SelectedSeparator = Separators[0]; } } } ================================================ FILE: DemoCenter/DemoCenter/ViewModels/Editors/DateEditorPageViewModel.cs ================================================ using System; using System.Collections.Generic; using System.Linq; using System.Text; using CommunityToolkit.Mvvm.ComponentModel; using DemoCenter.DemoData; using Eremex.AvaloniaUI.Controls.Editors; namespace DemoCenter.ViewModels { public partial class DateEditorPageViewModel : PageViewModelBase { [ObservableProperty] bool showNullButton; [ObservableProperty] ComponentPlacement nullValueButtonPosition; [ObservableProperty] DateTime? current; [ObservableProperty] DateTime? minimum; [ObservableProperty] DateTime? maximum; [ObservableProperty] string[] formats = new[] { "d", "D", "MMMM dd" }; [ObservableProperty] string selectedTextFormat; public DateEditorPageViewModel() { ShowNullButton = true; Current = DateTime.Now.AddDays(4); Maximum = DateTime.Now.AddMonths(4); SelectedTextFormat = formats[0]; } partial void OnShowNullButtonChanged(bool value) => NullValueButtonPosition = value ? ComponentPlacement.Popup : ComponentPlacement.None; } } ================================================ FILE: DemoCenter/DemoCenter/ViewModels/Editors/EditorsGroupViewModel.cs ================================================ using System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Text; using CommunityToolkit.Mvvm.ComponentModel; namespace DemoCenter.ViewModels { public partial class EditorsGroupViewModel : PageViewModelBase { public EditorsGroupViewModel() { } } } ================================================ FILE: DemoCenter/DemoCenter/ViewModels/Editors/EditorsOverviewPageViewModel.cs ================================================ using System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Text; using System.Threading.Tasks; using CommunityToolkit.Mvvm.ComponentModel; using CommunityToolkit.Mvvm.Input; using DemoCenter.DemoData; namespace DemoCenter.ViewModels { public partial class EditorsOverviewPageViewModel : PageViewModelBase { [ObservableProperty] DateTime selectedDate = DateTime.Today.AddDays(3); [ObservableProperty] GraphicView graphicView = GraphicView.Front; [ObservableProperty] ElementInfo selectedItem; [ObservableProperty] IEnumerable elements; public EditorsOverviewPageViewModel() { Elements = ElementsSources.Elements.Take(new Range(15, 25)); SelectedItem = Elements.ElementAt(3); } [RelayCommand] public void ShowPage(string parameter) { try { Process.Start(new ProcessStartInfo(parameter) { UseShellExecute = true }); } catch { }; } } } ================================================ FILE: DemoCenter/DemoCenter/ViewModels/Editors/EnumSourcePageViewModel.cs ================================================ using System; using System.Collections.Generic; using System.Linq; using System.Text; using CommunityToolkit.Mvvm.ComponentModel; using DemoCenter.DemoData; using Eremex.AvaloniaUI.Controls.Common; using Eremex.AvaloniaUI.Controls.DataControl; namespace DemoCenter.ViewModels { public partial class EnumSourcePageViewModel : PageViewModelBase { [ObservableProperty] GraphicPosition graphicPosition; [ObservableProperty] GraphicView graphicView; [ObservableProperty] EnumMembersSortMode sortMode; //public event Action UpdateEnumSources; public EnumSourcePageViewModel() { SortMode = EnumMembersSortMode.Default; GraphicPosition = GraphicPosition.Maximum; GraphicView = GraphicView.Top; } } } ================================================ FILE: DemoCenter/DemoCenter/ViewModels/Editors/HyperlinkEditorPageViewModel.cs ================================================ using System; using System.Collections.Generic; using System.Linq; using System.Text; using CommunityToolkit.Mvvm.ComponentModel; using CommunityToolkit.Mvvm.Input; using DemoCenter.DemoData; namespace DemoCenter.ViewModels { public partial class HyperlinkEditorPageViewModel : PageViewModelBase { [ObservableProperty] IEnumerable yachts; public HyperlinkEditorPageViewModel() { Yachts = CsvSources.Yachts; } public event Action SelectDemo; [RelayCommand] public void ShowDemo(string moduleName) { SelectDemo?.Invoke(moduleName); } } } ================================================ FILE: DemoCenter/DemoCenter/ViewModels/Editors/MemoEditorPageViewModel.cs ================================================ using Avalonia.Controls.Primitives; using CommunityToolkit.Mvvm.ComponentModel; namespace DemoCenter.ViewModels; public partial class MemoEditorPageViewModel : PageViewModelBase { [ObservableProperty] private ScrollBarVisibility horizontalScrollbarVisibility = ScrollBarVisibility.Auto; [ObservableProperty] private ScrollBarVisibility verticalScrollbarVisibility = ScrollBarVisibility.Auto; [ObservableProperty] private ScrollBarVisibility[] scrollbarVisibilityItems = new[] { ScrollBarVisibility.Auto, ScrollBarVisibility.Visible, ScrollBarVisibility.Hidden, ScrollBarVisibility.Disabled }; [ObservableProperty] private string text = "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, " + Environment.NewLine + "quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum " + Environment.NewLine + "dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. " + Environment.NewLine + "Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore " + Environment.NewLine + "veritatis et quasi architecto beatae vitae dicta sunt explicabo. Nemo enim ipsam voluptatem " + Environment.NewLine + "quia voluptas sit aspernatur aut odit aut fugit, " + Environment.NewLine + "sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt. " + Environment.NewLine + "Neque porro quisquam est, qui dolorem ipsum quia dolor sit amet, " + Environment.NewLine + "consectetur, adipisci velit, sed quia non numquam eius modi tempora incidunt ut labore et " + Environment.NewLine + "dolore magnam aliquam quaerat voluptatem. Ut enim ad " + Environment.NewLine + "minima veniam, quis nostrum exercitationem ullam corporis suscipit laboriosam, nisi ut aliquid " + Environment.NewLine + "ex ea commodi consequatur? Quis autem vel eum iure " + Environment.NewLine + "reprehenderit qui in ea voluptate velit esse quam nihil molestiae consequatur, vel illum " + Environment.NewLine + "qui dolorem eum fugiat quo voluptas nulla pariatur? " + Environment.NewLine + "At vero eos et accusamus et iusto odio dignissimos ducimus qui blanditiis " + Environment.NewLine + "praesentium voluptatum deleniti atque corrupti quos dolores et quas molestias " + Environment.NewLine + "excepturi sint occaecati cupiditate non provident, similique sunt in culpa qui " + Environment.NewLine + "officia deserunt mollitia animi, id est laborum et dolorum fuga. " + Environment.NewLine + "Et harum quidem rerum facilis est et expedita distinctio. Nam libero tempore, cum " + Environment.NewLine + "soluta nobis est eligendi optio cumque nihil impedit quo minus id " + Environment.NewLine + "quod maxime placeat facere possimus, omnis voluptas assumenda est, omnis dolor " + Environment.NewLine + "repellendus. Temporibus autem quibusdam et aut officiis debitis aut " + Environment.NewLine + "rerum necessitatibus saepe eveniet ut et voluptates repudiandae sint et molestiae " + Environment.NewLine + "non recusandae. Itaque earum rerum hic tenetur a sapiente delectus, " + Environment.NewLine + "ut aut reiciendis voluptatibus maiores alias consequatur aut perferendis doloribus asperiores repellat."; } ================================================ FILE: DemoCenter/DemoCenter/ViewModels/Editors/SegmentedEditorPageViewModel.cs ================================================ using System; using System.Collections.Generic; using System.Linq; using System.Text; using CommunityToolkit.Mvvm.ComponentModel; using DemoCenter.DemoData; using Eremex.AvaloniaUI.Controls.Common; using Eremex.AvaloniaUI.Controls.DataControl; namespace DemoCenter.ViewModels { public partial class SegmentedEditorPageViewModel : PageViewModelBase { [ObservableProperty] GraphicView graphicView; [ObservableProperty] string[] viewTypes; [ObservableProperty] string selectedViewType; public SegmentedEditorPageViewModel() { GraphicView = GraphicView.Top; ViewTypes = new[] { "Primary", "Secondary" }; SelectedViewType = ViewTypes[0]; } } } ================================================ FILE: DemoCenter/DemoCenter/ViewModels/Editors/SpinEditorPageViewModel.cs ================================================ using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using DemoCenter.DemoData; using CommunityToolkit.Mvvm.ComponentModel; using Eremex.AvaloniaUI.Controls.Common; namespace DemoCenter.ViewModels { public partial class SpinEditorPageViewModel : PageViewModelBase { [ObservableProperty] IEnumerable yachts; public SpinEditorPageViewModel() { Yachts = CsvSources.Yachts.Take(4); } } } ================================================ FILE: DemoCenter/DemoCenter/ViewModels/Editors/TextEditingPageViewModel.cs ================================================ using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using CommunityToolkit.Mvvm.ComponentModel; using CommunityToolkit.Mvvm.Input; using Eremex.AvaloniaUI.Controls.Common; using Eremex.AvaloniaUI.Controls.Editors; namespace DemoCenter.ViewModels { public partial class TextEditingPageViewModel : PageViewModelBase { [ObservableProperty] string logContent = string.Empty; [ObservableProperty] string selectedString = string.Empty; [ObservableProperty, NotifyCanExecuteChangedFor(nameof(ShowPreviousCommand)), NotifyCanExecuteChangedFor(nameof(ShowNextCommand))] string selectedEditor; [ObservableProperty] bool showError; [ObservableProperty] ValidationInfo validationInfo; List editors; public TextEditingPageViewModel() { editors = typeof(BaseEditor).Assembly .GetTypes() .Where(x => x.IsSubclassOf(typeof(BaseEditor))) .Select(x => x.Name) .ToList(); SelectedEditor = "TextEditor"; ShowError = true; } [RelayCommand] public void AddLogLine(string parameter) { LogContent += $"{parameter} button click!" + Environment.NewLine; } [RelayCommand(CanExecute = nameof(CanShowPrevious))] public void ShowPrevious(string parameter) => UpdateSelectedEditor(parameter, -1); public bool CanShowPrevious() => SelectedEditor != editors.First(); [RelayCommand(CanExecute = nameof(CanShowNext))] public void ShowNext(string parameter) => UpdateSelectedEditor(parameter, 1); public bool CanShowNext() => SelectedEditor != editors.Last(); void UpdateSelectedEditor(string parameter, int increment) { var index = editors.IndexOf(SelectedEditor); SelectedEditor = editors[index + increment]; AddLogLine(parameter); } [RelayCommand] public void ClearLog() => LogContent = string.Empty; partial void OnShowErrorChanged(bool value) { ValidationInfo = value ? new ValidationInfo("Incorrect text!") : null; } } } ================================================ FILE: DemoCenter/DemoCenter/ViewModels/Graphics3DControl/Graphics3DControlCameraViewModel.cs ================================================ using System.Numerics; using Avalonia.Media; using CommunityToolkit.Mvvm.ComponentModel; using Eremex.AvaloniaUI.Controls3D; namespace DemoCenter.ViewModels; public partial class Graphics3DControlCameraViewModel : Graphics3DControlViewModel { const float size = 10; const float max = size; const float min = -size; static Vector3 v1 = new(min, min, max); static Vector3 v2 = new(max, min, max); static Vector3 v3 = new(max, max, max); static Vector3 v4 = new(min, max, max); static Vector3 v5 = new(min, max, min); static Vector3 v6 = new(min, min, min); static Vector3 v7 = new(max, min, min); static Vector3 v8 = new(max, max, min); [ObservableProperty] List meshes = new() { new(new Vertex3D[] { new() { Position = v1, TextureCoord = new Vector2(0, 1), Normal = new Vector3(0, 0, 1) }, new() { Position = v2, TextureCoord = new Vector2(1, 1), Normal = new Vector3(0, 0, 1) }, new() { Position = v3, TextureCoord = new Vector2(1, 0), Normal = new Vector3(0, 0, 1) }, new() { Position = v4, TextureCoord = new Vector2(0, 0), Normal = new Vector3(0, 0, 1) } }, new uint[] { 0, 1, 2, 2, 3, 0 }) { MaterialKey = "Front", Name = "Front", }, new(new Vertex3D[] { new() { Position = v8, TextureCoord = new Vector2(0, 0), Normal = new Vector3(0, 0, -1) }, new() { Position = v7, TextureCoord = new Vector2(0, 1), Normal = new Vector3(0, 0, -1) }, new() { Position = v6, TextureCoord = new Vector2(1, 1), Normal = new Vector3(0, 0, -1) }, new() { Position = v5, TextureCoord = new Vector2(1, 0), Normal = new Vector3(0, 0, -1) } }, new uint[] { 0, 1, 2, 2, 3, 0 }) { MaterialKey = "Back", Name = "Back" }, new(new Vertex3D[] { new() { Position = v1, TextureCoord = new Vector2(1, 1), Normal = new Vector3(-1, 0, 0) }, new() { Position = v4, TextureCoord = new Vector2(1, 0), Normal = new Vector3(-1, 0, 0) }, new() { Position = v5, TextureCoord = new Vector2(0, 0), Normal = new Vector3(-1, 0, 0) }, new() { Position = v6, TextureCoord = new Vector2(0, 1), Normal = new Vector3(-1, 0, 0) } }, new uint[] { 0, 1, 2, 2, 3, 0 }) { MaterialKey = "Left", Name = "Left" }, new(new Vertex3D[] { new() { Position = v2, TextureCoord = new Vector2(0, 1), Normal = new Vector3(1, 0, 0) }, new() { Position = v7, TextureCoord = new Vector2(1, 1), Normal = new Vector3(1, 0, 0) }, new() { Position = v8, TextureCoord = new Vector2(1, 0), Normal = new Vector3(1, 0, 0) }, new() { Position = v3, TextureCoord = new Vector2(0, 0), Normal = new Vector3(1, 0, 0) } }, new uint[] { 0, 1, 2, 2, 3, 0 }) { MaterialKey = "Right", Name = "Right" }, new(new Vertex3D[] { new() { Position = v8, TextureCoord = new Vector2(1, 0), Normal = new Vector3(0, 1, 0)}, new() { Position = v5, TextureCoord = new Vector2(0, 0), Normal = new Vector3(0, 1, 0)}, new() { Position = v4, TextureCoord = new Vector2(0, 1), Normal = new Vector3(0, 1, 0)}, new() { Position = v3, TextureCoord = new Vector2(1, 1), Normal = new Vector3(0, 1, 0)} }, new uint[] { 0, 1, 2, 2, 3, 0 }) { MaterialKey = "Top", Name = "Top" }, new(new Vertex3D[] { new() { Position = v2, TextureCoord = new Vector2(1, 0), Normal = new Vector3(0, -1, 0) }, new() { Position = v1, TextureCoord = new Vector2(0, 0), Normal = new Vector3(0, -1, 0) }, new() { Position = v6, TextureCoord = new Vector2(0, 1), Normal = new Vector3(0, -1, 0) }, new() { Position = v7, TextureCoord = new Vector2(1, 1), Normal = new Vector3(0, -1, 0) } }, new uint[] { 0, 1, 2, 2, 3, 0 }) { MaterialKey = "Bottom", Name = "Bottom" } }; [ObservableProperty] List cameras = new() { new CameraItem(new PerspectiveCamera()), new(new IsometricCamera()) }; [ObservableProperty] CameraItem selectedCamera; [ObservableProperty] List materials = new() { new SimplePbrMaterial(Colors.Red, "Front"), new(Colors.Lime, "Back"), new(Colors.Blue, "Left"), new(Colors.Yellow, "Right"), new(Colors.Magenta, "Top"), new(Colors.Cyan, "Bottom"), }; public Graphics3DControlCameraViewModel() { SelectedCamera = Cameras[0]; } } public class CameraItem { public Camera Camera { get; } public bool IsPerspective => Camera is PerspectiveCamera; public float FieldOfView { get => Camera is PerspectiveCamera camera ? camera.FieldOfView : default; set { if (Camera is PerspectiveCamera camera) camera.FieldOfView = value; } } public string Name => Camera is PerspectiveCamera ? "Perspective Camera" : "Isometric Camera"; public CameraItem(Camera camera) { Camera = camera; } } ================================================ FILE: DemoCenter/DemoCenter/ViewModels/Graphics3DControl/Graphics3DControlHighlightingViewModel.cs ================================================ #nullable enable using System.Collections.ObjectModel; using System.ComponentModel; using System.Numerics; using CommunityToolkit.Mvvm.ComponentModel; using Eremex.AvaloniaUI.Controls3D; namespace DemoCenter.ViewModels; public partial class Graphics3DControlHighlightingViewModel : Graphics3DControlViewModel { [ObservableProperty] ObservableCollection models = new(); [ObservableProperty] SelectableElement? highlightedElement; [ObservableProperty] SelectableElement? selectedElement; public Graphics3DControlHighlightingViewModel() { const float offset = 3; AddCube(new Vector3(offset, 0, -offset)); AddPyramid(new Vector3(-offset, 0, offset)); var model = Model3DLoader.LoadModel("Teapot Model", "DemoCenter.Resources.Graphics3D.Models.Teapot.obj"); model.Meshes.Single().Hint = "Teapot Mesh"; models.Add(model); } void AddCube(Vector3 offset) { const float size = 1; const float max = size; const float min = -size; var v1 = new Vector3(min, min, max) + offset; var v2 = new Vector3(max, min, max) + offset; var v3 = new Vector3(max, max, max) + offset; var v4 = new Vector3(min, max, max) + offset; var v5 = new Vector3(min, max, min) + offset; var v6 = new Vector3(min, min, min) + offset; var v7 = new Vector3(max, min, min) + offset; var v8 = new Vector3(max, max, min) + offset; var geometry = new GeometryModel3D { Meshes = { new() { Vertices =new Vertex3D[] { new() { Position = v1, TextureCoord = new Vector2(0, 1), Normal = new Vector3(0, 0, 1) }, new() { Position = v2, TextureCoord = new Vector2(1, 1), Normal = new Vector3(0, 0, 1) }, new() { Position = v3, TextureCoord = new Vector2(1, 0), Normal = new Vector3(0, 0, 1) }, new() { Position = v4, TextureCoord = new Vector2(0, 0), Normal = new Vector3(0, 0, 1) } }, Indices =new uint[] { 0, 1, 2, 2, 3, 0 }, Hint = "Front" }, new() { Vertices = new Vertex3D[] { new() { Position = v8, TextureCoord = new Vector2(0, 0), Normal = new Vector3(0, 0, -1) }, new() { Position = v7, TextureCoord = new Vector2(0, 1), Normal = new Vector3(0, 0, -1) }, new() { Position = v6, TextureCoord = new Vector2(1, 1), Normal = new Vector3(0, 0, -1) }, new() { Position = v5, TextureCoord = new Vector2(1, 0), Normal = new Vector3(0, 0, -1) } }, Indices = new uint[] { 0, 1, 2, 2, 3, 0 }, Hint = "Back" }, new() { Vertices = new Vertex3D[] { new() { Position = v1, TextureCoord = new Vector2(1, 1), Normal = new Vector3(-1, 0, 0) }, new() { Position = v4, TextureCoord = new Vector2(1, 0), Normal = new Vector3(-1, 0, 0) }, new() { Position = v5, TextureCoord = new Vector2(0, 0), Normal = new Vector3(-1, 0, 0) }, new() { Position = v6, TextureCoord = new Vector2(0, 1), Normal = new Vector3(-1, 0, 0) } }, Indices = new uint[] { 0, 1, 2, 2, 3, 0 }, Hint = "Left" }, new() { Vertices = new Vertex3D[] { new() { Position = v2, TextureCoord = new Vector2(0, 1), Normal = new Vector3(1, 0, 0) }, new() { Position = v7, TextureCoord = new Vector2(1, 1), Normal = new Vector3(1, 0, 0) }, new() { Position = v8, TextureCoord = new Vector2(1, 0), Normal = new Vector3(1, 0, 0) }, new() { Position = v3, TextureCoord = new Vector2(0, 0), Normal = new Vector3(1, 0, 0) } }, Indices = new uint[] { 0, 1, 2, 2, 3, 0 }, Hint = "Right" }, new() { Vertices = new Vertex3D[] { new() { Position = v8, TextureCoord = new Vector2(1, 0), Normal = new Vector3(0, 1, 0) }, new() { Position = v5, TextureCoord = new Vector2(0, 0), Normal = new Vector3(0, 1, 0) }, new() { Position = v4, TextureCoord = new Vector2(0, 1), Normal = new Vector3(0, 1, 0) }, new() { Position = v3, TextureCoord = new Vector2(1, 1), Normal = new Vector3(0, 1, 0) } }, Indices = new uint[] { 0, 1, 2, 2, 3, 0 }, Hint = "Top" }, new() { Vertices = new Vertex3D[] { new() { Position = v2, TextureCoord = new Vector2(1, 0), Normal = new Vector3(0, -1, 0) }, new() { Position = v1, TextureCoord = new Vector2(0, 0), Normal = new Vector3(0, -1, 0) }, new() { Position = v6, TextureCoord = new Vector2(0, 1), Normal = new Vector3(0, -1, 0) }, new() { Position = v7, TextureCoord = new Vector2(1, 1), Normal = new Vector3(0, -1, 0) } }, Indices = new uint[] { 0, 1, 2, 2, 3, 0 }, Hint = "Bottom" } }, Hint = "Cube" }; Models.Add(geometry); } void AddPyramid(Vector3 offset) { var basis = new MeshGeometry3D { Vertices = new[] { new Vertex3D(new Vector3(-1, 0, -1) + offset, -Vector3.UnitY), new Vertex3D(new Vector3(-1, 0, 1) + offset, -Vector3.UnitY), new Vertex3D(new Vector3(1, 0, 1) + offset, -Vector3.UnitY), new Vertex3D(new Vector3(1, 0, -1) + offset, -Vector3.UnitY) }, Indices = new uint[] { 0, 1, 2, 0, 2, 3 }, Hint = "Basis" }; var triangle1 = CreateTriangle("Left", basis.Vertices[0].Position, basis.Vertices[1].Position); var triangle2 = CreateTriangle("Front", basis.Vertices[1].Position, basis.Vertices[2].Position); var triangle3 = CreateTriangle("Right", basis.Vertices[2].Position, basis.Vertices[3].Position); var triangle4 = CreateTriangle("Back", basis.Vertices[3].Position, basis.Vertices[0].Position); Models.Add(new GeometryModel3D { Hint = "Pyramid", Meshes = { basis, triangle1, triangle2, triangle3, triangle4 } }); MeshGeometry3D CreateTriangle(string name, Vector3 p1, Vector3 p2) { var p3 = new Vector3(0, 2, 0) + offset; var normal = Vector3.Cross(p2 - p1, p3 - p1); return new MeshGeometry3D { Vertices = new[] { new Vertex3D(p2, normal), new Vertex3D(p1, normal), new Vertex3D(p3, normal) }, Indices = new uint[] { 0, 1, 2 }, Hint = name }; } } } ================================================ FILE: DemoCenter/DemoCenter/ViewModels/Graphics3DControl/Graphics3DControlLightsViewModel.cs ================================================ using System.Collections.ObjectModel; using System.Numerics; using Avalonia.Media; using CommunityToolkit.Mvvm.ComponentModel; using Eremex.AvaloniaUI.Controls.Common; using Eremex.AvaloniaUI.Controls3D; namespace DemoCenter.ViewModels; public partial class Graphics3DControlLightsViewModel : Graphics3DControlViewModel { const float LightDistance = 40; const float LightHeight = 0; const float PlaneSize = 80; const float PlaneZ = -20; static float Normalize(byte value) => (float)value / byte.MaxValue; static Vector3 ToVector3(Color color) => new(Normalize(color.R), Normalize(color.G), Normalize(color.B)); [ObservableProperty] ObservableCollection models = new(); [ObservableProperty] ObservableCollection materials = new(); [ObservableProperty] ObservableCollection lights = new(); public Graphics3DControlLightsViewModel() { AddLight(Colors.White, new Vector3(LightDistance, LightHeight, 0), "White"); AddLight(Colors.Red, new Vector3(-LightDistance, LightHeight, 0), "Red"); AddLight(Colors.Lime, new Vector3(0, LightHeight, -LightDistance), "Green"); AddLight(Colors.Blue, new Vector3(0, LightHeight, LightDistance), "Blue"); AddSphere(15); AddPlane(); } void AddSphere(float scale) { var model = Model3DLoader.LoadModel(string.Empty, "DemoCenter.Resources.Graphics3D.Models.Sphere.obj"); model.Transform = Matrix4x4.CreateScale(scale); Models.Add(model); } void AddLight(Color color, Vector3 position, string materialKey) { var model = Model3DLoader.LoadModel(string.Empty, "DemoCenter.Resources.Graphics3D.Models.Sphere.obj"); model.Transform = CreateTransform(LightViewModel.DefaultRadius); model.Meshes.Single().MaterialKey = materialKey; model.Meshes.Single().Hint = materialKey; var lightMaterial = new SimplePbrMaterial { Key = materialKey, Albedo = LightViewModel.DefaultColorIntensity * ToVector3(color), AmbientOcclusion = 0, Roughness = 0, Metallic = 0, Emission = LightViewModel.DefaultColorIntensity * ToVector3(color) }; Materials.Add(lightMaterial); Models.Add(model); var light = new LightViewModel(position, color, materialKey); light.PropertyChanged += (s, e) => { if (e.PropertyName == nameof(LightViewModel.Radius)) model.Transform = CreateTransform(((LightViewModel)s)!.Radius); else if (e.PropertyName == nameof(LightViewModel.ColorIntensity)) { var colorVector = ToVector3(light.Color) * light.ColorIntensity; lightMaterial.Albedo = colorVector; lightMaterial.Emission = colorVector; } }; Lights.Add(light); Matrix4x4 CreateTransform(float radius) => Matrix4x4.CreateScale(radius / model.BoundingBox!.Value.Size.X) * Matrix4x4.CreateTranslation(position); } void AddPlane() { const string materialKey = "Plane"; Materials.Add(new SimplePbrMaterial { Key = materialKey, Albedo = Vector3.One, AmbientOcclusion = 0 }); var mesh = new MeshGeometry3D(); mesh.Vertices = new[] { new Vertex3D(new Vector3(-PlaneSize, PlaneZ, -PlaneSize), Vector3.UnitY), new Vertex3D(new Vector3(-PlaneSize, PlaneZ, PlaneSize), Vector3.UnitY), new Vertex3D(new Vector3(PlaneSize, PlaneZ, PlaneSize), Vector3.UnitY), new Vertex3D(new Vector3(PlaneSize, PlaneZ, -PlaneSize), Vector3.UnitY), }; mesh.Indices = new uint[] { 0, 1, 2, 0, 2, 3 }; mesh.MaterialKey = materialKey; Models.Add(new GeometryModel3D { Meshes = { mesh } }); } } public partial class LightViewModel : ViewModelBase { public const float DefaultRadius = 10; public const float DefaultColorIntensity = 1; [ObservableProperty] Vector3 position; [ObservableProperty] Color color; [ObservableProperty] float radius = DefaultRadius; [ObservableProperty] float colorIntensity = DefaultColorIntensity; public string Name { get; } public LightViewModel(Vector3 position, Color color, string name) { Position = position; Color = color; Name = name; } } ================================================ FILE: DemoCenter/DemoCenter/ViewModels/Graphics3DControl/Graphics3DControlLinesViewModel.cs ================================================ using System.Collections.ObjectModel; using System.ComponentModel; using System.Reflection; using Assimp; using CommunityToolkit.Mvvm.ComponentModel; using Eremex.AvaloniaUI.Controls3D; namespace DemoCenter.ViewModels; public partial class Graphics3DControlLinesViewModel : Graphics3DControlViewModel { static GeometryModel3D LoadModel(string modelName, string resourceName, string materialKey = null) { var assembly = Assembly.GetAssembly(typeof(Graphics3DControlViewModel)); var stream = assembly!.GetManifestResourceStream(resourceName); using var context = new AssimpContext(); var scene = context.ImportFileFromStream(stream); var model = new GeometryModel3D(); if (!string.IsNullOrEmpty(modelName)) model.Hint = modelName; foreach (var mesh in scene.Meshes) { var vertices = new Vertex3D[mesh.VertexCount]; for (int i = 0; i < mesh.VertexCount; ++i) vertices[i] = new Vertex3D { Normal = mesh.Normals[i], Position = mesh.Vertices[i] }; var indices = new List(); foreach (var face in mesh.Faces) { for (int i = 0; i < face.IndexCount - 1; ++i) { indices.Add((uint)face.Indices[i]); indices.Add((uint)face.Indices[i + 1]); } } model.Meshes.Add(new MeshGeometry3D { Vertices = vertices, Indices = indices.ToArray(), FillType = MeshFillType.Lines }); } return model; } [ObservableProperty] ObservableCollection models = new(); [ObservableProperty] float lineWidth = 1; public Graphics3DControlLinesViewModel() { var model = LoadModel("Teapot", "DemoCenter.Resources.Graphics3D.Models.Teapot_Quad.obj"); model.TranslateToZero(); models.Add(model); } protected override void OnPropertyChanged(PropertyChangedEventArgs e) { base.OnPropertyChanged(e); if (e.PropertyName == nameof(LineWidth)) { foreach (var mesh in Models.Single().Meshes) mesh.PrimitiveSize = LineWidth; } } } ================================================ FILE: DemoCenter/DemoCenter/ViewModels/Graphics3DControl/Graphics3DControlOverviewViewModel.cs ================================================ using System.Collections.ObjectModel; using System.ComponentModel; using System.Text; using CommunityToolkit.Mvvm.ComponentModel; using Eremex.AvaloniaUI.Controls3D; using Microsoft.Extensions.Logging; namespace DemoCenter.ViewModels; public partial class Graphics3DControlOverviewViewModel : Graphics3DControlViewModel { [ObservableProperty] ObservableCollection models = new(); [ObservableProperty] CustomLogger logger; public Graphics3DControlOverviewViewModel() { var model = Model3DLoader.LoadModel("Teapot", "DemoCenter.Resources.Graphics3D.Models.Teapot.obj"); model.TranslateToZero(); models.Add(model); Logger = new CustomLogger(); } } public class CustomLogger : ILogger, INotifyPropertyChanged { readonly StringBuilder sb = new(); public string Text => sb.ToString(); public event PropertyChangedEventHandler PropertyChanged; public IDisposable BeginScope(TState state) => null; public bool IsEnabled(LogLevel logLevel) => true; public void Log(LogLevel logLevel, EventId eventId, TState state, Exception exception, Func formatter) { if (IsEnabled(logLevel)) { var message = formatter(state, exception); sb.AppendLine($"[{logLevel}] {message}"); PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(Text))); } } } ================================================ FILE: DemoCenter/DemoCenter/ViewModels/Graphics3DControl/Graphics3DControlPointsViewModel.cs ================================================ using System.Collections.ObjectModel; using System.ComponentModel; using System.Numerics; using System.Reflection; using Avalonia.Media.Imaging; using CommunityToolkit.Mvvm.ComponentModel; using Eremex.AvaloniaUI.Controls3D; namespace DemoCenter.ViewModels; public partial class Graphics3DControlPointsViewModel : Graphics3DControlViewModel { class Arm { float Center { get; } float HalfAngle { get; } public float Min { get; } public float Max { get; } public float Length { get; } public Arm(float min, float max, float length) { Min = min; Max = max; Length = length; Center = 0.5f * (Max + Min); HalfAngle = 0.5f * (Max - Min); } public Vector2 GetRadiusAndElevation(Random random, float minRadius, float maxElevation, float angle) { float factorR = 1f - MathF.Abs((Center - angle) / HalfAngle); float radius = random.NextSingle() * ((1f - factorR * factorR) * Length + minRadius); float factorE = radius / (minRadius + Length); float elevation = (random.NextSingle() - 0.5f) * (1f - factorE * factorE * factorE) * maxElevation * 2f; return new Vector2(radius, elevation); } } const int StarsCount = 5_000_000; const float LargeArmRadius = 0.7f; const float SmallArmRadius = 0.5f; const float CenterRadius = 0.2f; const float MaxElevation = 0.1f; const float NoiseXY = MaxElevation; const float NoiseZ = MaxElevation * 0.5f; const float MaxRadius = CenterRadius + LargeArmRadius; [ObservableProperty] ObservableCollection meshes = new(); [ObservableProperty] float pointSize; [ObservableProperty] Bitmap emissionImage; public Graphics3DControlPointsViewModel() { var assembly = Assembly.GetAssembly(typeof(Graphics3DControlViewModel)); var stream = assembly!.GetManifestResourceStream("DemoCenter.Resources.Graphics3D.Textures.Galaxy.png"); EmissionImage = new Bitmap(stream!); var vertices = new Vertex3D[StarsCount]; var arms = new Dictionary(); arms.Add(0, new Arm(0, 0.5f * MathF.PI, LargeArmRadius)); arms.Add(1, arms[0]); arms.Add(2, new Arm(0.5f * MathF.PI, 0.75f * MathF.PI, SmallArmRadius)); arms.Add(3, new Arm(0.75f * MathF.PI, MathF.PI, SmallArmRadius)); arms.Add(4, new Arm(MathF.PI, 1.5f * MathF.PI, LargeArmRadius)); arms.Add(5, arms[4]); arms.Add(6, new Arm(1.5f * MathF.PI, 1.75f * MathF.PI, SmallArmRadius)); arms.Add(7, new Arm(1.75f * MathF.PI, 2f * MathF.PI, SmallArmRadius)); var random = new Random(42); for (int i = 0; i < StarsCount; i++) { float angle = random.NextSingle() * MathF.PI * 2f; int octave = (int)MathF.Min(arms.Count - 1, MathF.Floor(angle / (MathF.PI * 0.25f))); var vec = arms[octave].GetRadiusAndElevation(random, CenterRadius, MaxElevation, angle); float radius = vec.X; angle += vec.X / MaxRadius * MathF.PI * 1.5f; float x = MathF.Cos(angle) * radius + random.NextSingle() * NoiseXY; float z = MathF.Sin(angle) * radius + random.NextSingle() * NoiseXY; float y = random.NextSingle() * vec.Y + random.NextSingle() * NoiseZ; float textureU = MathF.Max(0f, MathF.Min(1f, radius / MaxRadius + (random.NextSingle() - 0.5f) * 0.25f)); vertices[i] = new Vertex3D { Position = new Vector3(x, y, z), TextureCoord = new Vector2(textureU, 0) }; } Meshes.Add(new MeshGeometry3D { FillType = MeshFillType.Points, Vertices = vertices, MaterialKey = "material" }); } protected override void OnPropertyChanged(PropertyChangedEventArgs e) { base.OnPropertyChanged(e); if (e.PropertyName == nameof(PointSize)) { foreach (var mesh in Meshes) mesh.PrimitiveSize = PointSize; } } } ================================================ FILE: DemoCenter/DemoCenter/ViewModels/Graphics3DControl/Graphics3DControlRobotArmViewModel.cs ================================================ using CommunityToolkit.Mvvm.ComponentModel; using Eremex.AvaloniaUI.Controls3D; using System.Collections.ObjectModel; using System.ComponentModel; using System.Reflection; using Assimp; using Num = System.Numerics; namespace DemoCenter.ViewModels; public partial class Graphics3DControlRobotArmViewModel : Graphics3DControlViewModel { List offsets = [ new(0, 0, 0), // Base new(0, 0, 5.15f), // Arm 1 new(0, 0, 4.8f), // Arm 2 new(0, 0, 4.6f), // Wrist new(-1.3f, 0, 1.7f), // Claw 1 new(1.3f, 0, 1.7f) // Claw 2 ]; [ObservableProperty] float claws = 0; [ObservableProperty] float wrist = 0; [ObservableProperty] float arm2 = 0; [ObservableProperty] float arm1X = 0; [ObservableProperty] float arm1Y = 0; [ObservableProperty] float arm1Z = 0; [ObservableProperty] ObservableCollection models; public Graphics3DControlRobotArmViewModel() { models = LoadModels("DemoCenter.Resources.Graphics3D.Models.robot_arm_2.fbx"); ApplyTransformations(); } protected override void OnPropertyChanged(PropertyChangedEventArgs e) { if (e.PropertyName is nameof(Claws) or nameof(Wrist) or nameof(Arm2) or nameof(Arm1X) or nameof(Arm1Y) or nameof(Arm1Z)) ApplyTransformations(); base.OnPropertyChanged(e); } void ApplyTransformations() { var transform = Num.Matrix4x4.CreateTranslation(0, 0, -11); for (int i = 0; i < Models.Count; i++) { var localTransform = GetTransform(i); Models[i].Transform = localTransform * Num.Matrix4x4.CreateTranslation(offsets[i]) * transform; if (i < 4) transform = Models[i].Transform; } } void ProcessNode(Node node, Scene scene, ObservableCollection result) { if (node.HasMeshes) { foreach (var index in node.MeshIndices) result.Add(GetModel(scene, node, index)); } if (node.HasChildren) { foreach (var childNode in node.Children) ProcessNode(childNode, scene, result); } } Num.Matrix4x4 GetTransform(int index) => index switch { 1 => Num.Matrix4x4.CreateFromYawPitchRoll(Arm1Y, Arm1X, Arm1Z), // Arm 1 2 => Num.Matrix4x4.CreateRotationY(Arm2), // Arm 2: Y 3 => Num.Matrix4x4.CreateRotationZ(Wrist), // Wrist: Z 4 => Num.Matrix4x4.CreateRotationY(Claws), // Claw 1: +Y 5 => Num.Matrix4x4.CreateRotationY(-Claws), // Claw 2: -Y _ => Num.Matrix4x4.Identity }; ObservableCollection LoadModels(string path) { var result = new ObservableCollection(); var assembly = Assembly.GetAssembly(typeof(Graphics3DControlRobotArmViewModel)); var stream = assembly!.GetManifestResourceStream(path); using var context = new AssimpContext(); var scene = context.ImportFileFromStream(stream); ProcessNode(scene.RootNode, scene, result); return result; } GeometryModel3D GetModel(Scene scene, Node node, int index) { var model = new GeometryModel3D { Name = node.Name }; var mesh = scene.Meshes[index]; var vertices = new Vertex3D[mesh.Vertices.Count]; for (int i = 0; i < mesh.Vertices.Count; i++) { vertices[i] = new Vertex3D { Position = mesh.Vertices[i], Normal = mesh.Normals[i] }; } model.Meshes.Add(new MeshGeometry3D { Hint = node.Name, Vertices = vertices, Indices = scene.Meshes[index].GetUnsignedIndices().ToArray(), }); return model; } } ================================================ FILE: DemoCenter/DemoCenter/ViewModels/Graphics3DControl/Graphics3DControlSimpleMaterialsViewModel.cs ================================================ #nullable enable using System.Collections.ObjectModel; using CommunityToolkit.Mvvm.ComponentModel; using Eremex.AvaloniaUI.Controls3D; namespace DemoCenter.ViewModels; public partial class Graphics3DControlSimpleMaterialsViewModel : Graphics3DControlViewModel { [ObservableProperty] ObservableCollection models = new(); [ObservableProperty] Skybox? skybox = null; public Graphics3DControlSimpleMaterialsViewModel() { var model = Model3DLoader.LoadModel(string.Empty, "DemoCenter.Resources.Graphics3D.Models.Sphere.obj"); models.Add(model); } } ================================================ FILE: DemoCenter/DemoCenter/ViewModels/Graphics3DControl/Graphics3DControlSkyboxViewModel.cs ================================================ using System.Collections.ObjectModel; using System.IO.Compression; using System.Numerics; using System.Reflection; using Assimp; using Avalonia.Media.Imaging; using CommunityToolkit.Mvvm.ComponentModel; using Eremex.AvaloniaUI.Controls3D; namespace DemoCenter.ViewModels; public partial class Graphics3DControlSkyboxViewModel : Graphics3DControlViewModel { static Skybox LoadSkybox(Assembly assembly, string resourceName) { var stream = assembly!.GetManifestResourceStream(resourceName); using var archive = new ZipArchive(stream!, ZipArchiveMode.Read); var skybox = new Skybox(); foreach (var entry in archive.Entries) { if (!entry.Name.EndsWith(".jpg")) continue; using var entryStream = entry.Open(); using var memoryStream = new MemoryStream(); entryStream.CopyTo(memoryStream); memoryStream.Seek(0, SeekOrigin.Begin); var bitmap = new Bitmap(memoryStream); if (entry.Name.StartsWith("negx")) skybox.Left = bitmap; else if (entry.Name.StartsWith("negy")) skybox.Bottom = bitmap; else if (entry.Name.StartsWith("negz")) skybox.Rear = bitmap; else if (entry.Name.StartsWith("posx")) skybox.Right = bitmap; else if (entry.Name.StartsWith("posy")) skybox.Top = bitmap; else if (entry.Name.StartsWith("posz")) skybox.Front = bitmap; } return skybox; } [ObservableProperty] string materialKey; [ObservableProperty] uint[] indices; [ObservableProperty] Vertex3D[] vertices; [ObservableProperty] ObservableCollection materials = new(); [ObservableProperty] ObservableCollection skyboxes = new(); [ObservableProperty] Skybox selectedSkybox = new(); public Graphics3DControlSkyboxViewModel() { var assembly = Assembly.GetAssembly(typeof(Graphics3DControlViewModel)); var material = Graphics3DControlTexturedMaterialsViewModel.LoadMaterial(assembly, "DemoCenter.Resources.Graphics3D.Materials.AlienPanels.zip"); materialKey = material.Key; materials.Add(material); var stream = assembly!.GetManifestResourceStream("DemoCenter.Resources.Graphics3D.Models.Sphere.obj"); using var context = new AssimpContext(); var scene = context.ImportFileFromStream(stream); var mesh = scene.Meshes.Single(); vertices = new Vertex3D[mesh.VertexCount]; for (int i = 0; i < mesh.VertexCount; ++i) vertices[i] = new Vertex3D { Normal = mesh.Normals[i], Position = mesh.Vertices[i], TextureCoord = new Vector2(mesh.TextureCoordinateChannels[0][i].X, mesh.TextureCoordinateChannels[0][i].Y) }; indices = mesh.GetUnsignedIndices().ToArray(); var skyboxNames = assembly!.GetManifestResourceNames().Where(name => name.StartsWith("DemoCenter.Resources.Graphics3D.Skyboxes.")); foreach (var skyboxName in skyboxNames) skyboxes.Add(LoadSkybox(assembly, skyboxName)); selectedSkybox = Skyboxes.First(); } } ================================================ FILE: DemoCenter/DemoCenter/ViewModels/Graphics3DControl/Graphics3DControlStlViewModel.cs ================================================ using System.Collections.ObjectModel; using System.IO.Compression; using System.Numerics; using System.Reflection; using Assimp; using Avalonia; using Avalonia.Media; using Avalonia.Media.Imaging; using CommunityToolkit.Mvvm.ComponentModel; using Eremex.AvaloniaUI.Controls3D; using Material = Eremex.AvaloniaUI.Controls3D.Material; using Vector = Avalonia.Vector; namespace DemoCenter.ViewModels; public partial class Graphics3DControlStlViewModel : Graphics3DControlViewModel { static GeometryModel3D LoadModel(string modelName, string resourceName) { var assembly = Assembly.GetAssembly(typeof(Graphics3DControlViewModel)); var stream = assembly!.GetManifestResourceStream(resourceName); using var archive = new ZipArchive(stream!, ZipArchiveMode.Read); using var stlStream = archive.Entries.Single().Open(); using var context = new AssimpContext(); var scene = context.ImportFileFromStream(stlStream); var model = new GeometryModel3D { Name = modelName }; int geometryIndex = 0; foreach (var mesh in scene.Meshes) { var vertices = new Vertex3D[mesh.VertexCount]; for (int i = 0; i < mesh.VertexCount; ++i) vertices[i] = new Vertex3D { Normal = mesh.Normals[i], Position = mesh.Vertices[i] }; model.Meshes.Add(new MeshGeometry3D { Hint = $"Solid {geometryIndex++}", MaterialKey = mesh.Name, Vertices = vertices, Indices = mesh.GetUnsignedIndices().ToArray() }); } return model; } [ObservableProperty] ObservableCollection models = new(); [ObservableProperty] ObservableCollection materials = new(); [ObservableProperty] Skybox skybox; public Graphics3DControlStlViewModel() { skybox = CreateSkybox(); var model = LoadModel("ddBox", "DemoCenter.Resources.Graphics3D.Models.ddBox-C1.zip"); models.Add(model); materials.Add(new SimplePbrMaterial { Key = "0", Emission = new Vector3(1f, 1f, 1f), AmbientOcclusion = 1f, Roughness = 0f, Metallic = 0f, Albedo = new Vector3(1f, 1f, 1f) }); materials.Add(new SimplePbrMaterial { Key = "1", Emission = new Vector3(0f, 0f, 0f), AmbientOcclusion = 1f, Roughness = 0.5f, Metallic = 0.5f, Albedo = new Vector3(0f, 0f, 0f) }); materials.Add(new SimplePbrMaterial { Key = "2", Emission = new Vector3(1f, 1f, 1f), AmbientOcclusion = 1f, Roughness = 0.5f, Metallic = 0.5f, Albedo = new Vector3(1f, 1f, 1f) }); materials.Add(new SimplePbrMaterial { Key = "3", Emission = new Vector3(0.06781025f, 0.009843134f, 0.0028190238f), AmbientOcclusion = 1f, Roughness = 0f, Metallic = 1f, Albedo = new Vector3(0.6117647f, 0.33333334f, 0.15294118f) }); materials.Add(new SimplePbrMaterial { Key = "4", Emission = new Vector3(0.0023305754f, 0.0023305754f, 0.0023305754f), AmbientOcclusion = 0.4f, Roughness = 0.19607843f, Metallic = 0.8f, Albedo = new Vector3(0.1254902f, 0.1254902f, 0.1254902f) }); materials.Add(new SimplePbrMaterial { Key = "5", Emission = new Vector3(0.09655207f, 0.12331263f, 0.19574657f), AmbientOcclusion = 0.4f, Roughness = 0.19607843f, Metallic = 0.8f, Albedo = new Vector3(0.6627451f, 0.69803923f, 0.7647059f) }); materials.Add(new SimplePbrMaterial { Key = "6", Emission = new Vector3(0.33176473f, 0.22588237f, 0.09176471f), AmbientOcclusion = 0.30200002f, Roughness = 0f, Metallic = 0.051000003f, Albedo = new Vector3(0.5529412f, 0.3764706f, 0.15294118f) }); materials.Add(new SimplePbrMaterial { Key = "7", Emission = new Vector3(0.18041758f, 0.18041758f, 0.18041758f), AmbientOcclusion = 0.4f, Roughness = 0.19607843f, Metallic = 0.8f, Albedo = new Vector3(0.7529412f, 0.7529412f, 0.7529412f) }); materials.Add(new SimplePbrMaterial { Key = "8", Emission = new Vector3(0.28941178f, 0.28941178f, 0.28941178f), AmbientOcclusion = 0.30200002f, Roughness = 0f, Metallic = 0.051000003f, Albedo = new Vector3(0.48235294f, 0.48235294f, 0.48235294f) }); materials.Add(new SimplePbrMaterial { Key = "9", Emission = new Vector3(0.03764706f, 0.01882353f, 0.01882353f), AmbientOcclusion = 0.30200002f, Roughness = 0f, Metallic = 0.051000003f, Albedo = new Vector3(0.0627451f, 0.03137255f, 0.03137255f) }); materials.Add(new SimplePbrMaterial { Key = "10", Emission = new Vector3(0.22588237f, 0.22588237f, 0.22588237f), AmbientOcclusion = 0.30200002f, Roughness = 0f, Metallic = 0.051000003f, Albedo = new Vector3(0.3764706f, 0.3764706f, 0.3764706f) }); materials.Add(new SimplePbrMaterial { Key = "11", Emission = new Vector3(0.0018750911f, 0.0018750911f, 0.0018750911f), AmbientOcclusion = 0.4f, Roughness = 0.19607843f, Metallic = 0.8f, Albedo = new Vector3(0.09411765f, 0.09411765f, 0.09411765f) }); materials.Add(new SimplePbrMaterial { Key = "12", Emission = new Vector3(0.08202213f, 0.09655207f, 0.107642084f), AmbientOcclusion = 0.4f, Roughness = 0.19607843f, Metallic = 0.8f, Albedo = new Vector3(0.6392157f, 0.6627451f, 0.6784314f) }); materials.Add(new SimplePbrMaterial { Key = "13", Emission = new Vector3(0.78298604f, 0.43056834f, 0.0625f), AmbientOcclusion = 0.4f, Roughness = 0.19607843f, Metallic = 0.8f, Albedo = new Vector3(0.9647059f, 0.8784314f, 0.6f) }); materials.Add(new SimplePbrMaterial { Key = "14", Emission = new Vector3(0.26733335f, 0.26733335f, 0.26733335f), AmbientOcclusion = 0.30200002f, Roughness = 0f, Metallic = 0.051000003f, Albedo = new Vector3(0.73333334f, 0.73333334f, 0.73333334f) }); materials.Add(new SimplePbrMaterial { Key = "15", Emission = new Vector3(0.78298604f, 0.43056834f, 0.0625f), AmbientOcclusion = 0.4f, Roughness = 0.19607843f, Metallic = 0.8f, Albedo = new Vector3(0.9647059f, 0.8784314f, 0.6f) }); materials.Add(new SimplePbrMaterial { Key = "16", Emission = new Vector3(0.022247758f, 0.071598776f, 0.024138017f), AmbientOcclusion = 0.4f, Roughness = 0.19607843f, Metallic = 0.8f, Albedo = new Vector3(0.4509804f, 0.61960787f, 0.4627451f) }); materials.Add(new SimplePbrMaterial { Key = "17", Emission = new Vector3(0.06599185f, 0.337129f, 0.08660467f), AmbientOcclusion = 0.4f, Roughness = 0.19607843f, Metallic = 0.8f, Albedo = new Vector3(0.60784316f, 0.84313726f, 0.64705884f) }); materials.Add(new SimplePbrMaterial { Key = "18", Emission = new Vector3(0.64731914f, 0.23042239f, 0.032550503f), AmbientOcclusion = 0.4f, Roughness = 0.19607843f, Metallic = 0.8f, Albedo = new Vector3(0.9372549f, 0.7882353f, 0.5058824f) }); materials.Add(new SimplePbrMaterial { Key = "19", Emission = new Vector3(0.071598776f, 0.0071034976f, 0.0015501967f), AmbientOcclusion = 0.4f, Roughness = 0.19607843f, Metallic = 0.8f, Albedo = new Vector3(0.61960787f, 0.28627452f, 0.06666667f) }); materials.Add(new SimplePbrMaterial { Key = "20", Emission = new Vector3(0f, 0f, 0f), AmbientOcclusion = 0.30200002f, Roughness = 0f, Metallic = 0.051000003f, Albedo = new Vector3(0f, 0f, 0f) }); materials.Add(new SimplePbrMaterial { Key = "21", Emission = new Vector3(0.15058824f, 0.15058824f, 0.15058824f), AmbientOcclusion = 0.30200002f, Roughness = 0f, Metallic = 0.051000003f, Albedo = new Vector3(0.2509804f, 0.2509804f, 0.2509804f) }); materials.Add(new SimplePbrMaterial { Key = "22", Emission = new Vector3(0.0f, 0.0f, 0.0f), AmbientOcclusion = 1f, Roughness = 0f, Metallic = 0.051000003f, Albedo = new Vector3(0.80f, 0.37f, 0.40f) }); materials.Add(new SimplePbrMaterial { Key = "23", Emission = new Vector3(0.18898825f, 0.18898825f, 0.18898825f), AmbientOcclusion = 0.30200002f, Roughness = 0f, Metallic = 0.051000003f, Albedo = new Vector3(0.3764706f, 0.3764706f, 0.3764706f) }); materials.Add(new SimplePbrMaterial { Key = "24", Emission = new Vector3(0.0925255f, 0.25395298f, 0.30513728f), AmbientOcclusion = 0.4f, Roughness = 0f, Metallic = 0.051000003f, Albedo = new Vector3(0.53f, 0.76f, 0.82f) }); materials.Add(new SimplePbrMaterial { Key = "25", Emission = new Vector3(0.026910512f, 0.026910512f, 0.026910512f), AmbientOcclusion = 0.4f, Roughness = 0.19607843f, Metallic = 0.8f, Albedo = new Vector3(0.47843137f, 0.47843137f, 0.47843137f) }); materials.Add(new SimplePbrMaterial { Key = "26", Emission = new Vector3(0.0101143615f, 0.0101143615f, 0.011276099f), AmbientOcclusion = 0.4f, Roughness = 0.19607843f, Metallic = 0.8f, Albedo = new Vector3(0.3372549f, 0.3372549f, 0.3529412f) }); materials.Add(new SimplePbrMaterial { Key = "27", Emission = new Vector3(0.17557949f, 0.17557949f, 0.17557949f), AmbientOcclusion = 0.4f, Roughness = 0.19607843f, Metallic = 0.8f, Albedo = new Vector3(0.7490196f, 0.7490196f, 0.7490196f) }); materials.Add(new SimplePbrMaterial { Key = "28", Emission = new Vector3(1f, 0.25688884f, 0.030001458f), AmbientOcclusion = 0.4f, Roughness = 0.19607843f, Metallic = 0.8f, Albedo = new Vector3(1f, 0.8039216f, 0.49411765f) }); materials.Add(new SimplePbrMaterial { Key = "29", Emission = new Vector3(0.001003472f, 0.004988914f, 0.29428673f), AmbientOcclusion = 0.4f, Roughness = 0.19607843f, Metallic = 0.8f, Albedo = new Vector3(0.003921569f, 0.23529412f, 0.8235294f) }); materials.Add(new SimplePbrMaterial { Key = "30", Emission = new Vector3(1f, 1f, 1f), AmbientOcclusion = 0.4f, Roughness = 0.19607843f, Metallic = 0.8f, Albedo = new Vector3(1f, 1f, 1f) }); materials.Add(new SimplePbrMaterial { Key = "31", Emission = new Vector3(0.11365596f, 0.06599185f, 0.038316723f), AmbientOcclusion = 0.4f, Roughness = 0.19607843f, Metallic = 0.8f, Albedo = new Vector3(0.6862745f, 0.60784316f, 0.5294118f) }); materials.Add(new SimplePbrMaterial { Key = "32", Emission = new Vector3(0.0025982664f, 0.025486596f, 0.0036995586f), AmbientOcclusion = 0.4f, Roughness = 0.19607843f, Metallic = 0.8f, Albedo = new Vector3(0.14117648f, 0.47058824f, 0.19215687f) }); materials.Add(new SimplePbrMaterial { Key = "33", Emission = new Vector3(0.24329598f, 0.29428673f, 0.64731914f), AmbientOcclusion = 0.4f, Roughness = 0.19607843f, Metallic = 0.8f, Albedo = new Vector3(0.79607844f, 0.8235294f, 0.9372549f) }); materials.Add(new SimplePbrMaterial { Key = "34", Emission = new Vector3(0.3758518f, 0.35596412f, 0.21823005f), AmbientOcclusion = 0.4f, Roughness = 0.19607843f, Metallic = 0.8f, Albedo = new Vector3(0.85882354f, 0.8509804f, 0.78039217f) }); materials.Add(new SimplePbrMaterial { Key = "35", Emission = new Vector3(0.08899106f, 0.057605617f, 0.043894872f), AmbientOcclusion = 0.4f, Roughness = 0.19607843f, Metallic = 0.8f, Albedo = new Vector3(0.6509804f, 0.5882353f, 0.54901963f) }); materials.Add(new SimplePbrMaterial { Key = "36", Emission = new Vector3(0.0015501967f, 0.0014681702f, 0.0012472285f), AmbientOcclusion = 0.4f, Roughness = 0.19607843f, Metallic = 0.8f, Albedo = new Vector3(0.06666667f, 0.05882353f, 0.03529412f) }); materials.Add(new SimplePbrMaterial { Key = "37", Emission = new Vector3(0.0055619394f, 0.0055619394f, 0.0055619394f), AmbientOcclusion = 0.4f, Roughness = 0.19607843f, Metallic = 0.8f, Albedo = new Vector3(0.2509804f, 0.2509804f, 0.2509804f) }); materials.Add(new SimplePbrMaterial { Key = "38", Emission = new Vector3(0.35596412f, 0.35596412f, 0.35596412f), AmbientOcclusion = 0.4f, Roughness = 0.19607843f, Metallic = 0.8f, Albedo = new Vector3(0.8509804f, 0.8509804f, 0.8509804f) }); materials.Add(new SimplePbrMaterial { Key = "39", Emission = new Vector3(0.0077070394f, 0.0077070394f, 0.0077070394f), AmbientOcclusion = 0.4f, Roughness = 0.19607843f, Metallic = 0.8f, Albedo = new Vector3(0.29803923f, 0.29803923f, 0.29803923f) }); materials.Add(new SimplePbrMaterial { Key = "40", Emission = new Vector3(0.25f, 0.25688884f, 0.25f), AmbientOcclusion = 0.4f, Roughness = 0.19607843f, Metallic = 0.8f, Albedo = new Vector3(0.8f, 0.8039216f, 0.8f) }); materials.Add(new SimplePbrMaterial { Key = "41", Emission = new Vector3(0f, 0f, 0f), AmbientOcclusion = 0.4f, Roughness = 0.19607843f, Metallic = 0.8f, Albedo = new Vector3(0f, 0f, 0f) }); materials.Add(new SimplePbrMaterial { Key = "42", Emission = new Vector3(0.09655207f, 0.12331263f, 0.19049743f), AmbientOcclusion = 0.4f, Roughness = 0.19607843f, Metallic = 0.8f, Albedo = new Vector3(0.6627451f, 0.69803923f, 0.7607843f) }); materials.Add(new SimplePbrMaterial { Key = "43", Emission = new Vector3(0.46715084f, 0.52080804f, 0.5966273f), AmbientOcclusion = 0.4f, Roughness = 0.19607843f, Metallic = 0.8f, Albedo = new Vector3(0.8901961f, 0.90588236f, 0.9254902f) }); materials.Add(new SimplePbrMaterial { Key = "44", Emission = new Vector3(0.23677175f, 0.27871513f, 0.61306757f), AmbientOcclusion = 0.4f, Roughness = 0.19607843f, Metallic = 0.8f, Albedo = new Vector3(0.7921569f, 0.8156863f, 0.92941177f) }); materials.Add(new SimplePbrMaterial { Key = "45", Emission = new Vector3(0.031677626f, 0.031677626f, 0.031677626f), AmbientOcclusion = 0.4f, Roughness = 0.19607843f, Metallic = 0.8f, Albedo = new Vector3(0.5019608f, 0.5019608f, 0.5019608f) }); materials.Add(new SimplePbrMaterial { Key = "46", Emission = new Vector3(0.7619897f, 0.7619897f, 0.7619897f), AmbientOcclusion = 1f, Roughness = 0f, Metallic = 0f, Albedo = new Vector3(0.9607843f, 0.9607843f, 0.9607843f) }); materials.Add(new SimplePbrMaterial { Key = "47", Emission = new Vector3(0.11678775f, 0.06599185f, 0.038316723f), AmbientOcclusion = 0.4f, Roughness = 0.19607843f, Metallic = 0.8f, Albedo = new Vector3(0.6901961f, 0.60784316f, 0.5294118f) }); materials.Add(new SimplePbrMaterial { Key = "48", Emission = new Vector3(0.18041758f, 0.06599185f, 0.00459823f), AmbientOcclusion = 0.4f, Roughness = 0.19607843f, Metallic = 0.8f, Albedo = new Vector3(0.7529412f, 0.60784316f, 0.22352941f) }); materials.Add(new SimplePbrMaterial { Key = "49", Emission = new Vector3(0.0012815954f, 0.004988914f, 0.0012815954f), AmbientOcclusion = 1f, Roughness = 0f, Metallic = 0f, Albedo = new Vector3(0.039215688f, 0.23529412f, 0.039215688f) }); } Skybox CreateSkybox() { var image = CreateImage(); return new Skybox { IsVisible = false, Left = image, Right = image, Top = image, Bottom = image, Front = image, Rear = image }; } Bitmap CreateImage() { const int size = 1000; var bitmap = new RenderTargetBitmap(new PixelSize(size, size), new Vector(96, 96)); using var context = bitmap.CreateDrawingContext(); var brush = new RadialGradientBrush { GradientStops = { new GradientStop(Colors.White, 0.0f), new GradientStop(Colors.Gray, 0.8f), } }; context.FillRectangle(brush, new Rect(0, 0, size, size)); return bitmap; } } ================================================ FILE: DemoCenter/DemoCenter/ViewModels/Graphics3DControl/Graphics3DControlTexturedMaterialsViewModel.cs ================================================ using System.Collections.ObjectModel; using System.IO.Compression; using System.Numerics; using System.Reflection; using Assimp; using Avalonia.Media.Imaging; using CommunityToolkit.Mvvm.ComponentModel; using Eremex.AvaloniaUI.Controls3D; namespace DemoCenter.ViewModels; public partial class Graphics3DControlTexturedMaterialsViewModel : Graphics3DControlViewModel { public static TexturedPbrMaterial LoadMaterial(Assembly assembly, string resourceName) { var stream = assembly!.GetManifestResourceStream(resourceName); using var archive = new ZipArchive(stream!, ZipArchiveMode.Read); var material = new TexturedPbrMaterial { Key = resourceName.Split('.')[^2] }; foreach (var entry in archive.Entries) { using var entryStream = entry.Open(); using var memoryStream = new MemoryStream(); entryStream.CopyTo(memoryStream); memoryStream.Seek(0, SeekOrigin.Begin); var bitmap = new Bitmap(memoryStream); if (entry.Name.StartsWith("Albedo")) material.Albedo = bitmap; else if (entry.Name.StartsWith("AO")) material.AmbientOcclusion = bitmap; else if (entry.Name.StartsWith("Metallic")) material.Metallic = bitmap; else if (entry.Name.StartsWith("Roughness")) material.Roughness = bitmap; else if (entry.Name.StartsWith("Normal")) material.Normal = bitmap; else if (entry.Name.StartsWith("Emissive")) material.Emission = bitmap; } return material; } [ObservableProperty] ObservableCollection materials = new(); [ObservableProperty] TexturedPbrMaterial selectedMaterial; [ObservableProperty] Vertex3D[] vertices; [ObservableProperty] uint[] indices; public Graphics3DControlTexturedMaterialsViewModel() { var assembly = Assembly.GetAssembly(typeof(Graphics3DControlViewModel)); var textureNames = assembly!.GetManifestResourceNames().Where(name => name.StartsWith("DemoCenter.Resources.Graphics3D.Materials.")); foreach (var textureName in textureNames) materials.Add(LoadMaterial(assembly, textureName)); selectedMaterial = Materials.First(); var stream = assembly!.GetManifestResourceStream("DemoCenter.Resources.Graphics3D.Models.Sphere.obj"); using var context = new AssimpContext(); var scene = context.ImportFileFromStream(stream); var mesh = scene.Meshes.Single(); vertices = new Vertex3D[mesh.VertexCount]; for (int i = 0; i < mesh.VertexCount; ++i) vertices[i] = new Vertex3D { Normal = mesh.Normals[i], Position = mesh.Vertices[i], TextureCoord = new Vector2(mesh.TextureCoordinateChannels[0][i].X, mesh.TextureCoordinateChannels[0][i].Y) }; indices = mesh.GetUnsignedIndices().ToArray(); } } ================================================ FILE: DemoCenter/DemoCenter/ViewModels/Graphics3DControl/Graphics3DControlTransformationViewModel.cs ================================================ using System.Collections.ObjectModel; using System.Numerics; using Avalonia.Media; using Avalonia.Threading; using CommunityToolkit.Mvvm.ComponentModel; using Eremex.AvaloniaUI.Controls3D; namespace DemoCenter.ViewModels; public partial class Graphics3DControlTransformationViewModel : Graphics3DControlViewModel { readonly DispatcherTimer timer = new(DispatcherPriority.Background); readonly Vector3[] offsets = new Vector3[] { new(0, -1, 1), new(0, -1, -1.9f), new(0, 1.8f, 1.9f) }; readonly float[] rotationSpeed = new float[] { 4000, -2000, -2000 }; readonly DateTime start = DateTime.Now; [ObservableProperty] ObservableCollection materials = new(); [ObservableProperty] ObservableCollection models = new(); public Graphics3DControlTransformationViewModel() { Materials.Add(new SimplePbrMaterial(Colors.Red, "Gear1")); Materials.Add(new SimplePbrMaterial(Colors.Green, "Gear2")); Materials.Add(new SimplePbrMaterial(Colors.Blue, "Gear3")); Models.Add(Model3DLoader.LoadModel("Gear 1", "DemoCenter.Resources.Graphics3D.Models.Gear_1.obj", "Gear1")); Models.Add(Model3DLoader.LoadModel("Gear 2", "DemoCenter.Resources.Graphics3D.Models.Gear_2.obj", "Gear2")); Models.Add(Model3DLoader.LoadModel("Gear 3", "DemoCenter.Resources.Graphics3D.Models.Gear_3.obj", "Gear3")); UpdateTransformations(); timer.Tick += TimerOnTick; timer.Interval = TimeSpan.FromMilliseconds(5); } void TimerOnTick(object sender, EventArgs e) => UpdateTransformations(); void UpdateTransformations() { float milliseconds = (float)Math.Floor((DateTime.Now - start).TotalMilliseconds); for (int i = 0; i < 3; i++) { float factor = (milliseconds % rotationSpeed[i]) / rotationSpeed[i]; var transform = Matrix4x4.CreateFromYawPitchRoll(0, MathF.PI * 2 * factor, MathF.PI * 0.5f); transform.M41 = offsets[i].X; transform.M42 = offsets[i].Y; transform.M43 = offsets[i].Z; Models[i].Transform = transform; } } public void Start() => timer.Start(); public void Stop() => timer.Stop(); } ================================================ FILE: DemoCenter/DemoCenter/ViewModels/Graphics3DControl/Graphics3DControlViewModel.cs ================================================ namespace DemoCenter.ViewModels; public class Graphics3DControlViewModel : PageViewModelBase { } ================================================ FILE: DemoCenter/DemoCenter/ViewModels/Graphics3DControl/MeshViewModel.cs ================================================ using CommunityToolkit.Mvvm.ComponentModel; using Eremex.AvaloniaUI.Controls3D; namespace DemoCenter.ViewModels; public partial class MeshViewModel : ObservableObject { [ObservableProperty] string name; [ObservableProperty] string materialKey; [ObservableProperty] Vertex3D[] vertices; [ObservableProperty] uint[] indices; [ObservableProperty] MeshFillType type; [ObservableProperty] uint size; public MeshViewModel(Vertex3D[] vertices, uint[] indices) { this.vertices = vertices; this.indices = indices; } } ================================================ FILE: DemoCenter/DemoCenter/ViewModels/Graphics3DControl/Model3DLoader.cs ================================================ using System.Reflection; using Assimp; using Eremex.AvaloniaUI.Controls3D; namespace DemoCenter.ViewModels; public static class Model3DLoader { public static GeometryModel3D LoadModel(string modelName, string resourceName, string materialKey = null) { var assembly = Assembly.GetAssembly(typeof(Graphics3DControlViewModel)); var stream = assembly!.GetManifestResourceStream(resourceName); using var context = new AssimpContext(); var scene = context.ImportFileFromStream(stream); var model = new GeometryModel3D(); if (!string.IsNullOrEmpty(modelName)) model.Hint = modelName; foreach (var mesh in scene.Meshes) { var vertices = new Vertex3D[mesh.VertexCount]; for (int i = 0; i < mesh.VertexCount; ++i) vertices[i] = new Vertex3D { Normal = mesh.Normals[i], Position = mesh.Vertices[i] }; var indices = mesh.GetUnsignedIndices().ToArray(); var meshGeometry = new MeshGeometry3D { Vertices = vertices, Indices = indices }; if (!string.IsNullOrEmpty(materialKey)) meshGeometry.MaterialKey = materialKey; model.Meshes.Add(meshGeometry); } return model; } } ================================================ FILE: DemoCenter/DemoCenter/ViewModels/MainViewModel.cs ================================================ using System.Collections.ObjectModel; using System.Globalization; using System.Reflection; using Avalonia.Styling; using CommunityToolkit.Mvvm.ComponentModel; using DemoCenter.ProductsData; using Eremex.AvaloniaUI.Controls.Common; namespace DemoCenter.ViewModels; public partial class MainViewModel : ViewModelBase { [ObservableProperty] ProductInfoBase currentProductItem; [ObservableProperty] PageViewModelBase currentProductItemViewModel; [ObservableProperty] string title; [ObservableProperty] List locales; [ObservableProperty] CultureInfo selectedLocale; [ObservableProperty] List themeVariants; [ObservableProperty] ThemeVariant selectedThemeVariant; [ObservableProperty] List products; public List FlatProducts = new List(); [ObservableProperty] ObservableCollection sourceFiles; [ObservableProperty] string sourceFile; [ObservableProperty] string selectedCode; [ObservableProperty] bool allowCode = true; [ObservableProperty] bool isDemoSelected = true; private readonly string titlePrefix; public MainViewModel() { } public MainViewModel(ThemeVariant startupThemeVariant = null) { var version = Assembly.GetExecutingAssembly().GetName().Version?.ToString(3) ?? "1.0"; titlePrefix = $"Demo Center v.{version}"; ThemeVariants = new List() { new("Light", ThemeVariant.Light), new("Dark", ThemeVariant.Dark), }; Locales = new List() { new("En", new CultureInfo("en-Us")), new("Ru", new CultureInfo("ru-Ru")), new("CN", new CultureInfo("zh-CN")), }; SelectedThemeVariant = startupThemeVariant == ThemeVariant.Dark ? ThemeVariant.Dark : ThemeVariant.Light; SelectedLocale = Locales.First().Locale;//EN Products = ProductsData.Products.GetOrCreate(); PopulateFlatCollection(); CurrentProductItem = FlatProducts.FirstOrDefault(x => x is PageInfo && AllowDemoContent(x)); } public void SelectProduct(string productName) => CurrentProductItem = FlatProducts.FirstOrDefault(x => string.Equals(x.Name, productName)); partial void OnCurrentProductItemChanged(ProductInfoBase value) { if (value is null) { CurrentProductItemViewModel = null; return; } if (value is GroupInfo) return; CreateTitle(value); var allowContent = AllowDemoContent(value); CurrentProductItemViewModel = allowContent ? CurrentProductItem?.ViewModelGetter?.Invoke() : new DesktopOnlyViewModel(); AllowCode = allowContent; if (!AllowCode) IsDemoSelected = true; var viewModelName = CurrentProductItemViewModel?.GetType().Name; var viewName = viewModelName.Replace("ViewModel", "View"); SourceFiles = new ObservableCollection { $"{viewName}.axaml", $"{viewName}.axaml.cs", $"{viewModelName}.cs", }; SourceFile = SourceFiles.First(); } private void CreateTitle(ProductInfoBase product) { var groupPrefix = string.Empty; var title = string.Empty; if (product is PageInfo page) { var group = GetGroupInfo(page); if (group != null) groupPrefix = $" - {group.Title}"; title = $" - {page.Title}"; } else title = $" - {product?.Title}"; Title = $"{titlePrefix}{groupPrefix}{title}"; } private GroupInfo GetGroupInfo(ProductInfoBase value) { if (value is PageInfo info) return Products.OfType().FirstOrDefault(x => x.Pages.Contains(info)); return null; } private bool AllowDemoContent(ProductInfoBase product) => !App.IsWebApp || (product.ShowInWeb && GetGroupInfo(product) is { } group && group.ShowInWeb); private void PopulateFlatCollection() { FlatProducts.Clear(); foreach (var product in Products) { FlatProducts.Add(product); if (product is GroupInfo productGroup) foreach (var page in productGroup.Pages) FlatProducts.Add(page); } } partial void OnSelectedLocaleChanged(CultureInfo value) { CultureInfo.CurrentCulture = value; CultureInfo.CurrentUICulture = value; var current = CurrentProductItem; CurrentProductItem = null; CurrentProductItem = current; } } public class ThemeVariantInfo { public string ThemeVariantName { get; init; } public ThemeVariant ThemeVariant { get; init; } public ThemeVariantInfo(string name, ThemeVariant themeVariant) { ThemeVariantName = name; ThemeVariant = themeVariant; } } public class LocaleInfo { public string LocaleName { get; init; } public CultureInfo Locale { get; init; } public LocaleInfo(string name, CultureInfo culture) { LocaleName = name; Locale = culture; } } ================================================ FILE: DemoCenter/DemoCenter/ViewModels/PageViewModelBase.cs ================================================ using Eremex.AvaloniaUI.Controls.Common; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace DemoCenter.ViewModels { public abstract partial class PageViewModelBase : ViewModelBase { } } ================================================ FILE: DemoCenter/DemoCenter/ViewModels/PropertyGrid/PropertyGridDataEditorsViewModel.cs ================================================ using CommunityToolkit.Mvvm.ComponentModel; using DemoCenter.DemoData; using Eremex.AvaloniaUI.Controls.Common; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace DemoCenter.ViewModels { public partial class PropertyGridDataEditorsViewModel : PageViewModelBase { [ObservableProperty] object selectedObject; public PropertyGridDataEditorsViewModel() { var employees = EmployeesData.GenerateEmployeeInfo(); SelectedObject = employees[new Random().Next(employees.Count)]; } } } ================================================ FILE: DemoCenter/DemoCenter/ViewModels/PropertyGrid/PropertyGridGroupViewModel.cs ================================================ using CommunityToolkit.Mvvm.ComponentModel; using Eremex.AvaloniaUI.Controls.Common; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace DemoCenter.ViewModels { public partial class PropertyGridGroupViewModel : PageViewModelBase { [ObservableProperty] string message; public PropertyGridGroupViewModel() { Message = GetType().FullName; } } } ================================================ FILE: DemoCenter/DemoCenter/ViewModels/PropertyGrid/PropertyGridTabItemsViewModel.cs ================================================ using CommunityToolkit.Mvvm.ComponentModel; using DemoCenter.DemoData; using Eremex.AvaloniaUI.Controls.Common; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace DemoCenter.ViewModels { public partial class PropertyGridTabItemsViewModel : PageViewModelBase { } } ================================================ FILE: DemoCenter/DemoCenter/ViewModels/Ribbon/RibbonGroupViewModel.cs ================================================ using CommunityToolkit.Mvvm.ComponentModel; namespace DemoCenter.ViewModels; public partial class RibbonGroupViewModel : PageViewModelBase { [ObservableProperty] string message; public RibbonGroupViewModel() { Message = GetType().FullName; } } ================================================ FILE: DemoCenter/DemoCenter/ViewModels/Ribbon/WordPadExampleViewModel.cs ================================================ using System.Collections.ObjectModel; using Avalonia.Media; using CommunityToolkit.Mvvm.ComponentModel; using DynamicData; namespace DemoCenter.ViewModels; public partial class WordPadExampleViewModel : PageViewModelBase { [ObservableProperty] private ObservableCollection fonts; [ObservableProperty] private ObservableCollection fontSizes; [ObservableProperty] private string selectedFont; [ObservableProperty] private int selectedSize; [ObservableProperty] private ObservableCollection fontStyles; public WordPadExampleViewModel() { fonts = new ObservableCollection(); fonts.AddRange(FontManager.Current.SystemFonts.Select(x => x.Name).OrderBy(x => x).ToList()); selectedFont = fonts.FirstOrDefault(f => f == "Arial"); if (selectedFont == null) selectedFont = fonts[0]; fontSizes = new ObservableCollection { 8, 9, 10, 11, 12, 14, 16, 18, 20, 22, 24, 26, 28, 36, 48, 72 }; selectedSize = 14; fontStyles = new ObservableCollection { new FontStyleGalleryItem { Header = "Normal", FontSize = 14 }, new FontStyleGalleryItem { Header = "Heading", FontSize = 22, Foreground = Brushes.SteelBlue }, new FontStyleGalleryItem { Header = "Heading 2", FontSize = 18, Foreground = Brushes.SteelBlue }, new FontStyleGalleryItem { Header = "Title", FontSize = 24 }, new FontStyleGalleryItem { Header = "Subtitle", FontSize = 14, Foreground = Brushes.DimGray }, new FontStyleGalleryItem { Header = "Subtle Empha", FontSize = 14, FontStyle = FontStyle.Italic, Foreground = Brushes.DimGray }, new FontStyleGalleryItem { Header = "Emphasis", FontSize = 14, FontStyle = FontStyle.Italic }, new FontStyleGalleryItem { Header = "Intense Emphasis", FontSize = 14, FontStyle = FontStyle.Italic, Foreground = Brushes.SteelBlue }, new FontStyleGalleryItem { Header = "Strong", FontSize = 14, FontWeight = FontWeight.Bold }, new FontStyleGalleryItem { Header = "Quote", FontSize = 14, FontStyle = FontStyle.Italic }, new FontStyleGalleryItem { Header = "Intense Refer", FontSize = 16, FontWeight = FontWeight.Bold, Foreground = Brushes.SteelBlue }, new FontStyleGalleryItem { Header = "Book Title", FontSize = 12, FontWeight = FontWeight.Bold, FontStyle = FontStyle.Italic }, new FontStyleGalleryItem { Header = "List Paragraph", FontSize = 14 } }; } } public class FontStyleGalleryItem : ObservableObject { public string Header { get; set; } public double FontSize { get; set; } public FontWeight FontWeight { get; set; } = FontWeight.Normal; public FontStyle FontStyle { get; set; } = FontStyle.Normal; public IBrush Foreground { get; set; } } ================================================ FILE: DemoCenter/DemoCenter/ViewModels/StandardControls/PrimitivesPageViewModel.cs ================================================ using Avalonia.Controls; using CommunityToolkit.Mvvm.ComponentModel; using Eremex.AvaloniaUI.Controls.Common; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace DemoCenter.ViewModels { public partial class PrimitivesPageViewModel : PageViewModelBase { public PrimitivesPageViewModel() { } } } ================================================ FILE: DemoCenter/DemoCenter/ViewModels/StandardControls/ProgressBarPageViewModel.cs ================================================ using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using CommunityToolkit.Mvvm.ComponentModel; using Eremex.AvaloniaUI.Controls.Common; namespace DemoCenter.ViewModels { public partial class ProgressBarPageViewModel : PageViewModelBase { [ObservableProperty] string [] formats = new[] { "{1:0}%", "{1:0}", "{1:N2}" } ; [ObservableProperty] string selectedTextFormat; public ProgressBarPageViewModel() { SelectedTextFormat = formats[0]; } } } ================================================ FILE: DemoCenter/DemoCenter/ViewModels/StandardControls/SliderPageViewModel.cs ================================================ using Avalonia.Controls; using CommunityToolkit.Mvvm.ComponentModel; using Eremex.AvaloniaUI.Controls.Common; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace DemoCenter.ViewModels { public partial class SliderPageViewModel : PageViewModelBase { [ObservableProperty] TickPlacement tickPlacement; public SliderPageViewModel() { } } } ================================================ FILE: DemoCenter/DemoCenter/ViewModels/StandardControls/StandardControlsGroupViewModel.cs ================================================ using CommunityToolkit.Mvvm.ComponentModel; using Eremex.AvaloniaUI.Controls.Common; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace DemoCenter.ViewModels { public partial class StandardControlsGroupViewModel : PageViewModelBase { public StandardControlsGroupViewModel() { } } } ================================================ FILE: DemoCenter/DemoCenter/ViewModels/StandardControls/StandardControlsOverviewPageViewModel.cs ================================================ using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using CommunityToolkit.Mvvm.ComponentModel; using Eremex.AvaloniaUI.Controls.Common; namespace DemoCenter.ViewModels { public partial class StandardControlsOverviewPageViewModel : PageViewModelBase { public StandardControlsOverviewPageViewModel() { } } } ================================================ FILE: DemoCenter/DemoCenter/ViewModels/StandardControls/UseCasesGroupViewModel.cs ================================================ namespace DemoCenter.ViewModels { public partial class UseCasesGroupViewModel : PageViewModelBase { public UseCasesGroupViewModel() { } } } ================================================ FILE: DemoCenter/DemoCenter/ViewModels/Tools/DeveloperToolsGroupViewModel.cs ================================================ namespace DemoCenter.ViewModels; public class DeveloperToolsGroupViewModel : PageViewModelBase { } ================================================ FILE: DemoCenter/DemoCenter/ViewModels/Tools/SvgIconsBrowserViewModel.cs ================================================ using System.ComponentModel; using System.Reflection; using Avalonia.Media; using CommunityToolkit.Mvvm.ComponentModel; using Eremex.AvaloniaUI.Controls.ListView; using Eremex.AvaloniaUI.Icons; namespace DemoCenter.ViewModels; public partial class SvgIconsBrowserViewModel : PageViewModelBase { [ObservableProperty] private List categories; [ObservableProperty] private SvgIconCategoryViewModel focusedCategory; [ObservableProperty] private List items; [ObservableProperty] private object focusedItem; [ObservableProperty] private string searchText; [ObservableProperty] private string iconPath; [ObservableProperty] private string iconAxamlPath; [ObservableProperty] private bool hintVisible; public SvgIconsBrowserViewModel() { LoadIcons(); focusedCategory = Categories.Count > 0? Categories[0]: null; focusedItem = Items[1]; } private readonly string[] prohibitedCategories = new[] { "Library", "Logo", "Painting", "PCB", "Scheme", "SimOne", "SimPCB", "Simtera", "Status", "_8", "_144" }; private readonly Dictionary mappingCategories = new() { {"_3D", "3D"}, {"Dimensional_lines", "Dimensions"}, {"Drawing", "Graphical Editor"}, {"CAM", "Factory"}, {"Graphics", "Charts"}, {"Models", "Schematic"}, {"Scaling", "Zoom"}, {"_12", "Glyphs"}, {"_40", "Status"} }; private void LoadIcons() { var cat = typeof(Basic).Assembly.GetTypes().Where(t => t.Namespace != null && t.Namespace.Contains(".Icons")).ToList(); List catList = new List(cat.Count); List iconList = new List(); foreach(var c in cat) { if(prohibitedCategories.Contains(c.Name)) continue; var icons = c.GetProperties(BindingFlags.Static | BindingFlags.Public).Where(p => p.PropertyType == typeof(IImage)).ToList(); if(icons.Count == 0) continue; string name = c.Name; mappingCategories.TryGetValue(name, out name); name ??= c.Name; var cm = new SvgIconCategoryViewModel(this) { DisplayName = name, Name = c.Name, IsChecked = true }; cm.PropertyChanged += OnSvgCategoryPropertyChanged; foreach(var pi in icons) { var ivm = new SvgIconViewModel(cm, pi.Name, (IImage)pi.GetValue(null)); iconList.Add(ivm); } catList.Add(cm); } Categories = catList; Items = iconList; } void OnSvgCategoryPropertyChanged(object sender, PropertyChangedEventArgs e) { if(e.PropertyName == nameof(SvgIconCategoryViewModel.IsChecked)) { RequestUpdateData?.Invoke(); } } public event Action RequestUpdateData; public event Action RequestScrollToCategory; partial void OnFocusedCategoryChanged(SvgIconCategoryViewModel value) { if(value is { IsChecked: true }) { RequestScrollToCategory?.Invoke(value); } } partial void OnFocusedItemChanged(object value) { if(value is SvgIconViewModel vm) { IconPath = vm.Path; IconAxamlPath = vm.AxamlPath; HintVisible = true; } else { IconPath = string.Empty; IconAxamlPath = string.Empty; HintVisible = false; } } public void OnCustomFilter(ListViewFilterEventArgs e) { SvgIconViewModel vm = (SvgIconViewModel)e.Item; e.Visible = vm.Category.IsChecked && (string.IsNullOrEmpty(SearchText) || vm.Name.Contains(SearchText, StringComparison.OrdinalIgnoreCase)); } public void OnCategoryCheckedChanged(SvgIconCategoryViewModel cat) { RequestUpdateData?.Invoke(); if(cat.IsChecked) { RequestScrollToCategory?.Invoke(cat); } } } public partial class SvgIconCategoryViewModel : ObservableObject, IComparable, IComparable { [ObservableProperty] private bool isChecked; [ObservableProperty] private string name; [ObservableProperty] private string displayName; [ObservableProperty] private bool isExpanded; public SvgIconCategoryViewModel(SvgIconsBrowserViewModel owner) { this.owner = owner; } private SvgIconsBrowserViewModel owner; public int CompareTo(SvgIconCategoryViewModel other) { return String.Compare(Name, other.Name, StringComparison.Ordinal); } public int CompareTo(object other) { return String.Compare(Name, ((SvgIconCategoryViewModel)other).Name, StringComparison.Ordinal); } partial void OnIsCheckedChanged(bool value) { this.owner.OnCategoryCheckedChanged(this); } } public partial class SvgIconViewModel : ObservableObject, IComparable, IComparable { [ObservableProperty] private string name; [ObservableProperty] private string path; [ObservableProperty] private string axamlPath; [ObservableProperty] private IImage icon; [ObservableProperty] private SvgIconCategoryViewModel category; public SvgIconViewModel(SvgIconCategoryViewModel category, string name, IImage icon) { this.category = category; this.name = name; path = $"{Category.Name}.{Name}"; axamlPath = $"{{x:Static mxi:{Category.Name}.{Name}}}"; this.icon = icon; } public string CategoryName => Category?.DisplayName; public int CompareTo(SvgIconViewModel other) { return String.Compare(Name, other.Name, StringComparison.Ordinal); } public int CompareTo(object other) { return String.Compare(Name, ((SvgIconViewModel)other)?.Name, StringComparison.Ordinal); } } ================================================ FILE: DemoCenter/DemoCenter/ViewModels/TreeList/FolderBrowserPageViewModel.cs ================================================ using CommunityToolkit.Mvvm.ComponentModel; namespace DemoCenter.ViewModels { public class FolderBrowserPageViewModel : PageViewModelBase { public FolderBrowserPageViewModel() { Drives = CreateDrives(); } public List Drives { get; } private List CreateDrives() { List drives = new(); Array.ForEach(Directory.GetLogicalDrives(), drive => drives.Add(new DriveFileSystemItemModel(drive))); return drives; } } public class DriveFileSystemItemModel : FolderFileSystemItem { public DriveFileSystemItemModel(string driveName) : base(driveName, driveName, FileSystemItem.DriveType, $"<{FileSystemItem.DriveType}>") { } } public class FolderFileSystemItem : FileSystemItem { private List items; public FolderFileSystemItem(string name, string fullName, string type, string size) : base(name, fullName, type, size) { } public List Items { get { if (items == null) items = CreateItems(); return items; } } private List CreateItems() { var items = new List(); CreateFolderItems(items); CreateFileItems(items); return items; } private void CreateFileItems(IList items) { try { var files = Directory.GetFiles(FullName); foreach (var file in files) { try { items.Add(new FileSystemItem(Path.GetFileName(file), file, FileSystemItem.FileType, GetFileSize(file))); } catch { } } } catch { } string GetFileSize(string fullName) => FileSizeHelper.FileSizeToString(new FileInfo(fullName).Length); } private void CreateFolderItems(IList items) { try { var directories = Directory.GetDirectories(FullName); foreach (var directory in directories) { try { items.Add(new FolderFileSystemItem(GetDirectoryName(directory), directory, FileSystemItem.FolderType, $"<{FileSystemItem.FolderType}>")); } catch { } } } catch { } string GetDirectoryName(string fullName) => new DirectoryInfo(fullName).Name; } } public class FileSystemItem { public const string FileType = "File", FolderType = "Folder", DriveType = "Drive"; public FileSystemItem(string name, string fullName, string type, string size) { Name = name; FullName = fullName; Type = type; Size = size; } public string Name { get; } public string FullName { get; } public string Type { get; } public string Size { get; } } internal static class FileSizeHelper { static readonly long BytesInKilobyte = 1024, BytesInMegabyte = BytesInKilobyte * 1024, BytesInGigabyte = BytesInMegabyte * 1024; public static string FileSizeToString(long size) { if (size > BytesInGigabyte) return $"{size / BytesInGigabyte:0.##} GB"; else if (size > BytesInMegabyte) return $"{size / BytesInMegabyte:0.##} MB"; else if (size > BytesInKilobyte) return $"{size / BytesInKilobyte:0.##} KB"; else return size > 0 ? $"1 KB" : $"0 KB"; } } } ================================================ FILE: DemoCenter/DemoCenter/ViewModels/TreeList/TreeListColumnBandsViewModel.cs ================================================ using DemoCenter.DemoData; using System.Collections.ObjectModel; namespace DemoCenter.ViewModels { public partial class TreeListColumnBandsViewModel : PageViewModelBase { public TreeListColumnBandsViewModel() { Sales = SalesData.GenerateData(); } public IList Sales { get; } } } ================================================ FILE: DemoCenter/DemoCenter/ViewModels/TreeList/TreeListDataEditorsPageViewModel.cs ================================================ using DemoCenter.DemoData; namespace DemoCenter.ViewModels { public partial class TreeListDataEditorsPageViewModel : PageViewModelBase { public TreeListDataEditorsPageViewModel() { Tasks = ProjectTasksGenerator.Generate(); } public List Tasks { get; } } } ================================================ FILE: DemoCenter/DemoCenter/ViewModels/TreeList/TreeListExportViewModel.cs ================================================ using CommunityToolkit.Mvvm.ComponentModel; using CommunityToolkit.Mvvm.Input; using DemoCenter.DemoData; using Eremex.DocumentProcessing.Exports; namespace DemoCenter.ViewModels { public partial class TreeListExportViewModel : PageViewModelBase { public TreeListExportViewModel() { InfrastructureItems = InfrastructureData.GenerateData(); } public List InfrastructureItems { get; } #region xlsx export properties [ObservableProperty] private bool xlsExportColumnHeaders = true; [ObservableProperty] private bool xlsExportBandHeaders = true; #endregion #region page export properties [ObservableProperty] private bool pageExportColumnHeaders = true; [ObservableProperty] private bool pageExportBandHeaders = true; [ObservableProperty] private bool fitToPageWidth = true; [ObservableProperty] private bool landscape = false; #endregion public IList ApparelProducts { get; } public event Action RequestExport; public event Action RequestExportImage; [RelayCommand] private void Export(ExportType type) { RequestExport?.Invoke(type); } [RelayCommand] private void ExportImage(MxImageFormat format) { RequestExportImage?.Invoke(format); } } } ================================================ FILE: DemoCenter/DemoCenter/ViewModels/TreeList/TreeListFilteringPageViewModel.cs ================================================ using DemoCenter.DemoData; namespace DemoCenter.ViewModels { public partial class TreeListFilteringPageViewModel : PageViewModelBase { public TreeListFilteringPageViewModel() { Tasks = ProjectTasksGenerator.Generate(); } public List Tasks { get; } } } ================================================ FILE: DemoCenter/DemoCenter/ViewModels/TreeList/TreeListGroupViewModel.cs ================================================ using CommunityToolkit.Mvvm.ComponentModel; using Eremex.AvaloniaUI.Controls.Common; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace DemoCenter.ViewModels { public partial class TreeListGroupViewModel : PageViewModelBase { [ObservableProperty] string message; public TreeListGroupViewModel() { Message = GetType().FullName; } } } ================================================ FILE: DemoCenter/DemoCenter/ViewModels/TreeList/TreeListMultipleSelectionPageViewModel.cs ================================================ using DemoCenter.DemoData; using System.Collections.ObjectModel; namespace DemoCenter.ViewModels { public partial class TreeListMultipleSelectionPageViewModel : PageViewModelBase { public TreeListMultipleSelectionPageViewModel() { Tasks = ProjectTasksGenerator.Generate(); SelectedTasks = new(Tasks[0].Tasks.Take(5)); } public List Tasks { get; } public ObservableCollection SelectedTasks { get; } } } ================================================ FILE: DemoCenter/DemoCenter/ViewModels/UseCases/FinancialServices/MortgageCalculatorViewModel.cs ================================================ using Avalonia.Media.Imaging; using Avalonia.Platform; using CommunityToolkit.Mvvm.ComponentModel; using DemoCenter.Models; using Eremex.AvaloniaUI.Charts; using System; namespace DemoCenter.ViewModels; public partial class MortgageCalculatorViewModel : PageViewModelBase { [ObservableProperty] decimal principal = 300000m; [ObservableProperty] decimal annualInterestRate = 5; [ObservableProperty] int loanTermYears = 30; [ObservableProperty] decimal monthlyPayment; [ObservableProperty] List amortizationSchedule = new(); [ObservableProperty] PaymentDetail selectedPaymentDetail; [ObservableProperty] Bitmap housePreviewImage; [ObservableProperty] SortedNumericDataAdapter principalSeriesDataAdapter, interestSeriesDataAdapter, totalMonthlyPaymentSeriesDataAdapter; [ObservableProperty] FuncLabelFormatter currencyFormatter = new(o => String.Format("{0:c}", o)); [ObservableProperty] FuncLabelFormatter argumentFormatter = new(o => String.Format("{0:0}", o)); public MortgageCalculatorViewModel() { CalculateMortgage(); } partial void OnPrincipalChanged(decimal value) { CalculateMortgage(); } partial void OnAnnualInterestRateChanged(decimal value) { CalculateMortgage(); } partial void OnLoanTermYearsChanged(int value) { CalculateMortgage(); } private void CalculateMortgage() { try { MonthlyPayment = SampleMortgageCalculator.CalculateMonthlyPayment( Principal, AnnualInterestRate, LoanTermYears); AmortizationSchedule = SampleMortgageCalculator.GenerateAmortizationSchedule( Principal, AnnualInterestRate, LoanTermYears); HousePreviewImage = CalcHousePreviewImage(Principal); } catch (ArgumentOutOfRangeException) { // Reset to default values if invalid input MonthlyPayment = 0; AmortizationSchedule = new List(); } var argumentList = AmortizationSchedule.Select(s => (double)s.MonthNumber).ToList(); InterestSeriesDataAdapter = new FormatedTextSortedNumericDataAdapter(argumentList, AmortizationSchedule.Select(s => (double)s.InterestAmount).ToList()); PrincipalSeriesDataAdapter = new FormatedTextSortedNumericDataAdapter(argumentList, AmortizationSchedule.Select(s => (double)s.PrincipalAmount).ToList()); TotalMonthlyPaymentSeriesDataAdapter = new FormatedTextSortedNumericDataAdapter(argumentList, AmortizationSchedule.Select(s => (double)s.PaymentAmount).ToList()); } static Bitmap GetImage(string imageName) { var imageUrl = "avares://DemoCenter/DemoData/HouseImages/" + imageName; return new Bitmap(AssetLoader.Open(new Uri(imageUrl))); } Dictionary houseImages = new Dictionary() { {0, GetImage("House-3-Level.jpg") }, {1, GetImage("House-4-Level.jpg") }, {2, GetImage("House-5-Level.jpg") }, {3, GetImage("House-6-Level.jpg") }, {4, GetImage("House-7-Level.jpg") }, {5, GetImage("House-Vip.jpg") }, }; private Bitmap CalcHousePreviewImage(decimal principal) { var minimum = 100000; var maximum = 1000000; var grade = (maximum - minimum) / 5; int index = (int)(principal - minimum) / grade; return houseImages[index]; } } public class FormatedTextSortedNumericDataAdapter : SortedNumericDataAdapter, ISeriesDataAdapter { public FormatedTextSortedNumericDataAdapter(IList arguments, IList values) : base(arguments, values) { } public string GetDataMemberPrefix(SeriesDataMemberType dataMember) { switch (dataMember) { case SeriesDataMemberType.Value: return "Payment "; default: return "Month "; } } } ================================================ FILE: DemoCenter/DemoCenter/ViewModels/UseCases/FinancialServices/SampleMortgageCalculator.cs ================================================ using System; using System.Collections.Generic; namespace DemoCenter.Models; public class SampleMortgageCalculator { /// /// Calculates the monthly payment for a mortgage /// /// The loan amount /// Annual interest rate (as a percentage, e.g., 3.5 for 3.5%) /// Loan term in years /// Monthly payment amount public static decimal CalculateMonthlyPayment( decimal principal, decimal annualInterestRate, int loanTermYears) { if (principal <= 0) throw new ArgumentOutOfRangeException(nameof(principal), "Principal must be positive"); if (annualInterestRate < 0) throw new ArgumentOutOfRangeException(nameof(annualInterestRate), "Interest rate cannot be negative"); if (loanTermYears <= 0) throw new ArgumentOutOfRangeException(nameof(loanTermYears), "Loan term must be positive"); if (annualInterestRate == 0) return principal / (loanTermYears * 12); var monthlyRate = annualInterestRate / 100 / 12; var numberOfPayments = loanTermYears * 12; var payment = principal * monthlyRate * (decimal)Math.Pow(1 + (double)monthlyRate, numberOfPayments) / (decimal)(Math.Pow(1 + (double)monthlyRate, numberOfPayments) - 1); return Math.Round(payment, 2); } /// /// Generates an amortization schedule for the mortgage /// /// The loan amount /// Annual interest rate (as a percentage) /// Loan term in years /// List of monthly payment details public static List GenerateAmortizationSchedule( decimal principal, decimal annualInterestRate, int loanTermYears) { var schedule = new List(); var monthlyPayment = CalculateMonthlyPayment(principal, annualInterestRate, loanTermYears); var monthlyRate = annualInterestRate / 100 / 12; var remainingBalance = principal; for (int month = 1; month <= loanTermYears * 12; month++) { var interestPayment = remainingBalance * monthlyRate; var principalPayment = monthlyPayment - interestPayment; if (month == loanTermYears * 12) { principalPayment = remainingBalance; interestPayment = monthlyPayment - principalPayment; remainingBalance = 0; } else { remainingBalance -= principalPayment; } schedule.Add(new PaymentDetail( month, monthlyPayment, principalPayment, interestPayment, remainingBalance > 0 ? remainingBalance : 0 )); } return schedule; } } public class PaymentDetail { public int MonthNumber { get; set; } public decimal PaymentAmount { get; set; } public decimal PrincipalAmount { get; set; } public decimal InterestAmount { get; set; } public decimal RemainingBalance { get; set; } public PaymentDetail( int monthNumber, decimal paymentAmount, decimal principalAmount, decimal interestAmount, decimal remainingBalance) { MonthNumber = monthNumber; PaymentAmount = Math.Round(paymentAmount, 2); PrincipalAmount = Math.Round(principalAmount, 2); InterestAmount = Math.Round(interestAmount, 2); RemainingBalance = Math.Round(remainingBalance, 2); } } ================================================ FILE: DemoCenter/DemoCenter/Views/Bars/BarItemsPageView.axaml ================================================ ================================================ FILE: DemoCenter/DemoCenter/Views/Bars/BarItemsPageView.axaml.cs ================================================ using Avalonia.Controls; using Avalonia.Interactivity; namespace DemoCenter.Views { public partial class BarItemsPageView : UserControl { public BarItemsPageView() { InitializeComponent(); PropertiesSelector.DataContext = ButtonItem; } private void OnRadioButtonCheckedChanged(object sender, RoutedEventArgs e) { var source = e.Source as RadioButton; if (source.IsChecked != true) return; if(source == ButtonItemSelector) PropertiesSelector.DataContext = ButtonItem; else if (source == ButtonCheckItemSelector) PropertiesSelector.DataContext = ButtonCheckItem; else if(source == ButtonDropDownItemSelector) PropertiesSelector.DataContext = ButtonDropDownItem; else if(source == TextItemSelector) PropertiesSelector.DataContext = TextItem; } } } ================================================ FILE: DemoCenter/DemoCenter/Views/Bars/BarsGroupView.axaml ================================================ ================================================ FILE: DemoCenter/DemoCenter/Views/Bars/BarsGroupView.axaml.cs ================================================ using Avalonia.Controls; namespace DemoCenter.Views { public partial class BarsGroupView : UserControl { public BarsGroupView() { InitializeComponent(); } } } ================================================ FILE: DemoCenter/DemoCenter/Views/Bars/BarsOverviewPageView.axaml ================================================ ================================================ FILE: DemoCenter/DemoCenter/Views/Bars/BarsOverviewPageView.axaml.cs ================================================ using Avalonia.Controls; namespace DemoCenter.Views { public partial class BarsOverviewPageView : UserControl { public BarsOverviewPageView() { InitializeComponent(); } } } ================================================ FILE: DemoCenter/DemoCenter/Views/Bars/ContextMenuPageView.axaml ================================================ ================================================ FILE: DemoCenter/DemoCenter/Views/Bars/ContextMenuPageView.axaml.cs ================================================ using Avalonia.Controls; namespace DemoCenter.Views { public partial class ContextMenuPageView : UserControl { public ContextMenuPageView() { InitializeComponent(); } } } ================================================ FILE: DemoCenter/DemoCenter/Views/Bars/Helpers/Converters.cs ================================================ using Avalonia; using Avalonia.Controls; using Avalonia.Data; using Avalonia.Data.Converters; using Avalonia.Interactivity; using Avalonia.Markup.Xaml; using Avalonia.Media; using System; using System.Data.Common; using System.Globalization; using System.Windows.Input; namespace DemoCenter.Views.Bars.Helpers; public class LineAndColumnToTextConverter : MarkupExtension, IMultiValueConverter { public override object ProvideValue(IServiceProvider serviceProvider) { return this; } public object Convert(IList values, Type targetType, object parameter, CultureInfo culture) { if (values.Count == 2 && values[0] is int line && values[1] is int column) { return $"Line {line}, Column {column}"; } return string.Empty; } } public class FontNameToFontFamilyConverter : MarkupExtension, IValueConverter { public override object ProvideValue(IServiceProvider serviceProvider) { return this; } public object Convert(object value, Type targetType, object parameter, CultureInfo culture) { return ((FontFamily)value).Name; } public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) { return new FontFamily((string)value); } } public class BoolToFontWeightConverter : MarkupExtension, IValueConverter { public override object ProvideValue(IServiceProvider serviceProvider) { return this; } public object Convert(object value, Type targetType, object parameter, CultureInfo culture) { return ((FontWeight)value) == FontWeight.Bold; } public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) { return (bool)value ? FontWeight.Bold : FontWeight.Normal; } } public class BoolToFontStyleConverter : MarkupExtension, IValueConverter { public override object ProvideValue(IServiceProvider serviceProvider) { return this; } public object Convert(object value, Type targetType, object parameter, CultureInfo culture) { return (FontStyle)value == FontStyle.Italic; } public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) { return (bool)value ? FontStyle.Italic : FontStyle.Normal; } } public class ColorToBrushConverter : MarkupExtension, IValueConverter { public override object ProvideValue(IServiceProvider serviceProvider) { return this; } public object Convert(object value, Type targetType, object parameter, CultureInfo culture) { if(value is SolidColorBrush brush) return brush.Color; return null; } public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) { return new SolidColorBrush((Color)value); } } ================================================ FILE: DemoCenter/DemoCenter/Views/Bars/Helpers/ScaleDecorator.cs ================================================ using Avalonia; using Avalonia.Controls; using Avalonia.Data; using Avalonia.Data.Converters; using Avalonia.Interactivity; using Avalonia.Markup.Xaml; using Avalonia.Media; using CommunityToolkit.Mvvm.Input; using System; using System.Data.Common; using System.Windows.Input; namespace DemoCenter.Views.Bars.Helpers; public class ScaleDecorator : Decorator { public static readonly StyledProperty ScaleProperty = AvaloniaProperty.Register(nameof(Scale), defaultValue: 1); static ScaleDecorator() { ScaleProperty.Changed.AddClassHandler((x, e) => x.OnScaleChanged()); } public ScaleDecorator() { DecreaseCommand = new RelayCommand(() => Scale -= 0.1, () => Scale > 0.2); IncreaseCommand = new RelayCommand(() => Scale += 0.1, () => Scale < 3); DefaultScaleCommand = new RelayCommand(() => Scale = 1, () => Scale != 1); } public double Scale { get => GetValue(ScaleProperty); set => SetValue(ScaleProperty, value); } public IRelayCommand DecreaseCommand { get; } public IRelayCommand IncreaseCommand { get; } public IRelayCommand DefaultScaleCommand { get; } private void OnScaleChanged() { DecreaseCommand.NotifyCanExecuteChanged(); IncreaseCommand.NotifyCanExecuteChanged(); DefaultScaleCommand.NotifyCanExecuteChanged(); InvalidateArrange(); Child.RenderTransform = new ScaleTransform(Scale, Scale); } protected override Size ArrangeOverride(Size finalSize) { var size = new Size(finalSize.Width / Scale, finalSize.Height / Scale); var position = new Point((finalSize.Width - size.Width) / 2, (finalSize.Height - size.Height) / 2); Child.Arrange(new Rect(position, size)); return finalSize; } } ================================================ FILE: DemoCenter/DemoCenter/Views/Bars/Helpers/TextBoxHelper.cs ================================================ using Avalonia; using Avalonia.Controls; using Avalonia.Data; using Avalonia.Data.Converters; using Avalonia.Interactivity; using Avalonia.Markup.Xaml; using System; using System.Data.Common; using System.Windows.Input; namespace DemoCenter.Views.Bars.Helpers; public class TextBoxHelper : AvaloniaObject { public static readonly AttachedProperty IsEnabledProperty = AvaloniaProperty.RegisterAttached("IsEnabled"); public static readonly AttachedProperty LineProperty = AvaloniaProperty.RegisterAttached("Line", defaultValue: 1); public static readonly AttachedProperty ColumnProperty = AvaloniaProperty.RegisterAttached("Column", defaultValue: 1); public static bool GetIsEnabled(TextBox textBox) { return textBox.GetValue(IsEnabledProperty); } public static void SetIsEnabled(TextBox textBox, bool isEnabled) { textBox.SetValue(IsEnabledProperty, isEnabled); } public static int GetLine(TextBox textBox) { return textBox.GetValue(LineProperty); } public static void SetLine(TextBox textBox, int line) { textBox.SetValue(LineProperty, line); } public static int GetColumn(TextBox textBox) { return textBox.GetValue(ColumnProperty); } public static void SetColumn(TextBox textBox, int column) { textBox.SetValue(ColumnProperty, column); } static TextBoxHelper() { IsEnabledProperty.Changed.Subscribe(x => OnIsEnabledChanged(x)); } private static void OnIsEnabledChanged(AvaloniaPropertyChangedEventArgs e) { var textBox = (TextBox)e.Sender; if (textBox == null) return; if(e.NewValue.Value) textBox.PropertyChanged += TextBox_PropertyChanged; else textBox.PropertyChanged -= TextBox_PropertyChanged; } private static void TextBox_PropertyChanged(object sender, AvaloniaPropertyChangedEventArgs e) { if (e.Property == TextBox.CaretIndexProperty) { var textBox = (TextBox)sender; SetLine(textBox, GetLineNumber(textBox)); SetColumn(textBox, GetColumnNumber(textBox)); } } private static int GetLineNumber(TextBox textBox) { int currentIndex = 0; int lineNumber = 1; while(currentIndex < textBox.CaretIndex) { if (textBox.Text.Length < currentIndex + textBox.NewLine.Length) break; if (textBox.Text.Substring(currentIndex, textBox.NewLine.Length) == textBox.NewLine) { lineNumber++; currentIndex += textBox.NewLine.Length; } else { currentIndex++; } } return lineNumber; } private static int GetColumnNumber(TextBox textBox) { int currentIndex = textBox.CaretIndex - textBox.NewLine.Length; while (currentIndex >= 0) { if (textBox.Text.Substring(currentIndex, textBox.NewLine.Length) == textBox.NewLine) { currentIndex += textBox.NewLine.Length; break; } else { currentIndex--; } } currentIndex = Math.Max(currentIndex, 0); return textBox.CaretIndex - currentIndex + 1; } } ================================================ FILE: DemoCenter/DemoCenter/Views/Bars/ToolbarAndMenuPageView.axaml ================================================ ================================================ FILE: DemoCenter/DemoCenter/Views/Bars/ToolbarAndMenuPageView.axaml.cs ================================================ using Avalonia; using Avalonia.Controls; using Avalonia.Interactivity; using Avalonia.Media; namespace DemoCenter.Views { public partial class ToolbarAndMenuPageView : UserControl { public static readonly AttachedProperty IsToolbarSelectedProperty = AvaloniaProperty.RegisterAttached("IsToolbarSelected"); public static bool GetIsToolbarSelected(AvaloniaObject target) { return target.GetValue(IsToolbarSelectedProperty); } public static void SetIsToolbarSelected(AvaloniaObject target, bool isToolbarSelected) { target.SetValue(IsToolbarSelectedProperty, isToolbarSelected); } IReadOnlyList fonts; public IReadOnlyList Fonts => fonts ?? (fonts = FontManager.Current.SystemFonts.Select(x => x.Name).OrderBy(x => x).ToList()); public IReadOnlyList FontSizes { get; } = new List() { 8, 9, 10, 11, 12, 14, 16, 18, 20, 22, 24, 26, 28, 36, 48, 72 }; public ToolbarAndMenuPageView() { InitializeComponent(); PropertiesSelector.DataContext = MainMenu; } private void OnRadioButtonCheckedChanged(object sender, RoutedEventArgs e) { var source = e.Source as RadioButton; if(source.IsChecked != true) return; if(PropertiesSelector.DataContext is AvaloniaObject oldToolbar) SetIsToolbarSelected(oldToolbar, false); if(source == MainMenuSelector) PropertiesSelector.DataContext = MainMenu; else if(source == FileToolbarSelector) PropertiesSelector.DataContext = FileToolbar; else if(source == EditToolbarSelector) PropertiesSelector.DataContext = EditToolbar; else if(source == FontToolbarSelector) PropertiesSelector.DataContext = FontToolbar; else if(source == StatusBarSelector) PropertiesSelector.DataContext = StatusBar; SetIsToolbarSelected((AvaloniaObject)PropertiesSelector.DataContext, true); } } } ================================================ FILE: DemoCenter/DemoCenter/Views/Charts/CartesianAreaSeriesViewView.axaml ================================================  ================================================ FILE: DemoCenter/DemoCenter/Views/Charts/CartesianAreaSeriesViewView.axaml.cs ================================================ using Avalonia.Controls; namespace DemoCenter.Views; public partial class CartesianAreaSeriesViewView : UserControl { public CartesianAreaSeriesViewView() { InitializeComponent(); } } ================================================ FILE: DemoCenter/DemoCenter/Views/Charts/CartesianCandlestickAggregationView.axaml ================================================  15 Minutes 30 Minutes 1 Hour 5 Hours 1 Day ================================================ FILE: DemoCenter/DemoCenter/Views/Charts/CartesianCandlestickAggregationView.axaml.cs ================================================ using Avalonia.Controls; namespace DemoCenter.Views; public partial class CartesianCandlestickAggregationView : UserControl { public CartesianCandlestickAggregationView() { InitializeComponent(); } } ================================================ FILE: DemoCenter/DemoCenter/Views/Charts/CartesianCandlestickSeriesViewView.axaml ================================================  Bitcoin Historical Data ================================================ FILE: DemoCenter/DemoCenter/Views/Charts/CartesianCandlestickSeriesViewView.axaml.cs ================================================ using Avalonia.Controls; namespace DemoCenter.Views; public partial class CartesianCandlestickSeriesViewView : UserControl { public CartesianCandlestickSeriesViewView() { InitializeComponent(); } } ================================================ FILE: DemoCenter/DemoCenter/Views/Charts/CartesianChartAxesPageView.axaml ================================================  ================================================ FILE: DemoCenter/DemoCenter/Views/Charts/CartesianChartAxesPageView.axaml.cs ================================================ using Avalonia.Controls; using Eremex.AvaloniaUI.Charts; namespace DemoCenter.Views; public partial class CartesianChartAxesPageView : UserControl { public CartesianChartAxesPageView() { InitializeComponent(); } } ================================================ FILE: DemoCenter/DemoCenter/Views/Charts/CartesianChartLargeDataPageView.axaml ================================================  Large data 2 series with 1 million points each ================================================ FILE: DemoCenter/DemoCenter/Views/Charts/CartesianChartLargeDataPageView.axaml.cs ================================================ using Avalonia.Controls; namespace DemoCenter.Views; public partial class CartesianChartLargeDataPageView : UserControl { public CartesianChartLargeDataPageView() { InitializeComponent(); } } ================================================ FILE: DemoCenter/DemoCenter/Views/Charts/CartesianChartLogarithmicScalePageView.axaml ================================================  Raw Frequency Response ================================================ FILE: DemoCenter/DemoCenter/Views/Charts/CartesianChartLogarithmicScalePageView.axaml.cs ================================================ using Avalonia.Controls; namespace DemoCenter.Views; public partial class CartesianChartLogarithmicScalePageView : UserControl { public CartesianChartLogarithmicScalePageView() { InitializeComponent(); } } ================================================ FILE: DemoCenter/DemoCenter/Views/Charts/CartesianChartRealtimePageView.axaml ================================================  Real-Time data 6 series with 500 points each ================================================ FILE: DemoCenter/DemoCenter/Views/Charts/CartesianChartRealtimePageView.axaml.cs ================================================ using Avalonia.Controls; using Avalonia.Interactivity; using DemoCenter.ViewModels; namespace DemoCenter.Views; public partial class CartesianChartRealtimePageView : UserControl { CartesianChartRealtimePageViewModel ViewModel => DataContext as CartesianChartRealtimePageViewModel; public CartesianChartRealtimePageView() { InitializeComponent(); } protected override void OnLoaded(RoutedEventArgs e) { base.OnLoaded(e); ViewModel?.Start(); } protected override void OnUnloaded(RoutedEventArgs e) { base.OnUnloaded(e); ViewModel?.Stop(); } } ================================================ FILE: DemoCenter/DemoCenter/Views/Charts/CartesianEmptyPointsView.axaml ================================================  ================================================ FILE: DemoCenter/DemoCenter/Views/Charts/CartesianEmptyPointsView.axaml.cs ================================================ using Avalonia.Controls; using DemoCenter.ViewModels; namespace DemoCenter.Views; public partial class CartesianEmptyPointsView : UserControl { CartesianEmptyPointsViewModel ViewModel => DataContext as CartesianEmptyPointsViewModel; public CartesianEmptyPointsView() { InitializeComponent(); } void ViewOnSelectionChanged(object sender, SelectionChangedEventArgs e) { if (ViewModel is not null && sender is ListBox { SelectedItems.Count: > 0 } listBox && listBox.SelectedItems[0] is ViewViewModel viewModel) { ViewModel.SelectedView = viewModel.View; ViewModel.DataAdapter = viewModel.DataAdapter; } } } ================================================ FILE: DemoCenter/DemoCenter/Views/Charts/CartesianFullStackedAreaSeriesViewView.axaml ================================================  ================================================ FILE: DemoCenter/DemoCenter/Views/Charts/CartesianFullStackedAreaSeriesViewView.axaml.cs ================================================ using Avalonia.Controls; namespace DemoCenter.Views; public partial class CartesianFullStackedAreaSeriesViewView : UserControl { public CartesianFullStackedAreaSeriesViewView() { InitializeComponent(); } } ================================================ FILE: DemoCenter/DemoCenter/Views/Charts/CartesianLineSeriesViewView.axaml ================================================  ================================================ FILE: DemoCenter/DemoCenter/Views/Charts/CartesianLineSeriesViewView.axaml.cs ================================================ using Avalonia.Controls; namespace DemoCenter.Views; public partial class CartesianLineSeriesViewView : UserControl { public CartesianLineSeriesViewView() { InitializeComponent(); } } ================================================ FILE: DemoCenter/DemoCenter/Views/Charts/CartesianLollipopSeriesViewView.axaml ================================================  ================================================ FILE: DemoCenter/DemoCenter/Views/Charts/CartesianLollipopSeriesViewView.axaml.cs ================================================ using Avalonia.Controls; namespace DemoCenter.Views; public partial class CartesianLollipopSeriesViewView : UserControl { public CartesianLollipopSeriesViewView() { InitializeComponent(); } } ================================================ FILE: DemoCenter/DemoCenter/Views/Charts/CartesianPointSeriesViewView.axaml ================================================  ================================================ FILE: DemoCenter/DemoCenter/Views/Charts/CartesianPointSeriesViewView.axaml.cs ================================================ using Avalonia.Controls; namespace DemoCenter.Views; public partial class CartesianPointSeriesViewView : UserControl { public CartesianPointSeriesViewView() { InitializeComponent(); } } ================================================ FILE: DemoCenter/DemoCenter/Views/Charts/CartesianRangeAreaSeriesViewView.axaml ================================================  ================================================ FILE: DemoCenter/DemoCenter/Views/Charts/CartesianRangeAreaSeriesViewView.axaml.cs ================================================ using Avalonia.Controls; namespace DemoCenter.Views; public partial class CartesianRangeAreaSeriesViewView : UserControl { public CartesianRangeAreaSeriesViewView() { InitializeComponent(); } } ================================================ FILE: DemoCenter/DemoCenter/Views/Charts/CartesianScatterLineSeriesViewView.axaml ================================================  ================================================ FILE: DemoCenter/DemoCenter/Views/Charts/CartesianScatterLineSeriesViewView.axaml.cs ================================================ using Avalonia.Controls; namespace DemoCenter.Views; public partial class CartesianScatterLineSeriesViewView : UserControl { public CartesianScatterLineSeriesViewView() { InitializeComponent(); } } ================================================ FILE: DemoCenter/DemoCenter/Views/Charts/CartesianSideBySideBarSeriesViewView.axaml ================================================  ================================================ FILE: DemoCenter/DemoCenter/Views/Charts/CartesianSideBySideBarSeriesViewView.axaml.cs ================================================ using Avalonia.Controls; namespace DemoCenter.Views; public partial class CartesianSideBySideBarSeriesViewView : UserControl { public CartesianSideBySideBarSeriesViewView() { InitializeComponent(); } } ================================================ FILE: DemoCenter/DemoCenter/Views/Charts/CartesianSideBySideRangeBarSeriesViewView.axaml ================================================  ================================================ FILE: DemoCenter/DemoCenter/Views/Charts/CartesianSideBySideRangeBarSeriesViewView.axaml.cs ================================================ using Avalonia.Controls; namespace DemoCenter.Views; public partial class CartesianSideBySideRangeBarSeriesViewView : UserControl { public CartesianSideBySideRangeBarSeriesViewView() { InitializeComponent(); } } ================================================ FILE: DemoCenter/DemoCenter/Views/Charts/CartesianStackedAreaSeriesViewView.axaml ================================================  ================================================ FILE: DemoCenter/DemoCenter/Views/Charts/CartesianStackedAreaSeriesViewView.axaml.cs ================================================ using Avalonia.Controls; namespace DemoCenter.Views; public partial class CartesianStackedAreaSeriesViewView : UserControl { public CartesianStackedAreaSeriesViewView() { InitializeComponent(); } } ================================================ FILE: DemoCenter/DemoCenter/Views/Charts/CartesianStepAreaSeriesViewView.axaml ================================================  ================================================ FILE: DemoCenter/DemoCenter/Views/Charts/CartesianStepAreaSeriesViewView.axaml.cs ================================================ using Avalonia.Controls; namespace DemoCenter.Views; public partial class CartesianStepAreaSeriesViewView : UserControl { public CartesianStepAreaSeriesViewView() { InitializeComponent(); } } ================================================ FILE: DemoCenter/DemoCenter/Views/Charts/CartesianStepLineSeriesViewView.axaml ================================================  ================================================ FILE: DemoCenter/DemoCenter/Views/Charts/CartesianStepLineSeriesViewView.axaml.cs ================================================ using Avalonia.Controls; namespace DemoCenter.Views; public partial class CartesianStepLineSeriesViewView : UserControl { public CartesianStepLineSeriesViewView() { InitializeComponent(); } } ================================================ FILE: DemoCenter/DemoCenter/Views/Charts/CartesianStripsAndConstantLinesView.axaml ================================================  Temperature Data ================================================ FILE: DemoCenter/DemoCenter/Views/Charts/CartesianStripsAndConstantLinesView.axaml.cs ================================================ using Avalonia.Controls; using Avalonia.Input; using DemoCenter.ViewModels; namespace DemoCenter.Views; public partial class CartesianStripsAndConstantLinesView : UserControl { CartesianStripsAndConstantLinesViewModel ViewModel => DataContext as CartesianStripsAndConstantLinesViewModel; public CartesianStripsAndConstantLinesView() { InitializeComponent(); } void DemoControl_OnPointerPressed(object sender, PointerPressedEventArgs e) { var point = e.GetCurrentPoint(DemoControl); if (point.Properties.IsRightButtonPressed && ViewModel is not null) { var coords = DemoControl.ScreenPointToDiagramPoint(point.Position); if (coords.InsideViewport) { object argument = coords.AxesX.First().Value; ViewModel.ConstantLines.Add(new ConstantLineViewModel { AxisValue = argument, Title = argument.ToString() }); } } } } ================================================ FILE: DemoCenter/DemoCenter/Views/Charts/HeatmapColorProvidersView.axaml ================================================  ================================================ FILE: DemoCenter/DemoCenter/Views/Charts/HeatmapColorProvidersView.axaml.cs ================================================ using Avalonia.Controls; namespace DemoCenter.Views; public partial class HeatmapColorProvidersView : UserControl { public HeatmapColorProvidersView() { InitializeComponent(); } } ================================================ FILE: DemoCenter/DemoCenter/Views/Charts/HeatmapRealTimeView.axaml ================================================  100 8 20 8 ================================================ FILE: DemoCenter/DemoCenter/Views/Charts/HeatmapRealTimeView.axaml.cs ================================================ #nullable enable using Avalonia.Controls; using Avalonia.Input; using Avalonia.Interactivity; using DemoCenter.ViewModels; namespace DemoCenter.Views; public partial class HeatmapRealTimeView : UserControl { readonly Cursor moveCursor = new(StandardCursorType.SizeWestEast); bool isChartSelected; bool isHeatmapSelected; HeatmapRealTimeViewModel? ViewModel => DataContext as HeatmapRealTimeViewModel; public HeatmapRealTimeView() { InitializeComponent(); } protected override void OnLoaded(RoutedEventArgs e) { base.OnLoaded(e); ViewModel?.Start(); } protected override void OnUnloaded(RoutedEventArgs e) { base.OnUnloaded(e); ViewModel?.Stop(); } void DemoChart_OnPointerPressed(object sender, PointerPressedEventArgs e) { if (Chart.ScreenPointToDiagramPoint(e.GetPosition(Chart)).InsideViewport) isChartSelected = true; } void DemoChart_OnPointerMoved(object sender, PointerEventArgs e) { if (isChartSelected) { Chart.Cursor = moveCursor; var diagramPoint = Chart.ScreenPointToDiagramPoint(e.GetPosition(Chart)); if (diagramPoint.AxesX.TryGetValue(AxisX, out var val) && val is string str) ViewModel?.UpdateFrequency(str); } } void DemoChart_OnPointerReleased(object sender, PointerReleasedEventArgs e) { var diagramPoint = Chart.ScreenPointToDiagramPoint(e.GetPosition(Chart)); if (diagramPoint.InsideViewport && diagramPoint.AxesX.TryGetValue(AxisX, out var val) && val is string str) ViewModel?.UpdateFrequency(str); isChartSelected = false; Chart.Cursor = null; } void DemoControl_OnPointerPressed(object sender, PointerPressedEventArgs e) { if (DemoControl.ScreenPointToDiagramPoint(e.GetPosition(DemoControl)).InsideViewport) isHeatmapSelected = true; } void DemoControl_OnPointerMoved(object sender, PointerEventArgs e) { if (isHeatmapSelected) { DemoControl.Cursor = moveCursor; var diagramPoint = DemoControl.ScreenPointToDiagramPoint(e.GetPosition(DemoControl)); if (diagramPoint.ArgumentX is not null) ViewModel?.UpdateFrequency(diagramPoint.ArgumentX); } } void DemoControl_OnPointerReleased(object sender, PointerReleasedEventArgs e) { var diagramPoint = DemoControl.ScreenPointToDiagramPoint(e.GetPosition(DemoControl)); if (diagramPoint is { InsideViewport: true, ArgumentX: not null }) ViewModel?.UpdateFrequency(diagramPoint.ArgumentX); isHeatmapSelected = false; DemoControl.Cursor = null; } } ================================================ FILE: DemoCenter/DemoCenter/Views/Charts/PolarAreaSeriesViewView.axaml ================================================  ================================================ FILE: DemoCenter/DemoCenter/Views/Charts/PolarAreaSeriesViewView.axaml.cs ================================================ using Avalonia.Controls; namespace DemoCenter.Views; public partial class PolarAreaSeriesViewView : UserControl { public PolarAreaSeriesViewView() { InitializeComponent(); } } ================================================ FILE: DemoCenter/DemoCenter/Views/Charts/PolarEmptyPointsView.axaml ================================================  ================================================ FILE: DemoCenter/DemoCenter/Views/Charts/PolarEmptyPointsView.axaml.cs ================================================ using Avalonia.Controls; using DemoCenter.ViewModels; namespace DemoCenter.Views; public partial class PolarEmptyPointsView : UserControl { PolarEmptyPointsViewModel ViewModel => DataContext as PolarEmptyPointsViewModel; public PolarEmptyPointsView() { InitializeComponent(); } void ViewOnSelectionChanged(object sender, SelectionChangedEventArgs e) { if (ViewModel is not null && sender is ListBox { SelectedItems.Count: > 0 } listBox && listBox.SelectedItems[0] is ViewViewModel viewModel) { ViewModel.SelectedView = viewModel.View; ViewModel.DataAdapter = viewModel.DataAdapter; } } } ================================================ FILE: DemoCenter/DemoCenter/Views/Charts/PolarLineSeriesViewView.axaml ================================================  ================================================ FILE: DemoCenter/DemoCenter/Views/Charts/PolarLineSeriesViewView.axaml.cs ================================================ using Avalonia.Controls; namespace DemoCenter.Views; public partial class PolarLineSeriesViewView : UserControl { public PolarLineSeriesViewView() { InitializeComponent(); } } ================================================ FILE: DemoCenter/DemoCenter/Views/Charts/PolarPointSeriesViewView.axaml ================================================  ================================================ FILE: DemoCenter/DemoCenter/Views/Charts/PolarPointSeriesViewView.axaml.cs ================================================ using Avalonia.Controls; namespace DemoCenter.Views; public partial class PolarPointSeriesViewView : UserControl { public PolarPointSeriesViewView() { InitializeComponent(); } } ================================================ FILE: DemoCenter/DemoCenter/Views/Charts/PolarRangeAreaSeriesViewView.axaml ================================================  ================================================ FILE: DemoCenter/DemoCenter/Views/Charts/PolarRangeAreaSeriesViewView.axaml.cs ================================================ using Avalonia.Controls; namespace DemoCenter.Views; public partial class PolarRangeAreaSeriesViewView : UserControl { public PolarRangeAreaSeriesViewView() { InitializeComponent(); } } ================================================ FILE: DemoCenter/DemoCenter/Views/Charts/PolarScatterLineSeriesViewView.axaml ================================================  ================================================ FILE: DemoCenter/DemoCenter/Views/Charts/PolarScatterLineSeriesViewView.axaml.cs ================================================ using Avalonia.Controls; namespace DemoCenter.Views; public partial class PolarScatterLineSeriesViewView : UserControl { public PolarScatterLineSeriesViewView() { InitializeComponent(); } } ================================================ FILE: DemoCenter/DemoCenter/Views/Charts/PolarStripsAndConstantLinesView.axaml ================================================  Radiation Pattern ================================================ FILE: DemoCenter/DemoCenter/Views/Charts/PolarStripsAndConstantLinesView.axaml.cs ================================================ using Avalonia.Controls; using Avalonia.Input; using DemoCenter.ViewModels; namespace DemoCenter.Views; public partial class PolarStripsAndConstantLinesView : UserControl { PolarStripsAndConstantLinesViewModel ViewModel => DataContext as PolarStripsAndConstantLinesViewModel; public PolarStripsAndConstantLinesView() { InitializeComponent(); } void DemoControl_OnPointerPressed(object sender, PointerPressedEventArgs e) { if(ViewModel is null) return; var point = e.GetCurrentPoint(DemoControl); var coords = DemoControl.ScreenPointToDiagramPoint(point.Position); if (coords.InsideViewport && coords.Argument.HasValue && coords.Value is not null) { if (point.Properties.IsLeftButtonPressed) ViewModel.ConstantLinesX.Add(new ConstantLineViewModel { AxisValue = coords.Argument, Title = coords.Argument.ToString() }); if (point.Properties.IsRightButtonPressed) ViewModel.ConstantLinesY.Add(new ConstantLineViewModel { AxisValue = coords.Value, Title = coords.Value.ToString() }); } } } ================================================ FILE: DemoCenter/DemoCenter/Views/Charts/SmithLineSeriesViewView.axaml ================================================  ================================================ FILE: DemoCenter/DemoCenter/Views/Charts/SmithLineSeriesViewView.axaml.cs ================================================ using Avalonia.Controls; namespace DemoCenter.Views; public partial class SmithPointSeriesViewView : UserControl { public SmithPointSeriesViewView() { InitializeComponent(); } } ================================================ FILE: DemoCenter/DemoCenter/Views/Charts/SmithPointSeriesViewView.axaml ================================================  ================================================ FILE: DemoCenter/DemoCenter/Views/Charts/SmithPointSeriesViewView.axaml.cs ================================================ using Avalonia.Controls; namespace DemoCenter.Views; public partial class SmithLineSeriesViewView : UserControl { public SmithLineSeriesViewView() { InitializeComponent(); } } ================================================ FILE: DemoCenter/DemoCenter/Views/CommonControls/CommonControlsGroupView.axaml ================================================ ================================================ FILE: DemoCenter/DemoCenter/Views/CommonControls/CommonControlsGroupView.axaml.cs ================================================ using Avalonia.Controls; namespace DemoCenter.Views { public partial class CommonControlsGroupView : UserControl { public CommonControlsGroupView() { InitializeComponent(); } } } ================================================ FILE: DemoCenter/DemoCenter/Views/CommonControls/MessageBoxPageView.axaml ================================================