Code Monkey home page Code Monkey logo

bmds-server's People

Stargazers

 avatar

Watchers

 avatar  avatar  avatar  avatar

bmds-server's Issues

for model selection, add "reset" button

ex

Add a new "reset" button that will reset the model selections to the default values. This would be the same values that are selected when a user changes the "Model Type".

I'm not sure where to put this button; feel free to place where it makes sense.

Asynchronous word/excel reports with toast display

Reporting can sometimes take a long time, especially with the formatting requested.

The download Excel and download Report capabilities may not return a synchronous response anymore as they currently do. Instead, If this is the first request, we will schedule a task to the redis job-queue for a report to be created, and a JSON response of pending will be submitted to indicate the job is ongoing. When the job is complete, it will report a docx/xlsx report. If the job has already completed and the report is cached, it may return on the first response.

Work started on #88; @bishwobhandari can tackle the frontend and myself or @rabstejnek can handle the backend.

specify models to run in the input settings

I’ll add a new option for “models”, which will be required. To get the tool with outputs in the current format, you would set to “default”, otherwise you can set to an array of objects. Each object will be a model name, and I’ll have to add a way to specify custom model settings for that model. For example, you should be able to do something like this:

{
 "models": [
    {"name": "Polynomial", "model_settings": {"degree": 2}},
    {"name": "Polynomial", "model_settings": {"degree": 3}},
    {"name": "Polynomial", "model_settings": {"degree": 4}}
  ],
}

Or this:

{
 "models": "default"
}

add optional identifier to datasets

Each dataset will have an optional identifier field, which can be a string or a number. This will be carried thorough to the outputs as well

Fix plotly issue where chart goes negative

Investigate why the x and y axes are incorrect on the plotly plot when things are changed. Determine if a fix can be made, and if so, fix it, otherwise document the issue.

Steps to recreate:

  1. Create a new dataset
  2. Change the "dose units" to non-empty text. After doing so, x and y axes on the plotly figure go from 1-6 and -1 to 4, instead of the true values

Before:
Screen Shot 2021-04-19 at 3 01 23 PM

After (with bug):
Screen Shot 2021-04-19 at 3 01 32 PM

show model-averaging summary data on "modal" on "results" table

When clicking a modal average summary result, the modal table will look different than standard model detail pages.

Please build the following data tables in the screenshot, including the prior column (shown on the summary table) as well:
image

In addition, the CDF table and plot should be shown, as well as the model dose-response visual being created in #121

revise Excel export

Akin to #127; update the Excel export so that the same summary data is shown in Excel exports. This is also higher priority than #128

revise data entry form

Update data entry form using the attached mockup:

Untitled Diagram (1)

  • remove the modal for dataset selection type
  • the "import datasets" does not yet do anything
  • the plot size can just be a placeholder for now
  • when creating a new dataset, by default create 5 rows
  • use fa-trash from font awesome instead of 'x'
  • the "save dataset" button which was previously present is no longer needed

On the data store, try to exactly mirror the structure of how the datasets object is returned from the server. Then it will be easy to pass the data back and forth

The components should roughly be (this is rough; feel free to change)

<DatasetFormContainer>
    <DatasetSelector/>
    <DatasetForm/>
    <DatasetScatterplot/>
<DatasetFormContainer/>

There will also be a selectedDatasetIndex, and whenever a new dataset is created or a different dataset is selected, this will update, and will change what is displayed on the DatasetForm and DatasetScatterplot visual components.

The layout above is rough and minor changes are fine, though keeping the three column layout is preferred if possible.

Update word report to mirror the html output tables

Make word output more consistent with changes in the output html page:

  • ensure summary output tables between frequentist and bayesian models are separated #120
  • add model averaging results table similar to the modal akin to #125
  • Add a placeholder for the model averaging plot if needed; this can be a separate PR.

Note that the effort required for this will likely result in a PR in both this repository and https://github.com/shapiromatron/bmds

Create different DoseResponsePlots for analysis types (frequentist vs bayesian)

