build method

  1. @override
Widget build(
  1. BuildContext context,
  2. WidgetRef ref
)
override

Describes the part of the user interface represented by this widget.

The framework calls this method when this widget is inserted into the tree in a given BuildContext and when the dependencies of this widget change (e.g., an InheritedWidget referenced by this widget changes). This method can potentially be called in every frame and should not have any side effects beyond building a widget.

The framework replaces the subtree below this widget with the widget returned by this method, either by updating the existing subtree or by removing the subtree and inflating a new subtree, depending on whether the widget returned by this method can update the root of the existing subtree, as determined by calling Widget.canUpdate.

Typically implementations return a newly created constellation of widgets that are configured with information from this widget's constructor and from the given BuildContext.

The given BuildContext contains information about the location in the tree at which this widget is being built. For example, the context provides the set of inherited widgets for this location in the tree. A given widget might be built with multiple different BuildContext arguments over time if the widget is moved around the tree or if the widget is inserted into the tree in multiple places at once.

The implementation of this method must only depend on:

If a widget's build method is to depend on anything else, use a StatefulWidget instead.

See also:

  • StatelessWidget, which contains the discussion on performance considerations.

Implementation

@override
Widget build(BuildContext context, WidgetRef ref) {
  // 20240809 gjw Delay the rStart() until we begin to load the dataset. This
  // may solve the Windows zip install issue whereby main.R is not being
  // loaded on startup yet the remainder of the R code does get loaded. Also,
  // we load it here rather than in rLoadDataset because at this time the user
  // is paused looking at the popup to load the dataset and we have time to
  // squeeze in and async run main.R before we get the `glimpse` missing
  // error.
  //
  // 20240809 gjw Revert for now until find the proper solution.
  //
  // 20240809 gjw Moved main.R into dataset_prep.R see if that works.

  // rStart(context, ref);

  // A state to hold the selected demo dataset.

  return AlertDialog(
    content: Column(
      mainAxisSize: MainAxisSize.min,
      children: [
        const Row(
          children: [
            Icon(Icons.data_usage, size: 24, color: Colors.blue),
            popupIconGap,
            Text(
              'Choose the Dataset Source:',
              style: TextStyle(fontSize: 24, fontWeight: FontWeight.bold),
            ),
          ],
        ),

        popupTitleGap,

        Row(
          mainAxisAlignment: MainAxisAlignment.spaceAround,
          children: [
            // FILENAME
            ElevatedButton(
              onPressed: () async {
                String path = await datasetSelectFile();
                if (path.isNotEmpty) {
                  ref.read(pathProvider.notifier).state = path;
                  if (context.mounted) await rLoadDataset(context, ref);
                  setStatus(ref, statusChooseVariableRoles);
                  datasetLoadedUpdate(ref);

                  // Save the dataset name in lowercase to the dsnameProvider
                  // from the path.

                  ref.read(dsnameProvider.notifier).state = path
                      .split(RegExp(r'[/\\]'))
                      .last
                      .split('.')
                      .first
                      .toLowerCase();
                }

                // Avoid the "Do not use BuildContexts across async gaps."
                // warning.

                if (!context.mounted) return;
                Navigator.pop(context, 'Local File');

                // Access the PageController via Riverpod and move to the second page.
                //
                // 20250226 gjw For now we try not moving to the dataset page
                // just yet. On a Mac there are reports of a grey ROLES
                // page. That could be because the R code is not yet finished
                // and some kind of time out. Or the dataset load has a
                // problem. By staying on the OVERVIEW we mightreduce the
                // liklihood?

                await ref.read(pageControllerProvider).animateToPage(
                      // Index of the second page.
                      1,
                      duration: const Duration(milliseconds: 300),
                      curve: Curves.easeInOut,
                    );
              },
              child: const MarkdownTooltip(
                message: '''

                **Local File:** Tap here to popup a window so that you can
                browse to a local **csv**, **xlsx**, or **txt** file that you
                would like to load into Rattle.

                ''',
                child: Text('Local File'),
              ),
            ),

            buttonGap,

            ElevatedButton(
              onPressed: () async {
                String? folderPath = await datasetSelectFolder();
                debugPrint('FOLDER PATH: $folderPath');
                if (folderPath != null && folderPath.isNotEmpty) {
                  // Store the folder path for later use.

                  ref.read(pathProvider.notifier).state = folderPath;

                  // Call the corpus loading code.
                  //
                  // Add the session_library as session_startup is not called
                  // for loading a corpus and in saving the SCRIPT package
                  // magrittr has not been loaded from the library. (gjw
                  // 20250507)

                  if (!context.mounted) return;

                  String sl = 'session_library';
                  String ss = 'session_setup';
                  String lc = 'dataset_load_corpus';
                  await rSource(context, ref, [sl, ss, lc]);

                  // Save the dataset name in lowercase to the dsnameProvider
                  // from the path.

                  ref.read(dsnameProvider.notifier).state = folderPath
                      .split(RegExp(r'[/\\]'))
                      .last
                      .split('.')
                      .first
                      .toLowerCase();

                  if (!context.mounted) return;
                  Navigator.pop(context, 'Local Corpus');

                  // Set appropriate status.

                  setStatus(ref, statusChooseVariableRoles);
                  datasetLoadedUpdate(ref);

                  // Access the PageController via Riverpod and move to the second page.
                  await ref.read(pageControllerProvider).animateToPage(
                        // Index of the second page.
                        1,
                        duration: const Duration(milliseconds: 300),
                        curve: Curves.easeInOut,
                      );
                }
              },
              child: const MarkdownTooltip(
                message: '''

                **Local Corpus:** Tap here to popup a window so that you can
                browse to a local folder containing text documents (**txt**)
                that you would like to **Text Mine**. At present only text
                files ending in **.txt** are supported by Rattle.

                ''',
                child: Text('Local Corpus'),
              ),
            ),

            buttonGap,

            ElevatedButton(
              // 20250205 gjw Disable the PACKAGE button for now until we move
              // the generation of the list of available datasets in R
              // packages from home.dart on startup to here with the button
              // press.
              //
              onPressed: null,
              style: ElevatedButton.styleFrom(
                backgroundColor:
                    Colors.grey, // Background color when disabled
                foregroundColor: Colors.white, // Text color when disabled
              ),
              // onPressed: () async {
              //   // scrape the packages
              //   String stdout = ref.read(stdoutProvider);
              //   String content =
              //       rExtract(stdout, '> package_datasets_cleaned');
              //   Map<String, List<String>> map = parsePackage(content);
              //   String path = await datasetSelectPackage(context, map, ref);
              //   if (path.isNotEmpty) {
              //     // ref.read(pathProvider.notifier).state = path;
              //     if (context.mounted) await rLoadDataset(context, ref);
              //     setStatus(ref, statusChooseVariableRoles);
              //     datasetLoadedUpdate(ref);
              //   }
              //   if (!context.mounted) return;
              //   Navigator.pop(context, 'Package');

              //   // Access the PageController via Riverpod and move to the second page.

              //   ref.read(pageControllerProvider).animateToPage(
              //         // Index of the second page.

              //         1,
              //         duration: const Duration(milliseconds: 300),
              //         curve: Curves.easeInOut,
              //       );
              // },
              child: const MarkdownTooltip(
                message: '''

                **Under Development** Eventually you will be able to tap here
                to popup a window to browse the list of available R datasets
                to choose one of them to load into Rattle.

                ''',
                child: Text('Package'),
              ),
            ),
          ],
        ),

        configRowGap,

        const MarkdownTooltip(
          message: '''

                **Demo Datasets** Rattle provides a number of small datasets
                so you can very quickly explore the Rattle functionality.  The
                *buttons* below will load one of the demo datasets. Hover over
                any of them to see a description of that dataset.

                ''',
          child: MarkdownBody(
            data: '**Demo Datasets:** '
                'Tap one of the following buttons to load one of the available demonstration datasets.',
          ),
        ),

        configRowGap,

        //  Buttons for selecting the demo dataset.
        Consumer(
          builder: (context, ref, child) {
            return Row(
              mainAxisAlignment: MainAxisAlignment.spaceAround,
              children: [
                buttonGap,
                MarkdownTooltip(
                  message: '''

                    **Weather:** Tap here to load a dataset that captures one
                    year of daily observations from a weather station in
                    Canberra, Australia. It is useful to demonstrate all steps
                    of the Data Science process, to **Explore**,
                    **Transform**, **Model**, and **Evaluate**. The **binary**
                    target variable for predictive modelling is *Rain
                    Tomorrow* with the amount of rain recored as **Risk
                    MM**. Most of the remaining variables can be used as
                    inputs for building a **Decision Tree**.

                    This is a subset of the full dataset available from
                    Togaware as
                    [weatherAus.csv](https://rattle.togaware.com/weatherAUS.csv). This
                    dataset has been collected from the Australian Bureau of
                    Meterology since 2007, covering over 50 weather stations
                    across Australia.

                    The **csv** file is available as
                    [weather.csv](https://github.com/gjwgit/rattleng/blob/dev/assets/data/weather.csv).

                    ''',
                  child: ElevatedButton(
                    onPressed: () async {
                      await loadDemoDataset(
                        ref,
                        context,
                        'data/weather.csv',
                        'Weather',
                      );

                      // Access the PageController via Riverpod and move to the second page.

                      await ref.read(pageControllerProvider).animateToPage(
                            // Index of the second page.
                            1,
                            duration: const Duration(milliseconds: 300),
                            curve: Curves.easeInOut,
                          );
                    },
                    child: const Text('Weather'),
                  ),
                ),
                buttonGap,
                MarkdownTooltip(
                  message: '''

                    **Weather 2007:** Tap here to load a dataset that captures
                    one year of daily observations from a weather station in
                    Canberra, Australia in 2007 (as used in Rattle V5). It is
                    useful to compare Rattle V6 with rattle V5 using the same
                    dataset.

                    The **csv** file is available as
                    [weather_2007.csv](https://github.com/gjwgit/rattleng/blob/dev/assets/data/weather_2007.csv).

                    ''',
                  child: ElevatedButton(
                    onPressed: () async {
                      await loadDemoDataset(
                        ref,
                        context,
                        'data/weather_2007.csv',
                        '2007',
                      );

                      // Access the PageController via Riverpod and move to the second page.

                      await ref.read(pageControllerProvider).animateToPage(
                            // Index of the second page.
                            1,
                            duration: const Duration(milliseconds: 300),
                            curve: Curves.easeInOut,
                          );
                    },
                    child: const Text('2007'),
                  ),
                ),
                buttonGap,
                MarkdownTooltip(
                  message: '''

                   **Audit:** Tap here to load a dataset for predicting
                    whether a govenrment revenue authority might need to audit
                    a taxpayer. The dataset consists of 2,000 fictional tax
                    payers who have previously been audited. It includes their
                    demographics and financial variables. The target variable
                    *Adjusted* records whether their financial data had to be
                    adjusted because their originally submitted data had
                    errors affting their tax obligation. The variable
                    *Adjustment* is the dollar amount of the adjustment - the
                    adjustment to their tax liability.

                    A **predictive** model could be used to predict the
                    likelihood of an audit of a tax payer resulting in an
                    adjustment. Auditors can thus not waste their time on
                    non-productive audits.

                    The **csv** file is available as
                    [audit.csv](https://github.com/gjwgit/rattleng/blob/dev/assets/data/audit.csv).

                    ''',
                  child: ElevatedButton(
                    onPressed: () async {
                      await loadDemoDataset(
                        ref,
                        context,
                        'data/audit.csv',
                        'Audit',
                      );

                      // Access the PageController via Riverpod and move to the second page.

                      await ref.read(pageControllerProvider).animateToPage(
                            // Index of the second page.
                            1,
                            duration: const Duration(milliseconds: 300),
                            curve: Curves.easeInOut,
                          );
                    },
                    child: const Text('Audit'),
                  ),
                ),
                buttonGap,
                MarkdownTooltip(
                  message: '''

                    **Protein:** Tap here to load this dataset from the
                    [Tippie College of Business, The University of
                    Iowa](http://www.biz.uiowa.edu/faculty/jledolter/DataMining/protein.csv). It
                    is useful for demonstrating **Cluster** analysis.

                    The **csv** file is available as
                    [protien.csv](https://github.com/gjwgit/rattleng/blob/dev/assets/data/protein.csv).

                    ''',
                  child: ElevatedButton(
                    onPressed: () async {
                      await loadDemoDataset(
                        ref,
                        context,
                        'data/protein.csv',
                        'Protein',
                      );

                      // Access the PageController via Riverpod and move to the second page.

                      await ref.read(pageControllerProvider).animateToPage(
                            // Index of the second page.
                            1,
                            duration: const Duration(milliseconds: 300),
                            curve: Curves.easeInOut,
                          );
                    },
                    child: const Text('Protein'),
                  ),
                ),
                buttonGap,
                MarkdownTooltip(
                  message: '''

                    **Movies:** Tap here to load this dataset of some
                    favourite movies. The dataset is useful for demonstrating
                    basket analysis available through the **Associations**
                    feature of the **Model** tab. The dataset has just two
                    columns, a **basket** which identifies a basket, and an
                    **item** which names an item contained in a basket. Thus,
                    each basket is uniquley identified and each basket can
                    contain 1 or more items.

                    The **csv** file is available as
                    [movies.csv](https://github.com/gjwgit/rattleng/blob/dev/assets/data/movies.csv).

                    ''',
                  child: ElevatedButton(
                    onPressed: () async {
                      await loadDemoDataset(
                        ref,
                        context,
                        'data/movies.csv',
                        'Movies',
                      );

                      // Access the PageController via Riverpod and move to the second page.

                      await ref.read(pageControllerProvider).animateToPage(
                            // Index of the second page.
                            1,
                            duration: const Duration(milliseconds: 300),
                            curve: Curves.easeInOut,
                          );
                    },
                    child: const Text('Movies'),
                  ),
                ),
                buttonGap,
                MarkdownTooltip(
                  message: '''

                    **Sherlock:** Tap here to load this text file for
                    demonstrating the **Word Cloud** feature of the **Model**
                    tab. It is a snippet from a Sherlock Holmes novel.

                    The **txt** file is available as
                    [sherlock.txt](https://github.com/gjwgit/rattleng/blob/dev/assets/data/sherlock.txt).

                    ''',
                  child: ElevatedButton(
                    onPressed: () async {
                      await loadDemoDataset(
                        ref,
                        context,
                        'data/sherlock.txt',
                        'Sherlock',
                      );

                      // Access the PageController via Riverpod and move to the second page.

                      await ref.read(pageControllerProvider).animateToPage(
                            // Index of the second page.
                            1,
                            duration: const Duration(milliseconds: 300),
                            curve: Curves.easeInOut,
                          );
                    },
                    child: const Text('Sherlock'),
                  ),
                ),
                buttonGap,
                MarkdownTooltip(
                  message: '''

                    **US Population:** Tap here to load a rather large dataset
                    from the U.S. Census Bureau, Population Division. The
                    variables are described
                    [there](https://www2.census.gov/programs-surveys/popest/datasets/2010-2016/counties/totals/co-est2016-alldata.pdf).

                    The **csv** file is available as
                    [co-est2016-alldata.csv](https://github.com/gjwgit/rattleng/blob/dev/assets/data/co-est2016-alldata.csv).

                    ''',
                  child: ElevatedButton(
                    onPressed: () async {
                      await loadDemoDataset(
                        ref,
                        context,
                        'data/co-est2016-alldata.csv',
                        'US Population',
                      );

                      // Access the PageController via Riverpod and move to the second page.

                      await ref.read(pageControllerProvider).animateToPage(
                            // Index of the second page.
                            1,
                            duration: const Duration(milliseconds: 300),
                            curve: Curves.easeInOut,
                          );
                    },
                    child: const Text('US Population'),
                  ),
                ),
              ],
            );
          },
        ),

        // SPACE between row of options and the cancel button.
        configRowGap,

        // Add a CANCEL button to do nothing but return.
        Row(
          mainAxisAlignment: MainAxisAlignment.end,
          children: [
            ElevatedButton(
              onPressed: () {
                Navigator.pop(context, 'Cancel');
              },
              child: const MarkdownTooltip(
                message: '''

                **Cancel:** Tap here to **not** proceed with loading a new
                  dataset.

                ''',
                child: Text('Cancel'),
              ),
            ),
          ],
        ),
      ],
    ),
  );
}