Previously, a single dose-response plot (and table) visualized all model outputs for frequentist and bayesian models. This plot was removed in #120, and should be restored with updated functionality.

  • Previously had one DoseResponsePlot src/components/common/DoseResponsePlot.js
  • We'll now create two plots a Frequentist Plot and a Bayesian Plot. These can be the same react component if they make sense, or could be separate components, whatever is easier to implement
  • The frequentist plot will have the same behavior as the previous dose response plot. If a frequentist model is selected, then it will always be shown. If a user hovers over a row in the table, it will be shown. This feature does not currently work, so it will need to be restored.
  • The bayesian plot will show all curves at the same time for bayesian data. There will be no changes when hovering. They should all be a lighter color blue with a thinner line. There is no selected-best fitting model for bayesian. In addition, we will also show a "model average" curve which will be a darker blue with a thicker line. In the future this will come from an additional dataset, but for now, just assume the model-average curve is the first row in the bayesian table.

We'll only show the frequentist table when frequentist models exist, and only show the bayesian table when bayesian models exist.

add read-only view for model and dataset views

Currently we've worked on the view where a user is configuring a bmds session and executing it. However there's also a read-only view of a bmds-session where settings cannot be configured or executed and should only be presented instead.

In this case, we'll need to present all form-based components in a read-only table style view. For example, the options or model selections should just be static tables. All buttons for saving, loading, or running, should be hidden, etc.

You can determine which mode we are in by reading the config on the page; if there's no editSettings component in the config, then we're in the read-only view. https://github.com/shapiromatron/bmds-server/blob/master/bmds_server/jobrunner/views.py#L51-L66

Update scales and legend layout for some datasets

This dataset demonstrates some visual behaviors that need to be fixed:

Dose	N	Mean	Std. Dev.
0	9	3302.8	410.9
0.05	10	3342.5	545.57
0.15	10	3342.5	800.35
0.5	10	1625	504.98

image

Items to change:

  • For continuous datasets, set the max y value based on the maximum mean value plus the confidence interval, and the min y value based on the minimum mean value minus the confidence interval, instead of just the mean value. I think dichotomous fixes the min/max between 0 and 1, but let me know if that's incorrect
  • The legend in this example should not be in the top-left but the top right - can we programmatically determine legend location? Maybe if the maximum y's x value is < the dose midpoint, make top right, else top left?
  • If user changes the plotly x/y scale and then hovers over a different model, the scale changes are lost. Instead, is it possible to just pass in new data instead of layout as well?

new header and footer styles for integration w/ EPA site

The header and footer for this application will be revised away from the default bootstrap4. A subsequent task will make the header and footer styles configurable based on settings configured at the application level so that we can use the EPA branding or more generic branding.

Read-only "logic" tab

Currently the "logic" tab when in read only mode is still an editable form. Modify to make a read-only view, like was done with other tabs.

continuous model setting restraints

Re-enable the "lognormal" setting.

In addition:

  • If lognormal is selected in any model option set, deselect and disable the Power, Polynomial, and Linear model
  • If lognomal is not selected in any model option set, enable the Power, Polynomial, and Linear model

Suggestion - create new computed boolean prop in the optionStore - hasLognormalDistribution.

There should be no changes for dichotomous datasets, just continuous.

This is higher priority that #128.

update bmds model selection and provide defaults

This is a collection of related updates on the user-interface for the "main" page.

  • Update how the bmds model checkbox logic is selected. Ideally, this would be done using a more react and mobx style way where the function event handlers. Suggest making helper method setModelSelection("frequentist_restricted", "Gamma", e.target.checked) that basically adds or removes the model (2nd argument) from the array (1st argument). That way we dont have to manage any intermediate state. This change should remove a fair amount of code and complexity.
  • When new session is created or model_type changes, create a default option set
  • When new session is created or model_type changes, change default selected models. These are the defaults:
    • dich
      • freq rest: dich hill, gamma, log logistic, multistage, weibull
      • freq unrest: logistic, logprobit, probit, quantal linear
    • continuous
      • freq rest: exp, hill, poly, power
      • freq unrest: linear
  • Remove bayesian model average for continuous data (but keep bayesian); keep both bayesian options for dichotomous data. We will likely add this feature back in future versions of the tool, but they are 1+ yr away (so if you can hide gracefully might be good)
  • The defaults when a new instance is created can be specified on the backend by updating thebmds_server.jobrunner.models.Job.default_input method, though if factored correctly it's probably less redundant to do it using the same handlers as the model_type change handler

prompt user to save before Run works

Users (understandably) didn't understand why an analysis couldn't be executed prior to saving.

Update this additional check and change the language at the top:

image

load analysis

create a button for loading analysis to load a json file.
hydrate the store with json file settings.

Revise summary tables for recommended models

The recommended model summary text takes up too much room and makes it hard to view results.

Thus, we will adjust layout using a few approaches:
Screen Shot 2021-07-13 at 10 51 37 AM

  • Modify the "Recommendation and notes" column so there are two different display types, which is toggleable
    • Put a button inside the header cell to show "collapsed" or "expanded" form, just use fa-eye and fa-eye-slash as an icon
    • Default to the collapsed view
    • The expanded view is the current view
      • No changes are required
    • The collapsed view
      • should show only the getModelBinLabel value, with no getRecommenderText
      • There should be a HelpTextPopover component that shows the
        • The title should be getModelBinLabel text
        • The content should be getRecommenderText

dataset plots

  • For continuous individual data, add dataset plot. Dose column is the x-axis, and response column is the y-axis
  • For all dataset plots, update the title to be the dataset name, eg., DatasetName 0
  • For all dataset plots, update the x-axis label to be the dose column name, eg., Dose
  • For all dataset plots, update the y-axis label. For continuous, Response, for continuous summary, Mean, for Dichotomous, Incidence
  • For Nested, should be plotted like dichotomous, where N = litter-size

Create "lollipop" or "dumbbell" plots in plotly

Create a plot like this showing bmdl/bmd/bmdu for frequentist models, and one for bayesian models. Each row would be a separate dose-response model (including model average), there would be up to three values for each row. Reorganize the figures so that the would take a full row and each would be col-6. Interactivity is minimal; if easy, add tooltips to show the bmd/bmdl/bmdu values.

https://towardsdatascience.com/lollipop-dumbbell-charts-with-plotly-696039d5f85

1_JiKJl07uHsbJ9KK9KUcfeQ

Update to latest javascript packages

Update dependencies in package.json to the latest versions. Do not worry about devDependencies. Test and make sure all functionality still works.

New links to download excel export and word report

A major requirement of the application is the ability to download the results of a bmds assessment in reports. We have some preliminary code that can generate these word and excel reports, but the purpose of this PR is just to stub out how users can access them and not actually connect them.

On the backend:

On the frontend:

  • create a new hamburger on the top-right on the lower "blue" navbar. A user should be able to click thew links to download Excel or Download Word. The reports should download succesfully.

Python-docx: https://python-docx.readthedocs.io/en/latest/

Link analysis selector w/ dataset selector logic

The Model type field on the Main page should filter the list of available data types on the Data page.

  • Continuous -> [C Summary or C Individual]
  • Dichotomous or D Multi Tumor -> [Dichotomous]
  • Dich Nested -> [Nested]

When a user changes the Model type, reset (aka delete) the options, datasets, and model selections which were previously made, since this is consistent with what is saved to the server.

simplify components

Review all rendered components and remove all unnecessary DOM elements and nesting.

Examples:

Update Models Store

  1. update model check box functions into smaller functions
  2. enable user input for prior weight models

use decouple instead of environment variables

Since I'm having troubles running processes with environment variables on Windows, use this library instead to store secrets.

In settings/production.py, replace all os.environ with config() calls, and create a new file to capture.

Add new "copy from Excel" option to populate dataset fields

Currently, entering a dataset into bmds-online, can be time consuming, especially if the dataset is large.

Therefore, we will add a new button named "Copy from Excel" to the "Data" tab of bmds-online. If this button is clicked, a modal with a single large textarea with a "save" button appears. A user can copy paste data from Excel into the form.

Fortunately, a copy/paste from excel is tab-delimited, eg.,

5	1	100
10	2	200
20	3	300
30	4	4000

We can parse the textarea, and if the number of columns matches the # columns for the dataset type (3 dichotomous, 2 continuous individual, 4 continuous summary), the data is saved, the modal is closed, the form/plot updates so the data are shown as well as the # row/columns.

Validation rules:

  • If the columns doesn't match, an error is shown
  • The data must be all numeric and tabular, if text is shown an error will shown

Help text:

Copy/paste data from Excel into the box below. Data must be all numeric with no headers or descriptive columns.

At any times, a user can hit save again to validate and save/close if successful or close the form.

Add model selection functionality

At the end of a BMD analysis, generally a user needs a single BMD as the "answer" for this analysis. When using the Bayesian model averaging approach, this selection will be done automatically by weighting all models based on fit and building a BMD estimate from all model weights.

However, in other cases, generally a decision logic tree is applied a model is recommend for selection. A user must manually select a best-fitting model however, and they need the ability to potentially override the selection.

Therefore, we'll need to update the UI to account for this. On the outputs tab, after a model has executed and results are shown:

  • Add new select name="selected_model_index" input, where options are add model indexes. Also add a -1 option (the default) with the option text none
  • Add new <textarea name="selected_model_notes"> input, where a user can add notes to describe why a model was selected
  • Add a "save" button to save to server (this can just be a stub to be implemented later
  • When a model is selected, update the output table and highlight the selected model with the <tr class="table-success">...</tr> class in bootstrap
  • When a model is selected, show the selected model on the output plot in blue. Continue to allow showing the hover models too, but the selected should always be shown (ok to bundle this subtask with #74 instead)

Update plotly dose-response and CDF layout

Refine how the plotly plots are currently rendered:

  • Update plot on the detail model to show the select dose-responne model (it is currently not showing)
  • Update the CDF chart to be a dot+line chart instead of a scatterplot
  • Fix the size of the plot
    • make the plot reactive and wider instead of capping at 400px so it fix the screen size
    • update layout.margin settings so the plot is as large as possible showing labels margin: {l: 50, r: 5, t: 50, b: 50}
    • update layout labels so that the correct x/y are shown based on dataset
    • update layout.legend so it's inside the plot, eg.,
      legend: {yanchor: "top", y: 0.99, xanchor: "left", x: 0.01}
    • remove grey background and override text options for labels/title

update model output table

Update the model output table for selected datasets. Currently, all model outputs regardless of model type (frequentist restricted, frequentist unrestricted, bayesian) are shown in a single output table and intermingled. Instead, we'll show frequentist models in one table, and bayesian models in a separate table. In additional, a table subheading will be shown for frequentist restricted and frequentist unrestricted models. See screenshots below:

image

The backend has to be updated with additional metadata to place models in the correct place; this will be done in a subsequent PR. For now, assume all output models are all three types; so the UI will show duplicate rows in different places until the backend has been revised; that's ok for the purposes of this PR...

split data store into substores

Our DataStore.js file has grown very large and now contains multiple different independent stores. Let's split the current DataStore.js into multiple files and combine them into a single root store, using a pattern similar to this:

https://mobx.js.org/best/store.html#combining-multiple-stores

class RootStore {
    constructor() {
        this.userStore = new UserStore(this)
        this.todoStore = new TodoStore(this)
    }
}

class UserStore {
    constructor(rootStore) {
        this.rootStore = rootStore
    }

    getTodos(user) {
        // access todoStore through the root store
        return this.rootStore.todoStore.todos.filter(todo => todo.author === user)
    }
}

class TodoStore {
    @observable todos = []

    constructor(rootStore) {
        this.rootStore = rootStore
    }
}

BMDS logic tab

The goal of this PR is to replicate the functionality of the Logic tab in the BMDS 3.1.2 excel software. In the future, the backend will support accepting data from the frontend with these data.

We'll need to create a new tab in a bmds setting and build a form similar to the Excel spreadsheet. This PR should be able to configure all options as expected, with outputs synced w/ the store.

// constants
const BINS = Object.freeze({
        NO_CHANGE: 0,
        WARNING: 1,
        FAILURE: 2,
    }),
    RULE_NAMES = Object.freeze({
        BMD_MISSING: "bmd_missing",
        BMDL_MISSING: "bmdl_missing",
        BMDU_MISSING: "bmdu_missing",
        AIC_MISSING: "aic_missing",
        ROI_MISSING: "roi_missing",
        VARIANCE_TYPE: "variance_type",
        VARIANCE_FIT: "variance_fit",
        GOF: "gof",
        GOF_CANCER: "gof_cancer",
        BMD_BMDL_RATIO_FAIL: "bmd_bmdl_ratio_fail",
        BMD_BMDL_RATIO_WARN: "bmd_bmdl_ratio_warn",
        ROI_LARGE: "roi_large",
        WARNINGS: "warnings",
        HIGH_BMD: "high_bmd",
        HIGH_BMDL: "high_bmdl",
        LOW_BMD_WARN: "low_bmd_warn",
        LOW_BMDL_WARN: "low_bmdl_warn",
        LOW_BMD_FAIL: "low_bmd_fail",
        LOW_BMDL_FAIL: "low_bmdl_fail",
        CONTROL_RESIDUAL_HIGH: "control_residual_high",
        CONTROL_STDEV_FIT: "control_stdev_fit",
        DOF_ZERO: "dof_zero",
    });

// example settings (with defaults but can be configured in store):

const logic = {
    recommend_viable: true,
    recommend_questionable: false,
    sufficiently_close_bmdl: 3,
    rules: {
        [RULE_NAMES.BMD_MISSING]: {
            enabled_continuous: true,
            enabled_dichotomous: true,
            enabled_nested: true,
            threshold: null, // null or float
            failure_bin: BINS.FAILURE,
        },
        [RULE_NAMES.VARIANCE_FIT]: {
            enabled_continuous: true,
            enabled_dichotomous: false,
            enabled_nested: false,
            threshold: 0.05, // null or float
            failure_bin: BINS.WARNING,
        },
        // ...
    },
};

Update css styling

Please work off the next branch.

  • Consolidate almost all changes into the frontend/src/components/Main/main.css, unless they are component specific
  • In general, remove hard-coded widths, margins, etc and use boostrap classes mb-2 etc where relevant instead
  • add a global override section for bootstrap4 settings.
  • remove font-size styles

It's ok if the colors and exact layout do not match our excel prototype. We've migrated to the web and now is a good time to allow for breaking changes.

update save analysis returned data

When save-analysis is performed the data returned is already data.inputs
when fetch-analysis is performed the data returned is data.

when we checking data.inputs in updateModelStateFromApi() , the data object is different each time that is why the is Executing is not True when save analysis is performed (because data object doesn't have inputs object. the returned data are follows for each case 👍

save analysis returned data
analysis_description: ""
analysis_name: ""
bmds_version: "BMDS312"
dataset_type: "D"
datasets: [{…}]
models: {frequentist_restricted: Array(2)}
options: [{…}]

fetchAnalysis returned data
api_url: "/api/v1/job/c35c5ae6-6a5c-433f-8b60-fbd422a3c57e/"
created: "2020-06-09T15:15:17.758652Z"
ended: null
errors: ""
excel_url: "/api/v1/job/c35c5ae6-6a5c-433f-8b60-fbd422a3c57e/excel/"
has_errors: false
id: "c35c5ae6-6a5c-433f-8b60-fbd422a3c57e"
input_url: "/api/v1/job/c35c5ae6-6a5c-433f-8b60-fbd422a3c57e/inputs/"
inputs: {bmds_version: "BMDS312", analysis_name: "", analysis_description: "", dataset_type: "D", models: {…}, …}
inputs_valid: true
is_executing: false
is_finished: false
output_url: "/api/v1/job/c35c5ae6-6a5c-433f-8b60-fbd422a3c57e/outputs/"
outputs: null
preferences: ""
started: null

Create new integration tests with local execution of bmds models

We recently merged in the integration test branch after successfully testing both locally and in gtihub actions #71 .

However, the initial integration tests were stubs of tests instead of actual tests. Actual tests should be created instead. The goal of these integration tests are to demonstrate proper rendering of the javascript frontend and successful execution of the models on the backed along with state and flow functioning properly

  • integration test instructions are here, they are written for mac/linux, but could work for windows with a little adaptation
  • implement dichotomous, continuous summary and individual
  • if local integration tests are performed on windows, this line may need to be revised

Points of reference:

  • HAWC has multiple examples of integration tests using helium and selenium that might be helpful for review.
  • An older version of #71 with partially functional integration tests are available on github, in case anything may be of value there.

on the output tab, show all curve-fits on the plot at the same time

Currently on the Output tab, curve-fits are only shown on when hovering over a row in the table. Change this so that all curves are shown by default, and when one is hovered upon the color changes to black and the line width is thicker.

When hovering over a curve, change the line color or width to indicate that its being shown.

Also, it might be good to investigate the React plotly update method instead of redrawing the plot entirely; that would speed up performance and wouldn't look as choppy.

Create plot visualizations

Add simple plot visuals to the site. Write components in a way so that they're well contained, so that we can swap out the plotting library in the future as needed, as requirements may change.

Would recommend using plotly as a starting point as it's a nice high level library that has the functionality that we need, but am open to other suggestions.

store updates

Update model store:

  • remove modelName.split("-") from modelsStore; pass in appropriate data via the calling method
  • Update store to pass required content without relying on string parsing.

Update to options store:

Updates to main store:

Component updates:

common components for input forms instead of custom html

Instead of using raw html for select and input components, use some predefined components to standardize the user-interface

  • use the existing components/common/SelectInput; modify as needed to work
  • use the existing components/common/FloatInput; modify as needed to work
  • create and use components/common/IntegerInput
  • create and use components/common/TextInput
  • create and use components/common/CheckboxInput if this make sense (but only if it makes sense; I know the model selection items ones are already heavily componentized so they may be fine as is)
  • create and use components/common/LabelInput if this make sense

Migrate from custom html to these components. It's ok to not migrate over very customized inputs if needed, but we should default to using the components when possible.

Update "output" page to move results selector

Currently the output selector (the blue "Dataset #1") on the far-left takes up a lot of vertical screen-space, which is needed for some of the output plots and visualizations. Per a suggestion from @bishwobhandari ; explore changing this to a select input or potentially a horizontal pill instead of a vertical pill.

Screen Shot 2021-06-03 at 12 43 56 PM

prevent execution if settings have changed

Add a new "dirty data" flag, where if any settings have been modified, then the software cannot be executed unless the settings have been saved. For now, it may just be a new dirtyData=false flag on the main store, and if content in any store changes, set true.

This would occur if an analysis has already been executed, and a user changes input settings. Only when the results are saved and the response is successful is the dirty data flag removed.

A half-baked version is available #110; feel free to use this branch or start a new one. I had an issue when data was hydrated from the server, the dirty flag would be triggered, which isn't what we'd want

nested dichotomous frontend design

Begin designing the frontend application for the nested dichotomous model. A subsequent request will design the backend to save the data, and more work for execution later.

Here are the items, and the enum values that we'll save as state:

  • Add a new "Model Type", Nested Dichotomous (ND)
  • Dataset entry example (dose, litter_n, incidence, litter_covariate)
    image
  • Model selection options (NestedLogistic, NCTR)
    image
  • Model option sets
    image
    • risk types - added (0) or extra (1)
    • litter specific covariates - overall mean (0) or control group mean (1)
    • background - estimated (1) or zero (0)
    • bootstrap seed - integer; default to 0

The example dataset should be:

Dose	Litter Size	Incidence	Covariate
0	16	1	16
0	9	1	9
0	15	2	15
0	14	3	14
0	13	3	13
0	9	0	9
0	10	2	10
0	14	2	14
0	10	1	10
0	11	2	11
0	14	4	14
25	9	5	9
25	14	6	14
25	9	2	9
25	13	6	13
25	12	3	12
25	10	1	10
25	10	2	10
25	11	4	11
25	14	3	14
50	11	4	11
50	11	5	11
50	14	5	14
50	11	4	11
50	10	5	10
50	11	4	11
50	10	5	10
50	15	6	15
50	7	2	7

refactor options form

Consistent with #101; update the OptionsForm to use the new approach described in that PR to update how content is saved; changed. You may want to investigate use of _.set() which allows you to change items in an array., eg _.set("options[2].bmr", event.target.value)

Make dataset selection independent on Data and Output tabs

Currently the selected dataset on the Data and Output tabs are synced, that is, if a user changes the selected dataset on one tab, it persists in the other. Update so that tab changes are independent.

We'll likely keep the dataStore injection, but the input props will change so that these props which will come from the relevant store are passed in (eg; feel free to adjust):

<DatasetList
   selectedModelIndex={outputStore.selectedModelIndex}
   onChange={outputStore.handleSelectedDatasetChange} />

update outputs with new bmds format

Previously, outputs which were created in BMDS were in a format which was speculative, but more recently, the format has stabilized and should be close to final BMDS#33.

Based on these changes, output values will need to be updated in the user interface of bmds-online.

  • Update summary table to pull values from new locations
  • Update summary plot to pull values from new locations
  • Update output modal components to pull values from new locations

**Design considerations: ** Generally the data format for continuous and dichotomous datasets are pretty different. Therefore, it is appropriate to separate components for output tables as needed for each table type. If you really want to use the same component, then just bake the constants directly in the file, since they'd only be used in one place. Feel free to discuss if it'd be valuable.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.