whylabs/whylogs-python

View on GitHub
python/examples/basic/Notebook_Profile_Visualizer.ipynb

Summary

Maintainability
Test Coverage
{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    ">### 🚩 *Create a free WhyLabs account to get more value out of whylogs!*<br> \n",
    ">*Did you know you can store, visualize, and monitor whylogs profiles with the [WhyLabs Observability Platform](https://whylabs.ai/whylogs-free-signup?utm_source=whylogs-Github&utm_medium=whylogs-example&utm_campaign=Notebook_Profile_Visualizer)? Sign up for a [free WhyLabs account](https://whylabs.ai/whylogs-free-signup?utm_source=whylogs-Github&utm_medium=whylogs-example&utm_campaign=Notebook_Profile_Visualizer) to leverage the power of whylogs and WhyLabs together!*"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Drift Analysis with Profile Visualizer"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "[![Open in Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/whylabs/whylogs/blob/mainline/python/examples/basic/Notebook_Profile_Visualizer.ipynb)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "> This is a `whylogs v1` example. For the analog feature in `v0`, please refer to [this example](https://github.com/whylabs/whylogs/blob/maintenance/0.7.x/examples/Notebook_Profile_Visualizer.ipynb)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "In this notebook, we'll show how you can use whylog's Notebook Profile Visualizer to compare two different sets of the same data. This includes:\n",
    "- __Data Drift__: Detecting feature drift between two datasets' distributions\n",
    "- __Data Visualization__: Comparing feature's histograms and bar charts\n",
    "- __Summary Statistics__: Visualizing Summary Statistics of individual features"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Data Drift on Wine Quality"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "To demonstrate the Profile Visualizer, let's use [UCI's Wine Quality Dataset](https://archive.ics.uci.edu/ml/datasets/wine+quality), frequently used for learning purposes. Classification is one possible task, where we predict the wine's quality based on its features, like pH, density and percent alcohol content.\n",
    "\n",
    "In this example, we will split the available dataset in two groups: wines with alcohol content (`alcohol` feature) below and above 11. The first group is considered our baseline (or reference) dataset, while the second will be our target dataset. The goal here is to induce a case of __Sample Selection Bias__, where the training sample is not representative of the population.\n",
    "\n",
    "The example used here was inspired by the article [A Primer on Data Drift](https://medium.com/data-from-the-trenches/a-primer-on-data-drift-18789ef252a6). If you're interested in more information on this use case, or the theory behind Data Drift, it's a great read!"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Installing Dependencies"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "To use the Profile Visualizer, we'll install whylogs with the extra package `viz`:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Note: you may need to restart the kernel to use updated packages.\n",
    "%pip install 'whylogs[viz]'"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Loading the data"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>fixed acidity</th>\n",
       "      <th>volatile acidity</th>\n",
       "      <th>citric acid</th>\n",
       "      <th>residual sugar</th>\n",
       "      <th>chlorides</th>\n",
       "      <th>free sulfur dioxide</th>\n",
       "      <th>total sulfur dioxide</th>\n",
       "      <th>density</th>\n",
       "      <th>pH</th>\n",
       "      <th>sulphates</th>\n",
       "      <th>alcohol</th>\n",
       "      <th>quality</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>7.4</td>\n",
       "      <td>0.70</td>\n",
       "      <td>0.00</td>\n",
       "      <td>1.9</td>\n",
       "      <td>0.076</td>\n",
       "      <td>11.0</td>\n",
       "      <td>34.0</td>\n",
       "      <td>0.9978</td>\n",
       "      <td>3.51</td>\n",
       "      <td>0.56</td>\n",
       "      <td>9.4</td>\n",
       "      <td>5</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>7.8</td>\n",
       "      <td>0.88</td>\n",
       "      <td>0.00</td>\n",
       "      <td>2.6</td>\n",
       "      <td>0.098</td>\n",
       "      <td>25.0</td>\n",
       "      <td>67.0</td>\n",
       "      <td>0.9968</td>\n",
       "      <td>3.20</td>\n",
       "      <td>0.68</td>\n",
       "      <td>9.8</td>\n",
       "      <td>5</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>7.8</td>\n",
       "      <td>0.76</td>\n",
       "      <td>0.04</td>\n",
       "      <td>2.3</td>\n",
       "      <td>0.092</td>\n",
       "      <td>15.0</td>\n",
       "      <td>54.0</td>\n",
       "      <td>0.9970</td>\n",
       "      <td>3.26</td>\n",
       "      <td>0.65</td>\n",
       "      <td>9.8</td>\n",
       "      <td>5</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>11.2</td>\n",
       "      <td>0.28</td>\n",
       "      <td>0.56</td>\n",
       "      <td>1.9</td>\n",
       "      <td>0.075</td>\n",
       "      <td>17.0</td>\n",
       "      <td>60.0</td>\n",
       "      <td>0.9980</td>\n",
       "      <td>3.16</td>\n",
       "      <td>0.58</td>\n",
       "      <td>9.8</td>\n",
       "      <td>6</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>7.4</td>\n",
       "      <td>0.70</td>\n",
       "      <td>0.00</td>\n",
       "      <td>1.9</td>\n",
       "      <td>0.076</td>\n",
       "      <td>11.0</td>\n",
       "      <td>34.0</td>\n",
       "      <td>0.9978</td>\n",
       "      <td>3.51</td>\n",
       "      <td>0.56</td>\n",
       "      <td>9.4</td>\n",
       "      <td>5</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "   fixed acidity  volatile acidity  citric acid  residual sugar  chlorides  \\\n",
       "0            7.4              0.70         0.00             1.9      0.076   \n",
       "1            7.8              0.88         0.00             2.6      0.098   \n",
       "2            7.8              0.76         0.04             2.3      0.092   \n",
       "3           11.2              0.28         0.56             1.9      0.075   \n",
       "4            7.4              0.70         0.00             1.9      0.076   \n",
       "\n",
       "   free sulfur dioxide  total sulfur dioxide  density    pH  sulphates  \\\n",
       "0                 11.0                  34.0   0.9978  3.51       0.56   \n",
       "1                 25.0                  67.0   0.9968  3.20       0.68   \n",
       "2                 15.0                  54.0   0.9970  3.26       0.65   \n",
       "3                 17.0                  60.0   0.9980  3.16       0.58   \n",
       "4                 11.0                  34.0   0.9978  3.51       0.56   \n",
       "\n",
       "   alcohol  quality  \n",
       "0      9.4        5  \n",
       "1      9.8        5  \n",
       "2      9.8        5  \n",
       "3      9.8        6  \n",
       "4      9.4        5  "
      ]
     },
     "execution_count": 2,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "import pandas as pd\n",
    "pd.options.mode.chained_assignment = None  # Disabling false positive warning\n",
    "\n",
    "# this is the same data as encountered in http://archive.ics.uci.edu/ml/machine-learning-databases/wine-quality/winequality-red.csv\n",
    "url = \"https://whylabs-public.s3.us-west-2.amazonaws.com/whylogs_examples/WineQuality/winequality-red.csv\"\n",
    "wine = pd.read_csv(url)\n",
    "wine.head()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "<class 'pandas.core.frame.DataFrame'>\n",
      "RangeIndex: 1599 entries, 0 to 1598\n",
      "Data columns (total 12 columns):\n",
      " #   Column                Non-Null Count  Dtype  \n",
      "---  ------                --------------  -----  \n",
      " 0   fixed acidity         1599 non-null   float64\n",
      " 1   volatile acidity      1599 non-null   float64\n",
      " 2   citric acid           1599 non-null   float64\n",
      " 3   residual sugar        1599 non-null   float64\n",
      " 4   chlorides             1599 non-null   float64\n",
      " 5   free sulfur dioxide   1599 non-null   float64\n",
      " 6   total sulfur dioxide  1599 non-null   float64\n",
      " 7   density               1599 non-null   float64\n",
      " 8   pH                    1599 non-null   float64\n",
      " 9   sulphates             1599 non-null   float64\n",
      " 10  alcohol               1599 non-null   float64\n",
      " 11  quality               1599 non-null   int64  \n",
      "dtypes: float64(11), int64(1)\n",
      "memory usage: 150.0 KB\n"
     ]
    }
   ],
   "source": [
    "wine.info()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "We'll split the wines in two groups. The ones with `alcohol` below 11 will form our reference sample, and the ones above 11 will form our target dataset."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [],
   "source": [
    "cond_reference = (wine['alcohol']<=11)\n",
    "wine_reference = wine.loc[cond_reference]\n",
    "\n",
    "cond_target = (wine['alcohol']>11)\n",
    "wine_target = wine.loc[cond_target]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Let's also add some missing values to `citric acid`, to see how this is reflected in the Profile Visualizer later on."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [],
   "source": [
    "ixs = wine_target.iloc[100:110].index\n",
    "wine_target.loc[ixs,'citric acid'] = None"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The `quality` feature is a numerical one, representing the wine's quality. Let's tranform it to a categorical feature, where each wine is classified as Good or Bad. Anything above 6.5 is a good a wine. Otherwise, it's bad."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [],
   "source": [
    "import pandas as pd\n",
    "\n",
    "bins = (2, 6.5, 8)\n",
    "group_names = ['bad', 'good']\n",
    "\n",
    "wine_reference['quality'] = pd.cut(wine_reference['quality'], bins = bins, labels = group_names)\n",
    "wine_target['quality'] = pd.cut(wine_target['quality'], bins = bins, labels = group_names)\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Now, we can profile our dataframes with `whylogs`.\n",
    "The `NotebookProfileVisualizer` accepts `profile_views` as arguments. Profile views are obtained from the profiles, and are used for visualization and merging purposes."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "⚠️ No session found. Call whylogs.init() to initialize a session and authenticate. See https://docs.whylabs.ai/docs/whylabs-whylogs-init for more information.\n"
     ]
    }
   ],
   "source": [
    "import whylogs as why\n",
    "result = why.log(pandas=wine_target)\n",
    "prof_view = result.view()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [],
   "source": [
    "result_ref = why.log(pandas=wine_reference)\n",
    "prof_view_ref = result_ref.view()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Let's instantiate `NotebookProfileVisualizer` and set the reference and target profile views:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [],
   "source": [
    "from whylogs.viz import NotebookProfileVisualizer\n",
    "\n",
    "visualization = NotebookProfileVisualizer()\n",
    "visualization.set_profiles(target_profile_view=prof_view, reference_profile_view=prof_view_ref)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Now, we're able to generate all sorts of plots and reports.\n",
    "Let's take a look at some of them."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Profile Summary"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "__Profile Summary__ brings you a summary for a single profile. It requires only the existence of `target_profile_view`. The report shows simple histograms for each feature, along with key statistics, such as number of missing values, mean, minimum and maximum values."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div></div><iframe srcdoc=\"&lt;!DOCTYPE html&gt;\n",
       "&lt;html lang=&quot;en&quot;&gt;\n",
       "  &lt;head&gt;\n",
       "    &lt;meta charset=&quot;UTF-8&quot; /&gt;\n",
       "    &lt;meta http-equiv=&quot;X-UA-Compatible&quot; content=&quot;IE=edge&quot; /&gt;\n",
       "    &lt;meta name=&quot;viewport&quot; content=&quot;width=device-width, initial-scale=1.0&quot; /&gt;\n",
       "    &lt;meta name=&quot;description&quot; content=&quot;&quot; /&gt;\n",
       "    &lt;meta name=&quot;author&quot; content=&quot;&quot; /&gt;\n",
       "\n",
       "    &lt;title&gt;Profile Visualizer | whylogs&lt;/title&gt;\n",
       "\n",
       "    &lt;link rel=&quot;icon&quot; href=&quot;images/whylabs-favicon.png&quot; type=&quot;image/png&quot; sizes=&quot;16x16&quot; /&gt;\n",
       "    &lt;link rel=&quot;preconnect&quot; href=&quot;https://fonts.googleapis.com&quot; /&gt;\n",
       "    &lt;link rel=&quot;preconnect&quot; href=&quot;https://fonts.gstatic.com&quot; crossorigin /&gt;\n",
       "    &lt;link href=&quot;https://fonts.googleapis.com/css2?family=Asap:wght@400;500;600;700&amp;display=swap&quot; rel=&quot;stylesheet&quot; /&gt;\n",
       "    &lt;link rel=&quot;preconnect&quot; href=&quot;https://fonts.gstatic.com&quot; /&gt;\n",
       "    &lt;link rel=&quot;stylesheet&quot; href=&quot;https://cdn.jsdelivr.net/npm/bootstrap@5.1.0/dist/css/bootstrap.min.css&quot; /&gt;\n",
       "\n",
       "    &lt;script\n",
       "      src=&quot;https://cdnjs.cloudflare.com/ajax/libs/handlebars.js/4.7.7/handlebars.min.js&quot;\n",
       "      integrity=&quot;sha512-RNLkV3d+aLtfcpEyFG8jRbnWHxUqVZozacROI4J2F1sTaDqo1dPQYs01OMi1t1w9Y2FdbSCDSQ2ZVdAC8bzgAg==&quot;\n",
       "      crossorigin=&quot;anonymous&quot;\n",
       "      referrerpolicy=&quot;no-referrer&quot;\n",
       "    &gt;&lt;/script&gt;\n",
       "\n",
       "    &lt;style type=&quot;text/css&quot;&gt;\n",
       "      :root {\n",
       "        /* CONSTANTS */\n",
       "        --SIDE-PANEL-WIDTH: 320px;\n",
       "        --PROPERTY-PANEL-WIDTH: 420px;\n",
       "\n",
       "        /* COLOR VARIABLES */\n",
       "        /** Standard colors */\n",
       "        --red: #d11010;\n",
       "        --orange: #f07028;\n",
       "        --yellow: #faaf40;\n",
       "        --olive: #b5cc18;\n",
       "        --green: #1dbb42;\n",
       "        --teal: #00b5ad;\n",
       "        --blue: #2683c9;\n",
       "        --violet: #6435c9;\n",
       "        --purple: #a333c8;\n",
       "        --pink: #ed45a4;\n",
       "        --brown: #ac724d;\n",
       "        --grey: #778183;\n",
       "        --black: #1b1c1d;\n",
       "        --white: #ffffff;\n",
       "\n",
       "        /** Branded colors */\n",
       "        --brandPrimary900: #0e7384;\n",
       "        --brandPrimary800: #228798;\n",
       "        --brandPrimary700: #369bac;\n",
       "        --brandPrimary600: #4aafc0;\n",
       "        --brandPrimary500: #5ec3d4;\n",
       "        --brandPrimary400: #72d7e8;\n",
       "        --brandPrimary300: #86ebfc;\n",
       "        --brandPrimary200: #a6f2ff;\n",
       "        --brandPrimary100: #cdf8ff;\n",
       "        --brandSecondary900: #4f595b;\n",
       "        --brandSecondary800: #636d6f;\n",
       "        --brandSecondary700: #778183;\n",
       "        --brandSecondary600: #8b9597;\n",
       "        --brandSecondary500: #9fa9ab;\n",
       "        --brandSecondary400: #b3bdbf;\n",
       "        --brandSecondary300: #c7d1d3;\n",
       "        --brandSecondary200: #dbe5e7;\n",
       "        --brandSecondary100: #ebf2f3;\n",
       "        --secondaryLight1000: #313b3d;\n",
       "        --brandRed4: #b30000;\n",
       "        --brandRed3: #d72424;\n",
       "        --brandRed2: #eb5656;\n",
       "        --brandRed1: #ff8282;\n",
       "        --night1: #021826;\n",
       "        /** Purpose colors */\n",
       "        --textColor: #4f595b;\n",
       "        --linkColor: #369bac;\n",
       "        --infoColor: #2683c9;\n",
       "        --warningColor: #faaf40;\n",
       "        --tealBackground: #eaf2f3;\n",
       "        --pageBackground: #e5e5e5;\n",
       "        --contrastTableRow: #fafafa;\n",
       "        --whiteBackground: #ffffff;\n",
       "        --primaryBackground: #e5e5e5;\n",
       "      }\n",
       "\n",
       "      /* RESET STYLE */\n",
       "      *,\n",
       "      *::after,\n",
       "      *::before {\n",
       "        margin: 0;\n",
       "        padding: 0;\n",
       "        box-sizing: border-box;\n",
       "        font-family: &quot;Asap&quot;, Arial, Helvetica, sans-serif;\n",
       "      }\n",
       "\n",
       "      /*\n",
       "      * Main content\n",
       "      */\n",
       "      .main {\n",
       "        position: relative;\n",
       "        background: #FFFFFF;\n",
       "        border: 1px solid #DBE5E7;\n",
       "        box-sizing: border-box;\n",
       "        border-radius: 4px;\n",
       "      }\n",
       "      .main .page-header {\n",
       "        margin-top: 0;\n",
       "      }\n",
       "\n",
       "      /* CSS DIV TABLE BASIC STYLE */\n",
       "\n",
       "      .wl-table-row .wl-table-head:first-child {\n",
       "        min-width: 360px;\n",
       "        z-index: 2;\n",
       "      }\n",
       "\n",
       "      .wl-table-wrap {\n",
       "        position: relative;\n",
       "      }\n",
       "\n",
       "      .wl-table {\n",
       "        display: table;\n",
       "        width: 100%;\n",
       "      }\n",
       "\n",
       "      .row&gt;* {\n",
       "        padding-right: 0 !important;\n",
       "        padding-left: 0 !important;\n",
       "      }\n",
       "\n",
       "      .wl-table-row {\n",
       "        display: table-row;\n",
       "      }\n",
       "\n",
       "      .wl-table-row:hover,\n",
       "      .wl-table-row:hover .wl-table-cell:first-child {\n",
       "        background-color: var(--brandSecondary100);\n",
       "      }\n",
       "      .wl-table-row--clickable:hover .wl-table-cell__title-button {\n",
       "        visibility: visible;\n",
       "      }\n",
       "\n",
       "      .wl-table-heading {\n",
       "        position: sticky;\n",
       "        top: 0;\n",
       "        z-index: 900;\n",
       "        display: table-header-group;\n",
       "        font-weight: 700;\n",
       "      }\n",
       "\n",
       "      .wl-table-cell,\n",
       "      .wl-table-head {\n",
       "        border-bottom: 1px solid var(--brandSecondary200);\n",
       "        display: table-cell;\n",
       "        padding: 12px 18px;\n",
       "      }\n",
       "\n",
       "      .wl-table-cell {\n",
       "        font-size: 14px;\n",
       "      }\n",
       "\n",
       "      .wl-table-cell--top-spacing {\n",
       "        padding-top: 35px; /* cell-top-padding + cell-title-height */\n",
       "      }\n",
       "\n",
       "      .wl-table-head-wraper {\n",
       "        background-color: var(--white);\n",
       "      }\n",
       "\n",
       "      .wl-table-head {\n",
       "        position: sticky;\n",
       "        left: 0;\n",
       "        min-width: 100px;\n",
       "        border-bottom: 2px solid var(--brandSecondary100);\n",
       "        font-size: 12px;\n",
       "        line-height: 1.67;\n",
       "        white-space: nowrap;\n",
       "      }\n",
       "\n",
       "      .wl-sub-table-head {\n",
       "        position: relative;\n",
       "      }\n",
       "\n",
       "      .wl-table-body {\n",
       "        display: table-row-group;\n",
       "      }\n",
       "\n",
       "      .wl-table-row .wl-table-cell:first-child{\n",
       "        position: sticky;\n",
       "        left: 0;\n",
       "        background-color: var(--white);\n",
       "        border-right-width: 2px;\n",
       "      }\n",
       "\n",
       "      /* Table custom style */\n",
       "\n",
       "      .wl-table-cell__title-wrap {\n",
       "        display: flex;\n",
       "        justify-content: space-between;\n",
       "      }\n",
       "\n",
       "      .wl-table-cell__title {\n",
       "        height: 25px;\n",
       "        margin: 0;\n",
       "        font-size: 14px;\n",
       "        font-weight: 700;\n",
       "        overflow: hidden;\n",
       "        white-space: nowrap;\n",
       "        text-overflow: ellipsis;\n",
       "      }\n",
       "\n",
       "      .wl-table-cell__bedge-wrap {\n",
       "        padding: 2px 0;\n",
       "        white-space: nowrap;\n",
       "        overflow: hidden;\n",
       "        font-style: italic;\n",
       "        text-align: center;\n",
       "        color: var(--brandSecondary400);\n",
       "      }\n",
       "      .wl-table-cell__bedge {\n",
       "        height: 24px;\n",
       "        margin: 1px;\n",
       "        padding: 2px 8px;\n",
       "        border: 1px solid var(--brandSecondary400);\n",
       "        font-style: normal;\n",
       "        color: var(--brandSecondary900);\n",
       "        border-radius: 20px;\n",
       "        white-space: nowrap;\n",
       "      }\n",
       "\n",
       "      /* Property side panel */\n",
       "\n",
       "      .wl-compare-profile {\n",
       "        z-index: 999;\n",
       "        position: absolute;\n",
       "        right: 0;\n",
       "        background: var(--white);;\n",
       "        border-bottom: 1px solid var(--brandSecondary200);\n",
       "      }\n",
       "\n",
       "      /* Screen on smaller screens */\n",
       "      .no-responsive {\n",
       "        display: none;\n",
       "        position: fixed;\n",
       "        top: 0;\n",
       "        left: 0;\n",
       "        z-index: 1031;\n",
       "        width: 100vw;\n",
       "        height: 100vh;\n",
       "        background-color: var(--tealBackground);\n",
       "        display: flex;\n",
       "        align-items: center;\n",
       "        justify-content: center;\n",
       "      }\n",
       "\n",
       "      .no-responsive__content {\n",
       "        max-width: 600px;\n",
       "        width: 100%;\n",
       "        padding: 0 24px;\n",
       "      }\n",
       "\n",
       "      .no-responsive__title {\n",
       "        font-size: 96px;\n",
       "        font-weight: 300;\n",
       "        color: var(--brandSecondary900);\n",
       "        line-height: 1.167;\n",
       "      }\n",
       "\n",
       "      .no-responsive__text {\n",
       "        margin: 0;\n",
       "        font-size: 16px;\n",
       "        font-weight: 400;\n",
       "        color: var(--brandSecondary900);\n",
       "        line-height: 1.5;\n",
       "      }\n",
       "\n",
       "      .space-between {\n",
       "        display: flex;\n",
       "        justify-content: space-between;\n",
       "      }\n",
       "\n",
       "      .align-items {\n",
       "        display: flex;\n",
       "        align-items: center;\n",
       "      }\n",
       "\n",
       "      .display-flex{\n",
       "        display: flex;\n",
       "      }\n",
       "\n",
       "      .table-border-none {\n",
       "        padding: 0;\n",
       "        border: none;\n",
       "      }\n",
       "\n",
       "      .flex-direction-colum {\n",
       "        display: flex;\n",
       "        flex-direction: column;\n",
       "      }\n",
       "\n",
       "      .align-items {\n",
       "        align-items: center;\n",
       "      }\n",
       "\n",
       "      .search-input{\n",
       "        padding-top: 0 !important;\n",
       "        padding-bottom: 0 !important;\n",
       "      }\n",
       "\n",
       "      .search-input input{\n",
       "        border: none;\n",
       "        background: none;\n",
       "        outline: none;\n",
       "        height: 40px;\n",
       "        width: 100%;\n",
       "        font-size: 14px;\n",
       "      }\n",
       "\n",
       "      .search-input img{\n",
       "        height: 19px;\n",
       "        pointer-events: none;\n",
       "      }\n",
       "\n",
       "      input::placeholder {\n",
       "        color: var(--secondaryLight1000);\n",
       "      }\n",
       "\n",
       "      .text-align-center {\n",
       "        text-align: center;\n",
       "      }\n",
       "\n",
       "      .text-align-end {\n",
       "        text-align: end;\n",
       "      }\n",
       "\n",
       "      .drift-detection {\n",
       "        justify-content: space-between;\n",
       "        align-items: center;\n",
       "      }\n",
       "\n",
       "     .drift-detection-info-circle {\n",
       "       width: 15px;\n",
       "       height: 15px;\n",
       "       border-radius: 50px;\n",
       "       display: inline-block;\n",
       "       margin-right: 8px;\n",
       "     }\n",
       "\n",
       "     .severe-drift-circle-color {\n",
       "         background: #D40D00;\n",
       "     }\n",
       "\n",
       "     .moderate-drift-circle-color {\n",
       "         background: #F5843C;\n",
       "     }\n",
       "\n",
       "     .mild-drift-circle-color {\n",
       "         background: #F2C142;\n",
       "     }\n",
       "\n",
       "     .minimal-drift-circle-color {\n",
       "         background: #ABCA52;\n",
       "     }\n",
       "\n",
       "     .drift-detection-info-drifts-item {\n",
       "         padding-right: 20px;\n",
       "     }\n",
       "\n",
       "     .drift-detection-info-title {\n",
       "       font-family: Arial;\n",
       "       font-weight: bold;\n",
       "       font-size: 16px;\n",
       "       line-height: 130%;\n",
       "       color: #313B3D;\n",
       "     }\n",
       "\n",
       "     .drift-detection-info-drifts-item-count {\n",
       "       font-family: Arial;\n",
       "       font-weight: bold;\n",
       "       font-size: 14px;\n",
       "       line-height: 16px;\n",
       "       color: #000000;\n",
       "       padding-right: 8px;\n",
       "     }\n",
       "\n",
       "     .drift-detection-info-drifts-item-name {\n",
       "       font-family: Arial;\n",
       "       font-style: normal;\n",
       "       font-weight: normal;\n",
       "       font-size: 12px;\n",
       "       line-height: 14px;\n",
       "       color: #000000;\n",
       "     }\n",
       "\n",
       "     .drift-detection-info-drifts-item-range {\n",
       "       font-family: Arial;\n",
       "       font-style: normal;\n",
       "       font-weight: normal;\n",
       "       font-size: 11px;\n",
       "       line-height: 13px;\n",
       "       color: #6C757D;\n",
       "     }\n",
       "\n",
       "     .drift-detection-search-input {\n",
       "       display: flex;\n",
       "       align-items: center;\n",
       "       background: rgba(255, 255, 255, 0.7);\n",
       "       border: 1px solid #DBE5E7;\n",
       "       box-sizing: border-box;\n",
       "       border-radius: 4px;\n",
       "       width: 170px;\n",
       "       padding-left: 10px;\n",
       "     }\n",
       "\n",
       "     .drift-detection-search-input img{\n",
       "       margin-right: 5px;\n",
       "     }\n",
       "\n",
       "     .drift-detection-search-input input::placeholder {\n",
       "       font-family: Arial;\n",
       "       font-weight: normal;\n",
       "       font-size: 13px;\n",
       "       line-height: 16px;\n",
       "       color: #313B3D;\n",
       "     }\n",
       "\n",
       "     .close-filter-button {\n",
       "       display: flex;\n",
       "       justify-content: center;\n",
       "       align-items: center;\n",
       "       background: rgba(255, 255, 255, 0.7);\n",
       "       border: 1px solid #369BAC;\n",
       "       box-sizing: border-box;\n",
       "       border-radius: 4px;\n",
       "       width: 40px;\n",
       "       height: 40px;\n",
       "       cursor: pointer;\n",
       "       margin-left: 10px;\n",
       "     }\n",
       "\n",
       "     .filter-options-title {\n",
       "       width: 240px;\n",
       "     }\n",
       "\n",
       "     .filter-options-title p {\n",
       "       margin: 0;\n",
       "     }\n",
       "\n",
       "     .dropdown-container {\n",
       "       position: absolute;\n",
       "       right: 18px;\n",
       "       z-index: 999;\n",
       "       background: #FFFFFF;\n",
       "       border: 1px solid #DBE5E7;\n",
       "       box-sizing: border-box;\n",
       "       box-shadow: 0px 2px 8px rgba(0, 0, 0, 0.05);\n",
       "       border-radius: 4px;\n",
       "       padding: 10px !important;\n",
       "       border: none !important;\n",
       "     }\n",
       "\n",
       "     .form-check-input:checked {\n",
       "       background-color: #0E7384;\n",
       "       border-color: #0E7384;\n",
       "     }\n",
       "\n",
       "     .form-check-input[type=checkbox] {\n",
       "       border-radius: 2px;\n",
       "     }\n",
       "\n",
       "      .justify-content-center {\n",
       "        justify-content: center;\n",
       "      }\n",
       "\n",
       "      .wl-table-cell__graph-wrap {\n",
       "        width: 0;\n",
       "      }\n",
       "\n",
       "      .svg-container {\n",
       "        display: inline-block;\n",
       "        position: relative;\n",
       "        width: 85%;\n",
       "        padding-bottom: 17%;\n",
       "        vertical-align: top;\n",
       "        overflow: hidden;\n",
       "      }\n",
       "\n",
       "      .svg-content-responsive {\n",
       "        display: inline-block;\n",
       "        position: absolute;\n",
       "        left: 0;\n",
       "      }\n",
       "\n",
       "      .reference-table-head {\n",
       "        min-width: 250px;\n",
       "      }\n",
       "\n",
       "      .wl__dropdown_arrow-icon {\n",
       "        position: relative;\n",
       "      }\n",
       "\n",
       "      .notif-circle-container{\n",
       "        position: absolute;\n",
       "        top: -4px;\n",
       "        right: -4px;\n",
       "        padding: 5.3px;\n",
       "        border-radius: 50%;\n",
       "        background-color: white;\n",
       "        cursor: pointer;\n",
       "      }\n",
       "\n",
       "      .notif-circle {\n",
       "        position: absolute;\n",
       "        top: 2px;\n",
       "        right: 2px;\n",
       "        padding: 3.3px;\n",
       "        border-radius: 50%;\n",
       "        background-color: #F2994A;\n",
       "      }\n",
       "\n",
       "\n",
       "      .header-title {\n",
       "        font-size: 26px;\n",
       "        font-weight: 700;\n",
       "        color: #444444;\n",
       "      }\n",
       "\n",
       "      .statistic-number-title {\n",
       "        font-family: Arial;\n",
       "        font-weight: normal;\n",
       "        font-size: 14px;\n",
       "        line-height: 20px;\n",
       "        color: #6C757D;\n",
       "      }\n",
       "\n",
       "      .statistic-number {\n",
       "        font-family: Arial;\n",
       "        font-weight: bold;\n",
       "        font-size: 20px;\n",
       "        line-height: 140%;\n",
       "        display: flex;\n",
       "        align-items: center;\n",
       "        color: #0E7384;\n",
       "      }\n",
       "\n",
       "      .statistic-measurement {\n",
       "        font-size: 15px !important;\n",
       "        margin-left: 3px;\n",
       "      }\n",
       "\n",
       "      .statistic-measurement-percent {\n",
       "        font-size: 15px !important;\n",
       "      }\n",
       "\n",
       "      .question-mark {\n",
       "        font-size: 10px;\n",
       "        font-weight: 900;\n",
       "        color: #0E7384;\n",
       "        border-radius: 50px;\n",
       "        border: 2px solid #0E7384;\n",
       "        padding: 0px 4px;\n",
       "        transition: 0.5s;\n",
       "        cursor: pointer;\n",
       "      }\n",
       "\n",
       "      .question-mark:hover {\n",
       "        color: white;\n",
       "        background: #0E7384;\n",
       "        border: 2px solid none;\n",
       "        transition: 0.5s;\n",
       "      }\n",
       "\n",
       "      .tooltip-full-number {\n",
       "        position: relative;\n",
       "        display: inline-block;\n",
       "      }\n",
       "\n",
       "      .tooltip-full-number .tooltiptext {\n",
       "        visibility: hidden;\n",
       "        background: black;\n",
       "        color: white;\n",
       "        border: 1px solid black;\n",
       "        text-align: start;\n",
       "        padding: 3px;\n",
       "        position: absolute;\n",
       "        z-index: 1002;\n",
       "        top: 0;\n",
       "        left: 100%;\n",
       "        margin-left: 5px;\n",
       "        opacity: 0;\n",
       "        transition: opacity 0.5s;\n",
       "        font-size: 13px;\n",
       "        font-weight: normal;\n",
       "        line-height: 100%;\n",
       "      }\n",
       "\n",
       "      .tooltip-full-number:hover .tooltiptext {\n",
       "        visibility: visible;\n",
       "        opacity: 1;\n",
       "      }\n",
       "\n",
       "      .display-flex {\n",
       "        display: flex;\n",
       "      }\n",
       "\n",
       "      .flex-direction-column {\n",
       "        flex-direction: column;\n",
       "      }\n",
       "\n",
       "      .justify-content-space-between {\n",
       "        justify-content: space-between;\n",
       "      }\n",
       "\n",
       "      .justify-content-center {\n",
       "        justify-content: center;\n",
       "      }\n",
       "\n",
       "      .align-items-center {\n",
       "        align-items: center;\n",
       "      }\n",
       "\n",
       "      .padding-right-30 {\n",
       "        padding-right: 30px;\n",
       "      }\n",
       "\n",
       "      .padding-5 {\n",
       "        padding: 5px;\n",
       "      }\n",
       "\n",
       "      .text-color {\n",
       "        color: var(--secondaryLight1000);\n",
       "      }\n",
       "\n",
       "      .error-message {\n",
       "        display: flex;\n",
       "        justify-content: center;\n",
       "        align-items: center;\n",
       "        color: rgb(255, 114, 71);\n",
       "        font-size: 30px;\n",
       "        font-weight: 900;\n",
       "      }\n",
       "\n",
       "      @media screen and (min-width: 500px) {\n",
       "        .desktop-content {\n",
       "          display: block;\n",
       "        }\n",
       "        .no-responsive {\n",
       "          display: none;\n",
       "        }\n",
       "      }\n",
       "    &lt;/style&gt;\n",
       "  &lt;/head&gt;\n",
       "\n",
       "  &lt;body id=&quot;generated-html&quot;&gt;&lt;/body&gt;\n",
       "\n",
       "  &lt;script id=&quot;entry-template&quot; type=&quot;text/x-handlebars-template&quot;&gt;\n",
       "    \n",
       "      &lt;div class=&quot;desktop-content&quot;&gt;\n",
       "        &lt;div class=&quot;container-fluid&quot;&gt;\n",
       "          &lt;div class=&quot;feature-summary-statistics-wrap&quot;&gt;\n",
       "            &lt;div class=&quot;feature-summary-statistics&quot;&gt;\n",
       "              &lt;div class=&quot;mb-4&quot;&gt;\n",
       "                  &lt;strong class=&quot;header-title&quot;&gt;Profile Summary&lt;/strong&gt;\n",
       "              &lt;/div&gt;\n",
       "              &lt;div class=&quot;display-flex statistics&quot;&gt;\n",
       "                &lt;div class=&quot;padding-right-30&quot;&gt;\n",
       "                  &lt;div class=&quot;statistic-number-title&quot;&gt;Observations\n",
       "                    &lt;div class=&quot;tooltip-full-number&quot;&gt;\n",
       "                      &lt;span class=&quot;question-mark&quot;&gt;?&lt;/span&gt;\n",
       "                    &lt;span class=&quot;tooltiptext&quot;&gt;\n",
       "                     &lt;div class=&quot;mb-1&quot;&gt;The sum of counts for each feature. For a single dataframe, it is equal to the number of cells, i.e., rows * columns.&lt;/div&gt;\n",
       "                    &lt;/span&gt;\n",
       "                    &lt;/div&gt;\n",
       "                    &lt;/div&gt;\n",
       "                  &lt;div class=&quot;statistic-number&quot;&gt;{{{observations this}}}&lt;/div&gt;\n",
       "                &lt;/div&gt;\n",
       "                &lt;div class=&quot;padding-right-30&quot;&gt;\n",
       "                  &lt;div class=&quot;statistic-number-title&quot;&gt;Missing Cells&lt;/div&gt;\n",
       "                  &lt;div class=&quot;statistic-number&quot;&gt;\n",
       "                    {{{missingCells this}}}\n",
       "                    &lt;div&gt;{{{missingCellsPercentage this}}}&lt;/div&gt;\n",
       "                  &lt;/div&gt;\n",
       "                &lt;/div&gt;\n",
       "                &lt;div class=&quot;wl-compare-profile&quot; id=&quot;compare-profile&quot; style=&quot;display: flex; justify-content: space-around&quot;&gt;\n",
       "                  &lt;div class=&quot;drift-detection-wrap&quot;&gt;\n",
       "                    &lt;div class=&quot;drift-detection display-flex&quot;&gt;\n",
       "                      &lt;div class=&quot;drift-detection-search-input-wrap display-flex&quot;&gt;\n",
       "                        &lt;div class=&quot;drift-detection-search-input search-input &quot;&gt;\n",
       "                          &lt;input type=&quot;text&quot; id=&quot;wl__feature-search&quot; placeholder=&quot;Quick search...&quot;/&gt;\n",
       "                          &lt;img src=&quot;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAGdSURBVHgBpZK7TkJBEIZnZoVocdTYyQNALxpNKPQBMEaNJsbCRMKhl8ISWwt6AaksCF5iTHgAGhJD4AHkAaAzGiwUsjvOQnO4SYh/cXbPzO43OxcEj9Zy92EiFSXNIfvPyE1kKFfdoxJMENpP6DrvLC0vJoEwCgwto7DWcxoIIHBYbA3NmKwnDltjAeuZhyul1DaTTlfPB6Nt5Z53DOgky4P875+nlctY2+unjZviLklkJhi5bPUa3y/7qJuQUM7PinMy7CdQc1Gh16vnBxPzrMROmlKQEgKNASAHLQCmSIGpS75O+O5pdQAgVXaIqTkNwDDXHmcnW3VmHZoGMLoTsOt88+NrAMCIZdu+iLTyTwKRa1Md6YKfOgXbzO7K8sWku5u5RxcRV5EpPezrzcHGbXEXWaUkgkweZ/UC9YrK3zqggFw5FBZfm8EUavHj7AjAKpIvBDrGn+pNnlcyhYgqbcC41idr1gvB4SdZkDbzQa21gwv0Vj07aPTtL07XdDOyDXohCDNoHIRmAVRie20f+RKybRDQDvxHkXy/7b/DrayncLbMwQAAAABJRU5ErkJggg==&quot;/&gt;\n",
       "                        &lt;/div&gt;\n",
       "                        &lt;div class=&quot;wl__dropdown_arrow-icon&quot; &gt;\n",
       "                          &lt;div onclick=&quot;openFilter()&quot; class=&quot;close-filter-button&quot;&gt;\n",
       "                            &lt;div class=&quot;display-flex close-filter-icon d-none&quot;&gt;\n",
       "                              &lt;img src=&quot;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAsAAAALCAYAAACprHcmAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAADFSURBVHgBfY+xDcIwEEXvnLQBZQkYAEhDwwKpEEK0CCZgAEjJCEmgjYSAygxAHTZgFRSOsyUjY5mcZFnn/+78PwBXf3+MoKWUPuYjVBPFnTwpr9t/oNJfcTfXsAhRAlDqDhhQIPYgpAqNMDqcUqSAYZT1epr9gAHt6uXshvYme4DYHQJNDKh0dD0m5WXB10Y3Fqjtuh7fROn3oREDWxfeMLyRsMnc0OgDzdduaA0Pi3Plgr7Q2kaAePeBqh6rueSNBVt6fgCwBV1JLF3rlAAAAABJRU5ErkJggg==&quot;/&gt;\n",
       "                            &lt;/div&gt;\n",
       "                            &lt;div class=&quot;display-flex filter-icon&quot;&gt;\n",
       "                              &lt;img src=&quot;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAPCAYAAADtc08vAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAACSSURBVHgBrZLBCYAwDEWTUjw7igcdwI1cxkNXUJzBEVzFAbSVKoKmaVrEB6GHJv/w+AACtRk7P9IONv1QOYUl96k0zv61m2tjARoLtSDI3EFsgIJ4uoXrMLazO72CRG2mzg/8BSdVlEjhpGZJjAWdAZJECpWalEhJSs1pHuUlMad5FFai1Lwg4Ckx1TxKIPFL8w55mEWd8VjPGAAAAABJRU5ErkJggg==&quot;/&gt;\n",
       "                            &lt;/div&gt;\n",
       "                          &lt;/div&gt;\n",
       "                          &lt;span class=&quot;notif-circle-container&quot;&gt;\n",
       "                            &lt;span class=&quot;notif-circle&quot;&gt;&lt;/span&gt;\n",
       "                          &lt;/span&gt;\n",
       "                        &lt;/div&gt;\n",
       "                      &lt;/div&gt;\n",
       "                    &lt;/div&gt;\n",
       "                  &lt;/div&gt;\n",
       "                  &lt;div class=&quot;dropdown-container flex-direction-colum mb-2 d-none&quot; id=&quot;dropdown-container&quot;&gt;\n",
       "                    &lt;div class=&quot;filter-options&quot;&gt;\n",
       "                      &lt;div class=&quot;filter-options-title space-between dropdown&quot;&gt;\n",
       "                        &lt;p&gt;Filter by type&lt;/p&gt;\n",
       "                      &lt;/div&gt;\n",
       "                      &lt;div class=&quot;form-check mb-1 mt-2&quot;&gt;\n",
       "                        &lt;input\n",
       "                          class=&quot;form-check-input wl__feature-filter-input&quot;\n",
       "                          type=&quot;checkbox&quot;\n",
       "                          name=&quot;checkbox&quot;\n",
       "                          value=&quot;Discrete&quot;\n",
       "                          id=&quot;inferredDiscrete&quot;\n",
       "                          onclick=&quot;changeDiscreteValue()&quot;\n",
       "                          checked\n",
       "                        /&gt;\n",
       "                        &lt;label class=&quot;form-check-label&quot; for=&quot;inferredDiscrete&quot;&gt;\n",
       "                          Inferred discrete (&lt;span class=&quot;wl__feature-count--discrete&quot;&gt;{{getDiscreteTypeCount}}&lt;/span&gt;)\n",
       "                        &lt;/label&gt;\n",
       "                      &lt;/div&gt;\n",
       "                      &lt;div class=&quot;form-check mb-1&quot;&gt;\n",
       "                        &lt;input\n",
       "                          class=&quot;form-check-input wl__feature-filter-input&quot;\n",
       "                          type=&quot;checkbox&quot;\n",
       "                          name=&quot;checkbox&quot;\n",
       "                          value=&quot;Non-discrete&quot;\n",
       "                          id=&quot;inferredNonDiscrete&quot;\n",
       "                          onclick=&quot;changeNonDiscreteValue()&quot;\n",
       "                          checked\n",
       "                        /&gt;\n",
       "                        &lt;label class=&quot;form-check-label&quot; for=&quot;inferredNonDiscrete&quot;&gt;\n",
       "                          Inferred non-discrete (&lt;span\n",
       "                            class=&quot;wl__feature-count--non-discrete&quot;\n",
       "                          &gt;{{getNonDiscreteTypeCount}}&lt;/span&gt;)\n",
       "                        &lt;/label&gt;\n",
       "                      &lt;/div&gt;\n",
       "                      &lt;div class=&quot;form-check mb-1&quot;&gt;\n",
       "                        &lt;input\n",
       "                          class=&quot;form-check-input wl__feature-filter-input&quot;\n",
       "                          type=&quot;checkbox&quot;\n",
       "                          name=&quot;checkbox&quot;\n",
       "                          value=&quot;Unknown&quot;\n",
       "                          id=&quot;inferredUnknown&quot;\n",
       "                          onclick=&quot;changeUnknwonValue()&quot;\n",
       "                          checked\n",
       "                        /&gt;\n",
       "                        &lt;label class=&quot;form-check-label&quot; for=&quot;inferredUnknown&quot;&gt;\n",
       "                          Unknown (&lt;span class=&quot;wl__feature-count--unknown&quot;&gt;{{getUnknownTypeCount}}&lt;/span&gt;)\n",
       "                        &lt;/label&gt;\n",
       "                      &lt;/div&gt;\n",
       "                    &lt;/div&gt;\n",
       "                  &lt;/div&gt;\n",
       "                  &lt;/div&gt;\n",
       "            &lt;/div&gt;\n",
       "          &lt;/div&gt;\n",
       "          &lt;div class=&quot;row&quot;&gt;\n",
       "            &lt;div class=&quot;main&quot;&gt;\n",
       "              &lt;div class=&quot;wl-table-wrap&quot; id=&quot;table-content&quot;&gt;\n",
       "                &lt;div class=&quot;wl-table&quot;&gt;\n",
       "                  &lt;div class=&quot;wl-table-heading&quot;&gt;\n",
       "                    &lt;div class=&quot;wl-table-row wl-table-row--bottom-shadow&quot;&gt;\n",
       "                      &lt;div class=&quot;wl-table-head wl-table-head-wraper&quot;&gt;\n",
       "                        &lt;div class=&quot;wl-table-head table-border-none graph-table-head&quot;&gt;Target&lt;/div&gt;\n",
       "                      &lt;/div&gt;\n",
       "                      &lt;div class=&quot;wl-table-head wl-table-head-wraper text-align-end&quot;&gt;Total count&lt;/div&gt;\n",
       "                      &lt;div class=&quot;wl-table-head wl-table-head-wraper text-align-end&quot;&gt;Missing&lt;/div&gt;\n",
       "                      &lt;div class=&quot;wl-table-head wl-table-head-wraper text-align-end&quot;&gt;Mean&lt;/div&gt;\n",
       "                      &lt;div class=&quot;wl-table-head wl-table-head-wraper text-align-end&quot;&gt;Min&lt;/div&gt;\n",
       "                      &lt;div class=&quot;wl-table-head wl-table-head-wraper text-align-end&quot;&gt;Max&lt;/div&gt;\n",
       "\n",
       "                    &lt;/div&gt;\n",
       "                  &lt;/div&gt;\n",
       "                  &lt;ul class=&quot;wl-table-body wl__table-body&quot; id=&quot;table-body&quot;&gt;\n",
       "{{#each this.columns}}                    &lt;li\n",
       "                    {{#if this.numberSummary}} class=&quot;wl-table-row wl-table-row--clickable&quot; {{else}} class=&quot;wl-table-row&quot; {{/if}}\n",
       "                    data-feature-name={{@key}}\n",
       "                    data-inferred-type={{inferredType this}}\n",
       "                    data-scroll-to-feature-name={{@key}}\n",
       "                  &gt;\n",
       "                      &lt;div class=&quot;wl-table-cell wl-table-cell__graph-wrap&quot;&gt;\n",
       "                        &lt;div class=&quot;wl-table-cell__title-wrap&quot;&gt;\n",
       "                          &lt;h4 class=&quot;wl-table-cell__title&quot;&gt;{{@key}}&lt;/h4&gt;\n",
       "                          &lt;div&gt;&lt;/div&gt;\n",
       "                        &lt;/div&gt;\n",
       "                          &lt;div class=&quot;display-flex&quot;&gt;\n",
       "                              {{{getGraphHtml this}}}\n",
       "                          &lt;/div&gt;\n",
       "                      &lt;/div&gt;\n",
       "                      &lt;div\n",
       "                        class=&quot;wl-table-cell wl-table-cell--top-spacing align-middle&quot;\n",
       "                      &gt;&lt;div class=&quot;text-align-end&quot;&gt;{{totalCount this}}&lt;/div&gt;&lt;/div&gt;\n",
       "                      &lt;div\n",
       "                        class=&quot;wl-table-cell wl-table-cell--top-spacing align-middle&quot;\n",
       "                      &gt;&lt;div class=&quot;text-align-end&quot;&gt;{{missing this}}&lt;/div&gt;&lt;/div&gt;\n",
       "                      &lt;div\n",
       "                        class=&quot;wl-table-cell wl-table-cell--top-spacing align-middle&quot;\n",
       "                      &gt;&lt;div class=&quot;text-align-end&quot;&gt;{{mean this}}&lt;/div&gt;&lt;/div&gt;\n",
       "                      &lt;div\n",
       "                        class=&quot;wl-table-cell wl-table-cell--top-spacing align-middle&quot;\n",
       "                      &gt;&lt;div class=&quot;text-align-end&quot;&gt;{{minimumValue this}}&lt;/div&gt;&lt;/div&gt;\n",
       "                      &lt;div\n",
       "                        class=&quot;wl-table-cell wl-table-cell--top-spacing align-middle&quot;\n",
       "                      &gt;&lt;div class=&quot;text-align-end&quot;&gt;{{maximumValue this}}&lt;/div&gt;&lt;/div&gt;\n",
       "\n",
       "                    &lt;/li&gt;\n",
       "{{/each}}                  &lt;/ul&gt;\n",
       "                &lt;/div&gt;\n",
       "              &lt;/div&gt;\n",
       "            &lt;/div&gt;\n",
       "          &lt;/div&gt;\n",
       "        &lt;/div&gt;\n",
       "      &lt;/div&gt;\n",
       "      &lt;div class=&quot;no-responsive&quot;&gt;\n",
       "        &lt;div class=&quot;no-responsive__content&quot;&gt;\n",
       "          &lt;h1 class=&quot;no-responsive__title&quot;&gt;Hold on! :)&lt;/h1&gt;\n",
       "          &lt;p class=&quot;no-responsive__text&quot;&gt;\n",
       "            It looks like your current screen size or device is not yet supported by the WhyLabs Sandbox. The Sandbox is\n",
       "            best experienced on a desktop computer. Please try maximizing this window or switching to another device. We\n",
       "            are working on adding support for a larger variety of devices.\n",
       "          &lt;/p&gt;\n",
       "        &lt;/div&gt;\n",
       "      &lt;/div&gt;\n",
       "    \n",
       "  &lt;/script&gt;\n",
       "\n",
       "  &lt;script src=&quot;https://code.jquery.com/jquery-3.6.0.min.js&quot; integrity=&quot;sha256-/xUj+3OJU5yExlq6GSYGSHk7tPXikynS7ogEvDej/m4=&quot; crossorigin=&quot;anonymous&quot;&gt;&lt;/script&gt;\n",
       "\n",
       "  &lt;script src=&quot;https://cdnjs.cloudflare.com/ajax/libs/d3/6.7.0/d3.min.js&quot; integrity=&quot;sha512-cd6CHE+XWDQ33ElJqsi0MdNte3S+bQY819f7p3NUHgwQQLXSKjE4cPZTeGNI+vaxZynk1wVU3hoHmow3m089wA==&quot; crossorigin=&quot;anonymous&quot; referrerpolicy=&quot;no-referrer&quot;&gt;&lt;/script&gt;\n",
       "\n",
       "  &lt;script&gt;\n",
       "    const getTargetProfile = () =&gt; { return {&quot;columns&quot;: {&quot;fixed acidity&quot;: {&quot;histogram&quot;: {&quot;start&quot;: 4.6, &quot;end&quot;: 15.90000159, &quot;width&quot;: 0, &quot;counts&quot;: [3, 17, 16, 17, 28, 39, 39, 30, 22, 30, 24, 35, 12, 13, 22, 23, 9, 6, 3, 4, 2, 3, 3, 2, 1, 0, 0, 0, 2, 3], &quot;max&quot;: 15.9, &quot;min&quot;: 4.6, &quot;bins&quot;: [4.6, 4.9766667196666665, 5.353333439333333, 5.730000158999999, 6.106666878666666, 6.483333598333333, 6.860000318, 7.236667037666667, 7.613333757333333, 7.990000477000001, 8.366667196666667, 8.743333916333334, 9.120000636, 9.496667355666666, 9.873334075333332, 10.250000795, 10.626667514666668, 11.003334234333334, 11.380000954, 11.756667673666666, 12.133334393333334, 12.510001113000001, 12.886667832666667, 13.263334552333333, 13.640001272000001, 14.016667991666667, 14.393334711333335, 14.770001431, 15.146668150666667, 15.523334870333334, 15.90000159], &quot;n&quot;: 408}, &quot;frequentItems&quot;: null, &quot;drift_from_ref&quot;: null, &quot;isDiscrete&quot;: false, &quot;featureStats&quot;: {&quot;total_count&quot;: 408, &quot;missing&quot;: 0, &quot;distinct&quot;: 20.588239538027807, &quot;min&quot;: 4.6, &quot;max&quot;: 15.9, &quot;range&quot;: 11.3, &quot;quantile_statistics&quot;: {&quot;fifth_percentile&quot;: 5.4, &quot;iqr&quot;: 2.7, &quot;q1&quot;: 6.7, &quot;median&quot;: 7.9, &quot;q3&quot;: 9.4, &quot;ninety_fifth_percentile&quot;: 11.6}, &quot;descriptive_statistics&quot;: {&quot;stddev&quot;: 2.013014441140909, &quot;coefficient_of_variation&quot;: 0.24676558362692394, &quot;sum&quot;: 3328.3, &quot;variance&quot;: 4.052227140241847, &quot;mean&quot;: 8.157598039215687}}}, &quot;volatile acidity&quot;: {&quot;histogram&quot;: {&quot;start&quot;: 0.12, &quot;end&quot;: 1.1150001115, &quot;width&quot;: 0, &quot;counts&quot;: [3, 8, 5, 8, 21, 32, 38, 37, 30, 35, 23, 24, 25, 23, 15, 15, 15, 14, 11, 4, 3, 3, 6, 2, 1, 2, 1, 2, 0, 2], &quot;max&quot;: 1.115, &quot;min&quot;: 0.12, &quot;bins&quot;: [0.12, 0.15316667038333331, 0.18633334076666666, 0.21950001115, 0.2526666815333333, 0.28583335191666664, 0.3190000223, 0.35216669268333334, 0.38533336306666666, 0.41850003345, 0.4516667038333333, 0.48483337421666667, 0.5180000445999999, 0.5511667149833333, 0.5843333853666667, 0.61750005575, 0.6506667261333333, 0.6838333965166666, 0.7170000669, 0.7501667372833333, 0.7833334076666666, 0.81650007805, 0.8496667484333333, 0.8828334188166667, 0.9160000892, 0.9491667595833333, 0.9823334299666666, 1.01550010035, 1.0486667707333335, 1.0818334411166668, 1.1150001115000001], &quot;n&quot;: 408}, &quot;frequentItems&quot;: null, &quot;drift_from_ref&quot;: null, &quot;isDiscrete&quot;: false, &quot;featureStats&quot;: {&quot;total_count&quot;: 408, &quot;missing&quot;: 0, &quot;distinct&quot;: 22.05882840516061, &quot;min&quot;: 0.12, &quot;max&quot;: 1.115, &quot;range&quot;: 0.995, &quot;quantile_statistics&quot;: {&quot;fifth_percentile&quot;: 0.24, &quot;iqr&quot;: 0.23999999999999994, &quot;q1&quot;: 0.34, &quot;median&quot;: 0.44, &quot;q3&quot;: 0.58, &quot;ninety_fifth_percentile&quot;: 0.8}, &quot;descriptive_statistics&quot;: {&quot;stddev&quot;: 0.17791965320497752, &quot;coefficient_of_variation&quot;: 0.3771756131540623, &quot;sum&quot;: 192.45999999999998, &quot;variance&quot;: 0.03165540299657947, &quot;mean&quot;: 0.47171568627450977}}}, &quot;citric acid&quot;: {&quot;histogram&quot;: {&quot;start&quot;: 0.0, &quot;end&quot;: 0.790000079, &quot;width&quot;: 0, &quot;counts&quot;: [57, 13, 7, 23, 10, 9, 4, 6, 7, 10, 12, 14, 28, 9, 24, 35, 11, 23, 31, 8, 10, 9, 5, 3, 8, 12, 2, 3, 4, 1], &quot;max&quot;: 0.79, &quot;min&quot;: 0.0, &quot;bins&quot;: [0.0, 0.026333335966666666, 0.05266667193333333, 0.0790000079, 0.10533334386666666, 0.13166667983333333, 0.1580000158, 0.18433335176666665, 0.21066668773333333, 0.2370000237, 0.26333335966666666, 0.2896666956333333, 0.3160000316, 0.34233336756666666, 0.3686667035333333, 0.3950000395, 0.42133337546666666, 0.4476667114333333, 0.4740000474, 0.5003333833666667, 0.5266667193333333, 0.5530000553, 0.5793333912666666, 0.6056667272333334, 0.6320000632, 0.6583333991666667, 0.6846667351333333, 0.7110000711, 0.7373334070666666, 0.7636667430333334, 0.790000079], &quot;n&quot;: 398}, &quot;frequentItems&quot;: null, &quot;drift_from_ref&quot;: null, &quot;isDiscrete&quot;: false, &quot;featureStats&quot;: {&quot;total_count&quot;: 398, &quot;missing&quot;: 10, &quot;distinct&quot;: 18.090455451204008, &quot;min&quot;: 0.0, &quot;max&quot;: 0.79, &quot;range&quot;: 0.79, &quot;quantile_statistics&quot;: {&quot;fifth_percentile&quot;: 0.0, &quot;iqr&quot;: 0.36, &quot;q1&quot;: 0.1, &quot;median&quot;: 0.34, &quot;q3&quot;: 0.46, &quot;ninety_fifth_percentile&quot;: 0.66}, &quot;descriptive_statistics&quot;: {&quot;stddev&quot;: 0.20859943016152155, &quot;coefficient_of_variation&quot;: 0.6620619872750046, &quot;sum&quot;: 125.4, &quot;variance&quot;: 0.04351372226371151, &quot;mean&quot;: 0.3150753768844221}}}, &quot;residual sugar&quot;: {&quot;histogram&quot;: {&quot;start&quot;: 0.9, &quot;end&quot;: 12.90000129, &quot;width&quot;: 0, &quot;counts&quot;: [8, 39, 118, 124, 40, 16, 11, 8, 13, 8, 4, 2, 2, 5, 3, 0, 1, 1, 3, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1], &quot;max&quot;: 12.9, &quot;min&quot;: 0.9, &quot;bins&quot;: [0.9, 1.300000043, 1.7000000860000002, 2.100000129, 2.500000172, 2.900000215, 3.3000002580000003, 3.700000301, 4.100000344000001, 4.500000387, 4.90000043, 5.300000473000001, 5.700000516000001, 6.100000559000001, 6.500000602000001, 6.900000645, 7.300000688000001, 7.700000731000001, 8.100000774, 8.500000817, 8.90000086, 9.300000903, 9.700000946000001, 10.100000989000002, 10.500001032000002, 10.900001075, 11.300001118, 11.700001161000001, 12.100001204000002, 12.500001247000002, 12.90000129], &quot;n&quot;: 408}, &quot;frequentItems&quot;: null, &quot;drift_from_ref&quot;: null, &quot;isDiscrete&quot;: false, &quot;featureStats&quot;: {&quot;total_count&quot;: 408, &quot;missing&quot;: 0, &quot;distinct&quot;: 15.931375081243552, &quot;min&quot;: 0.9, &quot;max&quot;: 12.9, &quot;range&quot;: 12.0, &quot;quantile_statistics&quot;: {&quot;fifth_percentile&quot;: 1.6, &quot;iqr&quot;: 0.7000000000000002, &quot;q1&quot;: 2.0, &quot;median&quot;: 2.3, &quot;q3&quot;: 2.7, &quot;ninety_fifth_percentile&quot;: 5.15}, &quot;descriptive_statistics&quot;: {&quot;stddev&quot;: 1.2990000858665753, &quot;coefficient_of_variation&quot;: 0.49437249664993493, &quot;sum&quot;: 1072.05, &quot;variance&quot;: 1.6874012230813702, &quot;mean&quot;: 2.6275735294117646}}}, &quot;chlorides&quot;: {&quot;histogram&quot;: {&quot;start&quot;: 0.012, &quot;end&quot;: 0.230000023, &quot;width&quot;: 0, &quot;counts&quot;: [2, 0, 0, 9, 21, 40, 45, 76, 64, 43, 33, 21, 20, 8, 9, 9, 3, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 1], &quot;max&quot;: 0.23, &quot;min&quot;: 0.012, &quot;bins&quot;: [0.012, 0.019266667433333332, 0.026533334866666668, 0.0338000023, 0.04106666973333333, 0.04833333716666667, 0.0556000046, 0.06286667203333333, 0.07013333946666667, 0.0774000069, 0.08466667433333333, 0.09193334176666666, 0.0992000092, 0.10646667663333333, 0.11373334406666666, 0.12100001149999999, 0.12826667893333332, 0.13553334636666667, 0.14280001380000001, 0.15006668123333333, 0.15733334866666668, 0.1646000161, 0.17186668353333334, 0.17913335096666666, 0.1864000184, 0.19366668583333332, 0.20093335326666667, 0.2082000207, 0.21546668813333333, 0.22273335556666665, 0.230000023], &quot;n&quot;: 408}, &quot;frequentItems&quot;: null, &quot;drift_from_ref&quot;: null, &quot;isDiscrete&quot;: false, &quot;featureStats&quot;: {&quot;total_count&quot;: 408, &quot;missing&quot;: 0, &quot;distinct&quot;: 21.813730257594944, &quot;min&quot;: 0.012, &quot;max&quot;: 0.23, &quot;range&quot;: 0.218, &quot;quantile_statistics&quot;: {&quot;fifth_percentile&quot;: 0.046, &quot;iqr&quot;: 0.025999999999999995, &quot;q1&quot;: 0.06, &quot;median&quot;: 0.071, &quot;q3&quot;: 0.086, &quot;ninety_fifth_percentile&quot;: 0.12}, &quot;descriptive_statistics&quot;: {&quot;stddev&quot;: 0.024213181268290383, &quot;coefficient_of_variation&quot;: 0.3226526212509791, &quot;sum&quot;: 30.618, &quot;variance&quot;: 0.0005862781471310883, &quot;mean&quot;: 0.07504411764705882}}}, &quot;free sulfur dioxide&quot;: {&quot;histogram&quot;: {&quot;start&quot;: 3.0, &quot;end&quot;: 51.0000051, &quot;width&quot;: 0, &quot;counts&quot;: [31, 79, 21, 21, 36, 16, 27, 26, 29, 22, 3, 13, 12, 11, 10, 5, 6, 4, 8, 6, 4, 8, 2, 1, 3, 0, 1, 0, 1, 2], &quot;max&quot;: 51.0, &quot;min&quot;: 3.0, &quot;bins&quot;: [3.0, 4.60000017, 6.200000340000001, 7.80000051, 9.400000680000002, 11.000000850000001, 12.60000102, 14.200001190000002, 15.800001360000001, 17.40000153, 19.000001700000002, 20.600001870000003, 22.20000204, 23.800002210000002, 25.400002380000004, 27.00000255, 28.600002720000003, 30.200002890000004, 31.80000306, 33.40000323, 35.000003400000004, 36.600003570000005, 38.20000374000001, 39.80000391, 41.40000408, 43.00000425, 44.600004420000005, 46.200004590000006, 47.80000476000001, 49.40000493, 51.0000051], &quot;n&quot;: 408}, &quot;frequentItems&quot;: null, &quot;drift_from_ref&quot;: null, &quot;isDiscrete&quot;: false, &quot;featureStats&quot;: {&quot;total_count&quot;: 408, &quot;missing&quot;: 0, &quot;distinct&quot;: 11.029412969947018, &quot;min&quot;: 3.0, &quot;max&quot;: 51.0, &quot;range&quot;: 48.0, &quot;quantile_statistics&quot;: {&quot;fifth_percentile&quot;: 3.0, &quot;iqr&quot;: 13.0, &quot;q1&quot;: 6.0, &quot;median&quot;: 13.0, &quot;q3&quot;: 19.0, &quot;ninety_fifth_percentile&quot;: 36.0}, &quot;descriptive_statistics&quot;: {&quot;stddev&quot;: 9.994223698460777, &quot;coefficient_of_variation&quot;: 0.6774056431550788, &quot;sum&quot;: 6019.5, &quot;variance&quot;: 99.884507334875, &quot;mean&quot;: 14.753676470588236}}}, &quot;total sulfur dioxide&quot;: {&quot;histogram&quot;: {&quot;start&quot;: 6.0, &quot;end&quot;: 289.0000289, &quot;width&quot;: 0, &quot;counts&quot;: [85, 92, 70, 47, 40, 14, 16, 10, 10, 10, 6, 2, 0, 0, 0, 3, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1], &quot;max&quot;: 289.0, &quot;min&quot;: 6.0, &quot;bins&quot;: [6.0, 15.433334296666667, 24.866668593333333, 34.30000289, 43.73333718666667, 53.16667148333333, 62.600005780000004, 72.03334007666666, 81.46667437333333, 90.90000867, 100.33334296666666, 109.76667726333334, 119.20001156000001, 128.63334585666666, 138.06668015333332, 147.50001445, 156.93334874666667, 166.36668304333332, 175.80001734, 185.23335163666667, 194.66668593333333, 204.10002023, 213.53335452666667, 222.96668882333333, 232.40002312000001, 241.83335741666667, 251.26669171333333, 260.70002601, 270.13336030666665, 279.56669460333336, 289.0000289], &quot;n&quot;: 408}, &quot;frequentItems&quot;: null, &quot;drift_from_ref&quot;: null, &quot;isDiscrete&quot;: false, &quot;featureStats&quot;: {&quot;total_count&quot;: 408, &quot;missing&quot;: 0, &quot;distinct&quot;: 22.303926553943704, &quot;min&quot;: 6.0, &quot;max&quot;: 289.0, &quot;range&quot;: 283.0, &quot;quantile_statistics&quot;: {&quot;fifth_percentile&quot;: 10.0, &quot;iqr&quot;: 29.0, &quot;q1&quot;: 17.0, &quot;median&quot;: 27.0, &quot;q3&quot;: 46.0, &quot;ninety_fifth_percentile&quot;: 93.0}, &quot;descriptive_statistics&quot;: {&quot;stddev&quot;: 31.68721099598923, &quot;coefficient_of_variation&quot;: 0.8554477659209692, &quot;sum&quot;: 15112.999999999998, &quot;variance&quot;: 1004.0793407043408, &quot;mean&quot;: 37.041666666666664}}}, &quot;density&quot;: {&quot;histogram&quot;: {&quot;start&quot;: 0.99007, &quot;end&quot;: 1.0032001003200002, &quot;width&quot;: 0, &quot;counts&quot;: [3, 4, 1, 9, 4, 12, 8, 32, 32, 36, 39, 49, 45, 25, 25, 19, 15, 8, 4, 8, 5, 6, 2, 5, 4, 1, 1, 2, 0, 4], &quot;max&quot;: 1.0032, &quot;min&quot;: 0.99007, &quot;bins&quot;: [0.99007, 0.9905076700106666, 0.9909453400213334, 0.991383010032, 0.9918206800426667, 0.9922583500533334, 0.992696020064, 0.9931336900746667, 0.9935713600853334, 0.9940090300960001, 0.9944467001066667, 0.9948843701173334, 0.9953220401280001, 0.9957597101386667, 0.9961973801493335, 0.9966350501600001, 0.9970727201706667, 0.9975103901813335, 0.9979480601920001, 0.9983857302026667, 0.9988234002133335, 0.9992610702240001, 0.9996987402346668, 1.0001364102453334, 1.0005740802560001, 1.0010117502666669, 1.0014494202773334, 1.0018870902880002, 1.002324760298667, 1.0027624303093334, 1.0032001003200002], &quot;n&quot;: 408}, &quot;frequentItems&quot;: null, &quot;drift_from_ref&quot;: null, &quot;isDiscrete&quot;: false, &quot;featureStats&quot;: {&quot;total_count&quot;: 408, &quot;missing&quot;: 0, &quot;distinct&quot;: 55.88238444546564, &quot;min&quot;: 0.99007, &quot;max&quot;: 1.0032, &quot;range&quot;: 0.013130000000000086, &quot;quantile_statistics&quot;: {&quot;fifth_percentile&quot;: 0.9922, &quot;iqr&quot;: 0.0023400000000000087, &quot;q1&quot;: 0.99396, &quot;median&quot;: 0.99516, &quot;q3&quot;: 0.9963, &quot;ninety_fifth_percentile&quot;: 0.9994}, &quot;descriptive_statistics&quot;: {&quot;stddev&quot;: 0.0021784570136347352, &quot;coefficient_of_variation&quot;: 0.002188682344428877, &quot;sum&quot;: 406.09385999999995, &quot;variance&quot;: 4.745674960254368e-06, &quot;mean&quot;: 0.995328088235294}}}, &quot;pH&quot;: {&quot;histogram&quot;: {&quot;start&quot;: 2.89, &quot;end&quot;: 4.010000401, &quot;width&quot;: 0, &quot;counts&quot;: [5, 1, 3, 4, 7, 5, 17, 20, 38, 36, 44, 29, 35, 41, 30, 11, 19, 17, 14, 10, 2, 9, 4, 2, 0, 1, 0, 2, 0, 2], &quot;max&quot;: 4.01, &quot;min&quot;: 2.89, &quot;bins&quot;: [2.89, 2.9273333467000002, 2.9646666934000003, 3.0020000401, 3.0393333868, 3.0766667335, 3.1140000802000003, 3.1513334269, 3.1886667736, 3.2260001203, 3.2633334670000003, 3.3006668137, 3.3380001604, 3.3753335071, 3.4126668538000002, 3.4500002005, 3.4873335472, 3.5246668939, 3.5620002406, 3.5993335873000003, 3.636666934, 3.6740002807, 3.7113336274, 3.7486669741, 3.7860003208000004, 3.8233336675, 3.8606670142, 3.8980003609000002, 3.9353337076, 3.9726670543, 4.010000401], &quot;n&quot;: 408}, &quot;frequentItems&quot;: null, &quot;drift_from_ref&quot;: null, &quot;isDiscrete&quot;: false, &quot;featureStats&quot;: {&quot;total_count&quot;: 408, &quot;missing&quot;: 0, &quot;distinct&quot;: 18.8725525817653, &quot;min&quot;: 2.89, &quot;max&quot;: 4.01, &quot;range&quot;: 1.1199999999999997, &quot;quantile_statistics&quot;: {&quot;fifth_percentile&quot;: 3.09, &quot;iqr&quot;: 0.2200000000000002, &quot;q1&quot;: 3.23, &quot;median&quot;: 3.33, &quot;q3&quot;: 3.45, &quot;ninety_fifth_percentile&quot;: 3.67}, &quot;descriptive_statistics&quot;: {&quot;stddev&quot;: 0.17649177660211463, &quot;coefficient_of_variation&quot;: 0.05273349702213279, &quot;sum&quot;: 1365.52, &quot;variance&quot;: 0.031149347208170735, &quot;mean&quot;: 3.346862745098039}}}, &quot;sulphates&quot;: {&quot;histogram&quot;: {&quot;start&quot;: 0.37, &quot;end&quot;: 1.130000113, &quot;width&quot;: 0, &quot;counts&quot;: [3, 2, 4, 4, 6, 18, 19, 45, 22, 37, 22, 32, 21, 29, 28, 27, 22, 12, 24, 7, 10, 1, 5, 1, 3, 1, 1, 0, 0, 2], &quot;max&quot;: 1.13, &quot;min&quot;: 0.37, &quot;bins&quot;: [0.37, 0.3953333371, 0.4206666742, 0.4460000113, 0.47133334839999996, 0.4966666855, 0.5220000226, 0.5473333597, 0.5726666968, 0.5980000339, 0.623333371, 0.6486667080999999, 0.6740000452, 0.6993333823, 0.7246667194, 0.7500000565, 0.7753333936, 0.8006667306999999, 0.8260000677999999, 0.8513334049, 0.8766667419999999, 0.9020000791, 0.9273334162, 0.9526667533, 0.9780000904, 1.0033334274999999, 1.0286667646, 1.0540001016999998, 1.0793334388, 1.1046667759, 1.130000113], &quot;n&quot;: 408}, &quot;frequentItems&quot;: null, &quot;drift_from_ref&quot;: null, &quot;isDiscrete&quot;: false, &quot;featureStats&quot;: {&quot;total_count&quot;: 408, &quot;missing&quot;: 0, &quot;distinct&quot;: 14.215688286897349, &quot;min&quot;: 0.37, &quot;max&quot;: 1.13, &quot;range&quot;: 0.7599999999999999, &quot;quantile_statistics&quot;: {&quot;fifth_percentile&quot;: 0.5, &quot;iqr&quot;: 0.19000000000000006, &quot;q1&quot;: 0.58, &quot;median&quot;: 0.66, &quot;q3&quot;: 0.77, &quot;ninety_fifth_percentile&quot;: 0.88}, &quot;descriptive_statistics&quot;: {&quot;stddev&quot;: 0.12701037402923776, &quot;coefficient_of_variation&quot;: 0.18776807233831805, &quot;sum&quot;: 275.97999999999996, &quot;variance&quot;: 0.016131635111046875, &quot;mean&quot;: 0.6764215686274508}}}, &quot;alcohol&quot;: {&quot;histogram&quot;: {&quot;start&quot;: 11.066666666666698, &quot;end&quot;: 14.900001490000001, &quot;width&quot;: 0, &quot;counts&quot;: [28, 68, 32, 30, 38, 29, 21, 21, 25, 12, 13, 27, 9, 17, 9, 8, 1, 3, 3, 6, 0, 0, 7, 0, 0, 0, 0, 0, 0, 1], &quot;max&quot;: 14.9, &quot;min&quot;: 11.066666666666698, &quot;bins&quot;: [11.066666666666698, 11.194444494111142, 11.322222321555586, 11.45000014900003, 11.577777976444471, 11.705555803888915, 11.833333631333359, 11.961111458777802, 12.088889286222246, 12.21666711366669, 12.344444941111133, 12.472222768555575, 12.600000596000019, 12.727778423444462, 12.855556250888906, 12.98333407833335, 13.111111905777793, 13.238889733222237, 13.36666756066668, 13.494445388111123, 13.622223215555566, 13.75000104300001, 13.877778870444454, 14.005556697888897, 14.13333452533334, 14.261112352777783, 14.388890180222226, 14.51666800766667, 14.644445835111114, 14.772223662555557, 14.900001490000001], &quot;n&quot;: 408}, &quot;frequentItems&quot;: null, &quot;drift_from_ref&quot;: null, &quot;isDiscrete&quot;: false, &quot;featureStats&quot;: {&quot;total_count&quot;: 408, &quot;missing&quot;: 0, &quot;distinct&quot;: 7.59803978178436, &quot;min&quot;: 11.066666666666698, &quot;max&quot;: 14.9, &quot;range&quot;: 3.833333333333302, &quot;quantile_statistics&quot;: {&quot;fifth_percentile&quot;: 11.1, &quot;iqr&quot;: 1.0, &quot;q1&quot;: 11.4, &quot;median&quot;: 11.8, &quot;q3&quot;: 12.4, &quot;ninety_fifth_percentile&quot;: 13.2}, &quot;descriptive_statistics&quot;: {&quot;stddev&quot;: 0.6824986635512768, &quot;coefficient_of_variation&quot;: 0.05725985668809312, &quot;sum&quot;: 4863.083333333334, &quot;variance&quot;: 0.4658044257492789, &quot;mean&quot;: 11.919321895424838}}}, &quot;quality&quot;: {&quot;histogram&quot;: null, &quot;frequentItems&quot;: [{&quot;value&quot;: &quot;bad&quot;, &quot;estimate&quot;: 267}, {&quot;value&quot;: &quot;good&quot;, &quot;estimate&quot;: 141}], &quot;drift_from_ref&quot;: null, &quot;isDiscrete&quot;: true, &quot;featureStats&quot;: {&quot;total_count&quot;: 408, &quot;missing&quot;: 0, &quot;distinct&quot;: 0.4901960796487877, &quot;min&quot;: NaN, &quot;max&quot;: NaN, &quot;range&quot;: NaN, &quot;quantile_statistics&quot;: null, &quot;descriptive_statistics&quot;: {&quot;stddev&quot;: null, &quot;coefficient_of_variation&quot;: null, &quot;sum&quot;: null, &quot;variance&quot;: null, &quot;mean&quot;: null}}}}, &quot;properties&quot;: {&quot;observations&quot;: 4896, &quot;missing_cells&quot;: 10, &quot;missing_percentage&quot;: 0.20424836601307192}} }\n",
       "    const targetProfile = getTargetProfile()\n",
       "\n",
       "    function fixNumberTo(number, decimals = 3) {\n",
       "      const fractionalDigits = String(number % 1).split(&#x27;&#x27;).slice(2, 2 + decimals).join(&#x27;&#x27;)\n",
       "      return `${Math.trunc(number)}.${fractionalDigits}`\n",
       "    }\n",
       "\n",
       "    function registerHandlebarHelperFunctions() {\n",
       "      //helper fun\n",
       "\n",
       "      class GenerateChartParams {\n",
       "        constructor(height, width, data, bottomMargin=20, topMargin=5) {\n",
       "          this.MARGIN = {\n",
       "            TOP: topMargin,\n",
       "            RIGHT: 5,\n",
       "            BOTTOM: bottomMargin,\n",
       "            LEFT: 55,\n",
       "          };\n",
       "          this.SVG_WIDTH = width;\n",
       "          this.SVG_HEIGHT = height;\n",
       "          this.CHART_WIDTH = this.SVG_WIDTH - this.MARGIN.LEFT - this.MARGIN.RIGHT;\n",
       "          this.CHART_HEIGHT = this.SVG_HEIGHT - this.MARGIN.TOP - this.MARGIN.BOTTOM;\n",
       "          this.svgEl = d3.create(&quot;svg&quot;)\n",
       "             .attr(&quot;preserveAspectRatio&quot;, &quot;xMinYMin meet&quot;)\n",
       "             .attr(&quot;viewBox&quot;, &quot;30 0 240 400&quot;)\n",
       "             .classed(&quot;svg-content-responsive&quot;, true)\n",
       "          this.maxYValue = d3.max(data, (d) =&gt; Math.abs(d.axisY));\n",
       "          this.xScale = d3\n",
       "            .scaleBand()\n",
       "            .domain(data.map((d) =&gt; d.axisX))\n",
       "            .range([this.MARGIN.LEFT, this.MARGIN.LEFT + this.CHART_WIDTH]);\n",
       "          this.yScale = d3\n",
       "            .scaleLinear()\n",
       "            .domain([0, this.maxYValue * 1.02])\n",
       "            .range([this.CHART_HEIGHT, 0]);\n",
       "        }\n",
       "      }\n",
       "\n",
       "      function generateChart(data, height = 70, width = 250, index = 0, referenceProfileExist = false) {\n",
       "        const sizes = new GenerateChartParams(height, width, data, 5)\n",
       "        const {\n",
       "          MARGIN,\n",
       "          SVG_WIDTH,\n",
       "          SVG_HEIGHT,\n",
       "          CHART_WIDTH,\n",
       "          CHART_HEIGHT,\n",
       "          svgEl,\n",
       "          maxYValue,\n",
       "          xScale,\n",
       "          yScale\n",
       "        } = sizes\n",
       "        const rectColors = [&quot;#44C0E7&quot;, &quot;#F5843C&quot;]\n",
       "\n",
       "        // Add the y Axis\n",
       "        if (!referenceProfileExist) {\n",
       "          svgEl\n",
       "            .append(&quot;g&quot;)\n",
       "            .attr(&quot;transform&quot;, &quot;translate(&quot; + MARGIN.LEFT + &quot;, &quot; + MARGIN.TOP + &quot;)&quot;)\n",
       "            .call(d3.axisLeft(yScale).tickValues([0, maxYValue/2, maxYValue]))\n",
       "            .selectAll(&quot;text&quot;)\n",
       "            .style(&quot;font-size&quot;, &quot;8&quot;)\n",
       "        }\n",
       "\n",
       "        const gChart = svgEl.append(&quot;g&quot;);\n",
       "        gChart\n",
       "          .attr(&quot;transform&quot;, &quot;translate(&quot; + 20 + &quot;, &quot; + 0 + &quot;)&quot;)\n",
       "          .selectAll(&quot;.bar&quot;)\n",
       "          .data(data)\n",
       "          .enter()\n",
       "          .append(&quot;rect&quot;)\n",
       "          .classed(&quot;bar&quot;, true)\n",
       "          .attr(&quot;width&quot;, xScale.bandwidth() - 1)\n",
       "          .attr(&quot;height&quot;, (d) =&gt; CHART_HEIGHT - yScale(d.axisY))\n",
       "          .attr(&quot;x&quot;, (d) =&gt; xScale(d.axisX))\n",
       "          .attr(&quot;y&quot;, (d) =&gt; yScale(d.axisY) + MARGIN.TOP)\n",
       "          .attr(&quot;fill&quot;, rectColors[index]);\n",
       "\n",
       "        return svgEl._groups[0][0].outerHTML;\n",
       "      }\n",
       "\n",
       "      function chartData(column) {\n",
       "        const data = [];\n",
       "        if (column.histogram) {\n",
       "          column.histogram.counts.slice(0, 30).forEach((count, index) =&gt; {\n",
       "            data.push({\n",
       "              axisY: count,\n",
       "              axisX: index,\n",
       "            });\n",
       "          });\n",
       "        } else if (column.frequentItems) {\n",
       "          Object.entries(column.frequentItems).forEach(([key, {value, estimate}], index) =&gt; {\n",
       "              data.push({\n",
       "                axisY: estimate,\n",
       "                axisX: value,\n",
       "              });\n",
       "            });\n",
       "        }\n",
       "\n",
       "        return data\n",
       "      }\n",
       "\n",
       "      function graph(column, key, referenceColumn) {\n",
       "        let data = [];\n",
       "        const columnKey = key.data.key\n",
       "        let chartValue = false\n",
       "        let chartColor = undefined\n",
       "        if(!!referenceColumn){\n",
       "          column = referenceColumn.columns[columnKey]\n",
       "          chartValue = true\n",
       "          chartColor = 1\n",
       "        } else if (referenceColumn === undefined) {\n",
       "          column = &quot;&quot;\n",
       "        }\n",
       "\n",
       "        if (column.histogram || column.frequentItems) {\n",
       "          data = chartData(column)\n",
       "        } else if (referenceColumn === null ) {\n",
       "            $(&quot;.svg-container&quot;).css(&quot;padding-bottom&quot;, &quot;0&quot;)\n",
       "            return &#x27;&lt;span class=&quot;wl-table-cell__bedge-wrap&quot;&gt;No data to show the chart&lt;/span&gt;&#x27;;\n",
       "        } else if (referenceColumn === undefined) {\n",
       "            $(document).ready(function() {\n",
       "              $(&quot;.reference-table-head&quot;).addClass(&quot;d-none&quot;)\n",
       "            });\n",
       "            return &#x27;&#x27;\n",
       "        } else if (referenceColumn.frequentItems === undefined){\n",
       "            return &#x27;&#x27;;\n",
       "        }\n",
       "        return `\n",
       "          &lt;div class=&quot;svg-container&quot;&gt;\n",
       "            ${generateChart(data, ...[,,], chartColor, chartValue)}\n",
       "          &lt;/div&gt;\n",
       "        `;\n",
       "      }\n",
       "\n",
       "      function formatLabelDate(timestamp) {\n",
       "        const date = new Date(timestamp);\n",
       "        const format = d3.timeFormat(&quot;%Y-%m-%d %I:%M:%S %p %Z&quot;);\n",
       "        return format(date);\n",
       "      }\n",
       "\n",
       "    abbreviate_number = function(value, fixed = 0) {\n",
       "      value = +value\n",
       "      if (value === null) { return null; } // terminate early\n",
       "      if (value === 0) { return &#x27;0&#x27;; } // terminate early\n",
       "      fixed = (!fixed || fixed &lt; 0) ? 0 : fixed; // number of decimal places to show\n",
       "      var b = (value).toPrecision(2).split(&quot;e&quot;), // get power\n",
       "          k = b.length === 1 ? 0 : Math.floor(Math.min(b[1].slice(1), 14) / 3), // floor at decimals, ceiling at trillions\n",
       "          c = k &lt; 1 ? value.toFixed(0 + fixed) : (value / Math.pow(10, k * 3) ).toFixed(1 + fixed), // divide by power\n",
       "          d = c &lt; 0 ? c : Math.abs(c), // enforce -0 is 0\n",
       "          newValue = d,\n",
       "          suffixe = [&#x27;&#x27;, &#x27;K&#x27;, &#x27;M&#x27;, &#x27;B&#x27;, &#x27;T&#x27;][k]; // append power\n",
       "      return {value, newValue, suffixe};\n",
       "    }\n",
       "\n",
       "     function formatBytes(bytes, decimals = 2) {\n",
       "       let newValue,\n",
       "       suffixe = &quot;&quot;\n",
       "       if (bytes === 0) return &#x27;0 Bytes&#x27;;\n",
       "\n",
       "       const k = 1024;\n",
       "       const dm = decimals &lt; 0 ? 0 : decimals;\n",
       "       const sizes = [&#x27;Bytes&#x27;, &#x27;KiB&#x27;, &#x27;MB&#x27;, &#x27;GB&#x27;, &#x27;TB&#x27;, &#x27;PB&#x27;, &#x27;EB&#x27;, &#x27;ZB&#x27;, &#x27;YB&#x27;];\n",
       "\n",
       "       const i = Math.floor(Math.log(bytes) / Math.log(k));\n",
       "       newValue = parseFloat((bytes / Math.pow(k, i)).toFixed(dm));\n",
       "       suffixe = sizes[i]\n",
       "       return {bytes, newValue, suffixe};\n",
       "     }\n",
       "\n",
       "     const valueSuffixe = (newNumber) =&gt; `\n",
       "       &lt;div class=&quot;statistic-measurement&quot;&gt;\n",
       "        ${newNumber}\n",
       "       &lt;/div&gt;`\n",
       "     const valueNumber = (newNumber) =&gt; `\n",
       "       &lt;div class=&quot;statistic-number&quot;&gt;\n",
       "        ${newNumber}\n",
       "       &lt;/div&gt;`\n",
       "\n",
       "     const numberWithSuffixe = (number, newNumber, suffixe) =&gt;\n",
       "       `&lt;div class=&quot;tooltip-full-number&quot;&gt;\n",
       "          &lt;div class=&quot;statistic-number&quot;&gt;\n",
       "             ${newNumber}\n",
       "            &lt;div class=&quot;statistic-measurement&quot;&gt;${suffixe}&lt;/div&gt;\n",
       "          &lt;/div&gt;\n",
       "          &lt;span class=&quot;tooltiptext&quot;&gt;${number}&lt;/span&gt;\n",
       "        &lt;/div&gt;`\n",
       "\n",
       "     Handlebars.registerHelper(&quot;observations&quot;, function (properties) {\n",
       "       const {value, newValue, suffixe} = abbreviate_number(targetProfile.properties.observations)\n",
       "       return numberWithSuffixe(value, valueNumber(newValue), valueNumber(suffixe));\n",
       "     });\n",
       "\n",
       "     Handlebars.registerHelper(&quot;missingCells&quot;, function (properties) {\n",
       "       const {value, newValue, suffixe} = abbreviate_number(targetProfile.properties.missing_cells)\n",
       "       if (typeof value !== &#x27;undefined&#x27; &amp;&amp; typeof newValue !== &#x27;undefined&#x27;  &amp;&amp; typeof suffixe !== &#x27;undefined&#x27; ) {\n",
       "        return numberWithSuffixe(value, valueSuffixe(`${newValue}`), suffixe);\n",
       "       }\n",
       "       return numberWithSuffixe(0, valueNumber(0), valueNumber(&#x27;&#x27;));\n",
       "     });\n",
       "\n",
       "     Handlebars.registerHelper(&quot;missingCellsPercentage&quot;, function (properties) {\n",
       "       const {value, newValue, suffixe} = abbreviate_number(targetProfile.properties.missing_percentage)\n",
       "       if (typeof value !== &#x27;undefined&#x27; &amp;&amp; typeof newValue !== &#x27;undefined&#x27;  &amp;&amp; typeof suffixe !== &#x27;undefined&#x27; ) {\n",
       "        return numberWithSuffixe(value, valueSuffixe(`(${newValue}%)`), suffixe);\n",
       "       }\n",
       "       return numberWithSuffixe(0, valueSuffixe(`(${0}%)`), &#x27;&#x27;);\n",
       "     });\n",
       "\n",
       "     Handlebars.registerHelper(&quot;getProfileTimeStamp&quot;, function (properties) {\n",
       "       return formatLabelDate(+properties.properties.dataTimestamp)\n",
       "     });\n",
       "\n",
       "     Handlebars.registerHelper(&quot;getProfileName&quot;, function (properties) {\n",
       "       return properties.properties.tags.name\n",
       "     });\n",
       "\n",
       "       const cheqValueTypeNumber = (profile, profileValue) =&gt; {\n",
       "         let validValue;\n",
       "         if (profile &amp;&amp; profileValue !== undefined &amp;&amp; typeof profileValue === &quot;number&quot;) {\n",
       "           return true\n",
       "         } else if (profileValue !== undefined &amp;&amp; typeof profileValue !== &quot;number&quot;) {\n",
       "           return false\n",
       "         }\n",
       "       }\n",
       "\n",
       "\n",
       "      Handlebars.registerHelper(&quot;inferredType&quot;, function (column) {\n",
       "        let infferedType = &quot;&quot;;\n",
       "\n",
       "        if (column.isDiscrete) {\n",
       "          infferedType = &quot;Discrete&quot;;\n",
       "        } else {\n",
       "          infferedType = &quot;Non-discrete&quot;;\n",
       "        }\n",
       "        return infferedType;\n",
       "      });\n",
       "\n",
       "      Handlebars.registerHelper(&quot;frequentItems&quot;, function (column) {\n",
       "        frequentItemsElemString = &quot;&quot;;\n",
       "        if (column.isDiscrete) {\n",
       "          const slicedFrequentItems = column.frequentItems.items.slice(0, 5);\n",
       "          for (let fi = 0; fi &lt; slicedFrequentItems.length; fi++) {\n",
       "            frequentItemsElemString +=\n",
       "              &#x27;&lt;span class=&quot;wl-table-cell__bedge&quot;&gt;&#x27; + slicedFrequentItems[fi].jsonValue + &quot;&lt;/span&gt;&quot;;\n",
       "          }\n",
       "        } else {\n",
       "          frequentItemsElemString += &quot;No data to show&quot;;\n",
       "        }\n",
       "        return frequentItemsElemString;\n",
       "      });\n",
       "\n",
       "      Handlebars.registerHelper(&quot;totalCount&quot;, function (column) {\n",
       "        if (column.featureStats) {\n",
       "          return column.featureStats.total_count;\n",
       "        }\n",
       "\n",
       "        return &quot;-&quot;;\n",
       "      });\n",
       "\n",
       "      Handlebars.registerHelper(&quot;missing&quot;, function (column) {\n",
       "        if (column.featureStats) {\n",
       "          return column.featureStats.missing;\n",
       "        }\n",
       "\n",
       "        return &quot;-&quot;;\n",
       "      });\n",
       "\n",
       "      Handlebars.registerHelper(&quot;minimumValue&quot;, function (column) {\n",
       "        if (column.featureStats) {\n",
       "          if (isNaN(column.featureStats.min)){return &quot;-&quot;}\n",
       "          return fixNumberTo(column.featureStats.min);\n",
       "        }\n",
       "\n",
       "        return &quot;-&quot;;\n",
       "      });\n",
       "\n",
       "      Handlebars.registerHelper(&quot;maximumValue&quot;, function (column) {\n",
       "        if (column.featureStats) {\n",
       "          if (isNaN(column.featureStats.max)){return &quot;-&quot;}\n",
       "          return fixNumberTo(column.featureStats.max);\n",
       "        }\n",
       "\n",
       "        return &quot;-&quot;;\n",
       "      });\n",
       "\n",
       "\n",
       "      Handlebars.registerHelper(&quot;mean&quot;, function (column) {\n",
       "        if (column.featureStats?.descriptive_statistics) {\n",
       "          if (isNaN(column.featureStats.descriptive_statistics.mean)){return &quot;-&quot;}\n",
       "          if (column.featureStats.descriptive_statistics.mean==null){return &quot;-&quot;}\n",
       "          return fixNumberTo(column.featureStats.descriptive_statistics.mean);\n",
       "        }\n",
       "        return &quot;-&quot;;\n",
       "      });\n",
       "\n",
       "      Handlebars.registerHelper(&quot;getGraphHtml&quot;,(column,key) =&gt; graph(column, key, null));\n",
       "\n",
       "      Handlebars.registerHelper(&quot;getDiscreteTypeCount&quot;, function () {\n",
       "        let count = 0;\n",
       "\n",
       "        Object.entries(this.columns).forEach((feature) =&gt; {\n",
       "          if (feature[1].isDiscrete === true) {\n",
       "            count++;\n",
       "          }\n",
       "        });\n",
       "        return count.toString();\n",
       "      });\n",
       "\n",
       "      Handlebars.registerHelper(&quot;getNonDiscreteTypeCount&quot;, function () {\n",
       "        let count = 0;\n",
       "\n",
       "        Object.entries(this.columns).forEach((feature) =&gt; {\n",
       "          if (feature[1].isDiscrete === false) {\n",
       "            count++;\n",
       "          }\n",
       "        });\n",
       "        return count;\n",
       "      });\n",
       "\n",
       "      Handlebars.registerHelper(&quot;getUnknownTypeCount&quot;, function () {\n",
       "        let count = 0;\n",
       "        return count;\n",
       "        Object.entries(this.columns).forEach((feature) =&gt; {\n",
       "          if (!feature[1].isDiscrete) {\n",
       "            count++;\n",
       "          }\n",
       "        });\n",
       "        return count;\n",
       "      });\n",
       "    }\n",
       "\n",
       "    function initHandlebarsTemplate() {\n",
       "      // Replace this context with JSON from .py file\n",
       "      const context = {&quot;columns&quot;: {&quot;fixed acidity&quot;: {&quot;histogram&quot;: {&quot;start&quot;: 4.6, &quot;end&quot;: 15.90000159, &quot;width&quot;: 0, &quot;counts&quot;: [3, 17, 16, 17, 28, 39, 39, 30, 22, 30, 24, 35, 12, 13, 22, 23, 9, 6, 3, 4, 2, 3, 3, 2, 1, 0, 0, 0, 2, 3], &quot;max&quot;: 15.9, &quot;min&quot;: 4.6, &quot;bins&quot;: [4.6, 4.9766667196666665, 5.353333439333333, 5.730000158999999, 6.106666878666666, 6.483333598333333, 6.860000318, 7.236667037666667, 7.613333757333333, 7.990000477000001, 8.366667196666667, 8.743333916333334, 9.120000636, 9.496667355666666, 9.873334075333332, 10.250000795, 10.626667514666668, 11.003334234333334, 11.380000954, 11.756667673666666, 12.133334393333334, 12.510001113000001, 12.886667832666667, 13.263334552333333, 13.640001272000001, 14.016667991666667, 14.393334711333335, 14.770001431, 15.146668150666667, 15.523334870333334, 15.90000159], &quot;n&quot;: 408}, &quot;frequentItems&quot;: null, &quot;drift_from_ref&quot;: null, &quot;isDiscrete&quot;: false, &quot;featureStats&quot;: {&quot;total_count&quot;: 408, &quot;missing&quot;: 0, &quot;distinct&quot;: 20.588239538027807, &quot;min&quot;: 4.6, &quot;max&quot;: 15.9, &quot;range&quot;: 11.3, &quot;quantile_statistics&quot;: {&quot;fifth_percentile&quot;: 5.4, &quot;iqr&quot;: 2.7, &quot;q1&quot;: 6.7, &quot;median&quot;: 7.9, &quot;q3&quot;: 9.4, &quot;ninety_fifth_percentile&quot;: 11.6}, &quot;descriptive_statistics&quot;: {&quot;stddev&quot;: 2.013014441140909, &quot;coefficient_of_variation&quot;: 0.24676558362692394, &quot;sum&quot;: 3328.3, &quot;variance&quot;: 4.052227140241847, &quot;mean&quot;: 8.157598039215687}}}, &quot;volatile acidity&quot;: {&quot;histogram&quot;: {&quot;start&quot;: 0.12, &quot;end&quot;: 1.1150001115, &quot;width&quot;: 0, &quot;counts&quot;: [3, 8, 5, 8, 21, 32, 38, 37, 30, 35, 23, 24, 25, 23, 15, 15, 15, 14, 11, 4, 3, 3, 6, 2, 1, 2, 1, 2, 0, 2], &quot;max&quot;: 1.115, &quot;min&quot;: 0.12, &quot;bins&quot;: [0.12, 0.15316667038333331, 0.18633334076666666, 0.21950001115, 0.2526666815333333, 0.28583335191666664, 0.3190000223, 0.35216669268333334, 0.38533336306666666, 0.41850003345, 0.4516667038333333, 0.48483337421666667, 0.5180000445999999, 0.5511667149833333, 0.5843333853666667, 0.61750005575, 0.6506667261333333, 0.6838333965166666, 0.7170000669, 0.7501667372833333, 0.7833334076666666, 0.81650007805, 0.8496667484333333, 0.8828334188166667, 0.9160000892, 0.9491667595833333, 0.9823334299666666, 1.01550010035, 1.0486667707333335, 1.0818334411166668, 1.1150001115000001], &quot;n&quot;: 408}, &quot;frequentItems&quot;: null, &quot;drift_from_ref&quot;: null, &quot;isDiscrete&quot;: false, &quot;featureStats&quot;: {&quot;total_count&quot;: 408, &quot;missing&quot;: 0, &quot;distinct&quot;: 22.05882840516061, &quot;min&quot;: 0.12, &quot;max&quot;: 1.115, &quot;range&quot;: 0.995, &quot;quantile_statistics&quot;: {&quot;fifth_percentile&quot;: 0.24, &quot;iqr&quot;: 0.23999999999999994, &quot;q1&quot;: 0.34, &quot;median&quot;: 0.44, &quot;q3&quot;: 0.58, &quot;ninety_fifth_percentile&quot;: 0.8}, &quot;descriptive_statistics&quot;: {&quot;stddev&quot;: 0.17791965320497752, &quot;coefficient_of_variation&quot;: 0.3771756131540623, &quot;sum&quot;: 192.45999999999998, &quot;variance&quot;: 0.03165540299657947, &quot;mean&quot;: 0.47171568627450977}}}, &quot;citric acid&quot;: {&quot;histogram&quot;: {&quot;start&quot;: 0.0, &quot;end&quot;: 0.790000079, &quot;width&quot;: 0, &quot;counts&quot;: [57, 13, 7, 23, 10, 9, 4, 6, 7, 10, 12, 14, 28, 9, 24, 35, 11, 23, 31, 8, 10, 9, 5, 3, 8, 12, 2, 3, 4, 1], &quot;max&quot;: 0.79, &quot;min&quot;: 0.0, &quot;bins&quot;: [0.0, 0.026333335966666666, 0.05266667193333333, 0.0790000079, 0.10533334386666666, 0.13166667983333333, 0.1580000158, 0.18433335176666665, 0.21066668773333333, 0.2370000237, 0.26333335966666666, 0.2896666956333333, 0.3160000316, 0.34233336756666666, 0.3686667035333333, 0.3950000395, 0.42133337546666666, 0.4476667114333333, 0.4740000474, 0.5003333833666667, 0.5266667193333333, 0.5530000553, 0.5793333912666666, 0.6056667272333334, 0.6320000632, 0.6583333991666667, 0.6846667351333333, 0.7110000711, 0.7373334070666666, 0.7636667430333334, 0.790000079], &quot;n&quot;: 398}, &quot;frequentItems&quot;: null, &quot;drift_from_ref&quot;: null, &quot;isDiscrete&quot;: false, &quot;featureStats&quot;: {&quot;total_count&quot;: 398, &quot;missing&quot;: 10, &quot;distinct&quot;: 18.090455451204008, &quot;min&quot;: 0.0, &quot;max&quot;: 0.79, &quot;range&quot;: 0.79, &quot;quantile_statistics&quot;: {&quot;fifth_percentile&quot;: 0.0, &quot;iqr&quot;: 0.36, &quot;q1&quot;: 0.1, &quot;median&quot;: 0.34, &quot;q3&quot;: 0.46, &quot;ninety_fifth_percentile&quot;: 0.66}, &quot;descriptive_statistics&quot;: {&quot;stddev&quot;: 0.20859943016152155, &quot;coefficient_of_variation&quot;: 0.6620619872750046, &quot;sum&quot;: 125.4, &quot;variance&quot;: 0.04351372226371151, &quot;mean&quot;: 0.3150753768844221}}}, &quot;residual sugar&quot;: {&quot;histogram&quot;: {&quot;start&quot;: 0.9, &quot;end&quot;: 12.90000129, &quot;width&quot;: 0, &quot;counts&quot;: [8, 39, 118, 124, 40, 16, 11, 8, 13, 8, 4, 2, 2, 5, 3, 0, 1, 1, 3, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1], &quot;max&quot;: 12.9, &quot;min&quot;: 0.9, &quot;bins&quot;: [0.9, 1.300000043, 1.7000000860000002, 2.100000129, 2.500000172, 2.900000215, 3.3000002580000003, 3.700000301, 4.100000344000001, 4.500000387, 4.90000043, 5.300000473000001, 5.700000516000001, 6.100000559000001, 6.500000602000001, 6.900000645, 7.300000688000001, 7.700000731000001, 8.100000774, 8.500000817, 8.90000086, 9.300000903, 9.700000946000001, 10.100000989000002, 10.500001032000002, 10.900001075, 11.300001118, 11.700001161000001, 12.100001204000002, 12.500001247000002, 12.90000129], &quot;n&quot;: 408}, &quot;frequentItems&quot;: null, &quot;drift_from_ref&quot;: null, &quot;isDiscrete&quot;: false, &quot;featureStats&quot;: {&quot;total_count&quot;: 408, &quot;missing&quot;: 0, &quot;distinct&quot;: 15.931375081243552, &quot;min&quot;: 0.9, &quot;max&quot;: 12.9, &quot;range&quot;: 12.0, &quot;quantile_statistics&quot;: {&quot;fifth_percentile&quot;: 1.6, &quot;iqr&quot;: 0.7000000000000002, &quot;q1&quot;: 2.0, &quot;median&quot;: 2.3, &quot;q3&quot;: 2.7, &quot;ninety_fifth_percentile&quot;: 5.15}, &quot;descriptive_statistics&quot;: {&quot;stddev&quot;: 1.2990000858665753, &quot;coefficient_of_variation&quot;: 0.49437249664993493, &quot;sum&quot;: 1072.05, &quot;variance&quot;: 1.6874012230813702, &quot;mean&quot;: 2.6275735294117646}}}, &quot;chlorides&quot;: {&quot;histogram&quot;: {&quot;start&quot;: 0.012, &quot;end&quot;: 0.230000023, &quot;width&quot;: 0, &quot;counts&quot;: [2, 0, 0, 9, 21, 40, 45, 76, 64, 43, 33, 21, 20, 8, 9, 9, 3, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 1], &quot;max&quot;: 0.23, &quot;min&quot;: 0.012, &quot;bins&quot;: [0.012, 0.019266667433333332, 0.026533334866666668, 0.0338000023, 0.04106666973333333, 0.04833333716666667, 0.0556000046, 0.06286667203333333, 0.07013333946666667, 0.0774000069, 0.08466667433333333, 0.09193334176666666, 0.0992000092, 0.10646667663333333, 0.11373334406666666, 0.12100001149999999, 0.12826667893333332, 0.13553334636666667, 0.14280001380000001, 0.15006668123333333, 0.15733334866666668, 0.1646000161, 0.17186668353333334, 0.17913335096666666, 0.1864000184, 0.19366668583333332, 0.20093335326666667, 0.2082000207, 0.21546668813333333, 0.22273335556666665, 0.230000023], &quot;n&quot;: 408}, &quot;frequentItems&quot;: null, &quot;drift_from_ref&quot;: null, &quot;isDiscrete&quot;: false, &quot;featureStats&quot;: {&quot;total_count&quot;: 408, &quot;missing&quot;: 0, &quot;distinct&quot;: 21.813730257594944, &quot;min&quot;: 0.012, &quot;max&quot;: 0.23, &quot;range&quot;: 0.218, &quot;quantile_statistics&quot;: {&quot;fifth_percentile&quot;: 0.046, &quot;iqr&quot;: 0.025999999999999995, &quot;q1&quot;: 0.06, &quot;median&quot;: 0.071, &quot;q3&quot;: 0.086, &quot;ninety_fifth_percentile&quot;: 0.12}, &quot;descriptive_statistics&quot;: {&quot;stddev&quot;: 0.024213181268290383, &quot;coefficient_of_variation&quot;: 0.3226526212509791, &quot;sum&quot;: 30.618, &quot;variance&quot;: 0.0005862781471310883, &quot;mean&quot;: 0.07504411764705882}}}, &quot;free sulfur dioxide&quot;: {&quot;histogram&quot;: {&quot;start&quot;: 3.0, &quot;end&quot;: 51.0000051, &quot;width&quot;: 0, &quot;counts&quot;: [31, 79, 21, 21, 36, 16, 27, 26, 29, 22, 3, 13, 12, 11, 10, 5, 6, 4, 8, 6, 4, 8, 2, 1, 3, 0, 1, 0, 1, 2], &quot;max&quot;: 51.0, &quot;min&quot;: 3.0, &quot;bins&quot;: [3.0, 4.60000017, 6.200000340000001, 7.80000051, 9.400000680000002, 11.000000850000001, 12.60000102, 14.200001190000002, 15.800001360000001, 17.40000153, 19.000001700000002, 20.600001870000003, 22.20000204, 23.800002210000002, 25.400002380000004, 27.00000255, 28.600002720000003, 30.200002890000004, 31.80000306, 33.40000323, 35.000003400000004, 36.600003570000005, 38.20000374000001, 39.80000391, 41.40000408, 43.00000425, 44.600004420000005, 46.200004590000006, 47.80000476000001, 49.40000493, 51.0000051], &quot;n&quot;: 408}, &quot;frequentItems&quot;: null, &quot;drift_from_ref&quot;: null, &quot;isDiscrete&quot;: false, &quot;featureStats&quot;: {&quot;total_count&quot;: 408, &quot;missing&quot;: 0, &quot;distinct&quot;: 11.029412969947018, &quot;min&quot;: 3.0, &quot;max&quot;: 51.0, &quot;range&quot;: 48.0, &quot;quantile_statistics&quot;: {&quot;fifth_percentile&quot;: 3.0, &quot;iqr&quot;: 13.0, &quot;q1&quot;: 6.0, &quot;median&quot;: 13.0, &quot;q3&quot;: 19.0, &quot;ninety_fifth_percentile&quot;: 36.0}, &quot;descriptive_statistics&quot;: {&quot;stddev&quot;: 9.994223698460777, &quot;coefficient_of_variation&quot;: 0.6774056431550788, &quot;sum&quot;: 6019.5, &quot;variance&quot;: 99.884507334875, &quot;mean&quot;: 14.753676470588236}}}, &quot;total sulfur dioxide&quot;: {&quot;histogram&quot;: {&quot;start&quot;: 6.0, &quot;end&quot;: 289.0000289, &quot;width&quot;: 0, &quot;counts&quot;: [85, 92, 70, 47, 40, 14, 16, 10, 10, 10, 6, 2, 0, 0, 0, 3, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1], &quot;max&quot;: 289.0, &quot;min&quot;: 6.0, &quot;bins&quot;: [6.0, 15.433334296666667, 24.866668593333333, 34.30000289, 43.73333718666667, 53.16667148333333, 62.600005780000004, 72.03334007666666, 81.46667437333333, 90.90000867, 100.33334296666666, 109.76667726333334, 119.20001156000001, 128.63334585666666, 138.06668015333332, 147.50001445, 156.93334874666667, 166.36668304333332, 175.80001734, 185.23335163666667, 194.66668593333333, 204.10002023, 213.53335452666667, 222.96668882333333, 232.40002312000001, 241.83335741666667, 251.26669171333333, 260.70002601, 270.13336030666665, 279.56669460333336, 289.0000289], &quot;n&quot;: 408}, &quot;frequentItems&quot;: null, &quot;drift_from_ref&quot;: null, &quot;isDiscrete&quot;: false, &quot;featureStats&quot;: {&quot;total_count&quot;: 408, &quot;missing&quot;: 0, &quot;distinct&quot;: 22.303926553943704, &quot;min&quot;: 6.0, &quot;max&quot;: 289.0, &quot;range&quot;: 283.0, &quot;quantile_statistics&quot;: {&quot;fifth_percentile&quot;: 10.0, &quot;iqr&quot;: 29.0, &quot;q1&quot;: 17.0, &quot;median&quot;: 27.0, &quot;q3&quot;: 46.0, &quot;ninety_fifth_percentile&quot;: 93.0}, &quot;descriptive_statistics&quot;: {&quot;stddev&quot;: 31.68721099598923, &quot;coefficient_of_variation&quot;: 0.8554477659209692, &quot;sum&quot;: 15112.999999999998, &quot;variance&quot;: 1004.0793407043408, &quot;mean&quot;: 37.041666666666664}}}, &quot;density&quot;: {&quot;histogram&quot;: {&quot;start&quot;: 0.99007, &quot;end&quot;: 1.0032001003200002, &quot;width&quot;: 0, &quot;counts&quot;: [3, 4, 1, 9, 4, 12, 8, 32, 32, 36, 39, 49, 45, 25, 25, 19, 15, 8, 4, 8, 5, 6, 2, 5, 4, 1, 1, 2, 0, 4], &quot;max&quot;: 1.0032, &quot;min&quot;: 0.99007, &quot;bins&quot;: [0.99007, 0.9905076700106666, 0.9909453400213334, 0.991383010032, 0.9918206800426667, 0.9922583500533334, 0.992696020064, 0.9931336900746667, 0.9935713600853334, 0.9940090300960001, 0.9944467001066667, 0.9948843701173334, 0.9953220401280001, 0.9957597101386667, 0.9961973801493335, 0.9966350501600001, 0.9970727201706667, 0.9975103901813335, 0.9979480601920001, 0.9983857302026667, 0.9988234002133335, 0.9992610702240001, 0.9996987402346668, 1.0001364102453334, 1.0005740802560001, 1.0010117502666669, 1.0014494202773334, 1.0018870902880002, 1.002324760298667, 1.0027624303093334, 1.0032001003200002], &quot;n&quot;: 408}, &quot;frequentItems&quot;: null, &quot;drift_from_ref&quot;: null, &quot;isDiscrete&quot;: false, &quot;featureStats&quot;: {&quot;total_count&quot;: 408, &quot;missing&quot;: 0, &quot;distinct&quot;: 55.88238444546564, &quot;min&quot;: 0.99007, &quot;max&quot;: 1.0032, &quot;range&quot;: 0.013130000000000086, &quot;quantile_statistics&quot;: {&quot;fifth_percentile&quot;: 0.9922, &quot;iqr&quot;: 0.0023400000000000087, &quot;q1&quot;: 0.99396, &quot;median&quot;: 0.99516, &quot;q3&quot;: 0.9963, &quot;ninety_fifth_percentile&quot;: 0.9994}, &quot;descriptive_statistics&quot;: {&quot;stddev&quot;: 0.0021784570136347352, &quot;coefficient_of_variation&quot;: 0.002188682344428877, &quot;sum&quot;: 406.09385999999995, &quot;variance&quot;: 4.745674960254368e-06, &quot;mean&quot;: 0.995328088235294}}}, &quot;pH&quot;: {&quot;histogram&quot;: {&quot;start&quot;: 2.89, &quot;end&quot;: 4.010000401, &quot;width&quot;: 0, &quot;counts&quot;: [5, 1, 3, 4, 7, 5, 17, 20, 38, 36, 44, 29, 35, 41, 30, 11, 19, 17, 14, 10, 2, 9, 4, 2, 0, 1, 0, 2, 0, 2], &quot;max&quot;: 4.01, &quot;min&quot;: 2.89, &quot;bins&quot;: [2.89, 2.9273333467000002, 2.9646666934000003, 3.0020000401, 3.0393333868, 3.0766667335, 3.1140000802000003, 3.1513334269, 3.1886667736, 3.2260001203, 3.2633334670000003, 3.3006668137, 3.3380001604, 3.3753335071, 3.4126668538000002, 3.4500002005, 3.4873335472, 3.5246668939, 3.5620002406, 3.5993335873000003, 3.636666934, 3.6740002807, 3.7113336274, 3.7486669741, 3.7860003208000004, 3.8233336675, 3.8606670142, 3.8980003609000002, 3.9353337076, 3.9726670543, 4.010000401], &quot;n&quot;: 408}, &quot;frequentItems&quot;: null, &quot;drift_from_ref&quot;: null, &quot;isDiscrete&quot;: false, &quot;featureStats&quot;: {&quot;total_count&quot;: 408, &quot;missing&quot;: 0, &quot;distinct&quot;: 18.8725525817653, &quot;min&quot;: 2.89, &quot;max&quot;: 4.01, &quot;range&quot;: 1.1199999999999997, &quot;quantile_statistics&quot;: {&quot;fifth_percentile&quot;: 3.09, &quot;iqr&quot;: 0.2200000000000002, &quot;q1&quot;: 3.23, &quot;median&quot;: 3.33, &quot;q3&quot;: 3.45, &quot;ninety_fifth_percentile&quot;: 3.67}, &quot;descriptive_statistics&quot;: {&quot;stddev&quot;: 0.17649177660211463, &quot;coefficient_of_variation&quot;: 0.05273349702213279, &quot;sum&quot;: 1365.52, &quot;variance&quot;: 0.031149347208170735, &quot;mean&quot;: 3.346862745098039}}}, &quot;sulphates&quot;: {&quot;histogram&quot;: {&quot;start&quot;: 0.37, &quot;end&quot;: 1.130000113, &quot;width&quot;: 0, &quot;counts&quot;: [3, 2, 4, 4, 6, 18, 19, 45, 22, 37, 22, 32, 21, 29, 28, 27, 22, 12, 24, 7, 10, 1, 5, 1, 3, 1, 1, 0, 0, 2], &quot;max&quot;: 1.13, &quot;min&quot;: 0.37, &quot;bins&quot;: [0.37, 0.3953333371, 0.4206666742, 0.4460000113, 0.47133334839999996, 0.4966666855, 0.5220000226, 0.5473333597, 0.5726666968, 0.5980000339, 0.623333371, 0.6486667080999999, 0.6740000452, 0.6993333823, 0.7246667194, 0.7500000565, 0.7753333936, 0.8006667306999999, 0.8260000677999999, 0.8513334049, 0.8766667419999999, 0.9020000791, 0.9273334162, 0.9526667533, 0.9780000904, 1.0033334274999999, 1.0286667646, 1.0540001016999998, 1.0793334388, 1.1046667759, 1.130000113], &quot;n&quot;: 408}, &quot;frequentItems&quot;: null, &quot;drift_from_ref&quot;: null, &quot;isDiscrete&quot;: false, &quot;featureStats&quot;: {&quot;total_count&quot;: 408, &quot;missing&quot;: 0, &quot;distinct&quot;: 14.215688286897349, &quot;min&quot;: 0.37, &quot;max&quot;: 1.13, &quot;range&quot;: 0.7599999999999999, &quot;quantile_statistics&quot;: {&quot;fifth_percentile&quot;: 0.5, &quot;iqr&quot;: 0.19000000000000006, &quot;q1&quot;: 0.58, &quot;median&quot;: 0.66, &quot;q3&quot;: 0.77, &quot;ninety_fifth_percentile&quot;: 0.88}, &quot;descriptive_statistics&quot;: {&quot;stddev&quot;: 0.12701037402923776, &quot;coefficient_of_variation&quot;: 0.18776807233831805, &quot;sum&quot;: 275.97999999999996, &quot;variance&quot;: 0.016131635111046875, &quot;mean&quot;: 0.6764215686274508}}}, &quot;alcohol&quot;: {&quot;histogram&quot;: {&quot;start&quot;: 11.066666666666698, &quot;end&quot;: 14.900001490000001, &quot;width&quot;: 0, &quot;counts&quot;: [28, 68, 32, 30, 38, 29, 21, 21, 25, 12, 13, 27, 9, 17, 9, 8, 1, 3, 3, 6, 0, 0, 7, 0, 0, 0, 0, 0, 0, 1], &quot;max&quot;: 14.9, &quot;min&quot;: 11.066666666666698, &quot;bins&quot;: [11.066666666666698, 11.194444494111142, 11.322222321555586, 11.45000014900003, 11.577777976444471, 11.705555803888915, 11.833333631333359, 11.961111458777802, 12.088889286222246, 12.21666711366669, 12.344444941111133, 12.472222768555575, 12.600000596000019, 12.727778423444462, 12.855556250888906, 12.98333407833335, 13.111111905777793, 13.238889733222237, 13.36666756066668, 13.494445388111123, 13.622223215555566, 13.75000104300001, 13.877778870444454, 14.005556697888897, 14.13333452533334, 14.261112352777783, 14.388890180222226, 14.51666800766667, 14.644445835111114, 14.772223662555557, 14.900001490000001], &quot;n&quot;: 408}, &quot;frequentItems&quot;: null, &quot;drift_from_ref&quot;: null, &quot;isDiscrete&quot;: false, &quot;featureStats&quot;: {&quot;total_count&quot;: 408, &quot;missing&quot;: 0, &quot;distinct&quot;: 7.59803978178436, &quot;min&quot;: 11.066666666666698, &quot;max&quot;: 14.9, &quot;range&quot;: 3.833333333333302, &quot;quantile_statistics&quot;: {&quot;fifth_percentile&quot;: 11.1, &quot;iqr&quot;: 1.0, &quot;q1&quot;: 11.4, &quot;median&quot;: 11.8, &quot;q3&quot;: 12.4, &quot;ninety_fifth_percentile&quot;: 13.2}, &quot;descriptive_statistics&quot;: {&quot;stddev&quot;: 0.6824986635512768, &quot;coefficient_of_variation&quot;: 0.05725985668809312, &quot;sum&quot;: 4863.083333333334, &quot;variance&quot;: 0.4658044257492789, &quot;mean&quot;: 11.919321895424838}}}, &quot;quality&quot;: {&quot;histogram&quot;: null, &quot;frequentItems&quot;: [{&quot;value&quot;: &quot;bad&quot;, &quot;estimate&quot;: 267}, {&quot;value&quot;: &quot;good&quot;, &quot;estimate&quot;: 141}], &quot;drift_from_ref&quot;: null, &quot;isDiscrete&quot;: true, &quot;featureStats&quot;: {&quot;total_count&quot;: 408, &quot;missing&quot;: 0, &quot;distinct&quot;: 0.4901960796487877, &quot;min&quot;: NaN, &quot;max&quot;: NaN, &quot;range&quot;: NaN, &quot;quantile_statistics&quot;: null, &quot;descriptive_statistics&quot;: {&quot;stddev&quot;: null, &quot;coefficient_of_variation&quot;: null, &quot;sum&quot;: null, &quot;variance&quot;: null, &quot;mean&quot;: null}}}}, &quot;properties&quot;: {&quot;observations&quot;: 4896, &quot;missing_cells&quot;: 10, &quot;missing_percentage&quot;: 0.20424836601307192}};\n",
       "      // Config handlebars and pass data to HBS template\n",
       "      const source = document.getElementById(&quot;entry-template&quot;).innerHTML;\n",
       "      const template = Handlebars.compile(source);\n",
       "      const html = template(context);\n",
       "      const target = document.getElementById(&quot;generated-html&quot;);\n",
       "      target.innerHTML = html;\n",
       "    }\n",
       "\n",
       "    function initWebsiteScripts() {\n",
       "      const $featureSearch = document.getElementById(&quot;wl__feature-search&quot;);\n",
       "      const $tableBody = document.getElementById(&quot;table-body&quot;);\n",
       "      const $discrete = document.getElementById(&quot;inferredDiscrete&quot;);\n",
       "      const $nonDiscrete = document.getElementById(&quot;inferredNonDiscrete&quot;);\n",
       "      const $unknown = document.getElementById(&quot;inferredUnknown&quot;);\n",
       "\n",
       "      const activeTypes = {\n",
       "        discrete: true,\n",
       "        &quot;non-discrete&quot;: true,\n",
       "        unknown: true,\n",
       "      };\n",
       "\n",
       "      let searchString = &quot;&quot;;\n",
       "\n",
       "      function debounce(func, wait, immediate) {\n",
       "        let timeout;\n",
       "\n",
       "        return function () {\n",
       "          const context = this;\n",
       "          const args = arguments;\n",
       "          const later = function () {\n",
       "            timeout = null;\n",
       "            if (!immediate) func.apply(context, args);\n",
       "          };\n",
       "\n",
       "          const callNow = immediate &amp;&amp; !timeout;\n",
       "          clearTimeout(timeout);\n",
       "          timeout = setTimeout(later, wait);\n",
       "          if (callNow) func.apply(context, args);\n",
       "        };\n",
       "      }\n",
       "\n",
       "      function filterNotification() {\n",
       "        const $notifCircleContainer = $(&quot;.notif-circle-container&quot;)\n",
       "        const $boxes = $(&#x27;.wl_filter-options&gt;.form-check&gt;input[name=checkbox]:checked&#x27;);\n",
       "        const item = Object.values($boxes).find(function(value) { return $(value)[0] === undefined});\n",
       "        if (item === undefined) {\n",
       "          $notifCircleContainer.removeClass(&quot;d-none&quot;)\n",
       "        } else {\n",
       "          $notifCircleContainer.addClass(&quot;d-none&quot;)\n",
       "        }\n",
       "      }\n",
       "\n",
       "      function handleSearch() {\n",
       "        const tableBodyChildren = $tableBody.children;\n",
       "\n",
       "        for (let i = 0; i &lt; tableBodyChildren.length; i++) {\n",
       "          const type = tableBodyChildren[i].dataset.inferredType.toLowerCase();\n",
       "          const name = tableBodyChildren[i].dataset.featureName.toLowerCase();\n",
       "\n",
       "          if (activeTypes[type] &amp;&amp; name.startsWith(searchString)) {\n",
       "            tableBodyChildren[i].style.display = &quot;&quot;;\n",
       "          } else {\n",
       "            tableBodyChildren[i].style.display = &quot;none&quot;;\n",
       "          }\n",
       "        }\n",
       "      }\n",
       "\n",
       "      $featureSearch.addEventListener(\n",
       "        &quot;keyup&quot;,\n",
       "        debounce((event) =&gt; {\n",
       "          searchString = event.target.value.toLowerCase();\n",
       "          handleSearch();\n",
       "        }, 100),\n",
       "      );\n",
       "\n",
       "      $discrete.addEventListener(&quot;change&quot;, (event) =&gt; {\n",
       "        if (event.currentTarget.checked) {\n",
       "          activeTypes[&quot;discrete&quot;] = true;\n",
       "        } else {\n",
       "          activeTypes[&quot;discrete&quot;] = false;\n",
       "        }\n",
       "        handleSearch();\n",
       "        filterNotification()\n",
       "      });\n",
       "\n",
       "      $nonDiscrete.addEventListener(&quot;change&quot;, (event) =&gt; {\n",
       "        if (event.currentTarget.checked) {\n",
       "          activeTypes[&quot;non-discrete&quot;] = true;\n",
       "        } else {\n",
       "          activeTypes[&quot;non-discrete&quot;] = false;\n",
       "        }\n",
       "        handleSearch();\n",
       "        filterNotification()\n",
       "      });\n",
       "\n",
       "      $unknown.addEventListener(&quot;change&quot;, (event) =&gt; {\n",
       "        if (event.currentTarget.checked) {\n",
       "          activeTypes[&quot;unknown&quot;] = true;\n",
       "        } else {\n",
       "          activeTypes[&quot;unknown&quot;] = false;\n",
       "        }\n",
       "        handleSearch();\n",
       "        filterNotification()\n",
       "      });\n",
       "\n",
       "\n",
       "      $(&quot;.svg-container&quot;).css(&quot;padding-bottom&quot;, &quot;27%&quot;)\n",
       "    }\n",
       "\n",
       "    function checkedBoxes() {\n",
       "      const $boxes = $(&#x27;input[name=checkbox]:checked&#x27;);\n",
       "      const $notifCircleContainer = $(&quot;.notif-circle-container&quot;)\n",
       "\n",
       "      if ($boxes.length) {\n",
       "        $notifCircleContainer.removeClass(&quot;d-none&quot;)\n",
       "      }\n",
       "    }\n",
       "\n",
       "    function openFilter() {\n",
       "      const $filterOptions = $(&quot;.dropdown-container&quot;);\n",
       "      const $notifCircleContainer = $(&quot;.notif-circle-container&quot;)\n",
       "      const filterClass = $filterOptions.attr(&quot;class&quot;);\n",
       "\n",
       "      if (filterClass.indexOf(&quot;d-none&quot;) &gt; 0) {\n",
       "        $notifCircleContainer.addClass(&quot;d-none&quot;)\n",
       "        $filterOptions.removeClass(&quot;d-none&quot;);\n",
       "        $(&quot;.filter-icon&quot;).addClass(&quot;d-none&quot;)\n",
       "        $(&quot;.close-filter-icon&quot;).removeClass(&quot;d-none&quot;)\n",
       "      } else {\n",
       "        $filterOptions.addClass(&quot;d-none&quot;);\n",
       "        $(&quot;.close-filter-icon&quot;).addClass(&quot;d-none&quot;)\n",
       "        $(&quot;.filter-icon&quot;).removeClass(&quot;d-none&quot;)\n",
       "        checkedBoxes()\n",
       "      }\n",
       "    }\n",
       "\n",
       "    // Invoke functions -- keep in mind invokation order\n",
       "    registerHandlebarHelperFunctions();\n",
       "    initHandlebarsTemplate();\n",
       "    initWebsiteScripts();\n",
       "  &lt;/script&gt;\n",
       "&lt;/html&gt;\n",
       "\" width=100% height=1000px\n",
       "        frameBorder=0></iframe>"
      ],
      "text/plain": [
       "<IPython.core.display.HTML object>"
      ]
     },
     "execution_count": 10,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "visualization.profile_summary()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Drift Summary"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "We can also compare two different profiles. With `summary_drift_report`, we have overview statistics, such as number of observations and missing cells, as well as a comparison between both profile's features, with regards to each feature's distribution, and drift calculations for numerical or categorical features.\n",
    "\n",
    "The report also displays alerts related to each of the feature's drift severity.\n",
    "\n",
    "You can also search for a specific feature, or filter by drift severity."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div></div><iframe srcdoc=\"&lt;!DOCTYPE html&gt;\n",
       "&lt;html lang=&quot;en&quot;&gt;\n",
       "  &lt;head&gt;\n",
       "    &lt;meta charset=&quot;UTF-8&quot; /&gt;\n",
       "    &lt;meta http-equiv=&quot;X-UA-Compatible&quot; content=&quot;IE=edge&quot; /&gt;\n",
       "    &lt;meta name=&quot;viewport&quot; content=&quot;width=device-width, initial-scale=1.0&quot; /&gt;\n",
       "    &lt;meta name=&quot;description&quot; content=&quot;&quot; /&gt;\n",
       "    &lt;meta name=&quot;author&quot; content=&quot;&quot; /&gt;\n",
       "\n",
       "    &lt;title&gt;Profile Visualizer | whylogs&lt;/title&gt;\n",
       "\n",
       "    &lt;link rel=&quot;icon&quot; href=&quot;images/whylabs-favicon.png&quot; type=&quot;image/png&quot; sizes=&quot;16x16&quot; /&gt;\n",
       "    &lt;link rel=&quot;preconnect&quot; href=&quot;https://fonts.googleapis.com&quot; /&gt;\n",
       "    &lt;link rel=&quot;preconnect&quot; href=&quot;https://fonts.gstatic.com&quot; crossorigin /&gt;\n",
       "    &lt;link href=&quot;https://fonts.googleapis.com/css2?family=Asap:wght@400;500;600;700&amp;display=swap&quot; rel=&quot;stylesheet&quot; /&gt;\n",
       "    &lt;link rel=&quot;preconnect&quot; href=&quot;https://fonts.gstatic.com&quot; /&gt;\n",
       "    &lt;link rel=&quot;stylesheet&quot; href=&quot;https://cdn.jsdelivr.net/npm/bootstrap@5.1.0/dist/css/bootstrap.min.css&quot; /&gt;\n",
       "\n",
       "    &lt;script\n",
       "      src=&quot;https://cdnjs.cloudflare.com/ajax/libs/handlebars.js/4.7.7/handlebars.min.js&quot;\n",
       "      integrity=&quot;sha512-RNLkV3d+aLtfcpEyFG8jRbnWHxUqVZozacROI4J2F1sTaDqo1dPQYs01OMi1t1w9Y2FdbSCDSQ2ZVdAC8bzgAg==&quot;\n",
       "      crossorigin=&quot;anonymous&quot;\n",
       "      referrerpolicy=&quot;no-referrer&quot;\n",
       "    &gt;&lt;/script&gt;\n",
       "\n",
       "    &lt;style type=&quot;text/css&quot;&gt;\n",
       "      :root {\n",
       "        /* CONSTANTS */\n",
       "        --SIDE-PANEL-WIDTH: 320px;\n",
       "        --PROPERTY-PANEL-WIDTH: 420px;\n",
       "\n",
       "        /* COLOR VARIABLES */\n",
       "        /** Standard colors */\n",
       "        --red: #d11010;\n",
       "        --orange: #f07028;\n",
       "        --yellow: #faaf40;\n",
       "        --olive: #b5cc18;\n",
       "        --green: #1dbb42;\n",
       "        --teal: #00b5ad;\n",
       "        --blue: #2683c9;\n",
       "        --violet: #6435c9;\n",
       "        --purple: #a333c8;\n",
       "        --pink: #ed45a4;\n",
       "        --brown: #ac724d;\n",
       "        --grey: #778183;\n",
       "        --black: #1b1c1d;\n",
       "        --white: #ffffff;\n",
       "\n",
       "        /** Branded colors */\n",
       "        --brandPrimary900: #0e7384;\n",
       "        --brandPrimary800: #228798;\n",
       "        --brandPrimary700: #369bac;\n",
       "        --brandPrimary600: #4aafc0;\n",
       "        --brandPrimary500: #5ec3d4;\n",
       "        --brandPrimary400: #72d7e8;\n",
       "        --brandPrimary300: #86ebfc;\n",
       "        --brandPrimary200: #a6f2ff;\n",
       "        --brandPrimary100: #cdf8ff;\n",
       "        --brandSecondary900: #4f595b;\n",
       "        --brandSecondary800: #636d6f;\n",
       "        --brandSecondary700: #778183;\n",
       "        --brandSecondary600: #8b9597;\n",
       "        --brandSecondary500: #9fa9ab;\n",
       "        --brandSecondary400: #b3bdbf;\n",
       "        --brandSecondary300: #c7d1d3;\n",
       "        --brandSecondary200: #dbe5e7;\n",
       "        --brandSecondary100: #ebf2f3;\n",
       "        --secondaryLight1000: #313b3d;\n",
       "        --brandRed4: #b30000;\n",
       "        --brandRed3: #d72424;\n",
       "        --brandRed2: #eb5656;\n",
       "        --brandRed1: #ff8282;\n",
       "        --night1: #021826;\n",
       "        /** Purpose colors */\n",
       "        --textColor: #4f595b;\n",
       "        --linkColor: #369bac;\n",
       "        --infoColor: #2683c9;\n",
       "        --warningColor: #faaf40;\n",
       "        --tealBackground: #eaf2f3;\n",
       "        --pageBackground: #e5e5e5;\n",
       "        --contrastTableRow: #fafafa;\n",
       "        --whiteBackground: #ffffff;\n",
       "        --primaryBackground: #e5e5e5;\n",
       "      }\n",
       "\n",
       "      /* RESET STYLE */\n",
       "      *,\n",
       "      *::after,\n",
       "      *::before {\n",
       "        margin: 0;\n",
       "        padding: 0;\n",
       "        box-sizing: border-box;\n",
       "        font-family: &quot;Asap&quot;, Arial, Helvetica, sans-serif;\n",
       "      }\n",
       "\n",
       "      /*\n",
       "      * Main content\n",
       "      */\n",
       "      .main {\n",
       "        position: relative;\n",
       "        background: #FFFFFF;\n",
       "        border: 1px solid #DBE5E7;\n",
       "        box-sizing: border-box;\n",
       "        border-radius: 4px;\n",
       "      }\n",
       "      .main .page-header {\n",
       "        margin-top: 0;\n",
       "      }\n",
       "\n",
       "      /* CSS DIV TABLE BASIC STYLE */\n",
       "\n",
       "      .wl-table-row .wl-table-head:first-child {\n",
       "        min-width: 360px;\n",
       "        z-index: 2;\n",
       "      }\n",
       "\n",
       "      .wl-table-wrap {\n",
       "        position: relative;\n",
       "      }\n",
       "\n",
       "      .wl-table {\n",
       "        display: table;\n",
       "        width: 100%;\n",
       "      }\n",
       "\n",
       "      .row&gt;* {\n",
       "        padding-right: 0 !important;\n",
       "        padding-left: 0 !important;\n",
       "      }\n",
       "\n",
       "      .wl-table-row {\n",
       "        display: table-row;\n",
       "      }\n",
       "\n",
       "      .wl-table-row:hover,\n",
       "      .wl-table-row:hover .wl-table-cell:first-child {\n",
       "        background-color: var(--brandSecondary100);\n",
       "      }\n",
       "      .wl-table-row--clickable:hover .wl-table-cell__title-button {\n",
       "        visibility: visible;\n",
       "      }\n",
       "\n",
       "      .wl-table-heading {\n",
       "        position: sticky;\n",
       "        top: 0;\n",
       "        z-index: 900;\n",
       "        display: table-header-group;\n",
       "        font-weight: 700;\n",
       "      }\n",
       "\n",
       "      .wl-table-cell,\n",
       "      .wl-table-head {\n",
       "        border-bottom: 1px solid var(--brandSecondary200);\n",
       "        display: table-cell;\n",
       "        padding: 12px 18px;\n",
       "      }\n",
       "\n",
       "      .wl-table-cell {\n",
       "        font-size: 14px;\n",
       "      }\n",
       "\n",
       "      .wl-table-cell--top-spacing {\n",
       "        padding-top: 35px; /* cell-top-padding + cell-title-height */\n",
       "      }\n",
       "\n",
       "      .wl-table-head-wraper {\n",
       "        background-color: var(--white);\n",
       "      }\n",
       "\n",
       "      .wl-table-head {\n",
       "        position: relative;\n",
       "        left: 0;\n",
       "        min-width: 100px;\n",
       "        border-bottom: 2px solid var(--brandSecondary100);\n",
       "        font-size: 12px;\n",
       "        line-height: 1.67;\n",
       "        white-space: nowrap;\n",
       "      }\n",
       "\n",
       "      .wl-sub-table-head {\n",
       "        position: relative;\n",
       "      }\n",
       "\n",
       "      .wl-table-body {\n",
       "        display: table-row-group;\n",
       "      }\n",
       "\n",
       "      .wl-table-row .wl-table-cell:first-child{\n",
       "        position: relative;\n",
       "        left: 0;\n",
       "        background-color: var(--white);\n",
       "        border-right-width: 2px;\n",
       "      }\n",
       "\n",
       "      /* Table custom style */\n",
       "\n",
       "      .wl-table-cell__title-wrap {\n",
       "        display: flex;\n",
       "        justify-content: space-between;\n",
       "      }\n",
       "\n",
       "      .wl-table-cell__title {\n",
       "        height: 25px;\n",
       "        margin: 0;\n",
       "        font-size: 14px;\n",
       "        font-weight: 700;\n",
       "        overflow: hidden;\n",
       "        white-space: nowrap;\n",
       "        text-overflow: ellipsis;\n",
       "      }\n",
       "\n",
       "      .wl-table-cell__bedge-wrap {\n",
       "        padding: 2px 0;\n",
       "        white-space: nowrap;\n",
       "        overflow: hidden;\n",
       "        font-style: italic;\n",
       "        text-align: center;\n",
       "        color: var(--brandSecondary400);\n",
       "      }\n",
       "      .wl-table-cell__bedge {\n",
       "        height: 24px;\n",
       "        margin: 1px;\n",
       "        padding: 2px 8px;\n",
       "        border: 1px solid var(--brandSecondary400);\n",
       "        font-style: normal;\n",
       "        color: var(--brandSecondary900);\n",
       "        border-radius: 20px;\n",
       "        white-space: nowrap;\n",
       "      }\n",
       "\n",
       "      /* Property side panel */\n",
       "\n",
       "      .wl-compare-profile {\n",
       "        position: relative;\n",
       "        left: 0;\n",
       "        padding: 18px;\n",
       "        background: var(--white);;\n",
       "        border-bottom: 1px solid var(--brandSecondary200);\n",
       "      }\n",
       "\n",
       "      /* Screen on smaller screens */\n",
       "      .no-responsive {\n",
       "        display: none;\n",
       "        position: fixed;\n",
       "        top: 0;\n",
       "        left: 0;\n",
       "        z-index: 1031;\n",
       "        width: 100vw;\n",
       "        height: 100vh;\n",
       "        background-color: var(--tealBackground);\n",
       "        display: flex;\n",
       "        align-items: center;\n",
       "        justify-content: center;\n",
       "      }\n",
       "\n",
       "      .no-responsive__content {\n",
       "        max-width: 600px;\n",
       "        width: 100%;\n",
       "        padding: 0 24px;\n",
       "      }\n",
       "\n",
       "      .no-responsive__title {\n",
       "        font-size: 96px;\n",
       "        font-weight: 300;\n",
       "        color: var(--brandSecondary900);\n",
       "        line-height: 1.167;\n",
       "      }\n",
       "\n",
       "      .no-responsive__text {\n",
       "        margin: 0;\n",
       "        font-size: 16px;\n",
       "        font-weight: 400;\n",
       "        color: var(--brandSecondary900);\n",
       "        line-height: 1.5;\n",
       "      }\n",
       "\n",
       "      .space-between {\n",
       "        display: flex;\n",
       "        justify-content: space-between;\n",
       "      }\n",
       "\n",
       "      .align-items {\n",
       "        display: flex;\n",
       "        align-items: center;\n",
       "      }\n",
       "\n",
       "      .display-flex{\n",
       "        display: flex;\n",
       "      }\n",
       "\n",
       "      .table-border-none {\n",
       "        padding: 0;\n",
       "        border: none;\n",
       "      }\n",
       "\n",
       "      .flex-direction-colum {\n",
       "        display: flex;\n",
       "        flex-direction: column;\n",
       "      }\n",
       "\n",
       "      .align-items {\n",
       "        align-items: center;\n",
       "      }\n",
       "\n",
       "      .search-input{\n",
       "        padding-top: 0 !important;\n",
       "        padding-bottom: 0 !important;\n",
       "      }\n",
       "\n",
       "      .search-input input{\n",
       "        border: none;\n",
       "        background: none;\n",
       "        outline: none;\n",
       "        height: 40px;\n",
       "        width: 100%;\n",
       "        font-size: 14px;\n",
       "      }\n",
       "\n",
       "      .search-input img{\n",
       "        height: 19px;\n",
       "        pointer-events: none;\n",
       "      }\n",
       "\n",
       "      input::placeholder {\n",
       "        color: var(--secondaryLight1000);\n",
       "      }\n",
       "\n",
       "      .text-align-center {\n",
       "        text-align: center;\n",
       "      }\n",
       "\n",
       "      .text-align-end {\n",
       "        text-align: end;\n",
       "      }\n",
       "\n",
       "      .drift-detection {\n",
       "        justify-content: space-between;\n",
       "        align-items: center;\n",
       "      }\n",
       "\n",
       "     .drift-detection-info-circle {\n",
       "       width: 15px;\n",
       "       height: 15px;\n",
       "       border-radius: 50px;\n",
       "       display: inline-block;\n",
       "       margin-right: 8px;\n",
       "     }\n",
       "\n",
       "     .severe-drift-circle-color {\n",
       "         background: #D40D00;\n",
       "     }\n",
       "\n",
       "     .moderate-drift-circle-color {\n",
       "         background: #F5843C;\n",
       "     }\n",
       "\n",
       "     .mild-drift-circle-color {\n",
       "         background: #F2C142;\n",
       "     }\n",
       "\n",
       "     .minimal-drift-circle-color {\n",
       "         background: #ABCA52;\n",
       "     }\n",
       "\n",
       "     .drift-detection-info-drifts-item {\n",
       "         padding-right: 20px;\n",
       "     }\n",
       "\n",
       "     .drift-detection-info-title {\n",
       "       font-family: Arial;\n",
       "       font-weight: bold;\n",
       "       font-size: 16px;\n",
       "       line-height: 130%;\n",
       "       color: #313B3D;\n",
       "     }\n",
       "\n",
       "     .drift-detection-info-drifts-item-count {\n",
       "       font-family: Arial;\n",
       "       font-weight: bold;\n",
       "       font-size: 14px;\n",
       "       line-height: 16px;\n",
       "       color: #000000;\n",
       "       padding-right: 8px;\n",
       "     }\n",
       "\n",
       "     .drift-detection-info-drifts-item-name {\n",
       "       font-family: Arial;\n",
       "       font-style: normal;\n",
       "       font-weight: normal;\n",
       "       font-size: 12px;\n",
       "       line-height: 14px;\n",
       "       color: #000000;\n",
       "     }\n",
       "\n",
       "     .drift-detection-info-drifts-item-range {\n",
       "       font-family: Arial;\n",
       "       font-style: normal;\n",
       "       font-weight: normal;\n",
       "       font-size: 11px;\n",
       "       line-height: 13px;\n",
       "       color: #6C757D;\n",
       "     }\n",
       "\n",
       "     .drift-detection-search-input {\n",
       "       display: flex;\n",
       "       align-items: center;\n",
       "       background: rgba(255, 255, 255, 0.7);\n",
       "       border: 1px solid #DBE5E7;\n",
       "       box-sizing: border-box;\n",
       "       border-radius: 4px;\n",
       "       width: 170px;\n",
       "       padding-left: 10px;\n",
       "     }\n",
       "\n",
       "     .drift-detection-search-input img{\n",
       "       margin-right: 5px;\n",
       "     }\n",
       "\n",
       "     .drift-detection-search-input input::placeholder {\n",
       "       font-family: Arial;\n",
       "       font-weight: normal;\n",
       "       font-size: 13px;\n",
       "       line-height: 16px;\n",
       "       color: #313B3D;\n",
       "     }\n",
       "\n",
       "     .close-filter-button {\n",
       "       display: flex;\n",
       "       justify-content: center;\n",
       "       align-items: center;\n",
       "       background: rgba(255, 255, 255, 0.7);\n",
       "       border: 1px solid #369BAC;\n",
       "       box-sizing: border-box;\n",
       "       border-radius: 4px;\n",
       "       width: 40px;\n",
       "       height: 40px;\n",
       "       cursor: pointer;\n",
       "       margin-left: 10px;\n",
       "     }\n",
       "\n",
       "     .filter-options-title {\n",
       "       width: 240px;\n",
       "     }\n",
       "\n",
       "     .filter-options-title p {\n",
       "       margin: 0;\n",
       "     }\n",
       "\n",
       "     .dropdown-container {\n",
       "       position: absolute;\n",
       "       right: 18px;\n",
       "       z-index: 999;\n",
       "       background: #FFFFFF;\n",
       "       border: 1px solid #DBE5E7;\n",
       "       box-sizing: border-box;\n",
       "       box-shadow: 0px 2px 8px rgba(0, 0, 0, 0.05);\n",
       "       border-radius: 4px;\n",
       "       padding: 10px !important;\n",
       "       border: none !important;\n",
       "     }\n",
       "\n",
       "     .form-check-input:checked {\n",
       "       background-color: #0E7384;\n",
       "       border-color: #0E7384;\n",
       "     }\n",
       "\n",
       "     .form-check-input[type=checkbox] {\n",
       "       border-radius: 2px;\n",
       "     }\n",
       "\n",
       "      .justify-content-center {\n",
       "        justify-content: center;\n",
       "      }\n",
       "\n",
       "      .wl-table-cell__graph-wrap {\n",
       "        width: 0;\n",
       "      }\n",
       "\n",
       "      .svg-container {\n",
       "        display: inline-block;\n",
       "        position: relative;\n",
       "        width: 85%;\n",
       "        padding-bottom: 17%;\n",
       "        vertical-align: top;\n",
       "        overflow: hidden;\n",
       "      }\n",
       "\n",
       "      .svg-content-responsive {\n",
       "        display: inline-block;\n",
       "        position: absolute;\n",
       "        left: 0;\n",
       "      }\n",
       "\n",
       "      .reference-table-head {\n",
       "        min-width: 250px;\n",
       "      }\n",
       "\n",
       "      .wl__dropdown_arrow-icon {\n",
       "        position: relative;\n",
       "      }\n",
       "\n",
       "      .notif-circle-container{\n",
       "        position: absolute;\n",
       "        top: -4px;\n",
       "        right: -4px;\n",
       "        padding: 5.3px;\n",
       "        border-radius: 50%;\n",
       "        background-color: white;\n",
       "        cursor: pointer;\n",
       "      }\n",
       "\n",
       "      .notif-circle {\n",
       "        position: absolute;\n",
       "        top: 2px;\n",
       "        right: 2px;\n",
       "        padding: 3.3px;\n",
       "        border-radius: 50%;\n",
       "        background-color: #F2994A;\n",
       "      }\n",
       "\n",
       "\n",
       "      .header-title {\n",
       "        font-size: 26px;\n",
       "        font-weight: 700;\n",
       "        color: #444444;\n",
       "      }\n",
       "\n",
       "      .statistic-number-title {\n",
       "        font-family: Arial;\n",
       "        font-weight: normal;\n",
       "        font-size: 14px;\n",
       "        line-height: 20px;\n",
       "        color: #6C757D;\n",
       "      }\n",
       "\n",
       "      .statistic-number {\n",
       "        font-family: Arial;\n",
       "        font-weight: bold;\n",
       "        font-size: 20px;\n",
       "        line-height: 140%;\n",
       "        display: flex;\n",
       "        align-items: center;\n",
       "        color: #0E7384;\n",
       "      }\n",
       "\n",
       "      .statistic-measurement {\n",
       "        font-size: 15px !important;\n",
       "        margin-left: 3px;\n",
       "      }\n",
       "\n",
       "      .statistic-measurement-percent {\n",
       "        font-size: 15px !important;\n",
       "      }\n",
       "\n",
       "      .question-mark {\n",
       "        font-size: 10px;\n",
       "        font-weight: 900;\n",
       "        color: #0E7384;\n",
       "        border-radius: 50px;\n",
       "        border: 2px solid #0E7384;\n",
       "        padding: 0px 4px;\n",
       "        transition: 0.5s;\n",
       "        cursor: pointer;\n",
       "      }\n",
       "\n",
       "      .question-mark:hover {\n",
       "        color: white;\n",
       "        background: #0E7384;\n",
       "        border: 2px solid none;\n",
       "        transition: 0.5s;\n",
       "      }\n",
       "\n",
       "      .tooltip-full-number {\n",
       "        position: relative;\n",
       "        display: inline-block;\n",
       "      }\n",
       "\n",
       "      .tooltip-full-number .tooltiptext {\n",
       "        visibility: hidden;\n",
       "        background: black;\n",
       "        color: white;\n",
       "        border: 1px solid black;\n",
       "        text-align: start;\n",
       "        padding: 3px;\n",
       "        position: absolute;\n",
       "        z-index: 1002;\n",
       "        top: 0;\n",
       "        left: 100%;\n",
       "        margin-left: 5px;\n",
       "        opacity: 0;\n",
       "        transition: opacity 0.5s;\n",
       "        font-size: 13px;\n",
       "        font-weight: normal;\n",
       "        line-height: 100%;\n",
       "      }\n",
       "\n",
       "      .tooltip-full-number:hover .tooltiptext {\n",
       "        visibility: visible;\n",
       "        opacity: 1;\n",
       "      }\n",
       "\n",
       "      .display-flex {\n",
       "        display: flex;\n",
       "      }\n",
       "\n",
       "      .flex-direction-column {\n",
       "        flex-direction: column;\n",
       "      }\n",
       "\n",
       "      .justify-content-space-between {\n",
       "        justify-content: space-between;\n",
       "      }\n",
       "\n",
       "      .justify-content-center {\n",
       "        justify-content: center;\n",
       "      }\n",
       "\n",
       "      .align-items-center {\n",
       "        align-items: center;\n",
       "      }\n",
       "\n",
       "      .padding-right-30 {\n",
       "        padding-right: 30px;\n",
       "      }\n",
       "\n",
       "      .padding-5 {\n",
       "        padding: 5px;\n",
       "      }\n",
       "\n",
       "      .text-color {\n",
       "        color: var(--secondaryLight1000);\n",
       "      }\n",
       "\n",
       "      .error-message {\n",
       "        display: flex;\n",
       "        justify-content: center;\n",
       "        align-items: center;\n",
       "        color: rgb(255, 114, 71);\n",
       "        font-size: 30px;\n",
       "        font-weight: 900;\n",
       "      }\n",
       "\n",
       "      @media screen and (min-width: 500px) {\n",
       "        .desktop-content {\n",
       "          display: block;\n",
       "        }\n",
       "        .no-responsive {\n",
       "          display: none;\n",
       "        }\n",
       "      }\n",
       "    &lt;/style&gt;\n",
       "  &lt;/head&gt;\n",
       "\n",
       "  &lt;body id=&quot;generated-html&quot;&gt;&lt;/body&gt;\n",
       "\n",
       "  &lt;script id=&quot;entry-template&quot; type=&quot;text/x-handlebars-template&quot;&gt;\n",
       "    \n",
       "      &lt;div class=&quot;desktop-content&quot;&gt;\n",
       "        &lt;div class=&quot;container-fluid&quot;&gt;\n",
       "          &lt;div class=&quot;feature-summary-statistics-wrap&quot;&gt;\n",
       "            &lt;div class=&quot;feature-summary-statistics&quot;&gt;\n",
       "              &lt;div class=&quot;mb-4&quot;&gt;\n",
       "                  &lt;strong class=&quot;header-title&quot;&gt;Profile Summary&lt;/strong&gt;\n",
       "              &lt;/div&gt;\n",
       "              &lt;div class=&quot;display-flex statistics&quot;&gt;\n",
       "                  &lt;div class=&quot;padding-right-30&quot;&gt;\n",
       "                    &lt;div class=&quot;statistic-number-title&quot;&gt;Observations\n",
       "                    &lt;div class=&quot;tooltip-full-number&quot;&gt;\n",
       "                      &lt;span class=&quot;question-mark&quot;&gt;?&lt;/span&gt;\n",
       "                    &lt;span class=&quot;tooltiptext&quot;&gt;\n",
       "                     &lt;div class=&quot;mb-1&quot;&gt;The sum of counts for each feature. For a single dataframe, it is equal to the number of cells, i.e., rows * columns.&lt;/div&gt;\n",
       "                    &lt;/span&gt;\n",
       "                    &lt;/div&gt;\n",
       "                    &lt;/div&gt;\n",
       "                    &lt;div class=&quot;statistic-number&quot;&gt;{{{observations this}}}&lt;/div&gt;\n",
       "\n",
       "                  &lt;/div&gt;\n",
       "                  &lt;div class=&quot;padding-right-30&quot;&gt;\n",
       "                    &lt;div class=&quot;statistic-number-title&quot;&gt;Missing Cells&lt;/div&gt;\n",
       "                    &lt;div class=&quot;statistic-number&quot;&gt;\n",
       "                      {{{missingCells this}}}\n",
       "                      &lt;div&gt;{{{missingCellsPercentage this}}}&lt;/div&gt;\n",
       "                    &lt;/div&gt;\n",
       "                  &lt;/div&gt;\n",
       "              &lt;/div&gt;\n",
       "            &lt;/div&gt;\n",
       "          &lt;/div&gt;\n",
       "          &lt;div class=&quot;row&quot;&gt;\n",
       "            &lt;div class=&quot;main&quot;&gt;\n",
       "              &lt;div class=&quot;wl-compare-profile&quot; id=&quot;compare-profile&quot;&gt;\n",
       "               &lt;div class=&quot;drift-detection-wrap&quot;&gt;\n",
       "                 &lt;div class=&quot;drift-detection display-flex&quot;&gt;\n",
       "                   &lt;div class=&quot;drift-detection-info flex-direction-colum&quot;&gt;\n",
       "                     &lt;div class=&quot;drift-detection-info-title-wrap display-flex&quot;&gt;\n",
       "                       &lt;p class=&quot;drift-detection-info-title&quot;&gt;\n",
       "                         Drift detected in\n",
       "                         &lt;span class=&quot;drift-count&quot;&gt;&lt;/span&gt;\n",
       "                         of\n",
       "                         &lt;span class=&quot;all-features&quot;&gt;&lt;/span&gt;\n",
       "                         features\n",
       "                       &lt;/p&gt;\n",
       "                     &lt;/div&gt;\n",
       "                     &lt;div class=&quot;drift-detection-info-drifts display-flex&quot; id=&quot;drift-detection-info-drifts&quot;&gt;\n",
       "                     &lt;/div&gt;\n",
       "                   &lt;/div&gt;\n",
       "                   &lt;div class=&quot;drift-detection-search-input-wrap display-flex&quot;&gt;\n",
       "                     &lt;div class=&quot;drift-detection-search-input search-input&quot;&gt;\n",
       "                       &lt;input type=&quot;text&quot; id=&quot;wl__feature-search&quot; placeholder=&quot;Quick search...&quot;/&gt;\n",
       "                       &lt;img src=&quot;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAGdSURBVHgBpZK7TkJBEIZnZoVocdTYyQNALxpNKPQBMEaNJsbCRMKhl8ISWwt6AaksCF5iTHgAGhJD4AHkAaAzGiwUsjvOQnO4SYh/cXbPzO43OxcEj9Zy92EiFSXNIfvPyE1kKFfdoxJMENpP6DrvLC0vJoEwCgwto7DWcxoIIHBYbA3NmKwnDltjAeuZhyul1DaTTlfPB6Nt5Z53DOgky4P875+nlctY2+unjZviLklkJhi5bPUa3y/7qJuQUM7PinMy7CdQc1Gh16vnBxPzrMROmlKQEgKNASAHLQCmSIGpS75O+O5pdQAgVXaIqTkNwDDXHmcnW3VmHZoGMLoTsOt88+NrAMCIZdu+iLTyTwKRa1Md6YKfOgXbzO7K8sWku5u5RxcRV5EpPezrzcHGbXEXWaUkgkweZ/UC9YrK3zqggFw5FBZfm8EUavHj7AjAKpIvBDrGn+pNnlcyhYgqbcC41idr1gvB4SdZkDbzQa21gwv0Vj07aPTtL07XdDOyDXohCDNoHIRmAVRie20f+RKybRDQDvxHkXy/7b/DrayncLbMwQAAAABJRU5ErkJggg==&quot;/&gt;\n",
       "                     &lt;/div&gt;\n",
       "                     &lt;div class=&quot;wl__dropdown_arrow-icon&quot;&gt;\n",
       "                       &lt;div onclick=&quot;openFilter()&quot; class=&quot;close-filter-button&quot;&gt;\n",
       "                         &lt;div class=&quot;display-flex close-filter-icon d-none&quot;&gt;\n",
       "                           &lt;img src=&quot;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAsAAAALCAYAAACprHcmAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAADFSURBVHgBfY+xDcIwEEXvnLQBZQkYAEhDwwKpEEK0CCZgAEjJCEmgjYSAygxAHTZgFRSOsyUjY5mcZFnn/+78PwBXf3+MoKWUPuYjVBPFnTwpr9t/oNJfcTfXsAhRAlDqDhhQIPYgpAqNMDqcUqSAYZT1epr9gAHt6uXshvYme4DYHQJNDKh0dD0m5WXB10Y3Fqjtuh7fROn3oREDWxfeMLyRsMnc0OgDzdduaA0Pi3Plgr7Q2kaAePeBqh6rueSNBVt6fgCwBV1JLF3rlAAAAABJRU5ErkJggg==&quot;/&gt;\n",
       "                         &lt;/div&gt;\n",
       "                         &lt;div class=&quot;display-flex filter-icon&quot;&gt;\n",
       "                           &lt;img src=&quot;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAPCAYAAADtc08vAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAACSSURBVHgBrZLBCYAwDEWTUjw7igcdwI1cxkNXUJzBEVzFAbSVKoKmaVrEB6GHJv/w+AACtRk7P9IONv1QOYUl96k0zv61m2tjARoLtSDI3EFsgIJ4uoXrMLazO72CRG2mzg/8BSdVlEjhpGZJjAWdAZJECpWalEhJSs1pHuUlMad5FFai1Lwg4Ckx1TxKIPFL8w55mEWd8VjPGAAAAABJRU5ErkJggg==&quot;/&gt;\n",
       "                         &lt;/div&gt;\n",
       "                       &lt;/div&gt;\n",
       "                       &lt;span class=&quot;notif-circle-container&quot;&gt;\n",
       "                         &lt;span class=&quot;notif-circle&quot;&gt;&lt;/span&gt;\n",
       "                       &lt;/span&gt;\n",
       "                     &lt;/div&gt;\n",
       "                   &lt;/div&gt;\n",
       "                 &lt;/div&gt;\n",
       "               &lt;/div&gt;\n",
       "               &lt;div class=&quot;dropdown-container flex-direction-colum mb-2 d-none&quot; id=&quot;dropdown-container&quot;&gt;\n",
       "                 &lt;div class=&quot;filter-options&quot;&gt;\n",
       "                   &lt;div class=&quot;filter-options-title space-between dropdown&quot;&gt;\n",
       "                     &lt;p&gt;Filter by type&lt;/p&gt;\n",
       "                   &lt;/div&gt;\n",
       "                   &lt;div class=&quot;form-check mb-1 mt-2&quot;&gt;\n",
       "                     &lt;input\n",
       "                       class=&quot;form-check-input wl__feature-filter-input&quot;\n",
       "                       type=&quot;checkbox&quot;\n",
       "                       name=&quot;checkbox&quot;\n",
       "                       value=&quot;Nodrift&quot;\n",
       "                       id=&quot;nodrift&quot;\n",
       "                       checked\n",
       "                     /&gt;\n",
       "                     &lt;label class=&quot;form-check-label&quot; for=&quot;nodrift&quot;&gt;\n",
       "                       No evidence of drift (&lt;span class=&quot;wl__feature-count--nodrift&quot;&gt;{{getNoDriftCount}}&lt;/span&gt;)\n",
       "                     &lt;/label&gt;\n",
       "                   &lt;/div&gt;\n",
       "                   &lt;div class=&quot;form-check mb-1&quot;&gt;\n",
       "                     &lt;input\n",
       "                       class=&quot;form-check-input wl__feature-filter-input&quot;\n",
       "                       type=&quot;checkbox&quot;\n",
       "                       name=&quot;checkbox&quot;\n",
       "                       value=&quot;Possibledrift&quot;\n",
       "                       id=&quot;possibledrift&quot;\n",
       "                       checked\n",
       "                     /&gt;\n",
       "                     &lt;label class=&quot;form-check-label&quot; for=&quot;possibledrift&quot;&gt;\n",
       "                       Possible drift (&lt;span\n",
       "                         class=&quot;wl__feature-count--possibledrift&quot;\n",
       "                       &gt;{{getPossibleDriftCount}}&lt;/span&gt;)\n",
       "                     &lt;/label&gt;\n",
       "                   &lt;/div&gt;\n",
       "                   &lt;div class=&quot;form-check mb-1&quot;&gt;\n",
       "                     &lt;input\n",
       "                       class=&quot;form-check-input wl__feature-filter-input&quot;\n",
       "                       type=&quot;checkbox&quot;\n",
       "                       name=&quot;checkbox&quot;\n",
       "                       value=&quot;Detecteddrift&quot;\n",
       "                       id=&quot;detecteddrift&quot;\n",
       "                       checked\n",
       "                     /&gt;\n",
       "                     &lt;label class=&quot;form-check-label&quot; for=&quot;detecteddrift&quot;&gt;\n",
       "                       Detected drift (&lt;span class=&quot;wl__feature-count--drift&quot;&gt;{{getDriftCount}}&lt;/span&gt;)\n",
       "                     &lt;/label&gt;\n",
       "                   &lt;/div&gt;\n",
       "                   &lt;div class=&quot;form-check mb-1&quot;&gt;\n",
       "                    &lt;input\n",
       "                      class=&quot;form-check-input wl__feature-filter-input&quot;\n",
       "                      type=&quot;checkbox&quot;\n",
       "                      name=&quot;checkbox&quot;\n",
       "                      value=&quot;Unknowndrift&quot;\n",
       "                      id=&quot;unknowndrift&quot;\n",
       "                      checked\n",
       "                    /&gt;\n",
       "                    &lt;label class=&quot;form-check-label&quot; for=&quot;unknowndrift&quot;&gt;\n",
       "                      Unknown (&lt;span\n",
       "                        class=&quot;wl__feature-count--unknown&quot;\n",
       "                      &gt;{{getUnknownDriftCount}}&lt;/span&gt;)\n",
       "                    &lt;/label&gt;\n",
       "                  &lt;/div&gt;\n",
       "\n",
       "                 &lt;/div&gt;\n",
       "               &lt;/div&gt;\n",
       "              &lt;/div&gt;\n",
       "              &lt;div class=&quot;wl-table-wrap&quot; id=&quot;table-content&quot;&gt;\n",
       "                &lt;div class=&quot;wl-table&quot;&gt;\n",
       "                  &lt;div class=&quot;wl-table-heading&quot;&gt;\n",
       "                    &lt;div class=&quot;wl-table-row wl-table-row--bottom-shadow&quot;&gt;\n",
       "                      &lt;div class=&quot;wl-table-head wl-table-head-wraper&quot;&gt;\n",
       "                        &lt;div class=&quot;wl-table-head table-border-none graph-table-head&quot;&gt;Target&lt;/div&gt;\n",
       "                        &lt;div class=&quot;wl-table-head table-border-none reference-table-head&quot;&gt;Reference&lt;/div&gt;\n",
       "                      &lt;/div&gt;\n",
       "                      &lt;div class=&quot;wl-table-head wl-table-head-wraper text-align-center&quot; style=&quot;cursor: pointer;&quot; id=&quot;diff-from-ref&quot;&gt;\n",
       "                        &lt;div class=&quot;pvalue&quot;&gt;Drift Score\n",
       "                          &lt;div class=&quot;tooltip-full-number&quot;&gt;\n",
       "                            &lt;span class=&quot;question-mark&quot;&gt;?&lt;/span&gt;\n",
       "                          &lt;span class=&quot;tooltiptext&quot;&gt;\n",
       "                           &lt;div class=&quot;mb-1&quot;&gt;Drift is evaluated against pvalue, if present, and against statistic otherwise.&lt;/div&gt;\n",
       "                          &lt;/span&gt;\n",
       "                        &lt;/div&gt;\n",
       "                        &lt;/div&gt;\n",
       "                      &lt;/div&gt;\n",
       "                      &lt;div class=&quot;wl-table-head wl-table-head-wraper text-align-end&quot;&gt;Data Drift&lt;/div&gt;\n",
       "                      &lt;div class=&quot;wl-table-head wl-table-head-wraper text-align-end&quot;&gt;Total count&lt;/div&gt;\n",
       "                    &lt;/div&gt;\n",
       "                  &lt;/div&gt;\n",
       "                  &lt;ul class=&quot;wl-table-body wl__table-body&quot; id=&quot;table-body&quot;&gt;\n",
       "{{#each this.columns}}                    &lt;li\n",
       "                    {{#if this.numberSummary}} class=&quot;wl-table-row wl-table-row--clickable&quot; {{else}} class=&quot;wl-table-row&quot; {{/if}}\n",
       "                    data-feature-name={{@key}}\n",
       "                    data-drift-category={{driftCategory this}}\n",
       "                    data-scroll-to-feature-name={{@key}}\n",
       "                    data-p-value={{getpvalue this}}\n",
       "                  &gt;\n",
       "                      &lt;div class=&quot;wl-table-cell wl-table-cell__graph-wrap&quot;&gt;\n",
       "                        &lt;div class=&quot;wl-table-cell__title-wrap&quot;&gt;\n",
       "                          &lt;h4 class=&quot;wl-table-cell__title&quot;&gt;{{@key}}&lt;/h4&gt;\n",
       "                          &lt;div&gt;&lt;/div&gt;\n",
       "                        &lt;/div&gt;\n",
       "                          &lt;div class=&quot;display-flex&quot;&gt;\n",
       "                              {{{getGraphHtml this}}}\n",
       "                              {{{getReferenceGraphHtml this}}}\n",
       "                          &lt;/div&gt;\n",
       "                      &lt;/div&gt;\n",
       "                      &lt;div\n",
       "                        class=&quot;diff-from-ref-table-cell wl-table-cell wl-table-cell--top-spacing align-middle&quot;\n",
       "                        style=&quot;max-width: 270px; padding-right: 18px&quot;\n",
       "                      &gt;&lt;div class=&quot;wl-table-cell__bedge-wrap text-align-end&quot;&gt;\n",
       "                           {{{getDiffFromRef this}}}\n",
       "                        &lt;/div&gt;&lt;/div&gt;&lt;div\n",
       "                        class=&quot;wl-table-cell wl-table-cell--top-spacing align-middle&quot;\n",
       "                      &gt;&lt;div class=&quot;text-align-end&quot;&gt;{{getDriftCategory this}}\n",
       "                        &lt;div class=&quot;tooltip-full-number&quot;&gt;\n",
       "                          &lt;span class=&quot;question-mark&quot;&gt;?&lt;/span&gt;\n",
       "                        &lt;span class=&quot;tooltiptext&quot;&gt;\n",
       "                        &lt;div class=&quot;mb-1&quot;&gt;&lt;pre class=&quot;mb-1&quot;&gt;{{getThresholds this}}&lt;/pre&gt;&lt;/div&gt;\n",
       "                        &lt;/span&gt;\n",
       "                      &lt;/div&gt;\n",
       "                      &lt;/div&gt;\n",
       "\n",
       "                      &lt;/div&gt;\n",
       "                      &lt;div\n",
       "                        class=&quot;wl-table-cell wl-table-cell--top-spacing align-middle&quot;\n",
       "                      &gt;&lt;div class=&quot;text-align-end&quot;&gt;{{totalCount this}}&lt;/div&gt;&lt;/div&gt;\n",
       "                    &lt;/li&gt;\n",
       "{{/each}}                  &lt;/ul&gt;\n",
       "                &lt;/div&gt;\n",
       "              &lt;/div&gt;\n",
       "            &lt;/div&gt;\n",
       "          &lt;/div&gt;\n",
       "        &lt;/div&gt;\n",
       "      &lt;/div&gt;\n",
       "      &lt;div class=&quot;no-responsive&quot;&gt;\n",
       "        &lt;div class=&quot;no-responsive__content&quot;&gt;\n",
       "          &lt;h1 class=&quot;no-responsive__title&quot;&gt;Hold on! :)&lt;/h1&gt;\n",
       "          &lt;p class=&quot;no-responsive__text&quot;&gt;\n",
       "            It looks like your current screen size or device is not yet supported by the WhyLabs Sandbox. The Sandbox is\n",
       "            best experienced on a desktop computer. Please try maximizing this window or switching to another device. We\n",
       "            are working on adding support for a larger variety of devices.\n",
       "          &lt;/p&gt;\n",
       "        &lt;/div&gt;\n",
       "      &lt;/div&gt;\n",
       "    \n",
       "  &lt;/script&gt;\n",
       "\n",
       "  &lt;script src=&quot;https://code.jquery.com/jquery-3.6.0.min.js&quot; integrity=&quot;sha256-/xUj+3OJU5yExlq6GSYGSHk7tPXikynS7ogEvDej/m4=&quot; crossorigin=&quot;anonymous&quot;&gt;&lt;/script&gt;\n",
       "\n",
       "  &lt;script src=&quot;https://cdnjs.cloudflare.com/ajax/libs/d3/6.7.0/d3.min.js&quot; integrity=&quot;sha512-cd6CHE+XWDQ33ElJqsi0MdNte3S+bQY819f7p3NUHgwQQLXSKjE4cPZTeGNI+vaxZynk1wVU3hoHmow3m089wA==&quot; crossorigin=&quot;anonymous&quot; referrerpolicy=&quot;no-referrer&quot;&gt;&lt;/script&gt;\n",
       "\n",
       "  &lt;script&gt;\n",
       "    const getReferenceProfile = () =&gt; { return {&quot;columns&quot;: {&quot;fixed acidity&quot;: {&quot;histogram&quot;: {&quot;start&quot;: 5.0, &quot;end&quot;: 15.0000015, &quot;width&quot;: 0, &quot;counts&quot;: [4, 5, 16, 24, 50, 124, 140, 120, 155, 90, 54, 85, 52, 38, 53, 24, 30, 22, 14, 28, 21, 10, 12, 8, 6, 0, 4, 0, 0, 2], &quot;max&quot;: 15.0, &quot;min&quot;: 5.0, &quot;bins&quot;: [5.0, 5.333333383333334, 5.666666766666666, 6.00000015, 6.333333533333334, 6.666666916666667, 7.0000003, 7.333333683333334, 7.666667066666667, 8.00000045, 8.333333833333334, 8.666667216666667, 9.0000006, 9.333333983333333, 9.666667366666667, 10.00000075, 10.333334133333334, 10.666667516666667, 11.0000009, 11.333334283333333, 11.666667666666667, 12.00000105, 12.333334433333334, 12.666667816666667, 13.0000012, 13.333334583333334, 13.666667966666667, 14.00000135, 14.333334733333334, 14.666668116666667, 15.0000015], &quot;n&quot;: 1191}, &quot;frequentItems&quot;: null, &quot;drift_from_ref&quot;: {&quot;algorithm&quot;: &quot;ks&quot;, &quot;pvalue&quot;: 6.69437210173219e-08, &quot;statistic&quot;: 0.1672408258013533, &quot;thresholds&quot;: {&quot;NO_DRIFT&quot;: [0.15, 1], &quot;POSSIBLE_DRIFT&quot;: [0.05, 0.15], &quot;DRIFT&quot;: [0, 0.05]}, &quot;drift_category&quot;: &quot;DRIFT&quot;, &quot;primary_value&quot;: 6.69437210173219e-08}, &quot;isDiscrete&quot;: false, &quot;featureStats&quot;: null}, &quot;volatile acidity&quot;: {&quot;histogram&quot;: {&quot;start&quot;: 0.18, &quot;end&quot;: 1.580000158, &quot;width&quot;: 0, &quot;counts&quot;: [14, 38, 63, 65, 115, 115, 92, 109, 161, 123, 100, 61, 46, 20, 23, 16, 8, 9, 5, 0, 2, 2, 0, 0, 2, 0, 0, 0, 0, 2], &quot;max&quot;: 1.58, &quot;min&quot;: 0.18, &quot;bins&quot;: [0.18, 0.22666667193333334, 0.27333334386666663, 0.3200000158, 0.36666668773333333, 0.4133333596666667, 0.46000003159999997, 0.5066667035333333, 0.5533333754666667, 0.6000000474, 0.6466667193333333, 0.6933333912666666, 0.7400000631999999, 0.7866667351333334, 0.8333334070666667, 0.880000079, 0.9266667509333333, 0.9733334228666666, 1.0200000948, 1.0666667667333334, 1.1133334386666667, 1.1600001106, 1.2066667825333333, 1.2533334544666666, 1.3000001263999998, 1.3466667983333334, 1.3933334702666667, 1.4400001422, 1.4866668141333332, 1.5333334860666665, 1.580000158], &quot;n&quot;: 1191}, &quot;frequentItems&quot;: null, &quot;drift_from_ref&quot;: {&quot;algorithm&quot;: &quot;ks&quot;, &quot;pvalue&quot;: 1.160530015945676e-13, &quot;statistic&quot;: 0.2221748901071764, &quot;thresholds&quot;: {&quot;NO_DRIFT&quot;: [0.15, 1], &quot;POSSIBLE_DRIFT&quot;: [0.05, 0.15], &quot;DRIFT&quot;: [0, 0.05]}, &quot;drift_category&quot;: &quot;DRIFT&quot;, &quot;primary_value&quot;: 1.160530015945676e-13}, &quot;isDiscrete&quot;: false, &quot;featureStats&quot;: null}, &quot;citric acid&quot;: {&quot;histogram&quot;: {&quot;start&quot;: 0.0, &quot;end&quot;: 1.0000001, &quot;width&quot;: 0, &quot;counts&quot;: [179, 64, 91, 49, 38, 77, 74, 106, 67, 63, 40, 51, 35, 39, 95, 28, 27, 23, 10, 16, 12, 0, 4, 1, 0, 0, 0, 0, 0, 2], &quot;max&quot;: 1.0, &quot;min&quot;: 0.0, &quot;bins&quot;: [0.0, 0.03333333666666667, 0.06666667333333334, 0.10000001000000001, 0.13333334666666669, 0.16666668333333334, 0.20000002000000003, 0.2333333566666667, 0.26666669333333337, 0.30000003000000003, 0.3333333666666667, 0.3666667033333334, 0.40000004000000006, 0.4333333766666667, 0.4666667133333334, 0.50000005, 0.5333333866666667, 0.5666667233333335, 0.6000000600000001, 0.6333333966666668, 0.6666667333333334, 0.7000000700000001, 0.7333334066666668, 0.7666667433333334, 0.8000000800000001, 0.8333334166666668, 0.8666667533333334, 0.9000000900000001, 0.9333334266666669, 0.9666667633333335, 1.0000001], &quot;n&quot;: 1191}, &quot;frequentItems&quot;: null, &quot;drift_from_ref&quot;: {&quot;algorithm&quot;: &quot;ks&quot;, &quot;pvalue&quot;: 1.3615177857137967e-12, &quot;statistic&quot;: 0.21519435970785916, &quot;thresholds&quot;: {&quot;NO_DRIFT&quot;: [0.15, 1], &quot;POSSIBLE_DRIFT&quot;: [0.05, 0.15], &quot;DRIFT&quot;: [0, 0.05]}, &quot;drift_category&quot;: &quot;DRIFT&quot;, &quot;primary_value&quot;: 1.3615177857137967e-12}, &quot;isDiscrete&quot;: false, &quot;featureStats&quot;: null}, &quot;residual sugar&quot;: {&quot;histogram&quot;: {&quot;start&quot;: 1.2, &quot;end&quot;: 15.50000155, &quot;width&quot;: 0, &quot;counts&quot;: [109, 475, 360, 108, 33, 26, 13, 4, 8, 17, 11, 3, 4, 1, 4, 2, 2, 0, 0, 2, 2, 0, 0, 0, 0, 0, 3, 0, 0, 4], &quot;max&quot;: 15.5, &quot;min&quot;: 1.2, &quot;bins&quot;: [1.2, 1.6766667183333333, 2.1533334366666668, 2.6300001550000003, 3.1066668733333334, 3.5833335916666664, 4.06000031, 4.5366670283333335, 5.0133337466666665, 5.4900004650000005, 5.966667183333334, 6.443333901666667, 6.920000620000001, 7.396667338333334, 7.873334056666667, 8.350000775, 8.826667493333334, 9.303334211666666, 9.78000093, 10.256667648333332, 10.733334366666666, 11.210001085, 11.686667803333332, 12.163334521666666, 12.64000124, 13.116667958333332, 13.593334676666666, 14.070001395, 14.546668113333332, 15.023334831666666, 15.50000155], &quot;n&quot;: 1191}, &quot;frequentItems&quot;: null, &quot;drift_from_ref&quot;: {&quot;algorithm&quot;: &quot;ks&quot;, &quot;pvalue&quot;: 0.0033840255260516663, &quot;statistic&quot;: 0.10182372697189707, &quot;thresholds&quot;: {&quot;NO_DRIFT&quot;: [0.15, 1], &quot;POSSIBLE_DRIFT&quot;: [0.05, 0.15], &quot;DRIFT&quot;: [0, 0.05]}, &quot;drift_category&quot;: &quot;DRIFT&quot;, &quot;primary_value&quot;: 0.0033840255260516663}, &quot;isDiscrete&quot;: false, &quot;featureStats&quot;: null}, &quot;chlorides&quot;: {&quot;histogram&quot;: {&quot;start&quot;: 0.038, &quot;end&quot;: 0.6110000610999999, &quot;width&quot;: 0, &quot;counts&quot;: [36, 379, 545, 131, 31, 10, 13, 6, 4, 6, 5, 3, 0, 0, 0, 4, 2, 2, 2, 8, 0, 0, 2, 0, 0, 0, 0, 0, 0, 2], &quot;max&quot;: 0.611, &quot;min&quot;: 0.038, &quot;bins&quot;: [0.038, 0.05710000203666667, 0.07620000407333333, 0.09530000611, 0.11440000814666665, 0.13350001018333332, 0.15260001222, 0.17170001425666664, 0.19080001629333332, 0.20990001833, 0.22900002036666664, 0.24810002240333331, 0.26720002443999996, 0.28630002647666664, 0.30540002851333325, 0.32450003054999993, 0.3436000325866666, 0.3627000346233333, 0.38180003665999995, 0.40090003869666657, 0.42000004073333325, 0.4391000427699999, 0.4582000448066666, 0.47730004684333327, 0.49640004887999994, 0.5155000509166666, 0.5346000529533332, 0.55370005499, 0.5728000570266666, 0.5919000590633333, 0.6110000610999999], &quot;n&quot;: 1191}, &quot;frequentItems&quot;: null, &quot;drift_from_ref&quot;: {&quot;algorithm&quot;: &quot;ks&quot;, &quot;pvalue&quot;: 1.784913412173917e-27, &quot;statistic&quot;: 0.3159418679310515, &quot;thresholds&quot;: {&quot;NO_DRIFT&quot;: [0.15, 1], &quot;POSSIBLE_DRIFT&quot;: [0.05, 0.15], &quot;DRIFT&quot;: [0, 0.05]}, &quot;drift_category&quot;: &quot;DRIFT&quot;, &quot;primary_value&quot;: 1.784913412173917e-27}, &quot;isDiscrete&quot;: false, &quot;featureStats&quot;: null}, &quot;free sulfur dioxide&quot;: {&quot;histogram&quot;: {&quot;start&quot;: 1.0, &quot;end&quot;: 72.0000072, &quot;width&quot;: 0, &quot;counts&quot;: [31, 107, 186, 105, 105, 132, 92, 63, 77, 47, 72, 36, 31, 39, 20, 5, 17, 3, 2, 4, 2, 6, 4, 0, 0, 0, 0, 1, 2, 2], &quot;max&quot;: 72.0, &quot;min&quot;: 1.0, &quot;bins&quot;: [1.0, 3.3666669066666666, 5.733333813333333, 8.10000072, 10.466667626666666, 12.833334533333332, 15.20000144, 17.566668346666667, 19.933335253333333, 22.30000216, 24.666669066666664, 27.033335973333333, 29.40000288, 31.766669786666665, 34.133336693333334, 36.5000036, 38.866670506666665, 41.23333741333333, 43.60000432, 45.96667122666666, 48.33333813333333, 50.70000504, 53.066671946666666, 55.43333885333333, 57.80000576, 60.16667266666666, 62.53333957333333, 64.90000648, 67.26667338666667, 69.63334029333333, 72.0000072], &quot;n&quot;: 1191}, &quot;frequentItems&quot;: null, &quot;drift_from_ref&quot;: {&quot;algorithm&quot;: &quot;ks&quot;, &quot;pvalue&quot;: 0.016036399887931697, &quot;statistic&quot;: 0.08850076554551295, &quot;thresholds&quot;: {&quot;NO_DRIFT&quot;: [0.15, 1], &quot;POSSIBLE_DRIFT&quot;: [0.05, 0.15], &quot;DRIFT&quot;: [0, 0.05]}, &quot;drift_category&quot;: &quot;DRIFT&quot;, &quot;primary_value&quot;: 0.016036399887931697}, &quot;isDiscrete&quot;: false, &quot;featureStats&quot;: null}, &quot;total sulfur dioxide&quot;: {&quot;histogram&quot;: {&quot;start&quot;: 6.0, &quot;end&quot;: 160.000016, &quot;width&quot;: 0, &quot;counts&quot;: [44, 96, 100, 99, 103, 68, 79, 98, 60, 56, 50, 51, 36, 28, 21, 37, 25, 23, 13, 18, 15, 5, 20, 10, 8, 6, 10, 6, 4, 2], &quot;max&quot;: 160.0, &quot;min&quot;: 6.0, &quot;bins&quot;: [6.0, 11.133333866666666, 16.266667733333332, 21.400001599999996, 26.533335466666664, 31.66666933333333, 36.80000319999999, 41.93333706666666, 47.06667093333333, 52.200004799999995, 57.33333866666666, 62.46667253333332, 67.60000639999998, 72.73334026666666, 77.86667413333332, 83.000008, 88.13334186666665, 93.26667573333332, 98.40000959999999, 103.53334346666665, 108.66667733333333, 113.80001119999999, 118.93334506666665, 124.06667893333332, 129.20001279999997, 134.33334666666664, 139.46668053333332, 144.6000144, 149.73334826666664, 154.8666821333333, 160.000016], &quot;n&quot;: 1191}, &quot;frequentItems&quot;: null, &quot;drift_from_ref&quot;: {&quot;algorithm&quot;: &quot;ks&quot;, &quot;pvalue&quot;: 2.0762015466878437e-12, &quot;statistic&quot;: 0.21148812169704156, &quot;thresholds&quot;: {&quot;NO_DRIFT&quot;: [0.15, 1], &quot;POSSIBLE_DRIFT&quot;: [0.05, 0.15], &quot;DRIFT&quot;: [0, 0.05]}, &quot;drift_category&quot;: &quot;DRIFT&quot;, &quot;primary_value&quot;: 2.0762015466878437e-12}, &quot;isDiscrete&quot;: false, &quot;featureStats&quot;: null}, &quot;density&quot;: {&quot;histogram&quot;: {&quot;start&quot;: 0.99236, &quot;end&quot;: 1.003690100369, &quot;width&quot;: 0, &quot;counts&quot;: [1, 1, 3, 2, 4, 11, 34, 42, 74, 95, 132, 136, 127, 128, 100, 84, 43, 43, 36, 31, 28, 16, 4, 6, 2, 0, 4, 2, 0, 2], &quot;max&quot;: 1.00369, &quot;min&quot;: 0.99236, &quot;bins&quot;: [0.99236, 0.9927376700123001, 0.9931153400246, 0.9934930100369, 0.9938706800492, 0.9942483500615, 0.9946260200738, 0.9950036900861, 0.9953813600984001, 0.9957590301107, 0.996136700123, 0.9965143701353, 0.9968920401476, 0.9972697101599, 0.9976473801722, 0.9980250501845, 0.9984027201968, 0.9987803902091, 0.9991580602214, 0.9995357302337, 0.999913400246, 1.0002910702582999, 1.0006687402706, 1.0010464102829, 1.0014240802952, 1.0018017503075, 1.0021794203198, 1.0025570903321, 1.0029347603443999, 1.0033124303567, 1.003690100369], &quot;n&quot;: 1191}, &quot;frequentItems&quot;: null, &quot;drift_from_ref&quot;: {&quot;algorithm&quot;: &quot;ks&quot;, &quot;pvalue&quot;: 7.9303277449007265e-81, &quot;statistic&quot;: 0.531918308885267, &quot;thresholds&quot;: {&quot;NO_DRIFT&quot;: [0.15, 1], &quot;POSSIBLE_DRIFT&quot;: [0.05, 0.15], &quot;DRIFT&quot;: [0, 0.05]}, &quot;drift_category&quot;: &quot;DRIFT&quot;, &quot;primary_value&quot;: 7.9303277449007265e-81}, &quot;isDiscrete&quot;: false, &quot;featureStats&quot;: null}, &quot;pH&quot;: {&quot;histogram&quot;: {&quot;start&quot;: 2.74, &quot;end&quot;: 3.750000375, &quot;width&quot;: 0, &quot;counts&quot;: [2, 0, 0, 2, 5, 8, 0, 10, 23, 24, 45, 42, 79, 99, 65, 87, 147, 92, 106, 126, 58, 62, 27, 35, 19, 15, 2, 7, 4, 0], &quot;max&quot;: 3.75, &quot;min&quot;: 2.74, &quot;bins&quot;: [2.74, 2.773666679166667, 2.8073333583333335, 2.8410000375, 2.874666716666667, 2.9083333958333335, 2.942000075, 2.975666754166667, 3.0093334333333335, 3.0430001125, 3.076666791666667, 3.1103334708333334, 3.14400015, 3.1776668291666668, 3.2113335083333334, 3.2450001875, 3.2786668666666667, 3.3123335458333334, 3.346000225, 3.3796669041666667, 3.4133335833333334, 3.4470002625, 3.4806669416666667, 3.5143336208333333, 3.5480003, 3.5816669791666667, 3.6153336583333333, 3.6490003375, 3.6826670166666666, 3.7163336958333333, 3.750000375], &quot;n&quot;: 1191}, &quot;frequentItems&quot;: null, &quot;drift_from_ref&quot;: {&quot;algorithm&quot;: &quot;ks&quot;, &quot;pvalue&quot;: 0.0003157364134524475, &quot;statistic&quot;: 0.11929545117795237, &quot;thresholds&quot;: {&quot;NO_DRIFT&quot;: [0.15, 1], &quot;POSSIBLE_DRIFT&quot;: [0.05, 0.15], &quot;DRIFT&quot;: [0, 0.05]}, &quot;drift_category&quot;: &quot;DRIFT&quot;, &quot;primary_value&quot;: 0.0003157364134524475}, &quot;isDiscrete&quot;: false, &quot;featureStats&quot;: null}, &quot;sulphates&quot;: {&quot;histogram&quot;: {&quot;start&quot;: 0.33, &quot;end&quot;: 2.0000002, &quot;width&quot;: 0, &quot;counts&quot;: [3, 30, 100, 219, 231, 215, 110, 84, 72, 31, 29, 14, 8, 13, 6, 10, 0, 4, 4, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 4], &quot;max&quot;: 2.0, &quot;min&quot;: 0.33, &quot;bins&quot;: [0.33, 0.3856666733333334, 0.4413333466666667, 0.49700002, 0.5526666933333333, 0.6083333666666666, 0.66400004, 0.7196667133333334, 0.7753333866666667, 0.83100006, 0.8866667333333333, 0.9423334066666667, 0.99800008, 1.0536667533333333, 1.1093334266666668, 1.1650001, 1.2206667733333334, 1.2763334466666667, 1.33200012, 1.3876667933333333, 1.4433334666666666, 1.4990001400000001, 1.5546668133333335, 1.6103334866666668, 1.66600016, 1.7216668333333334, 1.7773335066666667, 1.83300018, 1.8886668533333335, 1.9443335266666668, 2.0000002], &quot;n&quot;: 1191}, &quot;frequentItems&quot;: null, &quot;drift_from_ref&quot;: {&quot;algorithm&quot;: &quot;ks&quot;, &quot;pvalue&quot;: 1.3923726824145813e-09, &quot;statistic&quot;: 0.18502741146836565, &quot;thresholds&quot;: {&quot;NO_DRIFT&quot;: [0.15, 1], &quot;POSSIBLE_DRIFT&quot;: [0.05, 0.15], &quot;DRIFT&quot;: [0, 0.05]}, &quot;drift_category&quot;: &quot;DRIFT&quot;, &quot;primary_value&quot;: 1.3923726824145813e-09}, &quot;isDiscrete&quot;: false, &quot;featureStats&quot;: null}, &quot;alcohol&quot;: {&quot;histogram&quot;: {&quot;start&quot;: 8.4, &quot;end&quot;: 11.0000011, &quot;width&quot;: 0, &quot;counts&quot;: [2, 1, 0, 2, 2, 0, 31, 1, 22, 74, 59, 103, 139, 63, 53, 0, 79, 50, 69, 47, 45, 33, 0, 42, 69, 28, 26, 43, 50, 58], &quot;max&quot;: 11.0, &quot;min&quot;: 8.4, &quot;bins&quot;: [8.4, 8.486666703333334, 8.573333406666666, 8.66000011, 8.746666813333334, 8.833333516666666, 8.92000022, 9.006666923333334, 9.093333626666666, 9.18000033, 9.266667033333334, 9.353333736666666, 9.44000044, 9.526667143333334, 9.613333846666666, 9.70000055, 9.786667253333334, 9.873333956666666, 9.96000066, 10.046667363333334, 10.133334066666666, 10.22000077, 10.306667473333334, 10.393334176666666, 10.48000088, 10.566667583333334, 10.653334286666666, 10.74000099, 10.826667693333334, 10.913334396666666, 11.0000011], &quot;n&quot;: 1191}, &quot;frequentItems&quot;: null, &quot;drift_from_ref&quot;: {&quot;algorithm&quot;: &quot;ks&quot;, &quot;pvalue&quot;: 0.0, &quot;statistic&quot;: 1.0, &quot;thresholds&quot;: {&quot;NO_DRIFT&quot;: [0.15, 1], &quot;POSSIBLE_DRIFT&quot;: [0.05, 0.15], &quot;DRIFT&quot;: [0, 0.05]}, &quot;drift_category&quot;: &quot;DRIFT&quot;, &quot;primary_value&quot;: 1.0}, &quot;isDiscrete&quot;: false, &quot;featureStats&quot;: null}, &quot;quality&quot;: {&quot;histogram&quot;: null, &quot;frequentItems&quot;: [{&quot;value&quot;: &quot;bad&quot;, &quot;estimate&quot;: 1115}, {&quot;value&quot;: &quot;good&quot;, &quot;estimate&quot;: 76}], &quot;drift_from_ref&quot;: {&quot;algorithm&quot;: &quot;chi-square&quot;, &quot;pvalue&quot;: 4.72188097163335e-120, &quot;statistic&quot;: 542.7640823743186, &quot;thresholds&quot;: {&quot;NO_DRIFT&quot;: [0.15, 1], &quot;POSSIBLE_DRIFT&quot;: [0.05, 0.15], &quot;DRIFT&quot;: [0, 0.05]}, &quot;drift_category&quot;: &quot;DRIFT&quot;, &quot;primary_value&quot;: 4.72188097163335e-120}, &quot;isDiscrete&quot;: true, &quot;featureStats&quot;: null}}, &quot;properties&quot;: {&quot;observations&quot;: 4896, &quot;missing_cells&quot;: 10, &quot;missing_percentage&quot;: 0.20424836601307192}} }\n",
       "    const referenceProfile = getReferenceProfile()\n",
       "\n",
       "    function fixNumberTo(number, decimals = 3) {\n",
       "      const fractionalDigits = String(number % 1).split(&#x27;&#x27;).slice(2, 2 + decimals).join(&#x27;&#x27;)\n",
       "      return `${Math.trunc(number)}.${fractionalDigits}`\n",
       "    }\n",
       "\n",
       "    function registerHandlebarHelperFunctions() {\n",
       "      //helper fun\n",
       "\n",
       "      class GenerateChartParams {\n",
       "        constructor(height, width, data, bottomMargin=20, topMargin=5) {\n",
       "          this.MARGIN = {\n",
       "            TOP: topMargin,\n",
       "            RIGHT: 5,\n",
       "            BOTTOM: bottomMargin,\n",
       "            LEFT: 55,\n",
       "          };\n",
       "          this.SVG_WIDTH = width;\n",
       "          this.SVG_HEIGHT = height;\n",
       "          this.CHART_WIDTH = this.SVG_WIDTH - this.MARGIN.LEFT - this.MARGIN.RIGHT;\n",
       "          this.CHART_HEIGHT = this.SVG_HEIGHT - this.MARGIN.TOP - this.MARGIN.BOTTOM;\n",
       "          this.svgEl = d3.create(&quot;svg&quot;)\n",
       "             .attr(&quot;preserveAspectRatio&quot;, &quot;xMinYMin meet&quot;)\n",
       "             .attr(&quot;viewBox&quot;, &quot;30 0 240 400&quot;)\n",
       "             .classed(&quot;svg-content-responsive&quot;, true)\n",
       "          this.maxYValue = d3.max(data, (d) =&gt; Math.abs(d.axisY));\n",
       "          this.xScale = d3\n",
       "            .scaleBand()\n",
       "            .domain(data.map((d) =&gt; d.axisX))\n",
       "            .range([this.MARGIN.LEFT, this.MARGIN.LEFT + this.CHART_WIDTH]);\n",
       "          this.yScale = d3\n",
       "            .scaleLinear()\n",
       "            .domain([0, this.maxYValue * 1.02])\n",
       "            .range([this.CHART_HEIGHT, 0]);\n",
       "        }\n",
       "      }\n",
       "\n",
       "      function generateChart(data, height = 70, width = 250, index = 0, referenceProfileExist = false) {\n",
       "        const sizes = new GenerateChartParams(height, width, data, 5)\n",
       "        const {\n",
       "          MARGIN,\n",
       "          SVG_WIDTH,\n",
       "          SVG_HEIGHT,\n",
       "          CHART_WIDTH,\n",
       "          CHART_HEIGHT,\n",
       "          svgEl,\n",
       "          maxYValue,\n",
       "          xScale,\n",
       "          yScale\n",
       "        } = sizes\n",
       "        const rectColors = [&quot;#44C0E7&quot;, &quot;#F5843C&quot;]\n",
       "\n",
       "        // Add the y Axis\n",
       "        if (!referenceProfileExist) {\n",
       "          svgEl\n",
       "            .append(&quot;g&quot;)\n",
       "            .attr(&quot;transform&quot;, &quot;translate(&quot; + MARGIN.LEFT + &quot;, &quot; + MARGIN.TOP + &quot;)&quot;)\n",
       "            .call(d3.axisLeft(yScale).tickValues([0, maxYValue/2, maxYValue]))\n",
       "            .selectAll(&quot;text&quot;)\n",
       "            .style(&quot;font-size&quot;, &quot;8&quot;)\n",
       "        }\n",
       "\n",
       "        const gChart = svgEl.append(&quot;g&quot;);\n",
       "        gChart\n",
       "          .attr(&quot;transform&quot;, &quot;translate(&quot; + 20 + &quot;, &quot; + 0 + &quot;)&quot;)\n",
       "          .selectAll(&quot;.bar&quot;)\n",
       "          .data(data)\n",
       "          .enter()\n",
       "          .append(&quot;rect&quot;)\n",
       "          .classed(&quot;bar&quot;, true)\n",
       "          .attr(&quot;width&quot;, xScale.bandwidth() - 1)\n",
       "          .attr(&quot;height&quot;, (d) =&gt; CHART_HEIGHT - yScale(d.axisY))\n",
       "          .attr(&quot;x&quot;, (d) =&gt; xScale(d.axisX))\n",
       "          .attr(&quot;y&quot;, (d) =&gt; yScale(d.axisY) + MARGIN.TOP)\n",
       "          .attr(&quot;fill&quot;, rectColors[index]);\n",
       "\n",
       "        return svgEl._groups[0][0].outerHTML;\n",
       "      }\n",
       "\n",
       "      function chartData(column) {\n",
       "        const data = [];\n",
       "        if (column.histogram) {\n",
       "          column.histogram.counts.slice(0, 30).forEach((count, index) =&gt; {\n",
       "            data.push({\n",
       "              axisY: count,\n",
       "              axisX: index,\n",
       "            });\n",
       "          });\n",
       "        } else if (column.frequentItems) {\n",
       "          Object.entries(column.frequentItems).forEach(([key, {value, estimate}], index) =&gt; {\n",
       "              data.push({\n",
       "                axisY: estimate,\n",
       "                axisX: value,\n",
       "              });\n",
       "            });\n",
       "        }\n",
       "\n",
       "        return data\n",
       "      }\n",
       "\n",
       "      function graph(column, key, referenceColumn) {\n",
       "        let data = [];\n",
       "        const columnKey = key.data.key\n",
       "        let chartValue = false\n",
       "        let chartColor = undefined\n",
       "        if(!!referenceColumn){\n",
       "          column = referenceColumn.columns[columnKey]\n",
       "          chartValue = true\n",
       "          chartColor = 1\n",
       "        } else if (referenceColumn === undefined) {\n",
       "          column = &quot;&quot;\n",
       "        }\n",
       "\n",
       "        if (column.histogram || column.frequentItems) {\n",
       "          data = chartData(column)\n",
       "        } else if (referenceColumn === null ) {\n",
       "            $(&quot;.svg-container&quot;).css(&quot;padding-bottom&quot;, &quot;0&quot;)\n",
       "            return &#x27;&lt;span class=&quot;wl-table-cell__bedge-wrap&quot;&gt;No data to show the chart&lt;/span&gt;&#x27;;\n",
       "        } else if (referenceColumn === undefined) {\n",
       "            $(document).ready(function() {\n",
       "              $(&quot;.reference-table-head&quot;).addClass(&quot;d-none&quot;)\n",
       "            });\n",
       "            return &#x27;&#x27;\n",
       "        } else if (referenceColumn.frequentItems === undefined){\n",
       "            return &#x27;&#x27;;\n",
       "        }\n",
       "        return `\n",
       "          &lt;div class=&quot;svg-container&quot;&gt;\n",
       "            ${generateChart(data, ...[,,], chartColor, chartValue)}\n",
       "          &lt;/div&gt;\n",
       "        `;\n",
       "      }\n",
       "\n",
       "      function formatLabelDate(timestamp) {\n",
       "        const date = new Date(timestamp);\n",
       "        const format = d3.timeFormat(&quot;%Y-%m-%d %I:%M:%S %p %Z&quot;);\n",
       "        return format(date);\n",
       "      }\n",
       "\n",
       "      const driftCountElement = (driftCount, driftColor, driftName, driftRange) =&gt; `\n",
       "      &lt;div class=&quot;display-flex flex-direction-column&quot;&gt;\n",
       "        &lt;div class=&quot;drift-detection-info-drifts-item display-flex align-items&quot;&gt;\n",
       "          &lt;div class=&quot;drift-detection-info-drifts-item-text display-flex align-items&quot;&gt;\n",
       "            &lt;p class=&quot;drift-detection-info-drifts-item-count mb-0&quot;&gt;${driftCount}&lt;/p&gt;\n",
       "            &lt;p class=&quot;drift-detection-info-drifts-item-range display-flex justify-content-center mb-0&quot;&gt;${driftRange}&lt;/p&gt;\n",
       "          &lt;/div&gt;\n",
       "        &lt;/div&gt;\n",
       "      &lt;/div&gt;\n",
       "      `\n",
       "\n",
       "      const drifts = {\n",
       "        severe: {\n",
       "          count: 0,\n",
       "          range: &quot;with detected drift&quot;,\n",
       "        },\n",
       "        moderate: {\n",
       "          count: 0,\n",
       "          range: &quot;with possible drift&quot;,\n",
       "        },\n",
       "        mild: {\n",
       "          count: 0,\n",
       "          range: &quot;with no evidence of drift&quot;,\n",
       "        }\n",
       "      };\n",
       "\n",
       "      const countOfDrifts = (drift_from_ref, increment = true) =&gt; {\n",
       "        drift_class = drift_from_ref.drift_category\n",
       "        if (drift_class==&quot;NO_DRIFT&quot;) {\n",
       "          if (increment){Object.values(drifts)[2].count++}\n",
       "          return 0\n",
       "        }\n",
       "        if (drift_class==&quot;POSSIBLE_DRIFT&quot;) {\n",
       "          if (increment){Object.values(drifts)[1].count++}\n",
       "          return 1\n",
       "        }\n",
       "        if (drift_class==&quot;DRIFT&quot;) {\n",
       "          if (increment){Object.values(drifts)[0].count++}\n",
       "          return 2\n",
       "        }\n",
       "      }\n",
       "\n",
       "    abbreviate_number = function(value, fixed = 0) {\n",
       "      value = +value\n",
       "      if (value === null) { return null; } // terminate early\n",
       "      if (value === 0) { return &#x27;0&#x27;; } // terminate early\n",
       "      fixed = (!fixed || fixed &lt; 0) ? 0 : fixed; // number of decimal places to show\n",
       "      var b = (value).toPrecision(2).split(&quot;e&quot;), // get power\n",
       "          k = b.length === 1 ? 0 : Math.floor(Math.min(b[1].slice(1), 14) / 3), // floor at decimals, ceiling at trillions\n",
       "          c = k &lt; 1 ? value.toFixed(0 + fixed) : (value / Math.pow(10, k * 3) ).toFixed(1 + fixed), // divide by power\n",
       "          d = c &lt; 0 ? c : Math.abs(c), // enforce -0 is 0\n",
       "          newValue = d,\n",
       "          suffixe = [&#x27;&#x27;, &#x27;K&#x27;, &#x27;M&#x27;, &#x27;B&#x27;, &#x27;T&#x27;][k]; // append power\n",
       "      return {value, newValue, suffixe};\n",
       "    }\n",
       "\n",
       "     function formatBytes(bytes, decimals = 2) {\n",
       "       let newValue,\n",
       "       suffixe = &quot;&quot;\n",
       "       if (bytes === 0) return &#x27;0 Bytes&#x27;;\n",
       "\n",
       "       const k = 1024;\n",
       "       const dm = decimals &lt; 0 ? 0 : decimals;\n",
       "       const sizes = [&#x27;Bytes&#x27;, &#x27;KiB&#x27;, &#x27;MB&#x27;, &#x27;GB&#x27;, &#x27;TB&#x27;, &#x27;PB&#x27;, &#x27;EB&#x27;, &#x27;ZB&#x27;, &#x27;YB&#x27;];\n",
       "\n",
       "       const i = Math.floor(Math.log(bytes) / Math.log(k));\n",
       "       newValue = parseFloat((bytes / Math.pow(k, i)).toFixed(dm));\n",
       "       suffixe = sizes[i]\n",
       "       return {bytes, newValue, suffixe};\n",
       "     }\n",
       "\n",
       "     const valueSuffixe = (newNumber) =&gt; `\n",
       "       &lt;div class=&quot;statistic-measurement&quot;&gt;\n",
       "        ${newNumber}\n",
       "       &lt;/div&gt;`\n",
       "     const valueNumber = (newNumber) =&gt; `\n",
       "       &lt;div class=&quot;statistic-number&quot;&gt;\n",
       "        ${newNumber}\n",
       "       &lt;/div&gt;`\n",
       "\n",
       "     const numberWithSuffixe = (number, newNumber, suffixe) =&gt;\n",
       "       `&lt;div class=&quot;tooltip-full-number&quot;&gt;\n",
       "          &lt;div class=&quot;statistic-number&quot;&gt;\n",
       "             ${newNumber}\n",
       "            &lt;div class=&quot;statistic-measurement&quot;&gt;${suffixe}&lt;/div&gt;\n",
       "          &lt;/div&gt;\n",
       "          &lt;span class=&quot;tooltiptext&quot;&gt;${number}&lt;/span&gt;\n",
       "        &lt;/div&gt;`\n",
       "\n",
       "     Handlebars.registerHelper(&quot;observations&quot;, function (properties) {\n",
       "       const {value, newValue, suffixe} = abbreviate_number(referenceProfile.properties.observations)\n",
       "       return numberWithSuffixe(value, valueNumber(newValue), valueNumber(suffixe));\n",
       "     });\n",
       "\n",
       "     Handlebars.registerHelper(&quot;missingCells&quot;, function (properties) {\n",
       "       const {value, newValue, suffixe} = abbreviate_number(referenceProfile.properties.missing_cells)\n",
       "       if (typeof value !== &#x27;undefined&#x27; &amp;&amp; typeof newValue !== &#x27;undefined&#x27;  &amp;&amp; typeof suffixe !== &#x27;undefined&#x27; ) {\n",
       "        return numberWithSuffixe(value, valueSuffixe(`${newValue}`), suffixe);\n",
       "       }\n",
       "       return numberWithSuffixe(0, valueNumber(0), valueNumber(&#x27;&#x27;));\n",
       "     });\n",
       "\n",
       "     Handlebars.registerHelper(&quot;missingCellsPercentage&quot;, function (properties) {\n",
       "       const {value, newValue, suffixe} = abbreviate_number(referenceProfile.properties.missing_percentage)\n",
       "       if (typeof value !== &#x27;undefined&#x27; &amp;&amp; typeof newValue !== &#x27;undefined&#x27;  &amp;&amp; typeof suffixe !== &#x27;undefined&#x27; ) {\n",
       "        return numberWithSuffixe(value, valueSuffixe(`(${newValue}%)`), suffixe);\n",
       "       }\n",
       "       return numberWithSuffixe(0, valueSuffixe(`(${0}%)`), &#x27;&#x27;);\n",
       "     });\n",
       "\n",
       "     Handlebars.registerHelper(&quot;getProfileTimeStamp&quot;, function (properties) {\n",
       "       return formatLabelDate(+properties.properties.dataTimestamp)\n",
       "     });\n",
       "\n",
       "     Handlebars.registerHelper(&quot;getProfileName&quot;, function (properties) {\n",
       "       return properties.properties.tags.name\n",
       "     });\n",
       "\n",
       "      let driftCount = 0;\n",
       "      const diffFromRefTableElement = (driftFromRefNumber, circleColor) =&gt; `\n",
       "         &lt;div class=&quot;text-color padding-5 text-align-center justify-content-center&quot;&gt;\n",
       "          &lt;pre class=&quot;mb-1&quot;&gt; ${driftFromRefNumber} &lt;/pre&gt;\n",
       "         &lt;/div&gt;\n",
       "       `\n",
       "\n",
       "       const cheqValueTypeNumber = (profile, profileValue) =&gt; {\n",
       "         let validValue;\n",
       "         if (profile &amp;&amp; profileValue !== undefined &amp;&amp; typeof profileValue === &quot;number&quot;) {\n",
       "           return true\n",
       "         } else if (profileValue !== undefined &amp;&amp; typeof profileValue !== &quot;number&quot;) {\n",
       "           return false\n",
       "         }\n",
       "       }\n",
       "\n",
       "       const cheqDriftFromRef = (profile, driftFromRef) =&gt; {\n",
       "        if (profile &amp;&amp; driftFromRef){\n",
       "          console.log(&quot;drift from ref true&quot;)\n",
       "          return true\n",
       "        }\n",
       "        else {\n",
       "          console.log(&quot;drift from ref false&quot;)\n",
       "          return false\n",
       "        }\n",
       "       }\n",
       "\n",
       "       Handlebars.registerHelper(&quot;getpvalue&quot;, function (column, key) {\n",
       "        const columnKey = key.data.key\n",
       "        const {drift_from_ref} = referenceProfile.columns[columnKey]\n",
       "        if (cheqDriftFromRef(referenceProfile, drift_from_ref)){\n",
       "          if (cheqValueTypeNumber(referenceProfile, drift_from_ref.primary_value)) {\n",
       "          const driftFromRefNumber = drift_from_ref.primary_value.toPrecision(2)\n",
       "          return Number(driftFromRefNumber)\n",
       "\n",
       "        }\n",
       "        }\n",
       "        else {\n",
       "          return &quot;-&quot;\n",
       "        }\n",
       "      });\n",
       "\n",
       "\n",
       "      Handlebars.registerHelper(&quot;getDriftCategory&quot;, function (column, key) {\n",
       "        const columnKey = key.data.key\n",
       "        const {drift_from_ref} = referenceProfile.columns[columnKey]\n",
       "        const categories = {\n",
       "          0: &quot;No evidence of drift&quot;,\n",
       "          1: &quot;Possible drift&quot;,\n",
       "          2: &quot;Detected drift&quot;\n",
       "        }\n",
       "        if (cheqDriftFromRef(referenceProfile, drift_from_ref)){\n",
       "          if (cheqValueTypeNumber(referenceProfile, drift_from_ref.primary_value)) {\n",
       "            const driftFromRefNumber = drift_from_ref.primary_value.toPrecision(2)\n",
       "            const driftCategory = countOfDrifts(drift_from_ref, increment=false)\n",
       "            const circleColor = Object.values(drifts)[driftCategory].colorClass\n",
       "            return categories[driftCategory]\n",
       "\n",
       "          } else if (cheqValueTypeNumber(referenceProfile, drift_from_ref.primary_value) !== undefined) {\n",
       "            Object.values(drifts)[0].count++\n",
       "            return diffFromRefTableElement(&quot;undefined&quot;, &quot;severe-drift-circle-color&quot;)\n",
       "          }\n",
       "        }\n",
       "        else {\n",
       "          return &quot;Unknown&quot;\n",
       "        }\n",
       "\n",
       "        return &#x27;&lt;p style=&quot;color: black&quot;&gt;-&lt;/p&gt;&#x27;;\n",
       "      });\n",
       "\n",
       "\n",
       "\n",
       "      Handlebars.registerHelper(&quot;getDiffFromRef&quot;, function (column, key) {\n",
       "        const columnKey = key.data.key\n",
       "        const {drift_from_ref} = referenceProfile.columns[columnKey]\n",
       "        if (drift_from_ref==null){\n",
       "          return diffFromRefTableElement(&quot;-&quot;, &quot;&quot;)\n",
       "        }\n",
       "        if (cheqValueTypeNumber(referenceProfile, drift_from_ref.primary_value)) {\n",
       "          const driftFromRefNumber = drift_from_ref.primary_value.toPrecision(2)\n",
       "          const driftCategory = countOfDrifts(drift_from_ref)\n",
       "          const circleColor = Object.values(drifts)[driftCategory].colorClass\n",
       "          if (cheqValueTypeNumber(referenceProfile, drift_from_ref.pvalue)){\n",
       "            stats_string = `using algorithm: ${drift_from_ref.algorithm}\\npvalue is: ${drift_from_ref.pvalue.toPrecision(3)}`\n",
       "          }\n",
       "          else {\n",
       "            stats_string = `using algorithm: ${drift_from_ref.algorithm}\\nstatistic is: ${drift_from_ref.statistic.toPrecision(3)}`\n",
       "          }\n",
       "          if (driftCategory==1 || driftCategory == 2){\n",
       "            driftCount++\n",
       "          }\n",
       "          $(document).ready(() =&gt; {\n",
       "             $(&quot;.drift-count&quot;).html(driftCount)\n",
       "             $(&quot;.all-features&quot;).html(Object.keys(referenceProfile.columns).length)\n",
       "           })\n",
       "\n",
       "          return diffFromRefTableElement(stats_string, circleColor)\n",
       "\n",
       "        }\n",
       "        return &#x27;&lt;p style=&quot;color: black&quot;&gt;-&lt;/p&gt;&#x27;;\n",
       "      });\n",
       "\n",
       "\n",
       "      Handlebars.registerHelper(&quot;getThresholds&quot;, function (column, key) {\n",
       "        const columnKey = key.data.key\n",
       "        const {drift_from_ref} = referenceProfile.columns[columnKey]\n",
       "        if (drift_from_ref==null) {\n",
       "          return &quot;-&quot;\n",
       "        }\n",
       "        if (cheqValueTypeNumber(referenceProfile, drift_from_ref.primary_value)) {\n",
       "          thresholds_map = Object.entries(drift_from_ref.thresholds)\n",
       "          let thresholds_string = thresholds_map.map(([key, value]) =&gt; `${key}: ${value}`).join(&#x27;\\n&#x27;)\n",
       "          return &quot;thresholds:\\n&quot;+thresholds_string\n",
       "\n",
       "        }\n",
       "        return &#x27;&lt;p style=&quot;color: black&quot;&gt;-&lt;/p&gt;&#x27;;\n",
       "      });\n",
       "\n",
       "      $(document).ready(() =&gt;\n",
       "        Object.values(drifts).map(({count, name, colorClass, range}) =&gt;{\n",
       "          $(&quot;#drift-detection-info-drifts&quot;)\n",
       "          .append(driftCountElement(count, colorClass, name, range))\n",
       "        })\n",
       "      )\n",
       "\n",
       "      Handlebars.registerHelper(&quot;inferredType&quot;, function (column) {\n",
       "        let infferedType = &quot;&quot;;\n",
       "        console.log(column)\n",
       "        if (column.isDiscrete) {\n",
       "          infferedType = &quot;Discrete&quot;;\n",
       "        } else {\n",
       "          infferedType = &quot;Non-discrete&quot;;\n",
       "        }\n",
       "        return infferedType;\n",
       "      });\n",
       "\n",
       "      Handlebars.registerHelper(&quot;driftCategory&quot;, function (column, key) {\n",
       "        const columnKey = key.data.key\n",
       "        const {drift_from_ref} = referenceProfile.columns[columnKey]\n",
       "        if (drift_from_ref == null){\n",
       "          return &quot;unknowndrift&quot;\n",
       "        }\n",
       "        if (cheqValueTypeNumber(referenceProfile, drift_from_ref.primary_value)) {\n",
       "          console.log(drift_from_ref.drift_category)\n",
       "          console.log(Number(drift_from_ref.drift_category)==0)\n",
       "\n",
       "          if (drift_from_ref.drift_category==&quot;NO_DRIFT&quot;){\n",
       "            console.log(&quot;discrete&quot;)\n",
       "            return &quot;nodrift&quot;\n",
       "          }\n",
       "          if (drift_from_ref.drift_category==&quot;POSSIBLE_DRIFT&quot;){\n",
       "            console.log(&quot;non-discrete&quot;)\n",
       "            return &quot;possibledrift&quot;\n",
       "          }\n",
       "          if (drift_from_ref.drift_category==&quot;DRIFT&quot;){\n",
       "            console.log(&quot;unknown&quot;)\n",
       "            return &quot;drift&quot;\n",
       "          }\n",
       "\n",
       "          return Number(drift_from_ref.drift_category)\n",
       "\n",
       "        }\n",
       "      });\n",
       "\n",
       "\n",
       "      Handlebars.registerHelper(&quot;frequentItems&quot;, function (column) {\n",
       "        frequentItemsElemString = &quot;&quot;;\n",
       "        if (column.isDiscrete) {\n",
       "          const slicedFrequentItems = column.frequentItems.items.slice(0, 5);\n",
       "          for (let fi = 0; fi &lt; slicedFrequentItems.length; fi++) {\n",
       "            frequentItemsElemString +=\n",
       "              &#x27;&lt;span class=&quot;wl-table-cell__bedge&quot;&gt;&#x27; + slicedFrequentItems[fi].jsonValue + &quot;&lt;/span&gt;&quot;;\n",
       "          }\n",
       "        } else {\n",
       "          frequentItemsElemString += &quot;No data to show&quot;;\n",
       "        }\n",
       "        return frequentItemsElemString;\n",
       "      });\n",
       "\n",
       "      Handlebars.registerHelper(&quot;totalCount&quot;, function (column) {\n",
       "        if (column.featureStats) {\n",
       "          return column.featureStats.total_count;\n",
       "        }\n",
       "\n",
       "        return &quot;-&quot;;\n",
       "      });\n",
       "\n",
       "      Handlebars.registerHelper(&quot;mean&quot;, function (column) {\n",
       "        if (column.featureStats?.descriptive_statistics) {\n",
       "          if (isNaN(column.featureStats.descriptive_statistics.mean)){return &quot;-&quot;}\n",
       "          if (column.featureStats.descriptive_statistics.mean==null){return &quot;-&quot;}\n",
       "          return fixNumberTo(column.featureStats.descriptive_statistics.mean);\n",
       "        }\n",
       "        return &quot;-&quot;;\n",
       "      });\n",
       "\n",
       "      Handlebars.registerHelper(&quot;getGraphHtml&quot;,(column,key) =&gt; graph(column, key, null));\n",
       "      Handlebars.registerHelper(&quot;getReferenceGraphHtml&quot;,(column,key) =&gt; graph(column, key, referenceProfile));\n",
       "\n",
       "      Handlebars.registerHelper(&quot;getDiscreteTypeCount&quot;, function () {\n",
       "        let count = 0;\n",
       "\n",
       "        Object.entries(this.columns).forEach((feature) =&gt; {\n",
       "          if (feature[1].isDiscrete === true) {\n",
       "            count++;\n",
       "          }\n",
       "        });\n",
       "        return count.toString();\n",
       "      });\n",
       "\n",
       "      Handlebars.registerHelper(&quot;getNonDiscreteTypeCount&quot;, function () {\n",
       "        let count = 0;\n",
       "\n",
       "        Object.entries(referenceProfile.columns).forEach((feature) =&gt; {\n",
       "          if (feature[1].isDiscrete === false) {\n",
       "            count++;\n",
       "          }\n",
       "        });\n",
       "        return count;\n",
       "      });\n",
       "\n",
       "      Handlebars.registerHelper(&quot;getDriftCount&quot;, function () {\n",
       "        let count = 0;\n",
       "\n",
       "        Object.entries(referenceProfile.columns).forEach((feature) =&gt; {\n",
       "          if (feature[1].drift_from_ref != null){\n",
       "            console.log(&quot;drif ref not null&quot;)\n",
       "            if (feature[1].drift_from_ref.drift_category == &quot;DRIFT&quot;) {\n",
       "              count++;\n",
       "            }\n",
       "          }\n",
       "          else{\n",
       "            console.log(&quot;drift ref null&quot;)\n",
       "          }\n",
       "        });\n",
       "        return count;\n",
       "      });\n",
       "\n",
       "      Handlebars.registerHelper(&quot;getPossibleDriftCount&quot;, function () {\n",
       "        let count = 0;\n",
       "\n",
       "        Object.entries(referenceProfile.columns).forEach((feature) =&gt; {\n",
       "          if (feature[1].drift_from_ref != null){\n",
       "            console.log(&quot;drif ref not null&quot;)\n",
       "            if (feature[1].drift_from_ref.drift_category == &quot;POSSIBLE_DRIFT&quot;) {\n",
       "              count++;\n",
       "            }\n",
       "          }\n",
       "          else{\n",
       "            console.log(&quot;drift ref null&quot;)\n",
       "          }\n",
       "        });\n",
       "        return count;\n",
       "      });\n",
       "\n",
       "\n",
       "      Handlebars.registerHelper(&quot;getNoDriftCount&quot;, function () {\n",
       "        let count = 0;\n",
       "        Object.entries(referenceProfile.columns).forEach((feature) =&gt; {\n",
       "          if (feature[1].drift_from_ref != null){\n",
       "            console.log(&quot;drif ref not null&quot;)\n",
       "            if (feature[1].drift_from_ref.drift_category == &quot;NO_DRIFT&quot;) {\n",
       "              count++;\n",
       "            }\n",
       "          }\n",
       "          else{\n",
       "            console.log(&quot;drift ref null&quot;)\n",
       "          }\n",
       "        });\n",
       "        return count;\n",
       "      });\n",
       "\n",
       "      Handlebars.registerHelper(&quot;getUnknownDriftCount&quot;, function () {\n",
       "        let count = 0;\n",
       "        Object.entries(referenceProfile.columns).forEach((feature) =&gt; {\n",
       "          if (feature[1].drift_from_ref == null){\n",
       "            console.log(&quot;drif ref unknown&quot;)\n",
       "            count++;\n",
       "          }\n",
       "        });\n",
       "        return count;\n",
       "      });\n",
       "\n",
       "\n",
       "      Handlebars.registerHelper(&quot;getUnknownTypeCount&quot;, function () {\n",
       "        let count = 0;\n",
       "        return count;\n",
       "        Object.entries(this.columns).forEach((feature) =&gt; {\n",
       "          if (!feature[1].isDiscrete) {\n",
       "            count++;\n",
       "          }\n",
       "        });\n",
       "        return count;\n",
       "      });\n",
       "    }\n",
       "\n",
       "    function initHandlebarsTemplate() {\n",
       "      // Replace this context with JSON from .py file\n",
       "      const context = {&quot;columns&quot;: {&quot;fixed acidity&quot;: {&quot;histogram&quot;: {&quot;start&quot;: 4.6, &quot;end&quot;: 15.90000159, &quot;width&quot;: 0, &quot;counts&quot;: [3, 17, 16, 17, 28, 39, 39, 30, 22, 30, 24, 35, 12, 13, 22, 23, 9, 6, 3, 4, 2, 3, 3, 2, 1, 0, 0, 0, 2, 3], &quot;max&quot;: 15.9, &quot;min&quot;: 4.6, &quot;bins&quot;: [4.6, 4.9766667196666665, 5.353333439333333, 5.730000158999999, 6.106666878666666, 6.483333598333333, 6.860000318, 7.236667037666667, 7.613333757333333, 7.990000477000001, 8.366667196666667, 8.743333916333334, 9.120000636, 9.496667355666666, 9.873334075333332, 10.250000795, 10.626667514666668, 11.003334234333334, 11.380000954, 11.756667673666666, 12.133334393333334, 12.510001113000001, 12.886667832666667, 13.263334552333333, 13.640001272000001, 14.016667991666667, 14.393334711333335, 14.770001431, 15.146668150666667, 15.523334870333334, 15.90000159], &quot;n&quot;: 408}, &quot;frequentItems&quot;: null, &quot;drift_from_ref&quot;: null, &quot;isDiscrete&quot;: false, &quot;featureStats&quot;: {&quot;total_count&quot;: 408, &quot;missing&quot;: 0, &quot;distinct&quot;: 20.588239538027807, &quot;min&quot;: 4.6, &quot;max&quot;: 15.9, &quot;range&quot;: 11.3, &quot;quantile_statistics&quot;: {&quot;fifth_percentile&quot;: 5.4, &quot;iqr&quot;: 2.7, &quot;q1&quot;: 6.7, &quot;median&quot;: 7.9, &quot;q3&quot;: 9.4, &quot;ninety_fifth_percentile&quot;: 11.6}, &quot;descriptive_statistics&quot;: {&quot;stddev&quot;: 2.013014441140909, &quot;coefficient_of_variation&quot;: 0.24676558362692394, &quot;sum&quot;: 3328.3, &quot;variance&quot;: 4.052227140241847, &quot;mean&quot;: 8.157598039215687}}}, &quot;volatile acidity&quot;: {&quot;histogram&quot;: {&quot;start&quot;: 0.12, &quot;end&quot;: 1.1150001115, &quot;width&quot;: 0, &quot;counts&quot;: [3, 8, 5, 8, 21, 32, 38, 37, 30, 35, 23, 24, 25, 23, 15, 15, 15, 14, 11, 4, 3, 3, 6, 2, 1, 2, 1, 2, 0, 2], &quot;max&quot;: 1.115, &quot;min&quot;: 0.12, &quot;bins&quot;: [0.12, 0.15316667038333331, 0.18633334076666666, 0.21950001115, 0.2526666815333333, 0.28583335191666664, 0.3190000223, 0.35216669268333334, 0.38533336306666666, 0.41850003345, 0.4516667038333333, 0.48483337421666667, 0.5180000445999999, 0.5511667149833333, 0.5843333853666667, 0.61750005575, 0.6506667261333333, 0.6838333965166666, 0.7170000669, 0.7501667372833333, 0.7833334076666666, 0.81650007805, 0.8496667484333333, 0.8828334188166667, 0.9160000892, 0.9491667595833333, 0.9823334299666666, 1.01550010035, 1.0486667707333335, 1.0818334411166668, 1.1150001115000001], &quot;n&quot;: 408}, &quot;frequentItems&quot;: null, &quot;drift_from_ref&quot;: null, &quot;isDiscrete&quot;: false, &quot;featureStats&quot;: {&quot;total_count&quot;: 408, &quot;missing&quot;: 0, &quot;distinct&quot;: 22.05882840516061, &quot;min&quot;: 0.12, &quot;max&quot;: 1.115, &quot;range&quot;: 0.995, &quot;quantile_statistics&quot;: {&quot;fifth_percentile&quot;: 0.24, &quot;iqr&quot;: 0.23999999999999994, &quot;q1&quot;: 0.34, &quot;median&quot;: 0.44, &quot;q3&quot;: 0.58, &quot;ninety_fifth_percentile&quot;: 0.8}, &quot;descriptive_statistics&quot;: {&quot;stddev&quot;: 0.17791965320497752, &quot;coefficient_of_variation&quot;: 0.3771756131540623, &quot;sum&quot;: 192.45999999999998, &quot;variance&quot;: 0.03165540299657947, &quot;mean&quot;: 0.47171568627450977}}}, &quot;citric acid&quot;: {&quot;histogram&quot;: {&quot;start&quot;: 0.0, &quot;end&quot;: 0.790000079, &quot;width&quot;: 0, &quot;counts&quot;: [57, 13, 7, 23, 10, 9, 4, 6, 7, 10, 12, 14, 28, 9, 24, 35, 11, 23, 31, 8, 10, 9, 5, 3, 8, 12, 2, 3, 4, 1], &quot;max&quot;: 0.79, &quot;min&quot;: 0.0, &quot;bins&quot;: [0.0, 0.026333335966666666, 0.05266667193333333, 0.0790000079, 0.10533334386666666, 0.13166667983333333, 0.1580000158, 0.18433335176666665, 0.21066668773333333, 0.2370000237, 0.26333335966666666, 0.2896666956333333, 0.3160000316, 0.34233336756666666, 0.3686667035333333, 0.3950000395, 0.42133337546666666, 0.4476667114333333, 0.4740000474, 0.5003333833666667, 0.5266667193333333, 0.5530000553, 0.5793333912666666, 0.6056667272333334, 0.6320000632, 0.6583333991666667, 0.6846667351333333, 0.7110000711, 0.7373334070666666, 0.7636667430333334, 0.790000079], &quot;n&quot;: 398}, &quot;frequentItems&quot;: null, &quot;drift_from_ref&quot;: null, &quot;isDiscrete&quot;: false, &quot;featureStats&quot;: {&quot;total_count&quot;: 398, &quot;missing&quot;: 10, &quot;distinct&quot;: 18.090455451204008, &quot;min&quot;: 0.0, &quot;max&quot;: 0.79, &quot;range&quot;: 0.79, &quot;quantile_statistics&quot;: {&quot;fifth_percentile&quot;: 0.0, &quot;iqr&quot;: 0.36, &quot;q1&quot;: 0.1, &quot;median&quot;: 0.34, &quot;q3&quot;: 0.46, &quot;ninety_fifth_percentile&quot;: 0.66}, &quot;descriptive_statistics&quot;: {&quot;stddev&quot;: 0.20859943016152155, &quot;coefficient_of_variation&quot;: 0.6620619872750046, &quot;sum&quot;: 125.4, &quot;variance&quot;: 0.04351372226371151, &quot;mean&quot;: 0.3150753768844221}}}, &quot;residual sugar&quot;: {&quot;histogram&quot;: {&quot;start&quot;: 0.9, &quot;end&quot;: 12.90000129, &quot;width&quot;: 0, &quot;counts&quot;: [8, 39, 118, 124, 40, 16, 11, 8, 13, 8, 4, 2, 2, 5, 3, 0, 1, 1, 3, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1], &quot;max&quot;: 12.9, &quot;min&quot;: 0.9, &quot;bins&quot;: [0.9, 1.300000043, 1.7000000860000002, 2.100000129, 2.500000172, 2.900000215, 3.3000002580000003, 3.700000301, 4.100000344000001, 4.500000387, 4.90000043, 5.300000473000001, 5.700000516000001, 6.100000559000001, 6.500000602000001, 6.900000645, 7.300000688000001, 7.700000731000001, 8.100000774, 8.500000817, 8.90000086, 9.300000903, 9.700000946000001, 10.100000989000002, 10.500001032000002, 10.900001075, 11.300001118, 11.700001161000001, 12.100001204000002, 12.500001247000002, 12.90000129], &quot;n&quot;: 408}, &quot;frequentItems&quot;: null, &quot;drift_from_ref&quot;: null, &quot;isDiscrete&quot;: false, &quot;featureStats&quot;: {&quot;total_count&quot;: 408, &quot;missing&quot;: 0, &quot;distinct&quot;: 15.931375081243552, &quot;min&quot;: 0.9, &quot;max&quot;: 12.9, &quot;range&quot;: 12.0, &quot;quantile_statistics&quot;: {&quot;fifth_percentile&quot;: 1.6, &quot;iqr&quot;: 0.7000000000000002, &quot;q1&quot;: 2.0, &quot;median&quot;: 2.3, &quot;q3&quot;: 2.7, &quot;ninety_fifth_percentile&quot;: 5.15}, &quot;descriptive_statistics&quot;: {&quot;stddev&quot;: 1.2990000858665753, &quot;coefficient_of_variation&quot;: 0.49437249664993493, &quot;sum&quot;: 1072.05, &quot;variance&quot;: 1.6874012230813702, &quot;mean&quot;: 2.6275735294117646}}}, &quot;chlorides&quot;: {&quot;histogram&quot;: {&quot;start&quot;: 0.012, &quot;end&quot;: 0.230000023, &quot;width&quot;: 0, &quot;counts&quot;: [2, 0, 0, 9, 21, 40, 45, 76, 64, 43, 33, 21, 20, 8, 9, 9, 3, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 1], &quot;max&quot;: 0.23, &quot;min&quot;: 0.012, &quot;bins&quot;: [0.012, 0.019266667433333332, 0.026533334866666668, 0.0338000023, 0.04106666973333333, 0.04833333716666667, 0.0556000046, 0.06286667203333333, 0.07013333946666667, 0.0774000069, 0.08466667433333333, 0.09193334176666666, 0.0992000092, 0.10646667663333333, 0.11373334406666666, 0.12100001149999999, 0.12826667893333332, 0.13553334636666667, 0.14280001380000001, 0.15006668123333333, 0.15733334866666668, 0.1646000161, 0.17186668353333334, 0.17913335096666666, 0.1864000184, 0.19366668583333332, 0.20093335326666667, 0.2082000207, 0.21546668813333333, 0.22273335556666665, 0.230000023], &quot;n&quot;: 408}, &quot;frequentItems&quot;: null, &quot;drift_from_ref&quot;: null, &quot;isDiscrete&quot;: false, &quot;featureStats&quot;: {&quot;total_count&quot;: 408, &quot;missing&quot;: 0, &quot;distinct&quot;: 21.813730257594944, &quot;min&quot;: 0.012, &quot;max&quot;: 0.23, &quot;range&quot;: 0.218, &quot;quantile_statistics&quot;: {&quot;fifth_percentile&quot;: 0.046, &quot;iqr&quot;: 0.025999999999999995, &quot;q1&quot;: 0.06, &quot;median&quot;: 0.071, &quot;q3&quot;: 0.086, &quot;ninety_fifth_percentile&quot;: 0.12}, &quot;descriptive_statistics&quot;: {&quot;stddev&quot;: 0.024213181268290383, &quot;coefficient_of_variation&quot;: 0.3226526212509791, &quot;sum&quot;: 30.618, &quot;variance&quot;: 0.0005862781471310883, &quot;mean&quot;: 0.07504411764705882}}}, &quot;free sulfur dioxide&quot;: {&quot;histogram&quot;: {&quot;start&quot;: 3.0, &quot;end&quot;: 51.0000051, &quot;width&quot;: 0, &quot;counts&quot;: [31, 79, 21, 21, 36, 16, 27, 26, 29, 22, 3, 13, 12, 11, 10, 5, 6, 4, 8, 6, 4, 8, 2, 1, 3, 0, 1, 0, 1, 2], &quot;max&quot;: 51.0, &quot;min&quot;: 3.0, &quot;bins&quot;: [3.0, 4.60000017, 6.200000340000001, 7.80000051, 9.400000680000002, 11.000000850000001, 12.60000102, 14.200001190000002, 15.800001360000001, 17.40000153, 19.000001700000002, 20.600001870000003, 22.20000204, 23.800002210000002, 25.400002380000004, 27.00000255, 28.600002720000003, 30.200002890000004, 31.80000306, 33.40000323, 35.000003400000004, 36.600003570000005, 38.20000374000001, 39.80000391, 41.40000408, 43.00000425, 44.600004420000005, 46.200004590000006, 47.80000476000001, 49.40000493, 51.0000051], &quot;n&quot;: 408}, &quot;frequentItems&quot;: null, &quot;drift_from_ref&quot;: null, &quot;isDiscrete&quot;: false, &quot;featureStats&quot;: {&quot;total_count&quot;: 408, &quot;missing&quot;: 0, &quot;distinct&quot;: 11.029412969947018, &quot;min&quot;: 3.0, &quot;max&quot;: 51.0, &quot;range&quot;: 48.0, &quot;quantile_statistics&quot;: {&quot;fifth_percentile&quot;: 3.0, &quot;iqr&quot;: 13.0, &quot;q1&quot;: 6.0, &quot;median&quot;: 13.0, &quot;q3&quot;: 19.0, &quot;ninety_fifth_percentile&quot;: 36.0}, &quot;descriptive_statistics&quot;: {&quot;stddev&quot;: 9.994223698460777, &quot;coefficient_of_variation&quot;: 0.6774056431550788, &quot;sum&quot;: 6019.5, &quot;variance&quot;: 99.884507334875, &quot;mean&quot;: 14.753676470588236}}}, &quot;total sulfur dioxide&quot;: {&quot;histogram&quot;: {&quot;start&quot;: 6.0, &quot;end&quot;: 289.0000289, &quot;width&quot;: 0, &quot;counts&quot;: [85, 92, 70, 47, 40, 14, 16, 10, 10, 10, 6, 2, 0, 0, 0, 3, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1], &quot;max&quot;: 289.0, &quot;min&quot;: 6.0, &quot;bins&quot;: [6.0, 15.433334296666667, 24.866668593333333, 34.30000289, 43.73333718666667, 53.16667148333333, 62.600005780000004, 72.03334007666666, 81.46667437333333, 90.90000867, 100.33334296666666, 109.76667726333334, 119.20001156000001, 128.63334585666666, 138.06668015333332, 147.50001445, 156.93334874666667, 166.36668304333332, 175.80001734, 185.23335163666667, 194.66668593333333, 204.10002023, 213.53335452666667, 222.96668882333333, 232.40002312000001, 241.83335741666667, 251.26669171333333, 260.70002601, 270.13336030666665, 279.56669460333336, 289.0000289], &quot;n&quot;: 408}, &quot;frequentItems&quot;: null, &quot;drift_from_ref&quot;: null, &quot;isDiscrete&quot;: false, &quot;featureStats&quot;: {&quot;total_count&quot;: 408, &quot;missing&quot;: 0, &quot;distinct&quot;: 22.303926553943704, &quot;min&quot;: 6.0, &quot;max&quot;: 289.0, &quot;range&quot;: 283.0, &quot;quantile_statistics&quot;: {&quot;fifth_percentile&quot;: 10.0, &quot;iqr&quot;: 29.0, &quot;q1&quot;: 17.0, &quot;median&quot;: 27.0, &quot;q3&quot;: 46.0, &quot;ninety_fifth_percentile&quot;: 93.0}, &quot;descriptive_statistics&quot;: {&quot;stddev&quot;: 31.68721099598923, &quot;coefficient_of_variation&quot;: 0.8554477659209692, &quot;sum&quot;: 15112.999999999998, &quot;variance&quot;: 1004.0793407043408, &quot;mean&quot;: 37.041666666666664}}}, &quot;density&quot;: {&quot;histogram&quot;: {&quot;start&quot;: 0.99007, &quot;end&quot;: 1.0032001003200002, &quot;width&quot;: 0, &quot;counts&quot;: [3, 4, 1, 9, 4, 12, 8, 32, 32, 36, 39, 49, 45, 25, 25, 19, 15, 8, 4, 8, 5, 6, 2, 5, 4, 1, 1, 2, 0, 4], &quot;max&quot;: 1.0032, &quot;min&quot;: 0.99007, &quot;bins&quot;: [0.99007, 0.9905076700106666, 0.9909453400213334, 0.991383010032, 0.9918206800426667, 0.9922583500533334, 0.992696020064, 0.9931336900746667, 0.9935713600853334, 0.9940090300960001, 0.9944467001066667, 0.9948843701173334, 0.9953220401280001, 0.9957597101386667, 0.9961973801493335, 0.9966350501600001, 0.9970727201706667, 0.9975103901813335, 0.9979480601920001, 0.9983857302026667, 0.9988234002133335, 0.9992610702240001, 0.9996987402346668, 1.0001364102453334, 1.0005740802560001, 1.0010117502666669, 1.0014494202773334, 1.0018870902880002, 1.002324760298667, 1.0027624303093334, 1.0032001003200002], &quot;n&quot;: 408}, &quot;frequentItems&quot;: null, &quot;drift_from_ref&quot;: null, &quot;isDiscrete&quot;: false, &quot;featureStats&quot;: {&quot;total_count&quot;: 408, &quot;missing&quot;: 0, &quot;distinct&quot;: 55.88238444546564, &quot;min&quot;: 0.99007, &quot;max&quot;: 1.0032, &quot;range&quot;: 0.013130000000000086, &quot;quantile_statistics&quot;: {&quot;fifth_percentile&quot;: 0.9922, &quot;iqr&quot;: 0.0023400000000000087, &quot;q1&quot;: 0.99396, &quot;median&quot;: 0.99516, &quot;q3&quot;: 0.9963, &quot;ninety_fifth_percentile&quot;: 0.9994}, &quot;descriptive_statistics&quot;: {&quot;stddev&quot;: 0.0021784570136347352, &quot;coefficient_of_variation&quot;: 0.002188682344428877, &quot;sum&quot;: 406.09385999999995, &quot;variance&quot;: 4.745674960254368e-06, &quot;mean&quot;: 0.995328088235294}}}, &quot;pH&quot;: {&quot;histogram&quot;: {&quot;start&quot;: 2.89, &quot;end&quot;: 4.010000401, &quot;width&quot;: 0, &quot;counts&quot;: [5, 1, 3, 4, 7, 5, 17, 20, 38, 36, 44, 29, 35, 41, 30, 11, 19, 17, 14, 10, 2, 9, 4, 2, 0, 1, 0, 2, 0, 2], &quot;max&quot;: 4.01, &quot;min&quot;: 2.89, &quot;bins&quot;: [2.89, 2.9273333467000002, 2.9646666934000003, 3.0020000401, 3.0393333868, 3.0766667335, 3.1140000802000003, 3.1513334269, 3.1886667736, 3.2260001203, 3.2633334670000003, 3.3006668137, 3.3380001604, 3.3753335071, 3.4126668538000002, 3.4500002005, 3.4873335472, 3.5246668939, 3.5620002406, 3.5993335873000003, 3.636666934, 3.6740002807, 3.7113336274, 3.7486669741, 3.7860003208000004, 3.8233336675, 3.8606670142, 3.8980003609000002, 3.9353337076, 3.9726670543, 4.010000401], &quot;n&quot;: 408}, &quot;frequentItems&quot;: null, &quot;drift_from_ref&quot;: null, &quot;isDiscrete&quot;: false, &quot;featureStats&quot;: {&quot;total_count&quot;: 408, &quot;missing&quot;: 0, &quot;distinct&quot;: 18.8725525817653, &quot;min&quot;: 2.89, &quot;max&quot;: 4.01, &quot;range&quot;: 1.1199999999999997, &quot;quantile_statistics&quot;: {&quot;fifth_percentile&quot;: 3.09, &quot;iqr&quot;: 0.2200000000000002, &quot;q1&quot;: 3.23, &quot;median&quot;: 3.33, &quot;q3&quot;: 3.45, &quot;ninety_fifth_percentile&quot;: 3.67}, &quot;descriptive_statistics&quot;: {&quot;stddev&quot;: 0.17649177660211463, &quot;coefficient_of_variation&quot;: 0.05273349702213279, &quot;sum&quot;: 1365.52, &quot;variance&quot;: 0.031149347208170735, &quot;mean&quot;: 3.346862745098039}}}, &quot;sulphates&quot;: {&quot;histogram&quot;: {&quot;start&quot;: 0.37, &quot;end&quot;: 1.130000113, &quot;width&quot;: 0, &quot;counts&quot;: [3, 2, 4, 4, 6, 18, 19, 45, 22, 37, 22, 32, 21, 29, 28, 27, 22, 12, 24, 7, 10, 1, 5, 1, 3, 1, 1, 0, 0, 2], &quot;max&quot;: 1.13, &quot;min&quot;: 0.37, &quot;bins&quot;: [0.37, 0.3953333371, 0.4206666742, 0.4460000113, 0.47133334839999996, 0.4966666855, 0.5220000226, 0.5473333597, 0.5726666968, 0.5980000339, 0.623333371, 0.6486667080999999, 0.6740000452, 0.6993333823, 0.7246667194, 0.7500000565, 0.7753333936, 0.8006667306999999, 0.8260000677999999, 0.8513334049, 0.8766667419999999, 0.9020000791, 0.9273334162, 0.9526667533, 0.9780000904, 1.0033334274999999, 1.0286667646, 1.0540001016999998, 1.0793334388, 1.1046667759, 1.130000113], &quot;n&quot;: 408}, &quot;frequentItems&quot;: null, &quot;drift_from_ref&quot;: null, &quot;isDiscrete&quot;: false, &quot;featureStats&quot;: {&quot;total_count&quot;: 408, &quot;missing&quot;: 0, &quot;distinct&quot;: 14.215688286897349, &quot;min&quot;: 0.37, &quot;max&quot;: 1.13, &quot;range&quot;: 0.7599999999999999, &quot;quantile_statistics&quot;: {&quot;fifth_percentile&quot;: 0.5, &quot;iqr&quot;: 0.19000000000000006, &quot;q1&quot;: 0.58, &quot;median&quot;: 0.66, &quot;q3&quot;: 0.77, &quot;ninety_fifth_percentile&quot;: 0.88}, &quot;descriptive_statistics&quot;: {&quot;stddev&quot;: 0.12701037402923776, &quot;coefficient_of_variation&quot;: 0.18776807233831805, &quot;sum&quot;: 275.97999999999996, &quot;variance&quot;: 0.016131635111046875, &quot;mean&quot;: 0.6764215686274508}}}, &quot;alcohol&quot;: {&quot;histogram&quot;: {&quot;start&quot;: 11.066666666666698, &quot;end&quot;: 14.900001490000001, &quot;width&quot;: 0, &quot;counts&quot;: [28, 68, 32, 30, 38, 29, 21, 21, 25, 12, 13, 27, 9, 17, 9, 8, 1, 3, 3, 6, 0, 0, 7, 0, 0, 0, 0, 0, 0, 1], &quot;max&quot;: 14.9, &quot;min&quot;: 11.066666666666698, &quot;bins&quot;: [11.066666666666698, 11.194444494111142, 11.322222321555586, 11.45000014900003, 11.577777976444471, 11.705555803888915, 11.833333631333359, 11.961111458777802, 12.088889286222246, 12.21666711366669, 12.344444941111133, 12.472222768555575, 12.600000596000019, 12.727778423444462, 12.855556250888906, 12.98333407833335, 13.111111905777793, 13.238889733222237, 13.36666756066668, 13.494445388111123, 13.622223215555566, 13.75000104300001, 13.877778870444454, 14.005556697888897, 14.13333452533334, 14.261112352777783, 14.388890180222226, 14.51666800766667, 14.644445835111114, 14.772223662555557, 14.900001490000001], &quot;n&quot;: 408}, &quot;frequentItems&quot;: null, &quot;drift_from_ref&quot;: null, &quot;isDiscrete&quot;: false, &quot;featureStats&quot;: {&quot;total_count&quot;: 408, &quot;missing&quot;: 0, &quot;distinct&quot;: 7.59803978178436, &quot;min&quot;: 11.066666666666698, &quot;max&quot;: 14.9, &quot;range&quot;: 3.833333333333302, &quot;quantile_statistics&quot;: {&quot;fifth_percentile&quot;: 11.1, &quot;iqr&quot;: 1.0, &quot;q1&quot;: 11.4, &quot;median&quot;: 11.8, &quot;q3&quot;: 12.4, &quot;ninety_fifth_percentile&quot;: 13.2}, &quot;descriptive_statistics&quot;: {&quot;stddev&quot;: 0.6824986635512768, &quot;coefficient_of_variation&quot;: 0.05725985668809312, &quot;sum&quot;: 4863.083333333334, &quot;variance&quot;: 0.4658044257492789, &quot;mean&quot;: 11.919321895424838}}}, &quot;quality&quot;: {&quot;histogram&quot;: null, &quot;frequentItems&quot;: [{&quot;value&quot;: &quot;bad&quot;, &quot;estimate&quot;: 267}, {&quot;value&quot;: &quot;good&quot;, &quot;estimate&quot;: 141}], &quot;drift_from_ref&quot;: null, &quot;isDiscrete&quot;: true, &quot;featureStats&quot;: {&quot;total_count&quot;: 408, &quot;missing&quot;: 0, &quot;distinct&quot;: 0.4901960796487877, &quot;min&quot;: NaN, &quot;max&quot;: NaN, &quot;range&quot;: NaN, &quot;quantile_statistics&quot;: null, &quot;descriptive_statistics&quot;: {&quot;stddev&quot;: null, &quot;coefficient_of_variation&quot;: null, &quot;sum&quot;: null, &quot;variance&quot;: null, &quot;mean&quot;: null}}}}, &quot;properties&quot;: null};\n",
       "      // Config handlebars and pass data to HBS template\n",
       "      const source = document.getElementById(&quot;entry-template&quot;).innerHTML;\n",
       "      const template = Handlebars.compile(source);\n",
       "      const html = template(context);\n",
       "      const target = document.getElementById(&quot;generated-html&quot;);\n",
       "      target.innerHTML = html;\n",
       "    }\n",
       "\n",
       "    function initWebsiteScripts() {\n",
       "      const $featureSearch = document.getElementById(&quot;wl__feature-search&quot;);\n",
       "      const $tableBody = document.getElementById(&quot;table-body&quot;);\n",
       "      const $noDrift = document.getElementById(&quot;nodrift&quot;);\n",
       "      const $possibleDrift = document.getElementById(&quot;possibledrift&quot;);\n",
       "      const $drift = document.getElementById(&quot;detecteddrift&quot;);\n",
       "      const $diffFromRef = document.getElementById(&quot;diff-from-ref&quot;);\n",
       "      const $unknownDrift = document.getElementById(&quot;unknowndrift&quot;);\n",
       "\n",
       "      const activeTypes = {\n",
       "        nodrift: true,\n",
       "        possibledrift: true,\n",
       "        drift: true,\n",
       "        unknowndrift: true,\n",
       "      };\n",
       "\n",
       "      var driftOrder = {\n",
       "        original: true,\n",
       "        descending: false,\n",
       "        ascending: false,\n",
       "      };\n",
       "      var originalColumnOrder;\n",
       "\n",
       "      let searchString = &quot;&quot;;\n",
       "\n",
       "      function debounce(func, wait, immediate) {\n",
       "        let timeout;\n",
       "\n",
       "        return function () {\n",
       "          const context = this;\n",
       "          const args = arguments;\n",
       "          const later = function () {\n",
       "            timeout = null;\n",
       "            if (!immediate) func.apply(context, args);\n",
       "          };\n",
       "\n",
       "          const callNow = immediate &amp;&amp; !timeout;\n",
       "          clearTimeout(timeout);\n",
       "          timeout = setTimeout(later, wait);\n",
       "          if (callNow) func.apply(context, args);\n",
       "        };\n",
       "      }\n",
       "\n",
       "      function filterNotification() {\n",
       "        const $notifCircleContainer = $(&quot;.notif-circle-container&quot;)\n",
       "        const $boxes = $(&#x27;.wl_filter-options&gt;.form-check&gt;input[name=checkbox]:checked&#x27;);\n",
       "        const item = Object.values($boxes).find(function(value) { return $(value)[0] === undefined});\n",
       "        if (item === undefined) {\n",
       "          $notifCircleContainer.removeClass(&quot;d-none&quot;)\n",
       "        } else {\n",
       "          $notifCircleContainer.addClass(&quot;d-none&quot;)\n",
       "        }\n",
       "      }\n",
       "\n",
       "\n",
       "      function handleSearch() {\n",
       "        const tableBodyChildren = $tableBody.children;\n",
       "\n",
       "        for (let i = 0; i &lt; tableBodyChildren.length; i++) {\n",
       "          const type = tableBodyChildren[i].dataset.driftCategory.toLowerCase();\n",
       "          const name = tableBodyChildren[i].dataset.featureName.toLowerCase();\n",
       "          if (activeTypes[type] &amp;&amp; name.startsWith(searchString)) {\n",
       "            tableBodyChildren[i].style.display = &quot;&quot;;\n",
       "          } else {\n",
       "            tableBodyChildren[i].style.display = &quot;none&quot;;\n",
       "          }\n",
       "        }\n",
       "      }\n",
       "\n",
       "      $featureSearch.addEventListener(\n",
       "        &quot;keyup&quot;,\n",
       "        debounce((event) =&gt; {\n",
       "          searchString = event.target.value.toLowerCase();\n",
       "          handleSearch();\n",
       "        }, 100),\n",
       "      );\n",
       "\n",
       "      $noDrift.addEventListener(&quot;change&quot;, (event) =&gt; {\n",
       "        if (event.currentTarget.checked) {\n",
       "          activeTypes[&quot;nodrift&quot;] = true;\n",
       "        } else {\n",
       "          activeTypes[&quot;nodrift&quot;] = false;\n",
       "        }\n",
       "        handleSearch();\n",
       "        filterNotification()\n",
       "      });\n",
       "\n",
       "      $possibleDrift.addEventListener(&quot;change&quot;, (event) =&gt; {\n",
       "        if (event.currentTarget.checked) {\n",
       "          activeTypes[&quot;possibledrift&quot;] = true;\n",
       "        } else {\n",
       "          activeTypes[&quot;possibledrift&quot;] = false;\n",
       "        }\n",
       "        handleSearch();\n",
       "        filterNotification()\n",
       "      });\n",
       "\n",
       "      $unknownDrift.addEventListener(&quot;change&quot;, (event) =&gt; {\n",
       "        if (event.currentTarget.checked) {\n",
       "          activeTypes[&quot;unknowndrift&quot;] = true;\n",
       "        } else {\n",
       "          activeTypes[&quot;unknowndrift&quot;] = false;\n",
       "        }\n",
       "        handleSearch();\n",
       "        filterNotification()\n",
       "      });\n",
       "\n",
       "      $drift.addEventListener(&quot;change&quot;, (event) =&gt; {\n",
       "        if (event.currentTarget.checked) {\n",
       "          activeTypes[&quot;drift&quot;] = true;\n",
       "        } else {\n",
       "          activeTypes[&quot;drift&quot;] = false;\n",
       "        }\n",
       "        handleSearch();\n",
       "        filterNotification()\n",
       "      });\n",
       "\n",
       "      function checkCurrentProfile(item, referenceItem) {\n",
       "        if (referenceProfile &amp;&amp; Object.values(referenceProfile)) {\n",
       "          return referenceItem\n",
       "        } else {\n",
       "          return item\n",
       "        }\n",
       "      }\n",
       "\n",
       "      if(checkCurrentProfile(true, false)) {\n",
       "        $(&quot;.svg-container&quot;).css(&quot;padding-bottom&quot;, &quot;27%&quot;)\n",
       "        $(&quot;#diff-from-ref&quot;).addClass(&quot;d-none&quot;)\n",
       "        $(&quot;.diff-from-ref-table-cell&quot;).addClass(&quot;d-none&quot;)\n",
       "      } else {\n",
       "        $(&quot;#diff-from-ref&quot;).removeClass(&quot;d-none&quot;)\n",
       "        $(&quot;.diff-from-ref-table-cell&quot;).removeClass(&quot;d-none&quot;)\n",
       "      }\n",
       "    }\n",
       "\n",
       "    function checkedBoxes() {\n",
       "      const $boxes = $(&#x27;input[name=checkbox]:checked&#x27;);\n",
       "      const $notifCircleContainer = $(&quot;.notif-circle-container&quot;)\n",
       "\n",
       "      if ($boxes.length) {\n",
       "        $notifCircleContainer.removeClass(&quot;d-none&quot;)\n",
       "      }\n",
       "    }\n",
       "\n",
       "    function openFilter() {\n",
       "      const $filterOptions = $(&quot;.dropdown-container&quot;);\n",
       "      const $notifCircleContainer = $(&quot;.notif-circle-container&quot;)\n",
       "      const filterClass = $filterOptions.attr(&quot;class&quot;);\n",
       "\n",
       "      if (filterClass.indexOf(&quot;d-none&quot;) &gt; 0) {\n",
       "        $notifCircleContainer.addClass(&quot;d-none&quot;)\n",
       "        $filterOptions.removeClass(&quot;d-none&quot;);\n",
       "        $(&quot;.filter-icon&quot;).addClass(&quot;d-none&quot;)\n",
       "        $(&quot;.close-filter-icon&quot;).removeClass(&quot;d-none&quot;)\n",
       "      } else {\n",
       "        $filterOptions.addClass(&quot;d-none&quot;);\n",
       "        $(&quot;.close-filter-icon&quot;).addClass(&quot;d-none&quot;)\n",
       "        $(&quot;.filter-icon&quot;).removeClass(&quot;d-none&quot;)\n",
       "        checkedBoxes()\n",
       "      }\n",
       "    }\n",
       "\n",
       "    // Invoke functions -- keep in mind invokation order\n",
       "    registerHandlebarHelperFunctions();\n",
       "    initHandlebarsTemplate();\n",
       "    initWebsiteScripts();\n",
       "  &lt;/script&gt;\n",
       "&lt;/html&gt;\n",
       "\" width=100% height=1000px\n",
       "        frameBorder=0></iframe>"
      ],
      "text/plain": [
       "<IPython.core.display.HTML object>"
      ]
     },
     "execution_count": 11,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "visualization.summary_drift_report()"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "\n",
    "The drift values are calculated in different ways, depending on the existing metrics for each column. Kolmogorov-Smirnov Test is calculated if distribution metrics exists for said column. If not, Chi Square Test is calculated if frequent items, cardinality and count metric exists. If not, then no drift value is associated to the column.\n",
    " \n",
    "For `alcohol`, there's an alert of severe drift, with calculated p-value of 0.00. That makes sense, since both distributions are mutually exclusive.\n",
    "\n",
    "We can also conclude some thing just by visually inspecting the distributions. We can clearly see that the \"good-to-bad\" ratio changes significantly between both profiles. That in itself is a good indicator that the alcohol content might be correlated to the wine's quality\n",
    "\n",
    "The drift value is also relevant for a number of other features. For example, the `density` also is flagged with significant drift. Let's look at this feature in particular."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Histograms and Bar charts"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Now that we have a general idea of both profiles, let's take a look at some of the individual features.\n",
    "\n",
    "First, let's use the `double_histogram` to check on the `density` feature."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div></div><iframe srcdoc=\"&lt;!DOCTYPE html&gt;\n",
       "&lt;html lang=&quot;en&quot;&gt;\n",
       "  &lt;head&gt;\n",
       "    &lt;meta charset=&quot;UTF-8&quot; /&gt;\n",
       "    &lt;meta http-equiv=&quot;X-UA-Compatible&quot; content=&quot;IE=edge&quot; /&gt;\n",
       "    &lt;meta name=&quot;viewport&quot; content=&quot;width=device-width, initial-scale=1.0&quot; /&gt;\n",
       "    &lt;meta name=&quot;description&quot; content=&quot;&quot; /&gt;\n",
       "    &lt;meta name=&quot;author&quot; content=&quot;&quot; /&gt;\n",
       "\n",
       "    &lt;title&gt;Profile Visualizer | whylogs&lt;/title&gt;\n",
       "\n",
       "    &lt;link rel=&quot;icon&quot; href=&quot;images/whylabs-favicon.png&quot; type=&quot;image/png&quot; sizes=&quot;16x16&quot; /&gt;\n",
       "    &lt;link rel=&quot;preconnect&quot; href=&quot;https://fonts.googleapis.com&quot; /&gt;\n",
       "    &lt;link rel=&quot;preconnect&quot; href=&quot;https://fonts.gstatic.com&quot; crossorigin /&gt;\n",
       "    &lt;link href=&quot;https://fonts.googleapis.com/css2?family=Asap:wght@400;500;600;700&amp;display=swap&quot; rel=&quot;stylesheet&quot; /&gt;\n",
       "    &lt;link rel=&quot;preconnect&quot; href=&quot;https://fonts.gstatic.com&quot; /&gt;\n",
       "    &lt;link rel=&quot;stylesheet&quot; href=&quot;https://cdn.jsdelivr.net/npm/bootstrap@5.1.0/dist/css/bootstrap.min.css&quot; /&gt;\n",
       "\n",
       "    &lt;script\n",
       "      src=&quot;https://cdnjs.cloudflare.com/ajax/libs/handlebars.js/4.7.7/handlebars.min.js&quot;\n",
       "      integrity=&quot;sha512-RNLkV3d+aLtfcpEyFG8jRbnWHxUqVZozacROI4J2F1sTaDqo1dPQYs01OMi1t1w9Y2FdbSCDSQ2ZVdAC8bzgAg==&quot;\n",
       "      crossorigin=&quot;anonymous&quot;\n",
       "      referrerpolicy=&quot;no-referrer&quot;\n",
       "    &gt;&lt;/script&gt;\n",
       "\n",
       "    &lt;style type=&quot;text/css&quot;&gt;\n",
       "\n",
       "      :root {\n",
       "        /** Branded colors */\n",
       "        --brandSecondary900: #4f595b;\n",
       "        --secondaryLight1000: #313b3d;\n",
       "        /** Purpose colors */\n",
       "        --tealBackground: #eaf2f3;\n",
       "      }\n",
       "\n",
       "      /* RESET STYLE */\n",
       "      *,\n",
       "      *::after,\n",
       "      *::before {\n",
       "        margin: 0;\n",
       "        padding: 0;\n",
       "        box-sizing: border-box;\n",
       "        overflow-y: hidden;\n",
       "      }\n",
       "\n",
       "      /* Screen on smaller screens */\n",
       "      .no-responsive {\n",
       "        display: none;\n",
       "        position: fixed;\n",
       "        top: 0;\n",
       "        left: 0;\n",
       "        z-index: 1031;\n",
       "        width: 100vw;\n",
       "        height: 100vh;\n",
       "        background-color: var(--tealBackground);\n",
       "        display: flex;\n",
       "        align-items: center;\n",
       "        justify-content: center;\n",
       "      }\n",
       "\n",
       "      .desktop-content {\n",
       "        display: flex;\n",
       "        flex-direction: column;\n",
       "      }\n",
       "\n",
       "      .no-responsive__content {\n",
       "        max-width: 600px;\n",
       "        width: 100%;\n",
       "        padding: 0 24px;\n",
       "      }\n",
       "\n",
       "      .no-responsive__title {\n",
       "        font-size: 96px;\n",
       "        font-weight: 300;\n",
       "        color: var(--brandSecondary900);\n",
       "        line-height: 1.167;\n",
       "      }\n",
       "\n",
       "      .no-responsive__text {\n",
       "        margin: 0;\n",
       "        font-size: 16px;\n",
       "        font-weight: 400;\n",
       "        color: var(--brandSecondary900);\n",
       "        line-height: 1.5;\n",
       "      }\n",
       "\n",
       "      .svg-container {\n",
       "        display: inline-block;\n",
       "        position: relative;\n",
       "        width: 100%;\n",
       "        vertical-align: top;\n",
       "        overflow: hidden;\n",
       "      }\n",
       "\n",
       "      .svg-content-responsive {\n",
       "        display: inline-block;\n",
       "        position: absolute;\n",
       "        left: 0;\n",
       "      }\n",
       "\n",
       "      .circle-color {\n",
       "       display: inline-block;\n",
       "       padding: 5px;\n",
       "       border-radius: 50px;\n",
       "     }\n",
       "\n",
       "     .colors-for-distingushing-charts {\n",
       "       padding-right: 10px;\n",
       "     }\n",
       "\n",
       "     .display-flex{\n",
       "       display: flex;\n",
       "     }\n",
       "\n",
       "     .align-items-flex-end {\n",
       "       align-items: flex-end;\n",
       "     }\n",
       "\n",
       "     .chart-box-title {\n",
       "       width: 88%;\n",
       "       justify-content: space-between;\n",
       "       margin: 10px;\n",
       "       margin-top: 15px;\n",
       "       bottom: 0;\n",
       "     }\n",
       "\n",
       "     .chart-box-title p{\n",
       "       margin-bottom: 0;\n",
       "       font-family: Asap;\n",
       "       font-weight: bold;\n",
       "       font-size: 18px;\n",
       "       line-height: 16px;\n",
       "       color: #4F595B;\n",
       "     }\n",
       "\n",
       "    .bar {\n",
       "      font: 10px sans-serif;\n",
       "    }\n",
       "\n",
       "    .bar path,\n",
       "    .bar line {\n",
       "      fill: none;\n",
       "      stroke: #000;\n",
       "      shape-rendering: crispEdges;\n",
       "    }\n",
       "\n",
       "    .error-message {\n",
       "      display: flex;\n",
       "      justify-content: center;\n",
       "      align-items: center;\n",
       "      color: rgb(255, 114, 71);\n",
       "      font-size: 30px;\n",
       "      font-weight: 900;\n",
       "    }\n",
       "\n",
       "     @media screen and (min-width: 500px) {\n",
       "       .desktop-content {\n",
       "         display: block;\n",
       "       }\n",
       "       .no-responsive {\n",
       "         display: none;\n",
       "       }\n",
       "     }\n",
       "    &lt;/style&gt;\n",
       "  &lt;/head&gt;\n",
       "\n",
       "  &lt;body id=&quot;generated-html&quot;&gt;&lt;/body&gt;\n",
       "  &lt;script id=&quot;entry-template&quot; type=&quot;text/x-handlebars-template&quot;&gt;\n",
       "    \n",
       "      &lt;div class=&quot;desktop-content&quot;&gt;\n",
       "{{#each this}}              &lt;div class=&quot;chart-box&quot; id=&quot;chart-box&quot;&gt;\n",
       "                &lt;div class=&quot;chart-box-title display-flex&quot;&gt;\n",
       "                  &lt;p&gt;{{@key}}&lt;/p&gt;\n",
       "                  &lt;div class=&quot;display-flex&quot;&gt;\n",
       "                    &lt;div class=&quot;colors-for-distingushing-charts&quot;&gt;\n",
       "                      &lt;div class=&quot;circle-color&quot; style=&quot;background: #44C0E7;&quot;&gt;&lt;/div&gt;\n",
       "                      &lt;text alignment-baseline=&quot;middle&quot; style=&quot;font-size: 15px;&quot;&gt;Target&lt;/text&gt;\n",
       "                    &lt;/div&gt;\n",
       "                    &lt;div class=&quot;colors-for-distingushing-charts&quot;&gt;\n",
       "                      &lt;div class=&quot;circle-color&quot; style=&quot;background: #F5843C&quot;&gt;&lt;/div&gt;\n",
       "                      &lt;text alignment-baseline=&quot;middle&quot; style=&quot;font-size: 15px;&quot;&gt;Reference&lt;/text&gt;\n",
       "                    &lt;/div&gt;\n",
       "                  &lt;/div&gt;&lt;/div&gt;\n",
       "                &lt;div class=&quot;svg-container&quot;&gt;{{{getDoubleHistogramChart this}}}&lt;/div&gt;\n",
       "              &lt;/div&gt;\n",
       "{{/each}}      &lt;/div&gt;\n",
       "      &lt;div class=&quot;no-responsive&quot;&gt;\n",
       "        &lt;div class=&quot;no-responsive__content&quot;&gt;\n",
       "          &lt;h1 class=&quot;no-responsive__title&quot;&gt;Hold on! :)&lt;/h1&gt;\n",
       "          &lt;p class=&quot;no-responsive__text&quot;&gt;\n",
       "            It looks like your current screen size or device is not yet supported by the WhyLabs Sandbox. The Sandbox is\n",
       "            best experienced on a desktop computer. Please try maximizing this window or switching to another device. We\n",
       "            are working on adding support for a larger variety of devices.\n",
       "          &lt;/p&gt;\n",
       "        &lt;/div&gt;\n",
       "      &lt;/div&gt;\n",
       "    \n",
       "  &lt;/script&gt;\n",
       "\n",
       "  &lt;script src=&quot;https://code.jquery.com/jquery-3.6.0.min.js&quot; integrity=&quot;sha256-/xUj+3OJU5yExlq6GSYGSHk7tPXikynS7ogEvDej/m4=&quot; crossorigin=&quot;anonymous&quot;&gt;&lt;/script&gt;\n",
       "\n",
       "  &lt;script src=&quot;https://cdnjs.cloudflare.com/ajax/libs/d3/6.7.0/d3.min.js&quot; integrity=&quot;sha512-cd6CHE+XWDQ33ElJqsi0MdNte3S+bQY819f7p3NUHgwQQLXSKjE4cPZTeGNI+vaxZynk1wVU3hoHmow3m089wA==&quot; crossorigin=&quot;anonymous&quot; referrerpolicy=&quot;no-referrer&quot;&gt;&lt;/script&gt;\n",
       "\n",
       "  &lt;script&gt;\n",
       "    function registerHandlebarHelperFunctions() {\n",
       "      //helper fun\n",
       "\n",
       "      class GenerateChartParams {\n",
       "        constructor(height, width, targetData, referenceData, bottomMargin=30, topMargin=5) {\n",
       "          this.MARGIN = {\n",
       "            TOP: topMargin,\n",
       "            RIGHT: 5,\n",
       "            BOTTOM: bottomMargin,\n",
       "            LEFT: 55,\n",
       "          };\n",
       "          this.SVG_WIDTH = width;\n",
       "          this.SVG_HEIGHT = height;\n",
       "          this.CHART_WIDTH = this.SVG_WIDTH - this.MARGIN.LEFT - this.MARGIN.RIGHT;\n",
       "          this.CHART_HEIGHT = this.SVG_HEIGHT - this.MARGIN.TOP - this.MARGIN.BOTTOM;\n",
       "          this.svgEl = d3.create(&quot;svg&quot;)\n",
       "             .attr(&quot;preserveAspectRatio&quot;, &quot;xMinYMin meet&quot;)\n",
       "             .attr(&quot;viewBox&quot;, `0 0 ${$(window).width()+100} ${$(window).height()-30}`)\n",
       "             .classed(&quot;svg-content-responsive&quot;, true)\n",
       "          this.maxYValue = d3.max(targetData, (d) =&gt; Math.abs(d.axisY));\n",
       "          this.minYValue = d3.min(targetData, (d) =&gt; Math.abs(d.axisY));\n",
       "          const mergedReferenceData = referenceData.map(({axisX, axisY}) =&gt; {\n",
       "            return {axisX, axisY}\n",
       "          })\n",
       "          const mergedTargetedData = targetData.map(({axisX, axisY}) =&gt; {\n",
       "            return {axisX, axisY}\n",
       "          })\n",
       "\n",
       "          this.charts2 = mergedReferenceData.concat(mergedTargetedData)\n",
       "          this.charts2 = this.charts2.sort(function(a, b) { return a - b; });\n",
       "\n",
       "          this.targetBinWidth = targetData[1]?.axisX - targetData[0]?.axisX\n",
       "          this.referenceBinWidth = referenceData[1]?.axisX - referenceData[0]?.axisX\n",
       "          this.maxTargetXValue = d3.max(targetData, (d) =&gt; d.axisX);\n",
       "\n",
       "          this.maxReferenceXValue = d3.max(referenceData, (d) =&gt; d.axisX);\n",
       "\n",
       "          this.xScale = d3\n",
       "              .scaleLinear()\n",
       "         .domain([d3.min(this.charts2, function(d) { return parseFloat(d.axisX); }),(this.maxTargetXValue+this.targetBinWidth &gt;= this.maxReferenceXValue+this.referenceBinWidth) ? this.maxTargetXValue+this.targetBinWidth:this.maxReferenceXValue+this.referenceBinWidth])\n",
       "         .range([0, this.CHART_WIDTH ]);\n",
       "\n",
       "         this.svgEl.append(&quot;g&quot;)\n",
       "             .attr(&quot;transform&quot;, &quot;translate(&quot;+ this.MARGIN.LEFT +&quot;,&quot; + this.SVG_HEIGHT + &quot;)&quot;)\n",
       "             .call(d3.axisBottom(this.xScale));\n",
       "          this.yScale = d3.scaleLinear()\n",
       "              .range([this.CHART_HEIGHT , 0])\n",
       "              .domain([d3.min(this.charts2, function(d) { return parseFloat(d.axisY); }), d3.max(this.charts2, function(d) { return parseFloat(d.axisY); })*1.2])\n",
       "              .nice();\n",
       "        }\n",
       "      }\n",
       "\n",
       "      function chartData(column) {\n",
       "        const data = [];\n",
       "        if (column?.histogram) {\n",
       "          for (let i = 0; i&lt;column.histogram.bins.length; i++) {\n",
       "            data.push({\n",
       "              axisY: column.histogram.counts[i] || 0,\n",
       "              axisX: column.histogram.bins[i] || 0,\n",
       "            });\n",
       "          }\n",
       "        } else {\n",
       "            $(document).ready(() =&gt;\n",
       "              $(&quot;.desktop-content&quot;).html(`\n",
       "                &lt;p style=&quot;height: ${$(window).height()}px&quot; class=&quot;error-message&quot;&gt;\n",
       "                  Something went wrong. Please try again.\n",
       "                &lt;/p&gt;\n",
       "              `)\n",
       "            )\n",
       "          }\n",
       "\n",
       "        return data\n",
       "      }\n",
       "\n",
       "      function verticalLine(column) {\n",
       "        const line_data = [];\n",
       "        if (column?.vertical_line) {\n",
       "            line_data.push({\n",
       "              axisX: column?.vertical_line || 0,\n",
       "            });\n",
       "\n",
       "        }\n",
       "\n",
       "        return line_data\n",
       "      }\n",
       "\n",
       "      function generateDoubleHistogramChart(targetData, referenceData) {\n",
       "        let histogramData = [],\n",
       "            overlappedHistogramData = [];\n",
       "        let yFormat;\n",
       "\n",
       "        histogramData = chartData(targetData)\n",
       "        overlappedHistogramData = chartData(referenceData)\n",
       "        lineData = verticalLine(targetData)\n",
       "\n",
       "        const sizes = new GenerateChartParams($(window).height()-80, $(window).width(), histogramData, overlappedHistogramData)\n",
       "        const {\n",
       "          MARGIN,\n",
       "          SVG_WIDTH,\n",
       "          SVG_HEIGHT,\n",
       "          CHART_WIDTH,\n",
       "          CHART_HEIGHT,\n",
       "          svgEl,\n",
       "          maxYValue,\n",
       "          minYValue,\n",
       "          xScale,\n",
       "          yScale\n",
       "        } = sizes\n",
       "\n",
       "        const rectColors = [&quot;#44C0E7&quot;, &quot;#F5843C&quot;]\n",
       "        const yAxis = d3.axisLeft(yScale).ticks(SVG_HEIGHT / 40);\n",
       "\n",
       "        svgEl.append(&quot;g&quot;)\n",
       "          .attr(&quot;transform&quot;, `translate(${MARGIN.LEFT}, ${MARGIN.BOTTOM})`)\n",
       "          .call(yAxis)\n",
       "          .call(g =&gt; g.select(&quot;.domain&quot;).remove())\n",
       "          .call(g =&gt; g.selectAll(&quot;.tick line&quot;)\n",
       "              .attr(&quot;x2&quot;, CHART_WIDTH)\n",
       "              .attr(&quot;stroke-opacity&quot;, 0.1))\n",
       "          .call(g =&gt; g.append(&quot;text&quot;)\n",
       "              .attr(&quot;x&quot;, -MARGIN.LEFT)\n",
       "              .attr(&quot;y&quot;, 10)\n",
       "              .attr(&quot;fill&quot;, &quot;currentColor&quot;)\n",
       "              .attr(&quot;text-anchor&quot;, &quot;start&quot;))\n",
       "\n",
       "        svgEl.append(&quot;line&quot;)\n",
       "          .attr(&quot;transform&quot;, `translate(${MARGIN.LEFT}, ${MARGIN.BOTTOM})`)\n",
       "          .data(lineData)\n",
       "          .attr(&quot;x1&quot;, (d) =&gt; xScale(d.axisX))\n",
       "          .attr(&quot;y1&quot;, MARGIN.TOP + MARGIN.TOP)\n",
       "          .attr(&quot;x2&quot;, (d) =&gt; xScale(d.axisX))\n",
       "          .attr(&quot;y2&quot;, CHART_HEIGHT + MARGIN.TOP)\n",
       "          .style(&quot;stroke-width&quot;, 2)\n",
       "          .style(&quot;stroke&quot;, &quot;#44C0E7&quot;)\n",
       "          .style(&quot;stroke-dasharray&quot;, (3,3))\n",
       "          .style(&quot;fill&quot;, &quot;none&quot;);\n",
       "\n",
       "        svgEl.append(&quot;text&quot;)\n",
       "          .attr(&quot;transform&quot;, &quot;rotate(-90)&quot;)\n",
       "          .data(lineData)\n",
       "          .attr(&quot;y&quot;, (d) =&gt; xScale(d.axisX) + MARGIN.LEFT)\n",
       "          .attr(&quot;x&quot;, 0 - (SVG_HEIGHT / 2))\n",
       "          .attr(&quot;dy&quot;, &quot;1em&quot;)\n",
       "          .style(&quot;text-anchor&quot;, &quot;middle&quot;)\n",
       "          .text(&quot;single value&quot;)\n",
       "          .style(&quot;font-size&quot;, &quot;15&quot;)\n",
       "          .style(&quot;opacity&quot;, &quot;0.6&quot;)\n",
       "\n",
       "        svgEl.append(&quot;text&quot;)\n",
       "          .attr(&quot;transform&quot;,\n",
       "                &quot;translate(&quot; + (CHART_WIDTH/2) + &quot; ,&quot; +\n",
       "                               (CHART_HEIGHT + MARGIN.TOP + 75) + &quot;)&quot;)\n",
       "          .style(&quot;text-anchor&quot;, &quot;middle&quot;)\n",
       "          .text(&quot;Values&quot;)\n",
       "          .style(&quot;font-size&quot;, &quot;15&quot;)\n",
       "          .style(&quot;opacity&quot;, &quot;0.6&quot;)\n",
       "\n",
       "        svgEl.append(&quot;text&quot;)\n",
       "          .attr(&quot;transform&quot;, &quot;rotate(-90)&quot;)\n",
       "          .attr(&quot;y&quot;, 0)\n",
       "          .attr(&quot;x&quot;, 0 - (SVG_HEIGHT / 2))\n",
       "          .attr(&quot;dy&quot;, &quot;1em&quot;)\n",
       "          .style(&quot;text-anchor&quot;, &quot;middle&quot;)\n",
       "          .text(&quot;Counts&quot;)\n",
       "          .style(&quot;font-size&quot;, &quot;15&quot;)\n",
       "          .style(&quot;opacity&quot;, &quot;0.6&quot;)\n",
       "\n",
       "          const gChart = svgEl.append(&quot;g&quot;);\n",
       "          gChart\n",
       "          .attr(&quot;transform&quot;, &quot;translate(&quot;+ MARGIN.LEFT +&quot;,0)&quot;)\n",
       "          .selectAll(&quot;.bar&quot;)\n",
       "          .data(histogramData)\n",
       "          .enter()\n",
       "          .append(&quot;rect&quot;)\n",
       "          .style(&quot;stroke&quot;, &quot;#021826&quot;)\n",
       "          .classed(&quot;bar&quot;, true)\n",
       "          .attr(&quot;width&quot;, function(d) { return xScale(histogramData[1]?.axisX)-xScale(histogramData[0]?.axisX); })\n",
       "          .attr(&quot;height&quot;, (d) =&gt; CHART_HEIGHT - yScale(d.axisY))\n",
       "          .attr(&quot;x&quot;, 1)\n",
       "          .attr(&quot;transform&quot;, function(d) { return &quot;translate(&quot; + xScale(d.axisX) + &quot;,&quot; + 0  +  &quot;)&quot;; })\n",
       "          .attr(&quot;y&quot;, (d) =&gt; yScale(d.axisY) + MARGIN.TOP + MARGIN.BOTTOM)\n",
       "          .attr(&quot;fill&quot;, rectColors[0])\n",
       "          .style(&quot;opacity&quot;,&quot;0.6&quot;)\n",
       "\n",
       "          const gChart1 = svgEl.append(&quot;g&quot;);\n",
       "          gChart1\n",
       "          .attr(&quot;transform&quot;, &quot;translate(&quot;+ MARGIN.LEFT +&quot;,0)&quot;)\n",
       "          .selectAll(&quot;.bar&quot;)\n",
       "          .data(overlappedHistogramData)\n",
       "          .enter()\n",
       "          .append(&quot;rect&quot;)\n",
       "          .style(&quot;stroke&quot;, &quot;#021826&quot;)\n",
       "          .classed(&quot;bar&quot;, true)\n",
       "          .attr(&quot;width&quot;, function(d) { return xScale(overlappedHistogramData[1]?.axisX)-xScale(overlappedHistogramData[0]?.axisX); })\n",
       "          .attr(&quot;height&quot;, (d) =&gt; CHART_HEIGHT - yScale(d.axisY))\n",
       "          .attr(&quot;x&quot;, 1)\n",
       "          .attr(&quot;transform&quot;, function(d) { return &quot;translate(&quot; + xScale(d.axisX) + &quot;,&quot; + 0  +  &quot;)&quot;; })\n",
       "          .attr(&quot;y&quot;, (d) =&gt; yScale(d.axisY) + MARGIN.TOP + MARGIN.BOTTOM)\n",
       "          .attr(&quot;fill&quot;, rectColors[1])\n",
       "          .style(&quot;opacity&quot;,&quot;0.6&quot;)\n",
       "\n",
       "        return svgEl._groups[0][0].outerHTML;\n",
       "      }\n",
       "\n",
       "      const profileFromCSVfile = {&quot;density&quot;: {&quot;histogram&quot;: {&quot;start&quot;: 0.99236, &quot;end&quot;: 1.003690100369, &quot;width&quot;: 0, &quot;counts&quot;: [1, 1, 3, 2, 4, 11, 34, 42, 74, 95, 132, 136, 127, 128, 100, 84, 43, 43, 36, 31, 28, 16, 4, 6, 2, 0, 4, 2, 0, 2], &quot;max&quot;: 1.00369, &quot;min&quot;: 0.99236, &quot;bins&quot;: [0.99236, 0.9927376700123001, 0.9931153400246, 0.9934930100369, 0.9938706800492, 0.9942483500615, 0.9946260200738, 0.9950036900861, 0.9953813600984001, 0.9957590301107, 0.996136700123, 0.9965143701353, 0.9968920401476, 0.9972697101599, 0.9976473801722, 0.9980250501845, 0.9984027201968, 0.9987803902091, 0.9991580602214, 0.9995357302337, 0.999913400246, 1.0002910702582999, 1.0006687402706, 1.0010464102829, 1.0014240802952, 1.0018017503075, 1.0021794203198, 1.0025570903321, 1.0029347603443999, 1.0033124303567, 1.003690100369], &quot;n&quot;: 1191}}}\n",
       "\n",
       "      Handlebars.registerHelper(&quot;getDoubleHistogramChart&quot;,(column,key) =&gt; {\n",
       "          const columnKey = key.data.key\n",
       "        try {\n",
       "          if (profileFromCSVfile) {\n",
       "          return  generateDoubleHistogramChart (\n",
       "              column,\n",
       "              profileFromCSVfile[columnKey]\n",
       "            )\n",
       "          }\n",
       "        } catch (err) {\n",
       "          $(document).ready(() =&gt;\n",
       "            $(&quot;.desktop-content&quot;).html(`\n",
       "              &lt;p style=&quot;height: ${$(window).height()}px&quot; class=&quot;error-message&quot;&gt;\n",
       "                Something went wrong. Please try again.\n",
       "              &lt;/p&gt;\n",
       "            `)\n",
       "          )\n",
       "        }\n",
       "      });\n",
       "    }\n",
       "\n",
       "    function initWebsiteScripts() {\n",
       "      $(&quot;.svg-container&quot;).css(&quot;height&quot;, $(window).height() - 32)\n",
       "    }\n",
       "\n",
       "    function initHandlebarsTemplate() {\n",
       "      // Replace this context with JSON from .py file\n",
       "      const context = {&quot;density&quot;: {&quot;histogram&quot;: {&quot;start&quot;: 0.99007, &quot;end&quot;: 1.0032001003200002, &quot;width&quot;: 0, &quot;counts&quot;: [3, 4, 1, 9, 4, 12, 8, 32, 32, 36, 39, 49, 45, 25, 25, 19, 15, 8, 4, 8, 5, 6, 2, 5, 4, 1, 1, 2, 0, 4], &quot;max&quot;: 1.0032, &quot;min&quot;: 0.99007, &quot;bins&quot;: [0.99007, 0.9905076700106666, 0.9909453400213334, 0.991383010032, 0.9918206800426667, 0.9922583500533334, 0.992696020064, 0.9931336900746667, 0.9935713600853334, 0.9940090300960001, 0.9944467001066667, 0.9948843701173334, 0.9953220401280001, 0.9957597101386667, 0.9961973801493335, 0.9966350501600001, 0.9970727201706667, 0.9975103901813335, 0.9979480601920001, 0.9983857302026667, 0.9988234002133335, 0.9992610702240001, 0.9996987402346668, 1.0001364102453334, 1.0005740802560001, 1.0010117502666669, 1.0014494202773334, 1.0018870902880002, 1.002324760298667, 1.0027624303093334, 1.0032001003200002], &quot;n&quot;: 408}}};\n",
       "      // Config handlebars and pass data to HBS template\n",
       "      const source = document.getElementById(&quot;entry-template&quot;).innerHTML;\n",
       "      const template = Handlebars.compile(source);\n",
       "      const html = template(context);\n",
       "      const target = document.getElementById(&quot;generated-html&quot;);\n",
       "      target.innerHTML = html;\n",
       "    }\n",
       "\n",
       "    // Invoke functions -- keep in mind invokation order\n",
       "    registerHandlebarHelperFunctions();\n",
       "    initHandlebarsTemplate();\n",
       "    initWebsiteScripts();\n",
       "  &lt;/script&gt;\n",
       "&lt;/html&gt;\n",
       "\" width=100% height=300px\n",
       "        frameBorder=0></iframe>"
      ],
      "text/plain": [
       "<IPython.core.display.HTML object>"
      ]
     },
     "execution_count": 12,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "visualization.double_histogram(feature_name=\"density\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "We can visually assess that there seems to be a drift between both distributions indeed. Maybe the alcohol content plays a significant role on the wine's density.\n",
    "\n",
    "As is the case with the alcohol content, our potential model would see density values in production never before seen in the training test. We can certainly expect performance degradation during production."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "We can also pass a list of feature names to `double_histogram` to generate multiple plots. Let's check the `alcohol`  and `chlorides` features. For the alcohol feature, there's a clear separation between the distributions at the value of `11`."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div></div><iframe srcdoc=\"&lt;!DOCTYPE html&gt;\n",
       "&lt;html lang=&quot;en&quot;&gt;\n",
       "  &lt;head&gt;\n",
       "    &lt;meta charset=&quot;UTF-8&quot; /&gt;\n",
       "    &lt;meta http-equiv=&quot;X-UA-Compatible&quot; content=&quot;IE=edge&quot; /&gt;\n",
       "    &lt;meta name=&quot;viewport&quot; content=&quot;width=device-width, initial-scale=1.0&quot; /&gt;\n",
       "    &lt;meta name=&quot;description&quot; content=&quot;&quot; /&gt;\n",
       "    &lt;meta name=&quot;author&quot; content=&quot;&quot; /&gt;\n",
       "\n",
       "    &lt;title&gt;Profile Visualizer | whylogs&lt;/title&gt;\n",
       "\n",
       "    &lt;link rel=&quot;icon&quot; href=&quot;images/whylabs-favicon.png&quot; type=&quot;image/png&quot; sizes=&quot;16x16&quot; /&gt;\n",
       "    &lt;link rel=&quot;preconnect&quot; href=&quot;https://fonts.googleapis.com&quot; /&gt;\n",
       "    &lt;link rel=&quot;preconnect&quot; href=&quot;https://fonts.gstatic.com&quot; crossorigin /&gt;\n",
       "    &lt;link href=&quot;https://fonts.googleapis.com/css2?family=Asap:wght@400;500;600;700&amp;display=swap&quot; rel=&quot;stylesheet&quot; /&gt;\n",
       "    &lt;link rel=&quot;preconnect&quot; href=&quot;https://fonts.gstatic.com&quot; /&gt;\n",
       "    &lt;link rel=&quot;stylesheet&quot; href=&quot;https://cdn.jsdelivr.net/npm/bootstrap@5.1.0/dist/css/bootstrap.min.css&quot; /&gt;\n",
       "\n",
       "    &lt;script\n",
       "      src=&quot;https://cdnjs.cloudflare.com/ajax/libs/handlebars.js/4.7.7/handlebars.min.js&quot;\n",
       "      integrity=&quot;sha512-RNLkV3d+aLtfcpEyFG8jRbnWHxUqVZozacROI4J2F1sTaDqo1dPQYs01OMi1t1w9Y2FdbSCDSQ2ZVdAC8bzgAg==&quot;\n",
       "      crossorigin=&quot;anonymous&quot;\n",
       "      referrerpolicy=&quot;no-referrer&quot;\n",
       "    &gt;&lt;/script&gt;\n",
       "\n",
       "    &lt;style type=&quot;text/css&quot;&gt;\n",
       "\n",
       "      :root {\n",
       "        /** Branded colors */\n",
       "        --brandSecondary900: #4f595b;\n",
       "        --secondaryLight1000: #313b3d;\n",
       "        /** Purpose colors */\n",
       "        --tealBackground: #eaf2f3;\n",
       "      }\n",
       "\n",
       "      /* RESET STYLE */\n",
       "      *,\n",
       "      *::after,\n",
       "      *::before {\n",
       "        margin: 0;\n",
       "        padding: 0;\n",
       "        box-sizing: border-box;\n",
       "        overflow-y: hidden;\n",
       "      }\n",
       "\n",
       "      /* Screen on smaller screens */\n",
       "      .no-responsive {\n",
       "        display: none;\n",
       "        position: fixed;\n",
       "        top: 0;\n",
       "        left: 0;\n",
       "        z-index: 1031;\n",
       "        width: 100vw;\n",
       "        height: 100vh;\n",
       "        background-color: var(--tealBackground);\n",
       "        display: flex;\n",
       "        align-items: center;\n",
       "        justify-content: center;\n",
       "      }\n",
       "\n",
       "      .desktop-content {\n",
       "        display: flex;\n",
       "        flex-direction: column;\n",
       "      }\n",
       "\n",
       "      .no-responsive__content {\n",
       "        max-width: 600px;\n",
       "        width: 100%;\n",
       "        padding: 0 24px;\n",
       "      }\n",
       "\n",
       "      .no-responsive__title {\n",
       "        font-size: 96px;\n",
       "        font-weight: 300;\n",
       "        color: var(--brandSecondary900);\n",
       "        line-height: 1.167;\n",
       "      }\n",
       "\n",
       "      .no-responsive__text {\n",
       "        margin: 0;\n",
       "        font-size: 16px;\n",
       "        font-weight: 400;\n",
       "        color: var(--brandSecondary900);\n",
       "        line-height: 1.5;\n",
       "      }\n",
       "\n",
       "      .svg-container {\n",
       "        display: inline-block;\n",
       "        position: relative;\n",
       "        width: 100%;\n",
       "        vertical-align: top;\n",
       "        overflow: hidden;\n",
       "      }\n",
       "\n",
       "      .svg-content-responsive {\n",
       "        display: inline-block;\n",
       "        position: absolute;\n",
       "        left: 0;\n",
       "      }\n",
       "\n",
       "      .circle-color {\n",
       "       display: inline-block;\n",
       "       padding: 5px;\n",
       "       border-radius: 50px;\n",
       "     }\n",
       "\n",
       "     .colors-for-distingushing-charts {\n",
       "       padding-right: 10px;\n",
       "     }\n",
       "\n",
       "     .display-flex{\n",
       "       display: flex;\n",
       "     }\n",
       "\n",
       "     .align-items-flex-end {\n",
       "       align-items: flex-end;\n",
       "     }\n",
       "\n",
       "     .chart-box-title {\n",
       "       width: 88%;\n",
       "       justify-content: space-between;\n",
       "       margin: 10px;\n",
       "       margin-top: 15px;\n",
       "       bottom: 0;\n",
       "     }\n",
       "\n",
       "     .chart-box-title p{\n",
       "       margin-bottom: 0;\n",
       "       font-family: Asap;\n",
       "       font-weight: bold;\n",
       "       font-size: 18px;\n",
       "       line-height: 16px;\n",
       "       color: #4F595B;\n",
       "     }\n",
       "\n",
       "    .bar {\n",
       "      font: 10px sans-serif;\n",
       "    }\n",
       "\n",
       "    .bar path,\n",
       "    .bar line {\n",
       "      fill: none;\n",
       "      stroke: #000;\n",
       "      shape-rendering: crispEdges;\n",
       "    }\n",
       "\n",
       "    .error-message {\n",
       "      display: flex;\n",
       "      justify-content: center;\n",
       "      align-items: center;\n",
       "      color: rgb(255, 114, 71);\n",
       "      font-size: 30px;\n",
       "      font-weight: 900;\n",
       "    }\n",
       "\n",
       "     @media screen and (min-width: 500px) {\n",
       "       .desktop-content {\n",
       "         display: block;\n",
       "       }\n",
       "       .no-responsive {\n",
       "         display: none;\n",
       "       }\n",
       "     }\n",
       "    &lt;/style&gt;\n",
       "  &lt;/head&gt;\n",
       "\n",
       "  &lt;body id=&quot;generated-html&quot;&gt;&lt;/body&gt;\n",
       "  &lt;script id=&quot;entry-template&quot; type=&quot;text/x-handlebars-template&quot;&gt;\n",
       "    \n",
       "      &lt;div class=&quot;desktop-content&quot;&gt;\n",
       "{{#each this}}              &lt;div class=&quot;chart-box&quot; id=&quot;chart-box&quot;&gt;\n",
       "                &lt;div class=&quot;chart-box-title display-flex&quot;&gt;\n",
       "                  &lt;p&gt;{{@key}}&lt;/p&gt;\n",
       "                  &lt;div class=&quot;display-flex&quot;&gt;\n",
       "                    &lt;div class=&quot;colors-for-distingushing-charts&quot;&gt;\n",
       "                      &lt;div class=&quot;circle-color&quot; style=&quot;background: #44C0E7;&quot;&gt;&lt;/div&gt;\n",
       "                      &lt;text alignment-baseline=&quot;middle&quot; style=&quot;font-size: 15px;&quot;&gt;Target&lt;/text&gt;\n",
       "                    &lt;/div&gt;\n",
       "                    &lt;div class=&quot;colors-for-distingushing-charts&quot;&gt;\n",
       "                      &lt;div class=&quot;circle-color&quot; style=&quot;background: #F5843C&quot;&gt;&lt;/div&gt;\n",
       "                      &lt;text alignment-baseline=&quot;middle&quot; style=&quot;font-size: 15px;&quot;&gt;Reference&lt;/text&gt;\n",
       "                    &lt;/div&gt;\n",
       "                  &lt;/div&gt;&lt;/div&gt;\n",
       "                &lt;div class=&quot;svg-container&quot;&gt;{{{getDoubleHistogramChart this}}}&lt;/div&gt;\n",
       "              &lt;/div&gt;\n",
       "{{/each}}      &lt;/div&gt;\n",
       "      &lt;div class=&quot;no-responsive&quot;&gt;\n",
       "        &lt;div class=&quot;no-responsive__content&quot;&gt;\n",
       "          &lt;h1 class=&quot;no-responsive__title&quot;&gt;Hold on! :)&lt;/h1&gt;\n",
       "          &lt;p class=&quot;no-responsive__text&quot;&gt;\n",
       "            It looks like your current screen size or device is not yet supported by the WhyLabs Sandbox. The Sandbox is\n",
       "            best experienced on a desktop computer. Please try maximizing this window or switching to another device. We\n",
       "            are working on adding support for a larger variety of devices.\n",
       "          &lt;/p&gt;\n",
       "        &lt;/div&gt;\n",
       "      &lt;/div&gt;\n",
       "    \n",
       "  &lt;/script&gt;\n",
       "\n",
       "  &lt;script src=&quot;https://code.jquery.com/jquery-3.6.0.min.js&quot; integrity=&quot;sha256-/xUj+3OJU5yExlq6GSYGSHk7tPXikynS7ogEvDej/m4=&quot; crossorigin=&quot;anonymous&quot;&gt;&lt;/script&gt;\n",
       "\n",
       "  &lt;script src=&quot;https://cdnjs.cloudflare.com/ajax/libs/d3/6.7.0/d3.min.js&quot; integrity=&quot;sha512-cd6CHE+XWDQ33ElJqsi0MdNte3S+bQY819f7p3NUHgwQQLXSKjE4cPZTeGNI+vaxZynk1wVU3hoHmow3m089wA==&quot; crossorigin=&quot;anonymous&quot; referrerpolicy=&quot;no-referrer&quot;&gt;&lt;/script&gt;\n",
       "\n",
       "  &lt;script&gt;\n",
       "    function registerHandlebarHelperFunctions() {\n",
       "      //helper fun\n",
       "\n",
       "      class GenerateChartParams {\n",
       "        constructor(height, width, targetData, referenceData, bottomMargin=30, topMargin=5) {\n",
       "          this.MARGIN = {\n",
       "            TOP: topMargin,\n",
       "            RIGHT: 5,\n",
       "            BOTTOM: bottomMargin,\n",
       "            LEFT: 55,\n",
       "          };\n",
       "          this.SVG_WIDTH = width;\n",
       "          this.SVG_HEIGHT = height;\n",
       "          this.CHART_WIDTH = this.SVG_WIDTH - this.MARGIN.LEFT - this.MARGIN.RIGHT;\n",
       "          this.CHART_HEIGHT = this.SVG_HEIGHT - this.MARGIN.TOP - this.MARGIN.BOTTOM;\n",
       "          this.svgEl = d3.create(&quot;svg&quot;)\n",
       "             .attr(&quot;preserveAspectRatio&quot;, &quot;xMinYMin meet&quot;)\n",
       "             .attr(&quot;viewBox&quot;, `0 0 ${$(window).width()+100} ${$(window).height()-30}`)\n",
       "             .classed(&quot;svg-content-responsive&quot;, true)\n",
       "          this.maxYValue = d3.max(targetData, (d) =&gt; Math.abs(d.axisY));\n",
       "          this.minYValue = d3.min(targetData, (d) =&gt; Math.abs(d.axisY));\n",
       "          const mergedReferenceData = referenceData.map(({axisX, axisY}) =&gt; {\n",
       "            return {axisX, axisY}\n",
       "          })\n",
       "          const mergedTargetedData = targetData.map(({axisX, axisY}) =&gt; {\n",
       "            return {axisX, axisY}\n",
       "          })\n",
       "\n",
       "          this.charts2 = mergedReferenceData.concat(mergedTargetedData)\n",
       "          this.charts2 = this.charts2.sort(function(a, b) { return a - b; });\n",
       "\n",
       "          this.targetBinWidth = targetData[1]?.axisX - targetData[0]?.axisX\n",
       "          this.referenceBinWidth = referenceData[1]?.axisX - referenceData[0]?.axisX\n",
       "          this.maxTargetXValue = d3.max(targetData, (d) =&gt; d.axisX);\n",
       "\n",
       "          this.maxReferenceXValue = d3.max(referenceData, (d) =&gt; d.axisX);\n",
       "\n",
       "          this.xScale = d3\n",
       "              .scaleLinear()\n",
       "         .domain([d3.min(this.charts2, function(d) { return parseFloat(d.axisX); }),(this.maxTargetXValue+this.targetBinWidth &gt;= this.maxReferenceXValue+this.referenceBinWidth) ? this.maxTargetXValue+this.targetBinWidth:this.maxReferenceXValue+this.referenceBinWidth])\n",
       "         .range([0, this.CHART_WIDTH ]);\n",
       "\n",
       "         this.svgEl.append(&quot;g&quot;)\n",
       "             .attr(&quot;transform&quot;, &quot;translate(&quot;+ this.MARGIN.LEFT +&quot;,&quot; + this.SVG_HEIGHT + &quot;)&quot;)\n",
       "             .call(d3.axisBottom(this.xScale));\n",
       "          this.yScale = d3.scaleLinear()\n",
       "              .range([this.CHART_HEIGHT , 0])\n",
       "              .domain([d3.min(this.charts2, function(d) { return parseFloat(d.axisY); }), d3.max(this.charts2, function(d) { return parseFloat(d.axisY); })*1.2])\n",
       "              .nice();\n",
       "        }\n",
       "      }\n",
       "\n",
       "      function chartData(column) {\n",
       "        const data = [];\n",
       "        if (column?.histogram) {\n",
       "          for (let i = 0; i&lt;column.histogram.bins.length; i++) {\n",
       "            data.push({\n",
       "              axisY: column.histogram.counts[i] || 0,\n",
       "              axisX: column.histogram.bins[i] || 0,\n",
       "            });\n",
       "          }\n",
       "        } else {\n",
       "            $(document).ready(() =&gt;\n",
       "              $(&quot;.desktop-content&quot;).html(`\n",
       "                &lt;p style=&quot;height: ${$(window).height()}px&quot; class=&quot;error-message&quot;&gt;\n",
       "                  Something went wrong. Please try again.\n",
       "                &lt;/p&gt;\n",
       "              `)\n",
       "            )\n",
       "          }\n",
       "\n",
       "        return data\n",
       "      }\n",
       "\n",
       "      function verticalLine(column) {\n",
       "        const line_data = [];\n",
       "        if (column?.vertical_line) {\n",
       "            line_data.push({\n",
       "              axisX: column?.vertical_line || 0,\n",
       "            });\n",
       "\n",
       "        }\n",
       "\n",
       "        return line_data\n",
       "      }\n",
       "\n",
       "      function generateDoubleHistogramChart(targetData, referenceData) {\n",
       "        let histogramData = [],\n",
       "            overlappedHistogramData = [];\n",
       "        let yFormat;\n",
       "\n",
       "        histogramData = chartData(targetData)\n",
       "        overlappedHistogramData = chartData(referenceData)\n",
       "        lineData = verticalLine(targetData)\n",
       "\n",
       "        const sizes = new GenerateChartParams($(window).height()-80, $(window).width(), histogramData, overlappedHistogramData)\n",
       "        const {\n",
       "          MARGIN,\n",
       "          SVG_WIDTH,\n",
       "          SVG_HEIGHT,\n",
       "          CHART_WIDTH,\n",
       "          CHART_HEIGHT,\n",
       "          svgEl,\n",
       "          maxYValue,\n",
       "          minYValue,\n",
       "          xScale,\n",
       "          yScale\n",
       "        } = sizes\n",
       "\n",
       "        const rectColors = [&quot;#44C0E7&quot;, &quot;#F5843C&quot;]\n",
       "        const yAxis = d3.axisLeft(yScale).ticks(SVG_HEIGHT / 40);\n",
       "\n",
       "        svgEl.append(&quot;g&quot;)\n",
       "          .attr(&quot;transform&quot;, `translate(${MARGIN.LEFT}, ${MARGIN.BOTTOM})`)\n",
       "          .call(yAxis)\n",
       "          .call(g =&gt; g.select(&quot;.domain&quot;).remove())\n",
       "          .call(g =&gt; g.selectAll(&quot;.tick line&quot;)\n",
       "              .attr(&quot;x2&quot;, CHART_WIDTH)\n",
       "              .attr(&quot;stroke-opacity&quot;, 0.1))\n",
       "          .call(g =&gt; g.append(&quot;text&quot;)\n",
       "              .attr(&quot;x&quot;, -MARGIN.LEFT)\n",
       "              .attr(&quot;y&quot;, 10)\n",
       "              .attr(&quot;fill&quot;, &quot;currentColor&quot;)\n",
       "              .attr(&quot;text-anchor&quot;, &quot;start&quot;))\n",
       "\n",
       "        svgEl.append(&quot;line&quot;)\n",
       "          .attr(&quot;transform&quot;, `translate(${MARGIN.LEFT}, ${MARGIN.BOTTOM})`)\n",
       "          .data(lineData)\n",
       "          .attr(&quot;x1&quot;, (d) =&gt; xScale(d.axisX))\n",
       "          .attr(&quot;y1&quot;, MARGIN.TOP + MARGIN.TOP)\n",
       "          .attr(&quot;x2&quot;, (d) =&gt; xScale(d.axisX))\n",
       "          .attr(&quot;y2&quot;, CHART_HEIGHT + MARGIN.TOP)\n",
       "          .style(&quot;stroke-width&quot;, 2)\n",
       "          .style(&quot;stroke&quot;, &quot;#44C0E7&quot;)\n",
       "          .style(&quot;stroke-dasharray&quot;, (3,3))\n",
       "          .style(&quot;fill&quot;, &quot;none&quot;);\n",
       "\n",
       "        svgEl.append(&quot;text&quot;)\n",
       "          .attr(&quot;transform&quot;, &quot;rotate(-90)&quot;)\n",
       "          .data(lineData)\n",
       "          .attr(&quot;y&quot;, (d) =&gt; xScale(d.axisX) + MARGIN.LEFT)\n",
       "          .attr(&quot;x&quot;, 0 - (SVG_HEIGHT / 2))\n",
       "          .attr(&quot;dy&quot;, &quot;1em&quot;)\n",
       "          .style(&quot;text-anchor&quot;, &quot;middle&quot;)\n",
       "          .text(&quot;single value&quot;)\n",
       "          .style(&quot;font-size&quot;, &quot;15&quot;)\n",
       "          .style(&quot;opacity&quot;, &quot;0.6&quot;)\n",
       "\n",
       "        svgEl.append(&quot;text&quot;)\n",
       "          .attr(&quot;transform&quot;,\n",
       "                &quot;translate(&quot; + (CHART_WIDTH/2) + &quot; ,&quot; +\n",
       "                               (CHART_HEIGHT + MARGIN.TOP + 75) + &quot;)&quot;)\n",
       "          .style(&quot;text-anchor&quot;, &quot;middle&quot;)\n",
       "          .text(&quot;Values&quot;)\n",
       "          .style(&quot;font-size&quot;, &quot;15&quot;)\n",
       "          .style(&quot;opacity&quot;, &quot;0.6&quot;)\n",
       "\n",
       "        svgEl.append(&quot;text&quot;)\n",
       "          .attr(&quot;transform&quot;, &quot;rotate(-90)&quot;)\n",
       "          .attr(&quot;y&quot;, 0)\n",
       "          .attr(&quot;x&quot;, 0 - (SVG_HEIGHT / 2))\n",
       "          .attr(&quot;dy&quot;, &quot;1em&quot;)\n",
       "          .style(&quot;text-anchor&quot;, &quot;middle&quot;)\n",
       "          .text(&quot;Counts&quot;)\n",
       "          .style(&quot;font-size&quot;, &quot;15&quot;)\n",
       "          .style(&quot;opacity&quot;, &quot;0.6&quot;)\n",
       "\n",
       "          const gChart = svgEl.append(&quot;g&quot;);\n",
       "          gChart\n",
       "          .attr(&quot;transform&quot;, &quot;translate(&quot;+ MARGIN.LEFT +&quot;,0)&quot;)\n",
       "          .selectAll(&quot;.bar&quot;)\n",
       "          .data(histogramData)\n",
       "          .enter()\n",
       "          .append(&quot;rect&quot;)\n",
       "          .style(&quot;stroke&quot;, &quot;#021826&quot;)\n",
       "          .classed(&quot;bar&quot;, true)\n",
       "          .attr(&quot;width&quot;, function(d) { return xScale(histogramData[1]?.axisX)-xScale(histogramData[0]?.axisX); })\n",
       "          .attr(&quot;height&quot;, (d) =&gt; CHART_HEIGHT - yScale(d.axisY))\n",
       "          .attr(&quot;x&quot;, 1)\n",
       "          .attr(&quot;transform&quot;, function(d) { return &quot;translate(&quot; + xScale(d.axisX) + &quot;,&quot; + 0  +  &quot;)&quot;; })\n",
       "          .attr(&quot;y&quot;, (d) =&gt; yScale(d.axisY) + MARGIN.TOP + MARGIN.BOTTOM)\n",
       "          .attr(&quot;fill&quot;, rectColors[0])\n",
       "          .style(&quot;opacity&quot;,&quot;0.6&quot;)\n",
       "\n",
       "          const gChart1 = svgEl.append(&quot;g&quot;);\n",
       "          gChart1\n",
       "          .attr(&quot;transform&quot;, &quot;translate(&quot;+ MARGIN.LEFT +&quot;,0)&quot;)\n",
       "          .selectAll(&quot;.bar&quot;)\n",
       "          .data(overlappedHistogramData)\n",
       "          .enter()\n",
       "          .append(&quot;rect&quot;)\n",
       "          .style(&quot;stroke&quot;, &quot;#021826&quot;)\n",
       "          .classed(&quot;bar&quot;, true)\n",
       "          .attr(&quot;width&quot;, function(d) { return xScale(overlappedHistogramData[1]?.axisX)-xScale(overlappedHistogramData[0]?.axisX); })\n",
       "          .attr(&quot;height&quot;, (d) =&gt; CHART_HEIGHT - yScale(d.axisY))\n",
       "          .attr(&quot;x&quot;, 1)\n",
       "          .attr(&quot;transform&quot;, function(d) { return &quot;translate(&quot; + xScale(d.axisX) + &quot;,&quot; + 0  +  &quot;)&quot;; })\n",
       "          .attr(&quot;y&quot;, (d) =&gt; yScale(d.axisY) + MARGIN.TOP + MARGIN.BOTTOM)\n",
       "          .attr(&quot;fill&quot;, rectColors[1])\n",
       "          .style(&quot;opacity&quot;,&quot;0.6&quot;)\n",
       "\n",
       "        return svgEl._groups[0][0].outerHTML;\n",
       "      }\n",
       "\n",
       "      const profileFromCSVfile = {&quot;alcohol&quot;: {&quot;histogram&quot;: {&quot;start&quot;: 8.4, &quot;end&quot;: 11.0000011, &quot;width&quot;: 0, &quot;counts&quot;: [2, 1, 0, 2, 2, 0, 31, 1, 22, 74, 59, 103, 139, 63, 53, 0, 79, 50, 69, 47, 45, 33, 0, 42, 69, 28, 26, 43, 50, 58], &quot;max&quot;: 11.0, &quot;min&quot;: 8.4, &quot;bins&quot;: [8.4, 8.486666703333334, 8.573333406666666, 8.66000011, 8.746666813333334, 8.833333516666666, 8.92000022, 9.006666923333334, 9.093333626666666, 9.18000033, 9.266667033333334, 9.353333736666666, 9.44000044, 9.526667143333334, 9.613333846666666, 9.70000055, 9.786667253333334, 9.873333956666666, 9.96000066, 10.046667363333334, 10.133334066666666, 10.22000077, 10.306667473333334, 10.393334176666666, 10.48000088, 10.566667583333334, 10.653334286666666, 10.74000099, 10.826667693333334, 10.913334396666666, 11.0000011], &quot;n&quot;: 1191}}}\n",
       "\n",
       "      Handlebars.registerHelper(&quot;getDoubleHistogramChart&quot;,(column,key) =&gt; {\n",
       "          const columnKey = key.data.key\n",
       "        try {\n",
       "          if (profileFromCSVfile) {\n",
       "          return  generateDoubleHistogramChart (\n",
       "              column,\n",
       "              profileFromCSVfile[columnKey]\n",
       "            )\n",
       "          }\n",
       "        } catch (err) {\n",
       "          $(document).ready(() =&gt;\n",
       "            $(&quot;.desktop-content&quot;).html(`\n",
       "              &lt;p style=&quot;height: ${$(window).height()}px&quot; class=&quot;error-message&quot;&gt;\n",
       "                Something went wrong. Please try again.\n",
       "              &lt;/p&gt;\n",
       "            `)\n",
       "          )\n",
       "        }\n",
       "      });\n",
       "    }\n",
       "\n",
       "    function initWebsiteScripts() {\n",
       "      $(&quot;.svg-container&quot;).css(&quot;height&quot;, $(window).height() - 32)\n",
       "    }\n",
       "\n",
       "    function initHandlebarsTemplate() {\n",
       "      // Replace this context with JSON from .py file\n",
       "      const context = {&quot;alcohol&quot;: {&quot;histogram&quot;: {&quot;start&quot;: 11.066666666666698, &quot;end&quot;: 14.900001490000001, &quot;width&quot;: 0, &quot;counts&quot;: [28, 68, 32, 30, 38, 29, 21, 21, 25, 12, 13, 27, 9, 17, 9, 8, 1, 3, 3, 6, 0, 0, 7, 0, 0, 0, 0, 0, 0, 1], &quot;max&quot;: 14.9, &quot;min&quot;: 11.066666666666698, &quot;bins&quot;: [11.066666666666698, 11.194444494111142, 11.322222321555586, 11.45000014900003, 11.577777976444471, 11.705555803888915, 11.833333631333359, 11.961111458777802, 12.088889286222246, 12.21666711366669, 12.344444941111133, 12.472222768555575, 12.600000596000019, 12.727778423444462, 12.855556250888906, 12.98333407833335, 13.111111905777793, 13.238889733222237, 13.36666756066668, 13.494445388111123, 13.622223215555566, 13.75000104300001, 13.877778870444454, 14.005556697888897, 14.13333452533334, 14.261112352777783, 14.388890180222226, 14.51666800766667, 14.644445835111114, 14.772223662555557, 14.900001490000001], &quot;n&quot;: 408}}};\n",
       "      // Config handlebars and pass data to HBS template\n",
       "      const source = document.getElementById(&quot;entry-template&quot;).innerHTML;\n",
       "      const template = Handlebars.compile(source);\n",
       "      const html = template(context);\n",
       "      const target = document.getElementById(&quot;generated-html&quot;);\n",
       "      target.innerHTML = html;\n",
       "    }\n",
       "\n",
       "    // Invoke functions -- keep in mind invokation order\n",
       "    registerHandlebarHelperFunctions();\n",
       "    initHandlebarsTemplate();\n",
       "    initWebsiteScripts();\n",
       "  &lt;/script&gt;\n",
       "&lt;/html&gt;\n",
       "\" width=100% height=300px\n",
       "        frameBorder=0></iframe><br><div></div><iframe srcdoc=\"&lt;!DOCTYPE html&gt;\n",
       "&lt;html lang=&quot;en&quot;&gt;\n",
       "  &lt;head&gt;\n",
       "    &lt;meta charset=&quot;UTF-8&quot; /&gt;\n",
       "    &lt;meta http-equiv=&quot;X-UA-Compatible&quot; content=&quot;IE=edge&quot; /&gt;\n",
       "    &lt;meta name=&quot;viewport&quot; content=&quot;width=device-width, initial-scale=1.0&quot; /&gt;\n",
       "    &lt;meta name=&quot;description&quot; content=&quot;&quot; /&gt;\n",
       "    &lt;meta name=&quot;author&quot; content=&quot;&quot; /&gt;\n",
       "\n",
       "    &lt;title&gt;Profile Visualizer | whylogs&lt;/title&gt;\n",
       "\n",
       "    &lt;link rel=&quot;icon&quot; href=&quot;images/whylabs-favicon.png&quot; type=&quot;image/png&quot; sizes=&quot;16x16&quot; /&gt;\n",
       "    &lt;link rel=&quot;preconnect&quot; href=&quot;https://fonts.googleapis.com&quot; /&gt;\n",
       "    &lt;link rel=&quot;preconnect&quot; href=&quot;https://fonts.gstatic.com&quot; crossorigin /&gt;\n",
       "    &lt;link href=&quot;https://fonts.googleapis.com/css2?family=Asap:wght@400;500;600;700&amp;display=swap&quot; rel=&quot;stylesheet&quot; /&gt;\n",
       "    &lt;link rel=&quot;preconnect&quot; href=&quot;https://fonts.gstatic.com&quot; /&gt;\n",
       "    &lt;link rel=&quot;stylesheet&quot; href=&quot;https://cdn.jsdelivr.net/npm/bootstrap@5.1.0/dist/css/bootstrap.min.css&quot; /&gt;\n",
       "\n",
       "    &lt;script\n",
       "      src=&quot;https://cdnjs.cloudflare.com/ajax/libs/handlebars.js/4.7.7/handlebars.min.js&quot;\n",
       "      integrity=&quot;sha512-RNLkV3d+aLtfcpEyFG8jRbnWHxUqVZozacROI4J2F1sTaDqo1dPQYs01OMi1t1w9Y2FdbSCDSQ2ZVdAC8bzgAg==&quot;\n",
       "      crossorigin=&quot;anonymous&quot;\n",
       "      referrerpolicy=&quot;no-referrer&quot;\n",
       "    &gt;&lt;/script&gt;\n",
       "\n",
       "    &lt;style type=&quot;text/css&quot;&gt;\n",
       "\n",
       "      :root {\n",
       "        /** Branded colors */\n",
       "        --brandSecondary900: #4f595b;\n",
       "        --secondaryLight1000: #313b3d;\n",
       "        /** Purpose colors */\n",
       "        --tealBackground: #eaf2f3;\n",
       "      }\n",
       "\n",
       "      /* RESET STYLE */\n",
       "      *,\n",
       "      *::after,\n",
       "      *::before {\n",
       "        margin: 0;\n",
       "        padding: 0;\n",
       "        box-sizing: border-box;\n",
       "        overflow-y: hidden;\n",
       "      }\n",
       "\n",
       "      /* Screen on smaller screens */\n",
       "      .no-responsive {\n",
       "        display: none;\n",
       "        position: fixed;\n",
       "        top: 0;\n",
       "        left: 0;\n",
       "        z-index: 1031;\n",
       "        width: 100vw;\n",
       "        height: 100vh;\n",
       "        background-color: var(--tealBackground);\n",
       "        display: flex;\n",
       "        align-items: center;\n",
       "        justify-content: center;\n",
       "      }\n",
       "\n",
       "      .desktop-content {\n",
       "        display: flex;\n",
       "        flex-direction: column;\n",
       "      }\n",
       "\n",
       "      .no-responsive__content {\n",
       "        max-width: 600px;\n",
       "        width: 100%;\n",
       "        padding: 0 24px;\n",
       "      }\n",
       "\n",
       "      .no-responsive__title {\n",
       "        font-size: 96px;\n",
       "        font-weight: 300;\n",
       "        color: var(--brandSecondary900);\n",
       "        line-height: 1.167;\n",
       "      }\n",
       "\n",
       "      .no-responsive__text {\n",
       "        margin: 0;\n",
       "        font-size: 16px;\n",
       "        font-weight: 400;\n",
       "        color: var(--brandSecondary900);\n",
       "        line-height: 1.5;\n",
       "      }\n",
       "\n",
       "      .svg-container {\n",
       "        display: inline-block;\n",
       "        position: relative;\n",
       "        width: 100%;\n",
       "        vertical-align: top;\n",
       "        overflow: hidden;\n",
       "      }\n",
       "\n",
       "      .svg-content-responsive {\n",
       "        display: inline-block;\n",
       "        position: absolute;\n",
       "        left: 0;\n",
       "      }\n",
       "\n",
       "      .circle-color {\n",
       "       display: inline-block;\n",
       "       padding: 5px;\n",
       "       border-radius: 50px;\n",
       "     }\n",
       "\n",
       "     .colors-for-distingushing-charts {\n",
       "       padding-right: 10px;\n",
       "     }\n",
       "\n",
       "     .display-flex{\n",
       "       display: flex;\n",
       "     }\n",
       "\n",
       "     .align-items-flex-end {\n",
       "       align-items: flex-end;\n",
       "     }\n",
       "\n",
       "     .chart-box-title {\n",
       "       width: 88%;\n",
       "       justify-content: space-between;\n",
       "       margin: 10px;\n",
       "       margin-top: 15px;\n",
       "       bottom: 0;\n",
       "     }\n",
       "\n",
       "     .chart-box-title p{\n",
       "       margin-bottom: 0;\n",
       "       font-family: Asap;\n",
       "       font-weight: bold;\n",
       "       font-size: 18px;\n",
       "       line-height: 16px;\n",
       "       color: #4F595B;\n",
       "     }\n",
       "\n",
       "    .bar {\n",
       "      font: 10px sans-serif;\n",
       "    }\n",
       "\n",
       "    .bar path,\n",
       "    .bar line {\n",
       "      fill: none;\n",
       "      stroke: #000;\n",
       "      shape-rendering: crispEdges;\n",
       "    }\n",
       "\n",
       "    .error-message {\n",
       "      display: flex;\n",
       "      justify-content: center;\n",
       "      align-items: center;\n",
       "      color: rgb(255, 114, 71);\n",
       "      font-size: 30px;\n",
       "      font-weight: 900;\n",
       "    }\n",
       "\n",
       "     @media screen and (min-width: 500px) {\n",
       "       .desktop-content {\n",
       "         display: block;\n",
       "       }\n",
       "       .no-responsive {\n",
       "         display: none;\n",
       "       }\n",
       "     }\n",
       "    &lt;/style&gt;\n",
       "  &lt;/head&gt;\n",
       "\n",
       "  &lt;body id=&quot;generated-html&quot;&gt;&lt;/body&gt;\n",
       "  &lt;script id=&quot;entry-template&quot; type=&quot;text/x-handlebars-template&quot;&gt;\n",
       "    \n",
       "      &lt;div class=&quot;desktop-content&quot;&gt;\n",
       "{{#each this}}              &lt;div class=&quot;chart-box&quot; id=&quot;chart-box&quot;&gt;\n",
       "                &lt;div class=&quot;chart-box-title display-flex&quot;&gt;\n",
       "                  &lt;p&gt;{{@key}}&lt;/p&gt;\n",
       "                  &lt;div class=&quot;display-flex&quot;&gt;\n",
       "                    &lt;div class=&quot;colors-for-distingushing-charts&quot;&gt;\n",
       "                      &lt;div class=&quot;circle-color&quot; style=&quot;background: #44C0E7;&quot;&gt;&lt;/div&gt;\n",
       "                      &lt;text alignment-baseline=&quot;middle&quot; style=&quot;font-size: 15px;&quot;&gt;Target&lt;/text&gt;\n",
       "                    &lt;/div&gt;\n",
       "                    &lt;div class=&quot;colors-for-distingushing-charts&quot;&gt;\n",
       "                      &lt;div class=&quot;circle-color&quot; style=&quot;background: #F5843C&quot;&gt;&lt;/div&gt;\n",
       "                      &lt;text alignment-baseline=&quot;middle&quot; style=&quot;font-size: 15px;&quot;&gt;Reference&lt;/text&gt;\n",
       "                    &lt;/div&gt;\n",
       "                  &lt;/div&gt;&lt;/div&gt;\n",
       "                &lt;div class=&quot;svg-container&quot;&gt;{{{getDoubleHistogramChart this}}}&lt;/div&gt;\n",
       "              &lt;/div&gt;\n",
       "{{/each}}      &lt;/div&gt;\n",
       "      &lt;div class=&quot;no-responsive&quot;&gt;\n",
       "        &lt;div class=&quot;no-responsive__content&quot;&gt;\n",
       "          &lt;h1 class=&quot;no-responsive__title&quot;&gt;Hold on! :)&lt;/h1&gt;\n",
       "          &lt;p class=&quot;no-responsive__text&quot;&gt;\n",
       "            It looks like your current screen size or device is not yet supported by the WhyLabs Sandbox. The Sandbox is\n",
       "            best experienced on a desktop computer. Please try maximizing this window or switching to another device. We\n",
       "            are working on adding support for a larger variety of devices.\n",
       "          &lt;/p&gt;\n",
       "        &lt;/div&gt;\n",
       "      &lt;/div&gt;\n",
       "    \n",
       "  &lt;/script&gt;\n",
       "\n",
       "  &lt;script src=&quot;https://code.jquery.com/jquery-3.6.0.min.js&quot; integrity=&quot;sha256-/xUj+3OJU5yExlq6GSYGSHk7tPXikynS7ogEvDej/m4=&quot; crossorigin=&quot;anonymous&quot;&gt;&lt;/script&gt;\n",
       "\n",
       "  &lt;script src=&quot;https://cdnjs.cloudflare.com/ajax/libs/d3/6.7.0/d3.min.js&quot; integrity=&quot;sha512-cd6CHE+XWDQ33ElJqsi0MdNte3S+bQY819f7p3NUHgwQQLXSKjE4cPZTeGNI+vaxZynk1wVU3hoHmow3m089wA==&quot; crossorigin=&quot;anonymous&quot; referrerpolicy=&quot;no-referrer&quot;&gt;&lt;/script&gt;\n",
       "\n",
       "  &lt;script&gt;\n",
       "    function registerHandlebarHelperFunctions() {\n",
       "      //helper fun\n",
       "\n",
       "      class GenerateChartParams {\n",
       "        constructor(height, width, targetData, referenceData, bottomMargin=30, topMargin=5) {\n",
       "          this.MARGIN = {\n",
       "            TOP: topMargin,\n",
       "            RIGHT: 5,\n",
       "            BOTTOM: bottomMargin,\n",
       "            LEFT: 55,\n",
       "          };\n",
       "          this.SVG_WIDTH = width;\n",
       "          this.SVG_HEIGHT = height;\n",
       "          this.CHART_WIDTH = this.SVG_WIDTH - this.MARGIN.LEFT - this.MARGIN.RIGHT;\n",
       "          this.CHART_HEIGHT = this.SVG_HEIGHT - this.MARGIN.TOP - this.MARGIN.BOTTOM;\n",
       "          this.svgEl = d3.create(&quot;svg&quot;)\n",
       "             .attr(&quot;preserveAspectRatio&quot;, &quot;xMinYMin meet&quot;)\n",
       "             .attr(&quot;viewBox&quot;, `0 0 ${$(window).width()+100} ${$(window).height()-30}`)\n",
       "             .classed(&quot;svg-content-responsive&quot;, true)\n",
       "          this.maxYValue = d3.max(targetData, (d) =&gt; Math.abs(d.axisY));\n",
       "          this.minYValue = d3.min(targetData, (d) =&gt; Math.abs(d.axisY));\n",
       "          const mergedReferenceData = referenceData.map(({axisX, axisY}) =&gt; {\n",
       "            return {axisX, axisY}\n",
       "          })\n",
       "          const mergedTargetedData = targetData.map(({axisX, axisY}) =&gt; {\n",
       "            return {axisX, axisY}\n",
       "          })\n",
       "\n",
       "          this.charts2 = mergedReferenceData.concat(mergedTargetedData)\n",
       "          this.charts2 = this.charts2.sort(function(a, b) { return a - b; });\n",
       "\n",
       "          this.targetBinWidth = targetData[1]?.axisX - targetData[0]?.axisX\n",
       "          this.referenceBinWidth = referenceData[1]?.axisX - referenceData[0]?.axisX\n",
       "          this.maxTargetXValue = d3.max(targetData, (d) =&gt; d.axisX);\n",
       "\n",
       "          this.maxReferenceXValue = d3.max(referenceData, (d) =&gt; d.axisX);\n",
       "\n",
       "          this.xScale = d3\n",
       "              .scaleLinear()\n",
       "         .domain([d3.min(this.charts2, function(d) { return parseFloat(d.axisX); }),(this.maxTargetXValue+this.targetBinWidth &gt;= this.maxReferenceXValue+this.referenceBinWidth) ? this.maxTargetXValue+this.targetBinWidth:this.maxReferenceXValue+this.referenceBinWidth])\n",
       "         .range([0, this.CHART_WIDTH ]);\n",
       "\n",
       "         this.svgEl.append(&quot;g&quot;)\n",
       "             .attr(&quot;transform&quot;, &quot;translate(&quot;+ this.MARGIN.LEFT +&quot;,&quot; + this.SVG_HEIGHT + &quot;)&quot;)\n",
       "             .call(d3.axisBottom(this.xScale));\n",
       "          this.yScale = d3.scaleLinear()\n",
       "              .range([this.CHART_HEIGHT , 0])\n",
       "              .domain([d3.min(this.charts2, function(d) { return parseFloat(d.axisY); }), d3.max(this.charts2, function(d) { return parseFloat(d.axisY); })*1.2])\n",
       "              .nice();\n",
       "        }\n",
       "      }\n",
       "\n",
       "      function chartData(column) {\n",
       "        const data = [];\n",
       "        if (column?.histogram) {\n",
       "          for (let i = 0; i&lt;column.histogram.bins.length; i++) {\n",
       "            data.push({\n",
       "              axisY: column.histogram.counts[i] || 0,\n",
       "              axisX: column.histogram.bins[i] || 0,\n",
       "            });\n",
       "          }\n",
       "        } else {\n",
       "            $(document).ready(() =&gt;\n",
       "              $(&quot;.desktop-content&quot;).html(`\n",
       "                &lt;p style=&quot;height: ${$(window).height()}px&quot; class=&quot;error-message&quot;&gt;\n",
       "                  Something went wrong. Please try again.\n",
       "                &lt;/p&gt;\n",
       "              `)\n",
       "            )\n",
       "          }\n",
       "\n",
       "        return data\n",
       "      }\n",
       "\n",
       "      function verticalLine(column) {\n",
       "        const line_data = [];\n",
       "        if (column?.vertical_line) {\n",
       "            line_data.push({\n",
       "              axisX: column?.vertical_line || 0,\n",
       "            });\n",
       "\n",
       "        }\n",
       "\n",
       "        return line_data\n",
       "      }\n",
       "\n",
       "      function generateDoubleHistogramChart(targetData, referenceData) {\n",
       "        let histogramData = [],\n",
       "            overlappedHistogramData = [];\n",
       "        let yFormat;\n",
       "\n",
       "        histogramData = chartData(targetData)\n",
       "        overlappedHistogramData = chartData(referenceData)\n",
       "        lineData = verticalLine(targetData)\n",
       "\n",
       "        const sizes = new GenerateChartParams($(window).height()-80, $(window).width(), histogramData, overlappedHistogramData)\n",
       "        const {\n",
       "          MARGIN,\n",
       "          SVG_WIDTH,\n",
       "          SVG_HEIGHT,\n",
       "          CHART_WIDTH,\n",
       "          CHART_HEIGHT,\n",
       "          svgEl,\n",
       "          maxYValue,\n",
       "          minYValue,\n",
       "          xScale,\n",
       "          yScale\n",
       "        } = sizes\n",
       "\n",
       "        const rectColors = [&quot;#44C0E7&quot;, &quot;#F5843C&quot;]\n",
       "        const yAxis = d3.axisLeft(yScale).ticks(SVG_HEIGHT / 40);\n",
       "\n",
       "        svgEl.append(&quot;g&quot;)\n",
       "          .attr(&quot;transform&quot;, `translate(${MARGIN.LEFT}, ${MARGIN.BOTTOM})`)\n",
       "          .call(yAxis)\n",
       "          .call(g =&gt; g.select(&quot;.domain&quot;).remove())\n",
       "          .call(g =&gt; g.selectAll(&quot;.tick line&quot;)\n",
       "              .attr(&quot;x2&quot;, CHART_WIDTH)\n",
       "              .attr(&quot;stroke-opacity&quot;, 0.1))\n",
       "          .call(g =&gt; g.append(&quot;text&quot;)\n",
       "              .attr(&quot;x&quot;, -MARGIN.LEFT)\n",
       "              .attr(&quot;y&quot;, 10)\n",
       "              .attr(&quot;fill&quot;, &quot;currentColor&quot;)\n",
       "              .attr(&quot;text-anchor&quot;, &quot;start&quot;))\n",
       "\n",
       "        svgEl.append(&quot;line&quot;)\n",
       "          .attr(&quot;transform&quot;, `translate(${MARGIN.LEFT}, ${MARGIN.BOTTOM})`)\n",
       "          .data(lineData)\n",
       "          .attr(&quot;x1&quot;, (d) =&gt; xScale(d.axisX))\n",
       "          .attr(&quot;y1&quot;, MARGIN.TOP + MARGIN.TOP)\n",
       "          .attr(&quot;x2&quot;, (d) =&gt; xScale(d.axisX))\n",
       "          .attr(&quot;y2&quot;, CHART_HEIGHT + MARGIN.TOP)\n",
       "          .style(&quot;stroke-width&quot;, 2)\n",
       "          .style(&quot;stroke&quot;, &quot;#44C0E7&quot;)\n",
       "          .style(&quot;stroke-dasharray&quot;, (3,3))\n",
       "          .style(&quot;fill&quot;, &quot;none&quot;);\n",
       "\n",
       "        svgEl.append(&quot;text&quot;)\n",
       "          .attr(&quot;transform&quot;, &quot;rotate(-90)&quot;)\n",
       "          .data(lineData)\n",
       "          .attr(&quot;y&quot;, (d) =&gt; xScale(d.axisX) + MARGIN.LEFT)\n",
       "          .attr(&quot;x&quot;, 0 - (SVG_HEIGHT / 2))\n",
       "          .attr(&quot;dy&quot;, &quot;1em&quot;)\n",
       "          .style(&quot;text-anchor&quot;, &quot;middle&quot;)\n",
       "          .text(&quot;single value&quot;)\n",
       "          .style(&quot;font-size&quot;, &quot;15&quot;)\n",
       "          .style(&quot;opacity&quot;, &quot;0.6&quot;)\n",
       "\n",
       "        svgEl.append(&quot;text&quot;)\n",
       "          .attr(&quot;transform&quot;,\n",
       "                &quot;translate(&quot; + (CHART_WIDTH/2) + &quot; ,&quot; +\n",
       "                               (CHART_HEIGHT + MARGIN.TOP + 75) + &quot;)&quot;)\n",
       "          .style(&quot;text-anchor&quot;, &quot;middle&quot;)\n",
       "          .text(&quot;Values&quot;)\n",
       "          .style(&quot;font-size&quot;, &quot;15&quot;)\n",
       "          .style(&quot;opacity&quot;, &quot;0.6&quot;)\n",
       "\n",
       "        svgEl.append(&quot;text&quot;)\n",
       "          .attr(&quot;transform&quot;, &quot;rotate(-90)&quot;)\n",
       "          .attr(&quot;y&quot;, 0)\n",
       "          .attr(&quot;x&quot;, 0 - (SVG_HEIGHT / 2))\n",
       "          .attr(&quot;dy&quot;, &quot;1em&quot;)\n",
       "          .style(&quot;text-anchor&quot;, &quot;middle&quot;)\n",
       "          .text(&quot;Counts&quot;)\n",
       "          .style(&quot;font-size&quot;, &quot;15&quot;)\n",
       "          .style(&quot;opacity&quot;, &quot;0.6&quot;)\n",
       "\n",
       "          const gChart = svgEl.append(&quot;g&quot;);\n",
       "          gChart\n",
       "          .attr(&quot;transform&quot;, &quot;translate(&quot;+ MARGIN.LEFT +&quot;,0)&quot;)\n",
       "          .selectAll(&quot;.bar&quot;)\n",
       "          .data(histogramData)\n",
       "          .enter()\n",
       "          .append(&quot;rect&quot;)\n",
       "          .style(&quot;stroke&quot;, &quot;#021826&quot;)\n",
       "          .classed(&quot;bar&quot;, true)\n",
       "          .attr(&quot;width&quot;, function(d) { return xScale(histogramData[1]?.axisX)-xScale(histogramData[0]?.axisX); })\n",
       "          .attr(&quot;height&quot;, (d) =&gt; CHART_HEIGHT - yScale(d.axisY))\n",
       "          .attr(&quot;x&quot;, 1)\n",
       "          .attr(&quot;transform&quot;, function(d) { return &quot;translate(&quot; + xScale(d.axisX) + &quot;,&quot; + 0  +  &quot;)&quot;; })\n",
       "          .attr(&quot;y&quot;, (d) =&gt; yScale(d.axisY) + MARGIN.TOP + MARGIN.BOTTOM)\n",
       "          .attr(&quot;fill&quot;, rectColors[0])\n",
       "          .style(&quot;opacity&quot;,&quot;0.6&quot;)\n",
       "\n",
       "          const gChart1 = svgEl.append(&quot;g&quot;);\n",
       "          gChart1\n",
       "          .attr(&quot;transform&quot;, &quot;translate(&quot;+ MARGIN.LEFT +&quot;,0)&quot;)\n",
       "          .selectAll(&quot;.bar&quot;)\n",
       "          .data(overlappedHistogramData)\n",
       "          .enter()\n",
       "          .append(&quot;rect&quot;)\n",
       "          .style(&quot;stroke&quot;, &quot;#021826&quot;)\n",
       "          .classed(&quot;bar&quot;, true)\n",
       "          .attr(&quot;width&quot;, function(d) { return xScale(overlappedHistogramData[1]?.axisX)-xScale(overlappedHistogramData[0]?.axisX); })\n",
       "          .attr(&quot;height&quot;, (d) =&gt; CHART_HEIGHT - yScale(d.axisY))\n",
       "          .attr(&quot;x&quot;, 1)\n",
       "          .attr(&quot;transform&quot;, function(d) { return &quot;translate(&quot; + xScale(d.axisX) + &quot;,&quot; + 0  +  &quot;)&quot;; })\n",
       "          .attr(&quot;y&quot;, (d) =&gt; yScale(d.axisY) + MARGIN.TOP + MARGIN.BOTTOM)\n",
       "          .attr(&quot;fill&quot;, rectColors[1])\n",
       "          .style(&quot;opacity&quot;,&quot;0.6&quot;)\n",
       "\n",
       "        return svgEl._groups[0][0].outerHTML;\n",
       "      }\n",
       "\n",
       "      const profileFromCSVfile = {&quot;chlorides&quot;: {&quot;histogram&quot;: {&quot;start&quot;: 0.038, &quot;end&quot;: 0.6110000610999999, &quot;width&quot;: 0, &quot;counts&quot;: [36, 379, 545, 131, 31, 10, 13, 6, 4, 6, 5, 3, 0, 0, 0, 4, 2, 2, 2, 8, 0, 0, 2, 0, 0, 0, 0, 0, 0, 2], &quot;max&quot;: 0.611, &quot;min&quot;: 0.038, &quot;bins&quot;: [0.038, 0.05710000203666667, 0.07620000407333333, 0.09530000611, 0.11440000814666665, 0.13350001018333332, 0.15260001222, 0.17170001425666664, 0.19080001629333332, 0.20990001833, 0.22900002036666664, 0.24810002240333331, 0.26720002443999996, 0.28630002647666664, 0.30540002851333325, 0.32450003054999993, 0.3436000325866666, 0.3627000346233333, 0.38180003665999995, 0.40090003869666657, 0.42000004073333325, 0.4391000427699999, 0.4582000448066666, 0.47730004684333327, 0.49640004887999994, 0.5155000509166666, 0.5346000529533332, 0.55370005499, 0.5728000570266666, 0.5919000590633333, 0.6110000610999999], &quot;n&quot;: 1191}}}\n",
       "\n",
       "      Handlebars.registerHelper(&quot;getDoubleHistogramChart&quot;,(column,key) =&gt; {\n",
       "          const columnKey = key.data.key\n",
       "        try {\n",
       "          if (profileFromCSVfile) {\n",
       "          return  generateDoubleHistogramChart (\n",
       "              column,\n",
       "              profileFromCSVfile[columnKey]\n",
       "            )\n",
       "          }\n",
       "        } catch (err) {\n",
       "          $(document).ready(() =&gt;\n",
       "            $(&quot;.desktop-content&quot;).html(`\n",
       "              &lt;p style=&quot;height: ${$(window).height()}px&quot; class=&quot;error-message&quot;&gt;\n",
       "                Something went wrong. Please try again.\n",
       "              &lt;/p&gt;\n",
       "            `)\n",
       "          )\n",
       "        }\n",
       "      });\n",
       "    }\n",
       "\n",
       "    function initWebsiteScripts() {\n",
       "      $(&quot;.svg-container&quot;).css(&quot;height&quot;, $(window).height() - 32)\n",
       "    }\n",
       "\n",
       "    function initHandlebarsTemplate() {\n",
       "      // Replace this context with JSON from .py file\n",
       "      const context = {&quot;chlorides&quot;: {&quot;histogram&quot;: {&quot;start&quot;: 0.012, &quot;end&quot;: 0.230000023, &quot;width&quot;: 0, &quot;counts&quot;: [2, 0, 0, 9, 21, 40, 45, 76, 64, 43, 33, 21, 20, 8, 9, 9, 3, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 1], &quot;max&quot;: 0.23, &quot;min&quot;: 0.012, &quot;bins&quot;: [0.012, 0.019266667433333332, 0.026533334866666668, 0.0338000023, 0.04106666973333333, 0.04833333716666667, 0.0556000046, 0.06286667203333333, 0.07013333946666667, 0.0774000069, 0.08466667433333333, 0.09193334176666666, 0.0992000092, 0.10646667663333333, 0.11373334406666666, 0.12100001149999999, 0.12826667893333332, 0.13553334636666667, 0.14280001380000001, 0.15006668123333333, 0.15733334866666668, 0.1646000161, 0.17186668353333334, 0.17913335096666666, 0.1864000184, 0.19366668583333332, 0.20093335326666667, 0.2082000207, 0.21546668813333333, 0.22273335556666665, 0.230000023], &quot;n&quot;: 408}}};\n",
       "      // Config handlebars and pass data to HBS template\n",
       "      const source = document.getElementById(&quot;entry-template&quot;).innerHTML;\n",
       "      const template = Handlebars.compile(source);\n",
       "      const html = template(context);\n",
       "      const target = document.getElementById(&quot;generated-html&quot;);\n",
       "      target.innerHTML = html;\n",
       "    }\n",
       "\n",
       "    // Invoke functions -- keep in mind invokation order\n",
       "    registerHandlebarHelperFunctions();\n",
       "    initHandlebarsTemplate();\n",
       "    initWebsiteScripts();\n",
       "  &lt;/script&gt;\n",
       "&lt;/html&gt;\n",
       "\" width=100% height=300px\n",
       "        frameBorder=0></iframe>"
      ],
      "text/plain": [
       "<IPython.core.display.HTML object>"
      ]
     },
     "execution_count": 13,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "visualization.double_histogram(feature_name=[\"alcohol\",\"chlorides\"])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "In addition to the histograms, we can also plot distribution charts for categorical variables, like the `quality` feature."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div></div><iframe srcdoc=\"&lt;!DOCTYPE html&gt;\n",
       "&lt;html lang=&quot;en&quot;&gt;\n",
       "  &lt;head&gt;\n",
       "    &lt;meta charset=&quot;UTF-8&quot; /&gt;\n",
       "    &lt;meta http-equiv=&quot;X-UA-Compatible&quot; content=&quot;IE=edge&quot; /&gt;\n",
       "    &lt;meta name=&quot;viewport&quot; content=&quot;width=device-width, initial-scale=1.0&quot; /&gt;\n",
       "    &lt;meta name=&quot;description&quot; content=&quot;&quot; /&gt;\n",
       "    &lt;meta name=&quot;author&quot; content=&quot;&quot; /&gt;\n",
       "\n",
       "    &lt;title&gt;Profile Visualizer | whylogs&lt;/title&gt;\n",
       "\n",
       "    &lt;link rel=&quot;icon&quot; href=&quot;images/whylabs-favicon.png&quot; type=&quot;image/png&quot; sizes=&quot;16x16&quot; /&gt;\n",
       "    &lt;link rel=&quot;preconnect&quot; href=&quot;https://fonts.googleapis.com&quot; /&gt;\n",
       "    &lt;link rel=&quot;preconnect&quot; href=&quot;https://fonts.gstatic.com&quot; crossorigin /&gt;\n",
       "    &lt;link href=&quot;https://fonts.googleapis.com/css2?family=Asap:wght@400;500;600;700&amp;display=swap&quot; rel=&quot;stylesheet&quot; /&gt;\n",
       "    &lt;link rel=&quot;preconnect&quot; href=&quot;https://fonts.gstatic.com&quot; /&gt;\n",
       "    &lt;link rel=&quot;stylesheet&quot; href=&quot;https://cdn.jsdelivr.net/npm/bootstrap@5.1.0/dist/css/bootstrap.min.css&quot; /&gt;\n",
       "\n",
       "    &lt;script\n",
       "      src=&quot;https://cdnjs.cloudflare.com/ajax/libs/handlebars.js/4.7.7/handlebars.min.js&quot;\n",
       "      integrity=&quot;sha512-RNLkV3d+aLtfcpEyFG8jRbnWHxUqVZozacROI4J2F1sTaDqo1dPQYs01OMi1t1w9Y2FdbSCDSQ2ZVdAC8bzgAg==&quot;\n",
       "      crossorigin=&quot;anonymous&quot;\n",
       "      referrerpolicy=&quot;no-referrer&quot;\n",
       "    &gt;&lt;/script&gt;\n",
       "\n",
       "    &lt;style type=&quot;text/css&quot;&gt;\n",
       "\n",
       "      :root {\n",
       "        /** Branded colors */\n",
       "        --brandSecondary900: #4f595b;\n",
       "        --secondaryLight1000: #313b3d;\n",
       "        /** Purpose colors */\n",
       "        --tealBackground: #eaf2f3;\n",
       "      }\n",
       "\n",
       "      /* RESET STYLE */\n",
       "      *,\n",
       "      *::after,\n",
       "      *::before {\n",
       "        margin: 0;\n",
       "        padding: 0;\n",
       "        box-sizing: border-box;\n",
       "        overflow-y: hidden;\n",
       "      }\n",
       "\n",
       "      /* Screen on smaller screens */\n",
       "      .no-responsive {\n",
       "        display: none;\n",
       "        position: fixed;\n",
       "        top: 0;\n",
       "        left: 0;\n",
       "        z-index: 1031;\n",
       "        width: 100vw;\n",
       "        height: 100vh;\n",
       "        background-color: var(--tealBackground);\n",
       "        display: flex;\n",
       "        align-items: center;\n",
       "        justify-content: center;\n",
       "      }\n",
       "\n",
       "      .desktop-content {\n",
       "        display: flex;\n",
       "        flex-direction: column;\n",
       "      }\n",
       "\n",
       "      .no-responsive__content {\n",
       "        max-width: 600px;\n",
       "        width: 100%;\n",
       "        padding: 0 24px;\n",
       "      }\n",
       "\n",
       "      .no-responsive__title {\n",
       "        font-size: 96px;\n",
       "        font-weight: 300;\n",
       "        color: var(--brandSecondary900);\n",
       "        line-height: 1.167;\n",
       "      }\n",
       "\n",
       "      .no-responsive__text {\n",
       "        margin: 0;\n",
       "        font-size: 16px;\n",
       "        font-weight: 400;\n",
       "        color: var(--brandSecondary900);\n",
       "        line-height: 1.5;\n",
       "      }\n",
       "\n",
       "      .svg-container {\n",
       "        display: inline-block;\n",
       "        position: relative;\n",
       "        width: 100%;\n",
       "        vertical-align: top;\n",
       "        overflow: hidden;\n",
       "      }\n",
       "\n",
       "      .svg-content-responsive {\n",
       "        display: inline-block;\n",
       "        position: absolute;\n",
       "        left: 0;\n",
       "      }\n",
       "\n",
       "      .circle-color {\n",
       "       display: inline-block;\n",
       "       padding: 5px;\n",
       "       border-radius: 50px;\n",
       "     }\n",
       "\n",
       "     .colors-for-distingushing-charts {\n",
       "       padding-right: 10px;\n",
       "     }\n",
       "\n",
       "     .display-flex{\n",
       "       display: flex;\n",
       "     }\n",
       "\n",
       "     .flex-direction-column {\n",
       "       flex-direction: column;\n",
       "     }\n",
       "\n",
       "     .align-items-flex-end {\n",
       "       align-items: flex-end;\n",
       "     }\n",
       "\n",
       "     .chart-box-title {\n",
       "       width: 98%;\n",
       "       justify-content: space-between;\n",
       "       margin: 10px;\n",
       "       margin-top: 15px;\n",
       "       bottom: 0;\n",
       "     }\n",
       "\n",
       "     .chart-box-title p{\n",
       "       margin-bottom: 0;\n",
       "       font-family: Asap;\n",
       "       font-weight: bold;\n",
       "       font-size: 18px;\n",
       "       line-height: 16px;\n",
       "       color: #4F595B;\n",
       "     }\n",
       "\n",
       "     .error-message {\n",
       "       display: flex;\n",
       "       justify-content: center;\n",
       "       align-items: center;\n",
       "       color: rgb(255, 114, 71);\n",
       "       font-size: 30px;\n",
       "       font-weight: 900;\n",
       "     }\n",
       "\n",
       "     @media screen and (min-width: 500px) {\n",
       "       .desktop-content {\n",
       "         display: block;\n",
       "       }\n",
       "       .no-responsive {\n",
       "         display: none;\n",
       "       }\n",
       "     }\n",
       "    &lt;/style&gt;\n",
       "  &lt;/head&gt;\n",
       "\n",
       "  &lt;body id=&quot;generated-html&quot;&gt;&lt;/body&gt;\n",
       "  &lt;script id=&quot;entry-template&quot; type=&quot;text/x-handlebars-template&quot;&gt;\n",
       "    \n",
       "      &lt;div class=&quot;desktop-content&quot;&gt;\n",
       "{{#each this}}              &lt;div class=&quot;chart-box&quot; id=&quot;chart-box&quot;&gt;\n",
       "                &lt;div class=&quot;chart-box-title display-flex&quot;&gt;\n",
       "                  &lt;p&gt;{{@key}}&lt;/p&gt;\n",
       "                  &lt;div class=&quot;display-flex&quot;&gt;\n",
       "                    &lt;div class=&quot;colors-for-distingushing-charts&quot;&gt;\n",
       "                      &lt;div class=&quot;circle-color&quot; style=&quot;background: #44C0E7;&quot;&gt;&lt;/div&gt;\n",
       "                      &lt;text alignment-baseline=&quot;middle&quot; style=&quot;font-size: 15px;&quot;&gt;Target&lt;/text&gt;\n",
       "                    &lt;/div&gt;\n",
       "                    &lt;div class=&quot;colors-for-distingushing-charts&quot;&gt;\n",
       "                      &lt;div class=&quot;circle-color&quot; style=&quot;background: #F5843C&quot;&gt;&lt;/div&gt;\n",
       "                      &lt;text alignment-baseline=&quot;middle&quot; style=&quot;font-size: 15px;&quot;&gt;Reference&lt;/text&gt;\n",
       "                    &lt;/div&gt;\n",
       "                  &lt;/div&gt;&lt;/div&gt;\n",
       "                &lt;div class=&quot;svg-container&quot;&gt;\n",
       "                  {{{getDoubleHistogramChart this}}}\n",
       "                &lt;/div&gt;\n",
       "              &lt;/div&gt;\n",
       "{{/each}}      &lt;/div&gt;\n",
       "      &lt;div class=&quot;no-responsive&quot;&gt;\n",
       "        &lt;div class=&quot;no-responsive__content&quot;&gt;\n",
       "          &lt;h1 class=&quot;no-responsive__title&quot;&gt;Hold on! :)&lt;/h1&gt;\n",
       "          &lt;p class=&quot;no-responsive__text&quot;&gt;\n",
       "            It looks like your current screen size or device is not yet supported by the WhyLabs Sandbox. The Sandbox is\n",
       "            best experienced on a desktop computer. Please try maximizing this window or switching to another device. We\n",
       "            are working on adding support for a larger variety of devices.\n",
       "          &lt;/p&gt;\n",
       "        &lt;/div&gt;\n",
       "      &lt;/div&gt;\n",
       "    \n",
       "  &lt;/script&gt;\n",
       "\n",
       "  &lt;script src=&quot;https://code.jquery.com/jquery-3.6.0.min.js&quot; integrity=&quot;sha256-/xUj+3OJU5yExlq6GSYGSHk7tPXikynS7ogEvDej/m4=&quot; crossorigin=&quot;anonymous&quot;&gt;&lt;/script&gt;\n",
       "\n",
       "  &lt;script src=&quot;https://cdnjs.cloudflare.com/ajax/libs/d3/6.7.0/d3.min.js&quot; integrity=&quot;sha512-cd6CHE+XWDQ33ElJqsi0MdNte3S+bQY819f7p3NUHgwQQLXSKjE4cPZTeGNI+vaxZynk1wVU3hoHmow3m089wA==&quot; crossorigin=&quot;anonymous&quot; referrerpolicy=&quot;no-referrer&quot;&gt;&lt;/script&gt;\n",
       "\n",
       "  &lt;script&gt;\n",
       "   function registerHandlebarHelperFunctions() {\n",
       "\n",
       "    const findAndDeleteUndefined = (axisData) =&gt; {\n",
       "      const undefinedAxisIndex = axisData.findIndex((axis) =&gt; axis === undefined)\n",
       "      if (undefinedAxisIndex == -1) {\n",
       "        return axisData;\n",
       "      }\n",
       "\n",
       "      const result = [...axisData.slice(0, undefinedAxisIndex), ...axisData.slice(undefinedAxisIndex + 1)]\n",
       "      return result\n",
       "    }\n",
       "\n",
       "    const filterAndSortChartData = (overlappedHistogramData, histogramData) =&gt; {\n",
       "        const filteredData = overlappedHistogramData\n",
       "          .map((d) =&gt;\n",
       "            histogramData\n",
       "            .filter((ref) =&gt; d.axisX === ref.axisX )[0])\n",
       "            .sort((a, b) =&gt; {\n",
       "              if (+a.axisY &lt; +b.axisY) {\n",
       "                return 1;\n",
       "              }\n",
       "              if (+a.axisY &gt; +b.axisY) {\n",
       "                return -1;\n",
       "              }\n",
       "\n",
       "              return 0;\n",
       "            })\n",
       "            .slice(0, 20)\n",
       "\n",
       "        return findAndDeleteUndefined(filteredData)\n",
       "      }\n",
       "\n",
       "      class GenerateChartParams {\n",
       "        constructor(height, width, data, referenceData, bottomMargin=30, topMargin=5) {\n",
       "          this.MARGIN = {\n",
       "            TOP: topMargin,\n",
       "            RIGHT: 5,\n",
       "            BOTTOM: bottomMargin,\n",
       "            LEFT: 55,\n",
       "          };\n",
       "          this.SVG_WIDTH = width;\n",
       "          this.SVG_HEIGHT = height;\n",
       "          this.CHART_WIDTH = this.SVG_WIDTH - this.MARGIN.LEFT - this.MARGIN.RIGHT;\n",
       "          this.CHART_HEIGHT = this.SVG_HEIGHT - this.MARGIN.TOP - this.MARGIN.BOTTOM;\n",
       "          this.svgEl = d3.create(&quot;svg&quot;)\n",
       "             .attr(&quot;preserveAspectRatio&quot;, &quot;xMinYMin meet&quot;)\n",
       "             .attr(&quot;viewBox&quot;, `0 0 ${$(window).width()} ${$(window).height()-30}`)\n",
       "             .classed(&quot;svg-content-responsive&quot;, true)\n",
       "          this.maxYValue = d3.max([...data, ...referenceData], (d) =&gt; Math.abs(d.axisY));\n",
       "          this.xScale = d3\n",
       "            .scaleBand()\n",
       "            .domain(filterAndSortChartData(data, referenceData).map((sortedCounts) =&gt; sortedCounts?.axisX))\n",
       "            .range([this.MARGIN.LEFT, this.MARGIN.LEFT + this.CHART_WIDTH]);\n",
       "          this.yScale = d3\n",
       "            .scaleLinear()\n",
       "            .domain([0, this.maxYValue * 1.2])\n",
       "            .range([this.CHART_HEIGHT, 0]);\n",
       "        }\n",
       "      }\n",
       "\n",
       "      function chartData(column) {\n",
       "        const data = [];\n",
       "          if (column.frequentItems) {\n",
       "            Object.entries(column.frequentItems).forEach(([key, {value, estimate}], index) =&gt; {\n",
       "              data.push({\n",
       "                axisY: estimate,\n",
       "                axisX: value,\n",
       "              });\n",
       "            });\n",
       "          } else {\n",
       "            $(document).ready(() =&gt;\n",
       "              $(&quot;.desktop-content&quot;).html(`\n",
       "                &lt;p style=&quot;height: ${$(window).height()}px&quot; class=&quot;error-message&quot;&gt;\n",
       "                  Something went wrong. Please try again.\n",
       "                &lt;/p&gt;\n",
       "              `)\n",
       "            )\n",
       "          }\n",
       "\n",
       "        return data\n",
       "      }\n",
       "\n",
       "      function generateBarChart(histogramData, overlappedHistogramData) {\n",
       "        let yFormat,\n",
       "            xFormat;\n",
       "        const data = filterAndSortChartData(chartData(histogramData), chartData(overlappedHistogramData)).map((axis, index) =&gt; {\n",
       "          if (axis) {\n",
       "            const findIndex = chartData(histogramData).findIndex((value) =&gt; value.axisX === axis.axisX)\n",
       "            return {\n",
       "              group: axis.axisX,\n",
       "              profile: axis.axisY,\n",
       "              reference_profile: chartData(histogramData)[findIndex].axisY\n",
       "            }\n",
       "          }\n",
       "          return 0;\n",
       "        })\n",
       "\n",
       "        const sizes = new GenerateChartParams($(window).height()-60, $(window).width(), chartData(histogramData), chartData(overlappedHistogramData))\n",
       "        let {\n",
       "          MARGIN,\n",
       "          SVG_WIDTH,\n",
       "          SVG_HEIGHT,\n",
       "          CHART_WIDTH,\n",
       "          CHART_HEIGHT,\n",
       "          svgEl,\n",
       "          xScale,\n",
       "          yScale\n",
       "        } = sizes\n",
       "\n",
       "        const rectColors = [&quot;#44C0E7&quot;, &quot;#F5843C&quot;]\n",
       "        const subgroups = [&#x27;reference_profile&#x27;, &#x27;profile&#x27;]\n",
       "\n",
       "        xScale.padding([0.3])\n",
       "\n",
       "        const xAxis = d3.axisBottom(xScale).ticks(SVG_WIDTH / 80, xFormat).tickSizeOuter(0);\n",
       "        const yAxis = d3.axisLeft(yScale).ticks(SVG_HEIGHT / 40, yFormat);\n",
       "        yFormat = yScale.tickFormat(100, yFormat);\n",
       "\n",
       "        svgEl.append(&quot;g&quot;)\n",
       "          .attr(&quot;transform&quot;, `translate(${MARGIN.LEFT}, 0)`)\n",
       "          .attr(&quot;id&quot;, &quot;g1&quot;)\n",
       "          .call(yAxis)\n",
       "          .call(g =&gt; g.select(&quot;.domain&quot;).remove())\n",
       "          .call(g =&gt; g.selectAll(&quot;.tick line&quot;)\n",
       "              .attr(&quot;x2&quot;, CHART_WIDTH)\n",
       "              .attr(&quot;stroke-opacity&quot;, 0.1))\n",
       "          .call(g =&gt; g.append(&quot;text&quot;)\n",
       "              .attr(&quot;x&quot;, -MARGIN.LEFT)\n",
       "              .attr(&quot;y&quot;, 10)\n",
       "              .attr(&quot;fill&quot;, &quot;currentColor&quot;)\n",
       "              .attr(&quot;text-anchor&quot;, &quot;start&quot;));\n",
       "\n",
       "        svgEl.append(&quot;text&quot;)\n",
       "          .attr(&quot;transform&quot;,\n",
       "                &quot;translate(&quot; + (CHART_WIDTH/2) + &quot; ,&quot; +\n",
       "                               (CHART_HEIGHT + MARGIN.TOP + 40) + &quot;)&quot;)\n",
       "          .style(&quot;text-anchor&quot;, &quot;middle&quot;)\n",
       "          .text(&quot;Values&quot;)\n",
       "          .style(&quot;font-size&quot;, &quot;15&quot;)\n",
       "          .style(&quot;opacity&quot;, &quot;0.6&quot;)\n",
       "\n",
       "        svgEl.append(&quot;text&quot;)\n",
       "          .attr(&quot;transform&quot;, &quot;rotate(-90)&quot;)\n",
       "          .attr(&quot;y&quot;, 0)\n",
       "          .attr(&quot;x&quot;, 0 - (SVG_HEIGHT / 2))\n",
       "          .attr(&quot;dy&quot;, &quot;1em&quot;)\n",
       "          .style(&quot;text-anchor&quot;, &quot;middle&quot;)\n",
       "          .text(&quot;Counts&quot;)\n",
       "          .style(&quot;font-size&quot;, &quot;15&quot;)\n",
       "          .style(&quot;opacity&quot;, &quot;0.6&quot;)\n",
       "\n",
       "        svgEl.append(&quot;g&quot;)\n",
       "            .attr(&quot;transform&quot;, `translate(0,${SVG_HEIGHT - MARGIN.BOTTOM})`)\n",
       "            .attr(&quot;id&quot;, &quot;g2&quot;)\n",
       "            .call(xAxis)\n",
       "            .call(g =&gt; g.select(&quot;.domain&quot;).remove())\n",
       "            .call(g =&gt; g.selectAll(&quot;.tick line&quot;).remove())\n",
       "            .call(g =&gt; g.append(&quot;text&quot;)\n",
       "                .attr(&quot;x&quot;, SVG_WIDTH - MARGIN.RIGHT)\n",
       "                .attr(&quot;y&quot;, 27)\n",
       "                .attr(&quot;fill&quot;, &quot;currentColor&quot;)\n",
       "                .attr(&quot;text-anchor&quot;, &quot;end&quot;));\n",
       "\n",
       "        const xSubgroup = d3.scaleBand()\n",
       "          .domain(subgroups)\n",
       "          .range([0, xScale.bandwidth()])\n",
       "\n",
       "        const color = d3.scaleOrdinal()\n",
       "          .domain(subgroups)\n",
       "          .range(rectColors)\n",
       "\n",
       "        svgEl.append(&quot;g&quot;)\n",
       "           .attr(&quot;id&quot;, &quot;g3&quot;)\n",
       "           .selectAll(&quot;g&quot;)\n",
       "           .data(data)\n",
       "           .enter()\n",
       "           .append(&quot;g&quot;)\n",
       "             .attr(&quot;transform&quot;, function(d) { return &quot;translate(&quot; + xScale(d?.group) + &quot;,0)&quot;; })\n",
       "             .attr(&quot;id&quot;, &quot;g4&quot;)\n",
       "           .selectAll(&quot;rect&quot;)\n",
       "           .data(function(d) { return subgroups.map(function(key) { return {key: key, value: d &amp;&amp; d[key]}; }); })\n",
       "           .enter().append(&quot;rect&quot;)\n",
       "             .attr(&quot;x&quot;, function(d) { return xSubgroup(d.key); })\n",
       "             .attr(&quot;y&quot;, function(d) { return yScale(d.value); })\n",
       "             .attr(&quot;width&quot;, xSubgroup.bandwidth())\n",
       "             .attr(&quot;height&quot;, function(d) { return (CHART_HEIGHT - yScale(d.value)); })\n",
       "             .attr(&quot;fill&quot;, function(d) { return color(d.key); })\n",
       "             .style(&quot;opacity&quot;, &quot;0.8&quot;);\n",
       "\n",
       "\n",
       "         return svgEl._groups[0][0].outerHTML;\n",
       "      }\n",
       "\n",
       "\n",
       "      const profileFromCSVfile = {&quot;quality&quot;: {&quot;frequentItems&quot;: [{&quot;value&quot;: &quot;bad&quot;, &quot;estimate&quot;: 1115}, {&quot;value&quot;: &quot;good&quot;, &quot;estimate&quot;: 76}]}}\n",
       "\n",
       "      Handlebars.registerHelper(&quot;getDoubleHistogramChart&quot;,(column,key) =&gt; {\n",
       "        const columnKey = key.data.key\n",
       "        try {\n",
       "          if (profileFromCSVfile) {\n",
       "            return generateBarChart(\n",
       "                     column,\n",
       "                     profileFromCSVfile[columnKey]\n",
       "                   )\n",
       "          }\n",
       "        } catch (err) {\n",
       "          $(document).ready(() =&gt;\n",
       "            $(&quot;.desktop-content&quot;).html(`\n",
       "              &lt;p style=&quot;height: ${$(window).height()}px&quot; class=&quot;error-message&quot;&gt;\n",
       "                Something went wrong. Please try again.\n",
       "              &lt;/p&gt;\n",
       "            `)\n",
       "          )\n",
       "        }\n",
       "      });\n",
       "    }\n",
       "\n",
       "    function initWebsiteScripts() {\n",
       "      $(&quot;.svg-container&quot;).css(&quot;height&quot;, $(window).height() - 32)\n",
       "    }\n",
       "\n",
       "    function initHandlebarsTemplate() {\n",
       "      // Replace this context with JSON from .py file\n",
       "      const context = {&quot;quality&quot;: {&quot;frequentItems&quot;: [{&quot;value&quot;: &quot;bad&quot;, &quot;estimate&quot;: 267}, {&quot;value&quot;: &quot;good&quot;, &quot;estimate&quot;: 141}]}};\n",
       "      // Config handlebars and pass data to HBS template\n",
       "      const source = document.getElementById(&quot;entry-template&quot;).innerHTML;\n",
       "      const template = Handlebars.compile(source);\n",
       "      const html = template(context);\n",
       "      const target = document.getElementById(&quot;generated-html&quot;);\n",
       "      target.innerHTML = html;\n",
       "    }\n",
       "\n",
       "    // Invoke functions -- keep in mind invokation order\n",
       "    registerHandlebarHelperFunctions();\n",
       "    initHandlebarsTemplate();\n",
       "    initWebsiteScripts();\n",
       "  &lt;/script&gt;\n",
       "&lt;/html&gt;\n",
       "\" width=100% height=277px\n",
       "        frameBorder=0></iframe>"
      ],
      "text/plain": [
       "<IPython.core.display.HTML object>"
      ]
     },
     "execution_count": 14,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "visualization.distribution_chart(feature_name=\"quality\")\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "`distribution_charts` also accepts multiple feature names, but in this case we have a single categorical feature.\n",
    "\n",
    "We can also look at the difference between distributions:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div></div><iframe srcdoc=\"&lt;!DOCTYPE html&gt;\n",
       "&lt;html lang=&quot;en&quot;&gt;\n",
       "  &lt;head&gt;\n",
       "    &lt;meta charset=&quot;UTF-8&quot; /&gt;\n",
       "    &lt;meta http-equiv=&quot;X-UA-Compatible&quot; content=&quot;IE=edge&quot; /&gt;\n",
       "    &lt;meta name=&quot;viewport&quot; content=&quot;width=device-width, initial-scale=1.0&quot; /&gt;\n",
       "    &lt;meta name=&quot;description&quot; content=&quot;&quot; /&gt;\n",
       "    &lt;meta name=&quot;author&quot; content=&quot;&quot; /&gt;\n",
       "\n",
       "    &lt;title&gt;Profile Visualizer | whylogs&lt;/title&gt;\n",
       "\n",
       "    &lt;link rel=&quot;icon&quot; href=&quot;images/whylabs-favicon.png&quot; type=&quot;image/png&quot; sizes=&quot;16x16&quot; /&gt;\n",
       "    &lt;link rel=&quot;preconnect&quot; href=&quot;https://fonts.googleapis.com&quot; /&gt;\n",
       "    &lt;link rel=&quot;preconnect&quot; href=&quot;https://fonts.gstatic.com&quot; crossorigin /&gt;\n",
       "    &lt;link href=&quot;https://fonts.googleapis.com/css2?family=Asap:wght@400;500;600;700&amp;display=swap&quot; rel=&quot;stylesheet&quot; /&gt;\n",
       "    &lt;link rel=&quot;preconnect&quot; href=&quot;https://fonts.gstatic.com&quot; /&gt;\n",
       "    &lt;link rel=&quot;stylesheet&quot; href=&quot;https://cdn.jsdelivr.net/npm/bootstrap@5.1.0/dist/css/bootstrap.min.css&quot; /&gt;\n",
       "\n",
       "    &lt;script\n",
       "      src=&quot;https://cdnjs.cloudflare.com/ajax/libs/handlebars.js/4.7.7/handlebars.min.js&quot;\n",
       "      integrity=&quot;sha512-RNLkV3d+aLtfcpEyFG8jRbnWHxUqVZozacROI4J2F1sTaDqo1dPQYs01OMi1t1w9Y2FdbSCDSQ2ZVdAC8bzgAg==&quot;\n",
       "      crossorigin=&quot;anonymous&quot;\n",
       "      referrerpolicy=&quot;no-referrer&quot;\n",
       "    &gt;&lt;/script&gt;\n",
       "\n",
       "    &lt;style type=&quot;text/css&quot;&gt;\n",
       "\n",
       "      :root {\n",
       "        /** Branded colors */\n",
       "        --brandSecondary900: #4f595b;\n",
       "        --secondaryLight1000: #313b3d;\n",
       "        /** Purpose colors */\n",
       "        --tealBackground: #eaf2f3;\n",
       "      }\n",
       "\n",
       "      /* RESET STYLE */\n",
       "      *,\n",
       "      *::after,\n",
       "      *::before {\n",
       "        margin: 0;\n",
       "        padding: 0;\n",
       "        box-sizing: border-box;\n",
       "        overflow-y: hidden;\n",
       "      }\n",
       "\n",
       "      /* Screen on smaller screens */\n",
       "      .no-responsive {\n",
       "        display: none;\n",
       "        position: fixed;\n",
       "        top: 0;\n",
       "        left: 0;\n",
       "        z-index: 1031;\n",
       "        width: 100vw;\n",
       "        height: 100vh;\n",
       "        background-color: var(--tealBackground);\n",
       "        display: flex;\n",
       "        align-items: center;\n",
       "        justify-content: center;\n",
       "      }\n",
       "\n",
       "      .desktop-content {\n",
       "        display: flex;\n",
       "        flex-direction: column;\n",
       "      }\n",
       "\n",
       "      .no-responsive__content {\n",
       "        max-width: 600px;\n",
       "        width: 100%;\n",
       "        padding: 0 24px;\n",
       "      }\n",
       "\n",
       "      .no-responsive__title {\n",
       "        font-size: 96px;\n",
       "        font-weight: 300;\n",
       "        color: var(--brandSecondary900);\n",
       "        line-height: 1.167;\n",
       "      }\n",
       "\n",
       "      .no-responsive__text {\n",
       "        margin: 0;\n",
       "        font-size: 16px;\n",
       "        font-weight: 400;\n",
       "        color: var(--brandSecondary900);\n",
       "        line-height: 1.5;\n",
       "      }\n",
       "\n",
       "      .svg-container {\n",
       "        display: inline-block;\n",
       "        position: relative;\n",
       "        width: 100%;\n",
       "        vertical-align: top;\n",
       "        overflow: hidden;\n",
       "      }\n",
       "\n",
       "      .svg-content-responsive {\n",
       "        display: inline-block;\n",
       "        position: absolute;\n",
       "        left: 0;\n",
       "      }\n",
       "\n",
       "      .circle-color {\n",
       "       display: inline-block;\n",
       "       padding: 5px;\n",
       "       border-radius: 50px;\n",
       "     }\n",
       "\n",
       "     .colors-for-distingushing-charts {\n",
       "       padding-right: 10px;\n",
       "     }\n",
       "\n",
       "     .display-flex{\n",
       "       display: flex;\n",
       "     }\n",
       "\n",
       "     .flex-direction-column {\n",
       "       flex-direction: column;\n",
       "     }\n",
       "\n",
       "     .align-items-flex-end {\n",
       "       align-items: flex-end;\n",
       "     }\n",
       "\n",
       "     .chart-box-title {\n",
       "       width: 98%;\n",
       "       justify-content: space-between;\n",
       "       margin: 10px;\n",
       "       margin-top: 15px;\n",
       "       bottom: 0;\n",
       "     }\n",
       "\n",
       "     .chart-box-title p{\n",
       "       margin-bottom: 0;\n",
       "       font-family: Asap;\n",
       "       font-weight: bold;\n",
       "       font-size: 18px;\n",
       "       line-height: 16px;\n",
       "       color: #4F595B;\n",
       "     }\n",
       "\n",
       "     .bar.positive {\n",
       "       fill: #44C0E7;\n",
       "     }\n",
       "\n",
       "     .bar.negative {\n",
       "       fill: #F5843C;\n",
       "     }\n",
       "\n",
       "     .error-message {\n",
       "       display: flex;\n",
       "       justify-content: center;\n",
       "       align-items: center;\n",
       "       color: rgb(255, 114, 71);\n",
       "       font-size: 30px;\n",
       "       font-weight: 900;\n",
       "     }\n",
       "\n",
       "     @media screen and (min-width: 500px) {\n",
       "       .desktop-content {\n",
       "         display: block;\n",
       "       }\n",
       "       .no-responsive {\n",
       "         display: none;\n",
       "       }\n",
       "     }\n",
       "    &lt;/style&gt;\n",
       "  &lt;/head&gt;\n",
       "\n",
       "  &lt;body id=&quot;generated-html&quot;&gt;&lt;/body&gt;\n",
       "  &lt;script id=&quot;entry-template&quot; type=&quot;text/x-handlebars-template&quot;&gt;\n",
       "    \n",
       "      &lt;div class=&quot;desktop-content&quot;&gt;\n",
       "{{#each this}}              &lt;div class=&quot;chart-box&quot; id=&quot;chart-box&quot;&gt;\n",
       "                &lt;div class=&quot;chart-box-title display-flex&quot;&gt;\n",
       "                  &lt;p&gt;{{@key}}&lt;/p&gt;\n",
       "                  &lt;div class=&quot;display-flex&quot;&gt;\n",
       "                    &lt;div class=&quot;colors-for-distingushing-charts&quot;&gt;\n",
       "                      &lt;div class=&quot;circle-color&quot; style=&quot;background: #44C0E7;&quot;&gt;&lt;/div&gt;\n",
       "                      &lt;text alignment-baseline=&quot;middle&quot; style=&quot;font-size: 15px;&quot;&gt;Target&lt;/text&gt;\n",
       "                    &lt;/div&gt;\n",
       "                    &lt;div class=&quot;colors-for-distingushing-charts&quot;&gt;\n",
       "                      &lt;div class=&quot;circle-color&quot; style=&quot;background: #F5843C&quot;&gt;&lt;/div&gt;\n",
       "                      &lt;text alignment-baseline=&quot;middle&quot; style=&quot;font-size: 15px;&quot;&gt;Reference&lt;/text&gt;\n",
       "                    &lt;/div&gt;\n",
       "                  &lt;/div&gt;&lt;/div&gt;\n",
       "                &lt;div class=&quot;svg-container&quot;&gt;\n",
       "                  {{{getDoubleHistogramChart this}}}\n",
       "                &lt;/div&gt;\n",
       "              &lt;/div&gt;\n",
       "{{/each}}      &lt;/div&gt;\n",
       "      &lt;div class=&quot;no-responsive&quot;&gt;\n",
       "        &lt;div class=&quot;no-responsive__content&quot;&gt;\n",
       "          &lt;h1 class=&quot;no-responsive__title&quot;&gt;Hold on! :)&lt;/h1&gt;\n",
       "          &lt;p class=&quot;no-responsive__text&quot;&gt;\n",
       "            It looks like your current screen size or device is not yet supported by the WhyLabs Sandbox. The Sandbox is\n",
       "            best experienced on a desktop computer. Please try maximizing this window or switching to another device. We\n",
       "            are working on adding support for a larger variety of devices.\n",
       "          &lt;/p&gt;\n",
       "        &lt;/div&gt;\n",
       "      &lt;/div&gt;\n",
       "    \n",
       "  &lt;/script&gt;\n",
       "\n",
       "  &lt;script src=&quot;https://code.jquery.com/jquery-3.6.0.min.js&quot; integrity=&quot;sha256-/xUj+3OJU5yExlq6GSYGSHk7tPXikynS7ogEvDej/m4=&quot; crossorigin=&quot;anonymous&quot;&gt;&lt;/script&gt;\n",
       "\n",
       "  &lt;script src=&quot;https://cdnjs.cloudflare.com/ajax/libs/d3/6.7.0/d3.min.js&quot; integrity=&quot;sha512-cd6CHE+XWDQ33ElJqsi0MdNte3S+bQY819f7p3NUHgwQQLXSKjE4cPZTeGNI+vaxZynk1wVU3hoHmow3m089wA==&quot; crossorigin=&quot;anonymous&quot; referrerpolicy=&quot;no-referrer&quot;&gt;&lt;/script&gt;\n",
       "\n",
       "  &lt;script&gt;\n",
       "    function registerHandlebarHelperFunctions() {\n",
       "      //helper fun\n",
       "\n",
       "      const findAndDeleteUndefined = (axisData) =&gt; {\n",
       "        const undefinedAxisIndex = axisData.findIndex((axis) =&gt; axis === undefined)\n",
       "        if (undefinedAxisIndex &gt; 0) {\n",
       "          return [...axisData.slice(0, undefinedAxisIndex), ...axisData.slice(undefinedAxisIndex + 1)]\n",
       "        }\n",
       "        return axisData\n",
       "      }\n",
       "\n",
       "      const filterAndSortChartData = (overlappedHistogramData, histogramData) =&gt; {\n",
       "        const filteredData = overlappedHistogramData\n",
       "          .map((d) =&gt;\n",
       "            histogramData\n",
       "            .filter((ref) =&gt; d.axisX === ref.axisX )[0])\n",
       "            .sort((a, b) =&gt; {\n",
       "              if (+a.axisY &lt; +b.axisY) {\n",
       "                return 1;\n",
       "              }\n",
       "              if (+a.axisY &gt; +b.axisY) {\n",
       "                return -1;\n",
       "              }\n",
       "\n",
       "              return 0;\n",
       "            })\n",
       "            .slice(0, 20)\n",
       "\n",
       "        return findAndDeleteUndefined(filteredData)\n",
       "      }\n",
       "\n",
       "      class GenerateChartParams {\n",
       "        constructor(height, width, data, referenceData, bottomMargin=30, topMargin=5) {\n",
       "          this.MARGIN = {\n",
       "            TOP: topMargin,\n",
       "            RIGHT: 5,\n",
       "            BOTTOM: bottomMargin,\n",
       "            LEFT: 55,\n",
       "          };\n",
       "          this.SVG_WIDTH = width;\n",
       "          this.SVG_HEIGHT = height;\n",
       "          this.CHART_WIDTH = this.SVG_WIDTH - this.MARGIN.LEFT - this.MARGIN.RIGHT;\n",
       "          this.CHART_HEIGHT = this.SVG_HEIGHT - this.MARGIN.TOP - this.MARGIN.BOTTOM;\n",
       "          this.svgEl = d3.create(&quot;svg&quot;)\n",
       "             .attr(&quot;preserveAspectRatio&quot;, &quot;xMinYMin meet&quot;)\n",
       "             .attr(&quot;viewBox&quot;, `0 -10 ${$(window).width()} ${$(window).height()-30}`)\n",
       "             .classed(&quot;svg-content-responsive&quot;, true)\n",
       "          this.maxYValue = d3.max(data, (d) =&gt; Math.abs(d.axisY));\n",
       "          this.xScale = d3\n",
       "            .scaleBand()\n",
       "            .domain(filterAndSortChartData(data, referenceData).map((sortedCounts) =&gt; sortedCounts &amp;&amp; sortedCounts.axisX))\n",
       "            .rangeRound([this.MARGIN.LEFT, this.SVG_WIDTH])\n",
       "            .padding([0.1]);\n",
       "          this.yScale = d3\n",
       "            .scaleLinear()\n",
       "            .domain([0, this.maxYValue])\n",
       "            .range([this.CHART_HEIGHT, 0]);\n",
       "        }\n",
       "      }\n",
       "\n",
       "      function chartData(column) {\n",
       "        const data = [];\n",
       "          if (column.frequentItems) {\n",
       "            Object.entries(column.frequentItems).forEach(([key, {value, estimate}], index) =&gt; {\n",
       "              data.push({\n",
       "                axisY: estimate,\n",
       "                axisX: value,\n",
       "              });\n",
       "            });\n",
       "          } else {\n",
       "            $(document).ready(() =&gt;\n",
       "              $(&quot;.desktop-content&quot;).html(`\n",
       "                &lt;p style=&quot;height: ${$(window).height()}px&quot; class=&quot;error-message&quot;&gt;\n",
       "                  Something went wrong. Please try again.\n",
       "                &lt;/p&gt;\n",
       "              `)\n",
       "            )\n",
       "          }\n",
       "\n",
       "        return data\n",
       "      }\n",
       "\n",
       "      function generatePositiveNegativeChart(histogramData, overlappedHistogramData) {\n",
       "          const data = filterAndSortChartData(chartData(histogramData), chartData(overlappedHistogramData)).map((axis, index) =&gt; {\n",
       "            if (axis) {\n",
       "              const findIndex = chartData(histogramData).findIndex((value) =&gt; value.axisX === axis.axisX)\n",
       "              const difference = axis.axisY - chartData(histogramData)[findIndex].axisY\n",
       "              return [difference]\n",
       "            }\n",
       "            return 0;\n",
       "          }).flat()\n",
       "\n",
       "        let yFormat,\n",
       "            xFormat;\n",
       "\n",
       "        const sizes = new GenerateChartParams($(window).height()-60, $(window).width(), chartData(histogramData), chartData(overlappedHistogramData))\n",
       "        let {\n",
       "         MARGIN,\n",
       "         SVG_WIDTH,\n",
       "         SVG_HEIGHT,\n",
       "         CHART_WIDTH,\n",
       "         CHART_HEIGHT,\n",
       "         xScale,\n",
       "         svgEl\n",
       "        } = sizes\n",
       "\n",
       "        const rectColors = [&quot;bar positive&quot;, &quot;bar negative&quot;]\n",
       "        const maxY = Math.abs(d3.max(data));\n",
       "        const minY = Math.abs(d3.min(data));\n",
       "        let positiveY = Math.ceil(maxY) % 1 ? maxY + 2*(maxY/(maxY*10)) : maxY + 2*(maxY/(maxY/10)),\n",
       "            negativeY = Math.ceil(minY) % 1 ? minY + 2*(minY/(minY*10)) : minY + 2*(minY/(minY/10));\n",
       "\n",
       "        const yScale = d3.scaleLinear()\n",
       "            .range([CHART_HEIGHT,0])\n",
       "            .domain([-negativeY*1.2, positiveY*1.2 || 0])\n",
       "            .nice()\n",
       "\n",
       "        const xAxis = d3.axisBottom(xScale).ticks(SVG_WIDTH / 80, xFormat).tickSizeOuter(0);\n",
       "        const yAxis = d3.axisLeft(yScale).ticks(CHART_HEIGHT / 30, yFormat);\n",
       "        yFormat = yScale.tickFormat(100, yFormat);\n",
       "\n",
       "          svgEl.append(&quot;g&quot;)\n",
       "          .attr(&quot;transform&quot;, `translate(${MARGIN.LEFT}, 0)`)\n",
       "          .call(yAxis)\n",
       "          .call(g =&gt; g.select(&quot;.domain&quot;).remove())\n",
       "          .call(g =&gt; g.selectAll(&quot;.tick line&quot;)\n",
       "          .attr(&quot;x2&quot;, CHART_WIDTH )\n",
       "          .attr(&quot;stroke-opacity&quot;, 0.1))\n",
       "          .call(g =&gt; g.append(&quot;text&quot;)\n",
       "          .attr(&quot;x&quot;, - MARGIN.LEFT)\n",
       "          .attr(&quot;y&quot;, 10)\n",
       "          .attr(&quot;fill&quot;, &quot;currentColor&quot;)\n",
       "          .attr(&quot;text-anchor&quot;, &quot;start&quot;));\n",
       "\n",
       "          svgEl.append(&quot;text&quot;)\n",
       "          .attr(&quot;transform&quot;,\n",
       "                &quot;translate(&quot; + (CHART_WIDTH/2) + &quot; ,&quot; +\n",
       "                               (CHART_HEIGHT + MARGIN.TOP + 30) + &quot;)&quot;)\n",
       "          .style(&quot;text-anchor&quot;, &quot;middle&quot;)\n",
       "          .text(&quot;Values&quot;)\n",
       "          .style(&quot;font-size&quot;, &quot;15&quot;)\n",
       "          .style(&quot;opacity&quot;, &quot;0.6&quot;)\n",
       "\n",
       "        svgEl.append(&quot;text&quot;)\n",
       "          .attr(&quot;transform&quot;, &quot;rotate(-90)&quot;)\n",
       "          .attr(&quot;y&quot;, 0)\n",
       "          .attr(&quot;x&quot;, 0 - (SVG_HEIGHT / 2))\n",
       "          .attr(&quot;dy&quot;, &quot;1em&quot;)\n",
       "          .style(&quot;text-anchor&quot;, &quot;middle&quot;)\n",
       "          .text(&quot;Counts&quot;)\n",
       "          .style(&quot;font-size&quot;, &quot;15&quot;)\n",
       "          .style(&quot;opacity&quot;, &quot;0.6&quot;)\n",
       "\n",
       "          svgEl\n",
       "          .append(&quot;g&quot;)\n",
       "          .attr(&quot;transform&quot;, `translate(0,${SVG_HEIGHT - MARGIN.BOTTOM - 7})`)\n",
       "          .call(xAxis)\n",
       "          .call(g =&gt; g.select(&quot;.domain&quot;).remove())\n",
       "          .call(g =&gt; g.selectAll(&quot;.tick&gt;line&quot;).remove())\n",
       "          .call(g =&gt; g.append(&quot;text&quot;)\n",
       "              .attr(&quot;x&quot;, SVG_WIDTH - MARGIN.RIGHT)\n",
       "              .attr(&quot;y&quot;, 27)\n",
       "              .attr(&quot;fill&quot;, &quot;currentColor&quot;)\n",
       "              .attr(&quot;text-anchor&quot;, &quot;end&quot;));\n",
       "\n",
       "        svgEl.selectAll(&quot;.bar&quot;)\n",
       "            .data(data)\n",
       "          .enter()\n",
       "          .append(&quot;rect&quot;)\n",
       "            .attr(&quot;class&quot;, function(d) { return d &lt; 0 ? rectColors[0] : rectColors[1]; })\n",
       "            .attr(&quot;y&quot;, function(d) { return yScale(Math.max(0, d)); })\n",
       "            .attr(&quot;x&quot;, function(d, i) { return xScale(filterAndSortChartData(chartData(histogramData), chartData(overlappedHistogramData))[i]?.axisX) })\n",
       "            .attr(&quot;height&quot;, function(d) { return Math.abs(yScale(d) - yScale(0)); })\n",
       "            .attr(&quot;width&quot;, xScale.bandwidth())\n",
       "            .style(&quot;opacity&quot;, &quot;0.8&quot;)\n",
       "\n",
       "\n",
       "            return svgEl._groups[0][0].outerHTML;\n",
       "      }\n",
       "\n",
       "      const profileFromCSVfile = {&quot;quality&quot;: {&quot;frequentItems&quot;: [{&quot;value&quot;: &quot;bad&quot;, &quot;estimate&quot;: 1115}, {&quot;value&quot;: &quot;good&quot;, &quot;estimate&quot;: 76}]}}\n",
       "\n",
       "      Handlebars.registerHelper(&quot;getDoubleHistogramChart&quot;,(column,key) =&gt; {\n",
       "        const columnKey = key.data.key\n",
       "        try {\n",
       "          if (profileFromCSVfile) {\n",
       "            return generatePositiveNegativeChart(\n",
       "                     column,\n",
       "                     profileFromCSVfile[columnKey]\n",
       "                   )\n",
       "          }\n",
       "        } catch (err) {\n",
       "          $(document).ready(() =&gt;\n",
       "            $(&quot;.desktop-content&quot;).html(`\n",
       "              &lt;p style=&quot;height: ${$(window).height()}px&quot; class=&quot;error-message&quot;&gt;\n",
       "                Something went wrong. Please try again.\n",
       "              &lt;/p&gt;\n",
       "            `)\n",
       "          )\n",
       "        }\n",
       "      });\n",
       "    }\n",
       "\n",
       "    function initWebsiteScripts() {\n",
       "      $(&quot;.svg-container&quot;).css(&quot;height&quot;, $(window).height() - 32)\n",
       "    }\n",
       "\n",
       "    function initHandlebarsTemplate() {\n",
       "      // Replace this context with JSON from .py file\n",
       "      const context = {&quot;quality&quot;: {&quot;frequentItems&quot;: [{&quot;value&quot;: &quot;bad&quot;, &quot;estimate&quot;: 267}, {&quot;value&quot;: &quot;good&quot;, &quot;estimate&quot;: 141}]}};\n",
       "      // Config handlebars and pass data to HBS template\n",
       "      const source = document.getElementById(&quot;entry-template&quot;).innerHTML;\n",
       "      const template = Handlebars.compile(source);\n",
       "      const html = template(context);\n",
       "      const target = document.getElementById(&quot;generated-html&quot;);\n",
       "      target.innerHTML = html;\n",
       "    }\n",
       "\n",
       "    // Invoke functions -- keep in mind invokation order\n",
       "    registerHandlebarHelperFunctions();\n",
       "    initHandlebarsTemplate();\n",
       "    initWebsiteScripts();\n",
       "  &lt;/script&gt;\n",
       "&lt;/html&gt;\n",
       "\" width=100% height=277px\n",
       "        frameBorder=0></iframe>"
      ],
      "text/plain": [
       "<IPython.core.display.HTML object>"
      ]
     },
     "execution_count": 15,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "visualization.difference_distribution_chart(feature_name=\"quality\")\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "We can see that there is 800 or so more \"bads\" in the Reference profile, and 50 or so more \"goods\" on the target profile."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Feature Statistics"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "With `feature_statistics`, we have access to very useful statistics by passing the feature and profile name.\n",
    "\n",
    "As with the previous reports (double_histogram and distribution_chart) you can pass a string or a list of strings through `feature_name`. Let's take a look at the summary statistics for some of our features:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div></div><iframe srcdoc=\"&lt;!DOCTYPE html&gt;\n",
       "&lt;html lang=&quot;en&quot;&gt;\n",
       "  &lt;head&gt;\n",
       "    &lt;meta charset=&quot;UTF-8&quot; /&gt;\n",
       "    &lt;meta http-equiv=&quot;X-UA-Compatible&quot; content=&quot;IE=edge&quot; /&gt;\n",
       "    &lt;meta name=&quot;viewport&quot; content=&quot;width=device-width, initial-scale=1.0&quot; /&gt;\n",
       "    &lt;meta name=&quot;description&quot; content=&quot;&quot; /&gt;\n",
       "    &lt;meta name=&quot;author&quot; content=&quot;&quot; /&gt;\n",
       "\n",
       "    &lt;title&gt;Profile Visualizer | whylogs&lt;/title&gt;\n",
       "\n",
       "    &lt;link rel=&quot;icon&quot; href=&quot;images/whylabs-favicon.png&quot; type=&quot;image/png&quot; sizes=&quot;16x16&quot; /&gt;\n",
       "    &lt;link rel=&quot;preconnect&quot; href=&quot;https://fonts.googleapis.com&quot; /&gt;\n",
       "    &lt;link rel=&quot;preconnect&quot; href=&quot;https://fonts.gstatic.com&quot; crossorigin /&gt;\n",
       "    &lt;link href=&quot;https://fonts.googleapis.com/css2?family=Asap:wght@400;500;600;700&amp;display=swap&quot; rel=&quot;stylesheet&quot; /&gt;\n",
       "    &lt;link rel=&quot;preconnect&quot; href=&quot;https://fonts.gstatic.com&quot; /&gt;\n",
       "    &lt;link rel=&quot;stylesheet&quot; href=&quot;https://cdn.jsdelivr.net/npm/bootstrap@5.1.0/dist/css/bootstrap.min.css&quot; /&gt;\n",
       "\n",
       "    &lt;script\n",
       "      src=&quot;https://cdnjs.cloudflare.com/ajax/libs/handlebars.js/4.7.7/handlebars.min.js&quot;\n",
       "      integrity=&quot;sha512-RNLkV3d+aLtfcpEyFG8jRbnWHxUqVZozacROI4J2F1sTaDqo1dPQYs01OMi1t1w9Y2FdbSCDSQ2ZVdAC8bzgAg==&quot;\n",
       "      crossorigin=&quot;anonymous&quot;\n",
       "      referrerpolicy=&quot;no-referrer&quot;\n",
       "    &gt;&lt;/script&gt;\n",
       "\n",
       "    &lt;style type=&quot;text/css&quot;&gt;\n",
       "\n",
       "      /* Screen on smaller screens */\n",
       "      .no-responsive {\n",
       "        display: none;\n",
       "        position: fixed;\n",
       "        top: 0;\n",
       "        left: 0;\n",
       "        z-index: 1031;\n",
       "        width: 100vw;\n",
       "        height: 100vh;\n",
       "        background-color: var(--tealBackground);\n",
       "        display: flex;\n",
       "        align-items: center;\n",
       "        justify-content: center;\n",
       "      }\n",
       "\n",
       "      @media screen and (min-width: 1000px) {\n",
       "        .desktop-content {\n",
       "          display: block;\n",
       "        }\n",
       "        .no-responsive {\n",
       "          display: none;\n",
       "        }\n",
       "      }\n",
       "\n",
       "      .no-responsive__content {\n",
       "        max-width: 600px;\n",
       "        width: 100%;\n",
       "        padding: 0 24px;\n",
       "      }\n",
       "\n",
       "      .no-responsive__title {\n",
       "        font-size: 96px;\n",
       "        font-weight: 300;\n",
       "        color: var(--brandSecondary900);\n",
       "        line-height: 1.167;\n",
       "      }\n",
       "\n",
       "      .no-responsive__text {\n",
       "        margin: 0;\n",
       "        font-size: 16px;\n",
       "        font-weight: 400;\n",
       "        color: var(--brandSecondary900);\n",
       "        line-height: 1.5;\n",
       "      }\n",
       "\n",
       "      .header-title {\n",
       "        font-size: 26px;\n",
       "        font-weight: 700;\n",
       "        color: #444444;\n",
       "      }\n",
       "\n",
       "      .statistics-header-title {\n",
       "        font-size: 20px;\n",
       "        font-weight: 700;\n",
       "        color: #444444;\n",
       "      }\n",
       "\n",
       "      .statistic-number-title {\n",
       "        font-family: Arial;\n",
       "        font-weight: normal;\n",
       "        font-size: 14px;\n",
       "        line-height: 20px;\n",
       "        color: #6C757D;\n",
       "      }\n",
       "\n",
       "      .statistic-number {\n",
       "        font-family: Arial;\n",
       "        font-weight: bold;\n",
       "        font-size: 20px;\n",
       "        line-height: 140%;\n",
       "        display: flex;\n",
       "        align-items: center;\n",
       "        color: #4F595B;\n",
       "      }\n",
       "\n",
       "      .full-summary-statistics-wrap {\n",
       "        padding: 20px;\n",
       "      }\n",
       "\n",
       "      .statistics {\n",
       "        width: 100%;\n",
       "      }\n",
       "\n",
       "      .statistics-list {\n",
       "        width: 49% ;\n",
       "      }\n",
       "\n",
       "      .notif-circle-container{\n",
       "        position: absolute;\n",
       "        top: -8px;\n",
       "        right: -8px;\n",
       "        padding: 5.3px;\n",
       "        border-radius: 50%;\n",
       "        background-color: var(--brandSecondary100);\n",
       "        cursor: pointer;\n",
       "      }\n",
       "\n",
       "      .notif-circle {\n",
       "        position: absolute;\n",
       "        top: 2px;\n",
       "        right: 2px;\n",
       "        height: 16px;\n",
       "        width: 16px;\n",
       "        border-radius: 50%;\n",
       "        font-size: 10px;\n",
       "        color: #fff;\n",
       "        background-color: #ECB100;\n",
       "      }\n",
       "\n",
       "      .border-solid-gray {\n",
       "        border: 1px solid #CED4DA;\n",
       "        border-radius: 4px;\n",
       "        padding: 10px;\n",
       "      }\n",
       "\n",
       "      .display-flex {\n",
       "        display: flex;\n",
       "      }\n",
       "\n",
       "      .justify-content-space-between {\n",
       "        justify-content: space-between;\n",
       "      }\n",
       "\n",
       "      .justify-content-center {\n",
       "        justify-content: center;\n",
       "      }\n",
       "\n",
       "      .align-items-center {\n",
       "        align-items: center;\n",
       "      }\n",
       "\n",
       "      .padding-right-30 {\n",
       "        padding-right: 30px;\n",
       "      }\n",
       "\n",
       "      @media screen and (min-width: 500px) {\n",
       "        .desktop-content {\n",
       "          display: block;\n",
       "        }\n",
       "        .no-responsive {\n",
       "          display: none;\n",
       "        }\n",
       "      }\n",
       "    &lt;/style&gt;\n",
       "  &lt;/head&gt;\n",
       "\n",
       "  &lt;body id=&quot;generated-html&quot;&gt;&lt;/body&gt;\n",
       "\n",
       "  &lt;script id=&quot;entry-template&quot; type=&quot;text/x-handlebars-template&quot;&gt;\n",
       "    \n",
       "      &lt;div class=&quot;desktop-content&quot;&gt;\n",
       "        &lt;div class=&quot;full-summary-statistics-wrap&quot;&gt;\n",
       "          &lt;div class=&quot;full-summary-statistics&quot;&gt;\n",
       "            &lt;div class=&quot;mb-4&quot;&gt;\n",
       "                &lt;strong class=&quot;header-title&quot;&gt;{{featureName this}}: Summary Statistics&lt;/strong&gt;\n",
       "            &lt;/div&gt;\n",
       "            &lt;div class=&quot;statistics-wrap border-solid-gray display-flex justify-content-center mb-5&quot;&gt;\n",
       "              &lt;div class=&quot;statistics display-flex justify-content-space-between&quot;&gt;\n",
       "                  &lt;div class=&quot;statistic-item padding-right-30&quot;&gt;\n",
       "                    &lt;div class=&quot;statistic-number-title&quot;&gt;Distinct (%)&lt;/div&gt;\n",
       "                    &lt;div class=&quot;statistic-number&quot;&gt;{{distinct this}}&lt;/div&gt;\n",
       "                  &lt;/div&gt;\n",
       "                  &lt;div class=&quot;statistic-item padding-right-30&quot;&gt;\n",
       "                    &lt;div class=&quot;statistic-number-title&quot;&gt;Missing&lt;/div&gt;\n",
       "                    &lt;div class=&quot;statistic-number&quot;&gt;{{missing this}}&lt;/div&gt;\n",
       "                  &lt;/div&gt;\n",
       "                  &lt;div class=&quot;statistic-item padding-right-30&quot;&gt;\n",
       "                    &lt;div class=&quot;statistic-number-title&quot;&gt;Mean&lt;/div&gt;\n",
       "                    &lt;div class=&quot;statistic-number&quot;&gt;{{mean this}}&lt;/div&gt;\n",
       "                  &lt;/div&gt;\n",
       "                  &lt;div class=&quot;statistic-item padding-right-30&quot;&gt;\n",
       "                    &lt;div class=&quot;statistic-number-title&quot;&gt;Minimum&lt;/div&gt;\n",
       "                    &lt;div class=&quot;statistic-number&quot;&gt;{{minimum this}}&lt;/div&gt;\n",
       "                  &lt;/div&gt;\n",
       "                  &lt;div class=&quot;statistic-item padding-right-30&quot;&gt;\n",
       "                    &lt;div class=&quot;statistic-number-title&quot;&gt;Maximum&lt;/div&gt;\n",
       "                    &lt;div class=&quot;statistic-number&quot;&gt;{{maximum this}}&lt;/div&gt;\n",
       "                  &lt;/div&gt;\n",
       "              &lt;/div&gt;\n",
       "            &lt;/div&gt;\n",
       "            &lt;div&gt;\n",
       "              &lt;div class=&quot;display-flex justify-content-space-between&quot;&gt;\n",
       "                &lt;div class=&quot;statistics-list border-solid-gray&quot;&gt;\n",
       "                  &lt;div&gt;\n",
       "                    &lt;div class=&quot;mb-3&quot;&gt;\n",
       "                      &lt;strong class=&quot;statistics-header-title&quot;&gt;Quantile statistics&lt;/strong&gt;\n",
       "                    &lt;/div&gt;\n",
       "                    &lt;div&gt;\n",
       "                      &lt;div class=&quot;display-flex justify-content-space-between mb-2&quot;&gt;\n",
       "                        &lt;div&gt;5-th percentile&lt;/div&gt;\n",
       "                        &lt;div&gt;{{fifthPercentile this}}&lt;/div&gt;\n",
       "                      &lt;/div&gt;\n",
       "                      &lt;div class=&quot;display-flex justify-content-space-between mb-2&quot;&gt;\n",
       "                        &lt;div&gt;Q1&lt;/div&gt;\n",
       "                        &lt;div&gt;{{q1 this}}&lt;/div&gt;\n",
       "                      &lt;/div&gt;\n",
       "                      &lt;div class=&quot;display-flex justify-content-space-between mb-2&quot;&gt;\n",
       "                        &lt;div&gt;median&lt;/div&gt;\n",
       "                        &lt;div&gt;{{median this}}&lt;/div&gt;\n",
       "                      &lt;/div&gt;\n",
       "                      &lt;div class=&quot;display-flex justify-content-space-between mb-2&quot;&gt;\n",
       "                        &lt;div&gt;Q3&lt;/div&gt;\n",
       "                        &lt;div&gt;{{q3 this}}&lt;/div&gt;\n",
       "                      &lt;/div&gt;\n",
       "                      &lt;div class=&quot;display-flex justify-content-space-between mb-2&quot;&gt;\n",
       "                        &lt;div&gt;95-th percentile&lt;/div&gt;\n",
       "                        &lt;div&gt;{{ninetyFifthPercentile this}}&lt;/div&gt;\n",
       "                      &lt;/div&gt;\n",
       "                      &lt;div class=&quot;display-flex justify-content-space-between mb-2&quot;&gt;\n",
       "                        &lt;div&gt;Range&lt;/div&gt;\n",
       "                        &lt;div&gt;{{range this}}&lt;/div&gt;\n",
       "                      &lt;/div&gt;\n",
       "                      &lt;div class=&quot;display-flex justify-content-space-between mb-2&quot;&gt;\n",
       "                        &lt;div&gt;Interquartile range (IQR)&lt;/div&gt;\n",
       "                        &lt;div&gt;{{iqr this}}&lt;/div&gt;\n",
       "                      &lt;/div&gt;\n",
       "                    &lt;/div&gt;\n",
       "                  &lt;/div&gt;\n",
       "                &lt;/div&gt;\n",
       "                &lt;div class=&quot;statistics-list border-solid-gray&quot;&gt;\n",
       "                  &lt;div&gt;\n",
       "                    &lt;div class=&quot;mb-3&quot;&gt;\n",
       "                      &lt;strong class=&quot;statistics-header-title&quot;&gt;Descriptive statistics&lt;/strong&gt;\n",
       "                    &lt;/div&gt;\n",
       "                    &lt;div&gt;\n",
       "                      &lt;div class=&quot;display-flex justify-content-space-between mb-2&quot;&gt;\n",
       "                        &lt;div&gt;Standard deviation&lt;/div&gt;\n",
       "                        &lt;div&gt;{{stddev this}}&lt;/div&gt;\n",
       "                      &lt;/div&gt;\n",
       "                      &lt;div class=&quot;display-flex justify-content-space-between mb-2&quot;&gt;\n",
       "                        &lt;div&gt;Coefficient of variation (CV)&lt;/div&gt;\n",
       "                        &lt;div&gt;{{coefficientOfVariation this}}&lt;/div&gt;\n",
       "                      &lt;/div&gt;\n",
       "                      &lt;div class=&quot;display-flex justify-content-space-between mb-2&quot;&gt;\n",
       "                        &lt;div&gt;Sum&lt;/div&gt;\n",
       "                        &lt;div&gt;{{getSum this}}&lt;/div&gt;\n",
       "                      &lt;/div&gt;\n",
       "                      &lt;div class=&quot;display-flex justify-content-space-between mb-2&quot;&gt;\n",
       "                        &lt;div&gt;Variance&lt;/div&gt;\n",
       "                        &lt;div&gt;{{variance this}}&lt;/div&gt;\n",
       "                      &lt;/div&gt;\n",
       "                    &lt;/div&gt;\n",
       "                  &lt;/div&gt;\n",
       "                &lt;/div&gt;\n",
       "              &lt;/div&gt;\n",
       "            &lt;/div&gt;\n",
       "          &lt;/div&gt;\n",
       "        &lt;/div&gt;\n",
       "      &lt;/div&gt;\n",
       "      &lt;div class=&quot;no-responsive&quot;&gt;\n",
       "        &lt;div class=&quot;no-responsive__content&quot;&gt;\n",
       "          &lt;h1 class=&quot;no-responsive__title&quot;&gt;Hold on! :)&lt;/h1&gt;\n",
       "          &lt;p class=&quot;no-responsive__text&quot;&gt;\n",
       "            It looks like your current screen size or device is not yet supported by the WhyLabs Sandbox. The Sandbox is\n",
       "            best experienced on a desktop computer. Please try maximizing this window or switching to another device. We\n",
       "            are working on adding support for a larger variety of devices.\n",
       "          &lt;/p&gt;\n",
       "        &lt;/div&gt;\n",
       "      &lt;/div&gt;\n",
       "    \n",
       "  &lt;/script&gt;\n",
       "\n",
       "  &lt;script src=&quot;https://code.jquery.com/jquery-3.6.0.min.js&quot; integrity=&quot;sha256-/xUj+3OJU5yExlq6GSYGSHk7tPXikynS7ogEvDej/m4=&quot; crossorigin=&quot;anonymous&quot;&gt;&lt;/script&gt;\n",
       "\n",
       "  &lt;script src=&quot;https://cdnjs.cloudflare.com/ajax/libs/d3/6.7.0/d3.min.js&quot; integrity=&quot;sha512-cd6CHE+XWDQ33ElJqsi0MdNte3S+bQY819f7p3NUHgwQQLXSKjE4cPZTeGNI+vaxZynk1wVU3hoHmow3m089wA==&quot; crossorigin=&quot;anonymous&quot; referrerpolicy=&quot;no-referrer&quot;&gt;&lt;/script&gt;\n",
       "\n",
       "  &lt;script&gt;\n",
       "    function registerHandlebarHelperFunctions() {\n",
       "      //helper fun\n",
       "      // function formatLabelDate(timestamp) {\n",
       "      //   const date = new Date(timestamp);\n",
       "      //   const format = d3.timeFormat(&quot;%Y-%m-%d %I:%M:%S %p %Z&quot;);\n",
       "      //   return format(date);\n",
       "      // }\n",
       "\n",
       "      function fixNumberTo(number, decimals = 3) {\n",
       "        return parseFloat(number).toFixed(decimals);\n",
       "      }\n",
       "\n",
       "      Handlebars.registerHelper(&quot;variance&quot;, function (column) {\n",
       "        const feature = Object.values(column)[0]\n",
       "\n",
       "        if (feature.descriptive_statistics &amp;&amp; typeof feature.descriptive_statistics.variance === &#x27;number&#x27;) {\n",
       "          if (isNaN(feature.descriptive_statistics.variance)){return &quot;-&quot;}\n",
       "          if (feature.descriptive_statistics.variance==null){return &quot;-&quot;}\n",
       "          return fixNumberTo(feature.descriptive_statistics.variance,2);\n",
       "        }\n",
       "        return &quot;-&quot;;\n",
       "      });\n",
       "\n",
       "      Handlebars.registerHelper(&quot;coefficientOfVariation&quot;, function (column) {\n",
       "        const feature = Object.values(column)[0]\n",
       "\n",
       "        if (feature.descriptive_statistics &amp;&amp; typeof feature.descriptive_statistics.coefficient_of_variation === &#x27;number&#x27;) {\n",
       "          if (isNaN(feature.descriptive_statistics.coefficient_of_variation)){return &quot;-&quot;}\n",
       "          if (feature.descriptive_statistics.coefficient_of_variation==null){return &quot;-&quot;}\n",
       "          return fixNumberTo(feature.descriptive_statistics.coefficient_of_variation,2);\n",
       "        }\n",
       "        return &quot;-&quot;;\n",
       "      });\n",
       "\n",
       "      Handlebars.registerHelper(&quot;median&quot;, function (column) {\n",
       "        const feature = Object.values(column)[0]\n",
       "\n",
       "        if (feature.quantile_statistics &amp;&amp; typeof feature.quantile_statistics.median === &#x27;number&#x27;) {\n",
       "          if (isNaN(feature.quantile_statistics.median)){return &quot;-&quot;}\n",
       "          if (feature.quantile_statistics.median==null){return &quot;-&quot;}\n",
       "          return fixNumberTo(feature.quantile_statistics.median);\n",
       "        }\n",
       "        return &quot;-&quot;;\n",
       "      });\n",
       "\n",
       "      Handlebars.registerHelper(&quot;fifthPercentile&quot;, function (column) {\n",
       "        const feature = Object.values(column)[0]\n",
       "\n",
       "        if (feature.quantile_statistics &amp;&amp; typeof feature.quantile_statistics.fifth_percentile === &#x27;number&#x27;) {\n",
       "          if (isNaN(feature.quantile_statistics.fifth_percentile)){return &quot;-&quot;}\n",
       "          if (feature.quantile_statistics.fifth_percentile==null){return &quot;-&quot;}\n",
       "          return fixNumberTo(feature.quantile_statistics.fifth_percentile);\n",
       "        }\n",
       "        return &quot;-&quot;;\n",
       "      });\n",
       "\n",
       "      Handlebars.registerHelper(&quot;ninetyFifthPercentile&quot;, function (column) {\n",
       "        const feature = Object.values(column)[0]\n",
       "\n",
       "        if (feature.quantile_statistics &amp;&amp; typeof feature.quantile_statistics.ninety_fifth_percentile === &#x27;number&#x27;) {\n",
       "          if (isNaN(feature.quantile_statistics.ninety_fifth_percentile)){return &quot;-&quot;}\n",
       "          if (feature.quantile_statistics.ninety_fifth_percentile==null){return &quot;-&quot;}\n",
       "          return fixNumberTo(feature.quantile_statistics.ninety_fifth_percentile);\n",
       "        }\n",
       "        return &quot;-&quot;;\n",
       "      });\n",
       "\n",
       "      Handlebars.registerHelper(&quot;range&quot;, function (column) {\n",
       "        const feature = Object.values(column)[0]\n",
       "\n",
       "        if (feature.range &amp;&amp; typeof feature.range === &#x27;number&#x27;) {\n",
       "          if (isNaN(feature.range)){return &quot;-&quot;}\n",
       "          if (feature.range==null){return &quot;-&quot;}\n",
       "          return fixNumberTo(feature.range);\n",
       "        }\n",
       "        return &quot;-&quot;;\n",
       "      });\n",
       "\n",
       "      Handlebars.registerHelper(&quot;q3&quot;, function (column) {\n",
       "        const feature = Object.values(column)[0]\n",
       "\n",
       "        if (feature.quantile_statistics &amp;&amp; typeof feature.quantile_statistics.q3 === &#x27;number&#x27;) {\n",
       "          if (isNaN(feature.quantile_statistics.q3)){return &quot;-&quot;}\n",
       "          if (feature.quantile_statistics.q3==null){return &quot;-&quot;}\n",
       "          return fixNumberTo(feature.quantile_statistics.q3);\n",
       "        }\n",
       "        return &quot;-&quot;;\n",
       "      });\n",
       "\n",
       "      Handlebars.registerHelper(&quot;q1&quot;, function (column) {\n",
       "        const feature = Object.values(column)[0]\n",
       "\n",
       "        if (feature.quantile_statistics &amp;&amp; typeof feature.quantile_statistics.q1 === &#x27;number&#x27;) {\n",
       "          if (isNaN(feature.quantile_statistics.q1)){return &quot;-&quot;}\n",
       "          if (feature.quantile_statistics.q1==null){return &quot;-&quot;}\n",
       "          return fixNumberTo(feature.quantile_statistics.q1);\n",
       "        }\n",
       "        return &quot;-&quot;;\n",
       "      });\n",
       "\n",
       "      Handlebars.registerHelper(&quot;getSum&quot;, function (column) {\n",
       "        const feature = Object.values(column)[0]\n",
       "\n",
       "        if (feature.descriptive_statistics &amp;&amp; typeof feature.descriptive_statistics.sum === &#x27;number&#x27;) {\n",
       "          if (isNaN(feature.descriptive_statistics.sum)){return &quot;-&quot;}\n",
       "          if (feature.descriptive_statistics.sum==null){return &quot;-&quot;}\n",
       "          return fixNumberTo(feature.descriptive_statistics.sum,2);\n",
       "        }\n",
       "        return &quot;-&quot;;\n",
       "      });\n",
       "\n",
       "      Handlebars.registerHelper(&quot;iqr&quot;, function (column) {\n",
       "        const feature = Object.values(column)[0]\n",
       "\n",
       "        if (feature.quantile_statistics &amp;&amp; typeof feature.quantile_statistics.iqr === &#x27;number&#x27; ) {\n",
       "          if (isNaN(feature.quantile_statistics.iqr)){return &quot;-&quot;}\n",
       "          if (feature.quantile_statistics.iqr==null){return &quot;-&quot;}\n",
       "          return fixNumberTo(feature.quantile_statistics.iqr);\n",
       "        }\n",
       "        return &quot;-&quot;;\n",
       "      });\n",
       "\n",
       "\n",
       "      Handlebars.registerHelper(&quot;distinct&quot;, function (column) {\n",
       "        const feature = Object.values(column)[0]\n",
       "        const distinct_pct = feature.distinct\n",
       "\n",
       "        return fixNumberTo(distinct_pct,2);\n",
       "      });\n",
       "\n",
       "      Handlebars.registerHelper(&quot;missing&quot;, function (column) {\n",
       "        const feature = Object.values(column)[0]\n",
       "        if (feature.missing) {\n",
       "          return feature.missing;\n",
       "        }\n",
       "        return &quot;0&quot;;\n",
       "      });\n",
       "\n",
       "      Handlebars.registerHelper(&quot;mean&quot;, function (column) {\n",
       "        const feature = Object.values(column)[0]\n",
       "\n",
       "        if (feature.descriptive_statistics &amp;&amp; typeof feature.descriptive_statistics.mean === &#x27;number&#x27;) {\n",
       "          if (isNaN(feature.descriptive_statistics.mean)){return &quot;-&quot;}\n",
       "          if (feature.descriptive_statistics.mean==null){return &quot;-&quot;}\n",
       "          return fixNumberTo(feature.descriptive_statistics.mean);\n",
       "        }\n",
       "        return &quot;-&quot;;\n",
       "      });\n",
       "\n",
       "      Handlebars.registerHelper(&quot;stddev&quot;, function (column) {\n",
       "        const feature = Object.values(column)[0]\n",
       "\n",
       "        if (feature.descriptive_statistics &amp;&amp; typeof feature.descriptive_statistics.stddev === &#x27;number&#x27;) {\n",
       "          if (isNaN(feature.descriptive_statistics.stddev)){return &quot;-&quot;}\n",
       "          if (feature.descriptive_statistics.stddev==null){return &quot;-&quot;}\n",
       "          return fixNumberTo(feature.descriptive_statistics.stddev);\n",
       "        }\n",
       "        return &quot;-&quot;;\n",
       "      });\n",
       "\n",
       "      Handlebars.registerHelper(&quot;minimum&quot;, function (column) {\n",
       "        const feature = Object.values(column)[0]\n",
       "        if (typeof feature.min === &#x27;number&#x27;) {\n",
       "          if (isNaN(feature.min)){return &quot;-&quot;}\n",
       "          if (feature.min==null){return &quot;-&quot;}\n",
       "          return fixNumberTo(feature.min);\n",
       "        }\n",
       "        return &quot;-&quot;;\n",
       "      });\n",
       "\n",
       "      Handlebars.registerHelper(&quot;maximum&quot;, function (column) {\n",
       "        const feature = Object.values(column)[0]\n",
       "\n",
       "        if (typeof feature.max === &#x27;number&#x27;) {\n",
       "          if (isNaN(feature.max)){return &quot;-&quot;}\n",
       "          if (feature.max==null){return &quot;-&quot;}\n",
       "          return fixNumberTo(feature.max);\n",
       "        }\n",
       "        return &quot;-&quot;;\n",
       "      });\n",
       "\n",
       "      // Handlebars.registerHelper(&quot;getProfileTimeStamp&quot;, function (column) {\n",
       "      //   return formatLabelDate(+column.properties.dataTimestamp)\n",
       "      // });\n",
       "\n",
       "      // Handlebars.registerHelper(&quot;getProfileName&quot;, function (column) {\n",
       "      //   return column.properties.tags.name\n",
       "      // });\n",
       "\n",
       "      Handlebars.registerHelper(&quot;featureName&quot;, function (column) {\n",
       "        const featureName = Object.keys(column)[0]\n",
       "        return featureName\n",
       "      });\n",
       "    }\n",
       "\n",
       "    function initHandlebarsTemplate() {\n",
       "      // Replace this context with JSON from .py file\n",
       "      const context = {&quot;density&quot;: {&quot;total_count&quot;: 408, &quot;missing&quot;: 0, &quot;distinct&quot;: 55.88238444546564, &quot;min&quot;: 0.99007, &quot;max&quot;: 1.0032, &quot;range&quot;: 0.013130000000000086, &quot;quantile_statistics&quot;: {&quot;fifth_percentile&quot;: 0.9922, &quot;iqr&quot;: 0.0023400000000000087, &quot;q1&quot;: 0.99396, &quot;median&quot;: 0.99516, &quot;q3&quot;: 0.9963, &quot;ninety_fifth_percentile&quot;: 0.9994}, &quot;descriptive_statistics&quot;: {&quot;stddev&quot;: 0.0021784570136347352, &quot;coefficient_of_variation&quot;: 0.002188682344428877, &quot;sum&quot;: 406.09385999999995, &quot;variance&quot;: 4.745674960254368e-06, &quot;mean&quot;: 0.995328088235294}}};\n",
       "      // Config handlebars and pass data to HBS template\n",
       "      const source = document.getElementById(&quot;entry-template&quot;).innerHTML;\n",
       "      const template = Handlebars.compile(source);\n",
       "      const html = template(context);\n",
       "      const target = document.getElementById(&quot;generated-html&quot;);\n",
       "      target.innerHTML = html;\n",
       "    }\n",
       "\n",
       "    // Invoke functions -- keep in mind invokation order\n",
       "    registerHandlebarHelperFunctions();\n",
       "    initHandlebarsTemplate();\n",
       "  &lt;/script&gt;\n",
       "&lt;/html&gt;\n",
       "\" width=100% height=650px\n",
       "        frameBorder=0></iframe><br><div></div><iframe srcdoc=\"&lt;!DOCTYPE html&gt;\n",
       "&lt;html lang=&quot;en&quot;&gt;\n",
       "  &lt;head&gt;\n",
       "    &lt;meta charset=&quot;UTF-8&quot; /&gt;\n",
       "    &lt;meta http-equiv=&quot;X-UA-Compatible&quot; content=&quot;IE=edge&quot; /&gt;\n",
       "    &lt;meta name=&quot;viewport&quot; content=&quot;width=device-width, initial-scale=1.0&quot; /&gt;\n",
       "    &lt;meta name=&quot;description&quot; content=&quot;&quot; /&gt;\n",
       "    &lt;meta name=&quot;author&quot; content=&quot;&quot; /&gt;\n",
       "\n",
       "    &lt;title&gt;Profile Visualizer | whylogs&lt;/title&gt;\n",
       "\n",
       "    &lt;link rel=&quot;icon&quot; href=&quot;images/whylabs-favicon.png&quot; type=&quot;image/png&quot; sizes=&quot;16x16&quot; /&gt;\n",
       "    &lt;link rel=&quot;preconnect&quot; href=&quot;https://fonts.googleapis.com&quot; /&gt;\n",
       "    &lt;link rel=&quot;preconnect&quot; href=&quot;https://fonts.gstatic.com&quot; crossorigin /&gt;\n",
       "    &lt;link href=&quot;https://fonts.googleapis.com/css2?family=Asap:wght@400;500;600;700&amp;display=swap&quot; rel=&quot;stylesheet&quot; /&gt;\n",
       "    &lt;link rel=&quot;preconnect&quot; href=&quot;https://fonts.gstatic.com&quot; /&gt;\n",
       "    &lt;link rel=&quot;stylesheet&quot; href=&quot;https://cdn.jsdelivr.net/npm/bootstrap@5.1.0/dist/css/bootstrap.min.css&quot; /&gt;\n",
       "\n",
       "    &lt;script\n",
       "      src=&quot;https://cdnjs.cloudflare.com/ajax/libs/handlebars.js/4.7.7/handlebars.min.js&quot;\n",
       "      integrity=&quot;sha512-RNLkV3d+aLtfcpEyFG8jRbnWHxUqVZozacROI4J2F1sTaDqo1dPQYs01OMi1t1w9Y2FdbSCDSQ2ZVdAC8bzgAg==&quot;\n",
       "      crossorigin=&quot;anonymous&quot;\n",
       "      referrerpolicy=&quot;no-referrer&quot;\n",
       "    &gt;&lt;/script&gt;\n",
       "\n",
       "    &lt;style type=&quot;text/css&quot;&gt;\n",
       "\n",
       "      /* Screen on smaller screens */\n",
       "      .no-responsive {\n",
       "        display: none;\n",
       "        position: fixed;\n",
       "        top: 0;\n",
       "        left: 0;\n",
       "        z-index: 1031;\n",
       "        width: 100vw;\n",
       "        height: 100vh;\n",
       "        background-color: var(--tealBackground);\n",
       "        display: flex;\n",
       "        align-items: center;\n",
       "        justify-content: center;\n",
       "      }\n",
       "\n",
       "      @media screen and (min-width: 1000px) {\n",
       "        .desktop-content {\n",
       "          display: block;\n",
       "        }\n",
       "        .no-responsive {\n",
       "          display: none;\n",
       "        }\n",
       "      }\n",
       "\n",
       "      .no-responsive__content {\n",
       "        max-width: 600px;\n",
       "        width: 100%;\n",
       "        padding: 0 24px;\n",
       "      }\n",
       "\n",
       "      .no-responsive__title {\n",
       "        font-size: 96px;\n",
       "        font-weight: 300;\n",
       "        color: var(--brandSecondary900);\n",
       "        line-height: 1.167;\n",
       "      }\n",
       "\n",
       "      .no-responsive__text {\n",
       "        margin: 0;\n",
       "        font-size: 16px;\n",
       "        font-weight: 400;\n",
       "        color: var(--brandSecondary900);\n",
       "        line-height: 1.5;\n",
       "      }\n",
       "\n",
       "      .header-title {\n",
       "        font-size: 26px;\n",
       "        font-weight: 700;\n",
       "        color: #444444;\n",
       "      }\n",
       "\n",
       "      .statistics-header-title {\n",
       "        font-size: 20px;\n",
       "        font-weight: 700;\n",
       "        color: #444444;\n",
       "      }\n",
       "\n",
       "      .statistic-number-title {\n",
       "        font-family: Arial;\n",
       "        font-weight: normal;\n",
       "        font-size: 14px;\n",
       "        line-height: 20px;\n",
       "        color: #6C757D;\n",
       "      }\n",
       "\n",
       "      .statistic-number {\n",
       "        font-family: Arial;\n",
       "        font-weight: bold;\n",
       "        font-size: 20px;\n",
       "        line-height: 140%;\n",
       "        display: flex;\n",
       "        align-items: center;\n",
       "        color: #4F595B;\n",
       "      }\n",
       "\n",
       "      .full-summary-statistics-wrap {\n",
       "        padding: 20px;\n",
       "      }\n",
       "\n",
       "      .statistics {\n",
       "        width: 100%;\n",
       "      }\n",
       "\n",
       "      .statistics-list {\n",
       "        width: 49% ;\n",
       "      }\n",
       "\n",
       "      .notif-circle-container{\n",
       "        position: absolute;\n",
       "        top: -8px;\n",
       "        right: -8px;\n",
       "        padding: 5.3px;\n",
       "        border-radius: 50%;\n",
       "        background-color: var(--brandSecondary100);\n",
       "        cursor: pointer;\n",
       "      }\n",
       "\n",
       "      .notif-circle {\n",
       "        position: absolute;\n",
       "        top: 2px;\n",
       "        right: 2px;\n",
       "        height: 16px;\n",
       "        width: 16px;\n",
       "        border-radius: 50%;\n",
       "        font-size: 10px;\n",
       "        color: #fff;\n",
       "        background-color: #ECB100;\n",
       "      }\n",
       "\n",
       "      .border-solid-gray {\n",
       "        border: 1px solid #CED4DA;\n",
       "        border-radius: 4px;\n",
       "        padding: 10px;\n",
       "      }\n",
       "\n",
       "      .display-flex {\n",
       "        display: flex;\n",
       "      }\n",
       "\n",
       "      .justify-content-space-between {\n",
       "        justify-content: space-between;\n",
       "      }\n",
       "\n",
       "      .justify-content-center {\n",
       "        justify-content: center;\n",
       "      }\n",
       "\n",
       "      .align-items-center {\n",
       "        align-items: center;\n",
       "      }\n",
       "\n",
       "      .padding-right-30 {\n",
       "        padding-right: 30px;\n",
       "      }\n",
       "\n",
       "      @media screen and (min-width: 500px) {\n",
       "        .desktop-content {\n",
       "          display: block;\n",
       "        }\n",
       "        .no-responsive {\n",
       "          display: none;\n",
       "        }\n",
       "      }\n",
       "    &lt;/style&gt;\n",
       "  &lt;/head&gt;\n",
       "\n",
       "  &lt;body id=&quot;generated-html&quot;&gt;&lt;/body&gt;\n",
       "\n",
       "  &lt;script id=&quot;entry-template&quot; type=&quot;text/x-handlebars-template&quot;&gt;\n",
       "    \n",
       "      &lt;div class=&quot;desktop-content&quot;&gt;\n",
       "        &lt;div class=&quot;full-summary-statistics-wrap&quot;&gt;\n",
       "          &lt;div class=&quot;full-summary-statistics&quot;&gt;\n",
       "            &lt;div class=&quot;mb-4&quot;&gt;\n",
       "                &lt;strong class=&quot;header-title&quot;&gt;{{featureName this}}: Summary Statistics&lt;/strong&gt;\n",
       "            &lt;/div&gt;\n",
       "            &lt;div class=&quot;statistics-wrap border-solid-gray display-flex justify-content-center mb-5&quot;&gt;\n",
       "              &lt;div class=&quot;statistics display-flex justify-content-space-between&quot;&gt;\n",
       "                  &lt;div class=&quot;statistic-item padding-right-30&quot;&gt;\n",
       "                    &lt;div class=&quot;statistic-number-title&quot;&gt;Distinct (%)&lt;/div&gt;\n",
       "                    &lt;div class=&quot;statistic-number&quot;&gt;{{distinct this}}&lt;/div&gt;\n",
       "                  &lt;/div&gt;\n",
       "                  &lt;div class=&quot;statistic-item padding-right-30&quot;&gt;\n",
       "                    &lt;div class=&quot;statistic-number-title&quot;&gt;Missing&lt;/div&gt;\n",
       "                    &lt;div class=&quot;statistic-number&quot;&gt;{{missing this}}&lt;/div&gt;\n",
       "                  &lt;/div&gt;\n",
       "                  &lt;div class=&quot;statistic-item padding-right-30&quot;&gt;\n",
       "                    &lt;div class=&quot;statistic-number-title&quot;&gt;Mean&lt;/div&gt;\n",
       "                    &lt;div class=&quot;statistic-number&quot;&gt;{{mean this}}&lt;/div&gt;\n",
       "                  &lt;/div&gt;\n",
       "                  &lt;div class=&quot;statistic-item padding-right-30&quot;&gt;\n",
       "                    &lt;div class=&quot;statistic-number-title&quot;&gt;Minimum&lt;/div&gt;\n",
       "                    &lt;div class=&quot;statistic-number&quot;&gt;{{minimum this}}&lt;/div&gt;\n",
       "                  &lt;/div&gt;\n",
       "                  &lt;div class=&quot;statistic-item padding-right-30&quot;&gt;\n",
       "                    &lt;div class=&quot;statistic-number-title&quot;&gt;Maximum&lt;/div&gt;\n",
       "                    &lt;div class=&quot;statistic-number&quot;&gt;{{maximum this}}&lt;/div&gt;\n",
       "                  &lt;/div&gt;\n",
       "              &lt;/div&gt;\n",
       "            &lt;/div&gt;\n",
       "            &lt;div&gt;\n",
       "              &lt;div class=&quot;display-flex justify-content-space-between&quot;&gt;\n",
       "                &lt;div class=&quot;statistics-list border-solid-gray&quot;&gt;\n",
       "                  &lt;div&gt;\n",
       "                    &lt;div class=&quot;mb-3&quot;&gt;\n",
       "                      &lt;strong class=&quot;statistics-header-title&quot;&gt;Quantile statistics&lt;/strong&gt;\n",
       "                    &lt;/div&gt;\n",
       "                    &lt;div&gt;\n",
       "                      &lt;div class=&quot;display-flex justify-content-space-between mb-2&quot;&gt;\n",
       "                        &lt;div&gt;5-th percentile&lt;/div&gt;\n",
       "                        &lt;div&gt;{{fifthPercentile this}}&lt;/div&gt;\n",
       "                      &lt;/div&gt;\n",
       "                      &lt;div class=&quot;display-flex justify-content-space-between mb-2&quot;&gt;\n",
       "                        &lt;div&gt;Q1&lt;/div&gt;\n",
       "                        &lt;div&gt;{{q1 this}}&lt;/div&gt;\n",
       "                      &lt;/div&gt;\n",
       "                      &lt;div class=&quot;display-flex justify-content-space-between mb-2&quot;&gt;\n",
       "                        &lt;div&gt;median&lt;/div&gt;\n",
       "                        &lt;div&gt;{{median this}}&lt;/div&gt;\n",
       "                      &lt;/div&gt;\n",
       "                      &lt;div class=&quot;display-flex justify-content-space-between mb-2&quot;&gt;\n",
       "                        &lt;div&gt;Q3&lt;/div&gt;\n",
       "                        &lt;div&gt;{{q3 this}}&lt;/div&gt;\n",
       "                      &lt;/div&gt;\n",
       "                      &lt;div class=&quot;display-flex justify-content-space-between mb-2&quot;&gt;\n",
       "                        &lt;div&gt;95-th percentile&lt;/div&gt;\n",
       "                        &lt;div&gt;{{ninetyFifthPercentile this}}&lt;/div&gt;\n",
       "                      &lt;/div&gt;\n",
       "                      &lt;div class=&quot;display-flex justify-content-space-between mb-2&quot;&gt;\n",
       "                        &lt;div&gt;Range&lt;/div&gt;\n",
       "                        &lt;div&gt;{{range this}}&lt;/div&gt;\n",
       "                      &lt;/div&gt;\n",
       "                      &lt;div class=&quot;display-flex justify-content-space-between mb-2&quot;&gt;\n",
       "                        &lt;div&gt;Interquartile range (IQR)&lt;/div&gt;\n",
       "                        &lt;div&gt;{{iqr this}}&lt;/div&gt;\n",
       "                      &lt;/div&gt;\n",
       "                    &lt;/div&gt;\n",
       "                  &lt;/div&gt;\n",
       "                &lt;/div&gt;\n",
       "                &lt;div class=&quot;statistics-list border-solid-gray&quot;&gt;\n",
       "                  &lt;div&gt;\n",
       "                    &lt;div class=&quot;mb-3&quot;&gt;\n",
       "                      &lt;strong class=&quot;statistics-header-title&quot;&gt;Descriptive statistics&lt;/strong&gt;\n",
       "                    &lt;/div&gt;\n",
       "                    &lt;div&gt;\n",
       "                      &lt;div class=&quot;display-flex justify-content-space-between mb-2&quot;&gt;\n",
       "                        &lt;div&gt;Standard deviation&lt;/div&gt;\n",
       "                        &lt;div&gt;{{stddev this}}&lt;/div&gt;\n",
       "                      &lt;/div&gt;\n",
       "                      &lt;div class=&quot;display-flex justify-content-space-between mb-2&quot;&gt;\n",
       "                        &lt;div&gt;Coefficient of variation (CV)&lt;/div&gt;\n",
       "                        &lt;div&gt;{{coefficientOfVariation this}}&lt;/div&gt;\n",
       "                      &lt;/div&gt;\n",
       "                      &lt;div class=&quot;display-flex justify-content-space-between mb-2&quot;&gt;\n",
       "                        &lt;div&gt;Sum&lt;/div&gt;\n",
       "                        &lt;div&gt;{{getSum this}}&lt;/div&gt;\n",
       "                      &lt;/div&gt;\n",
       "                      &lt;div class=&quot;display-flex justify-content-space-between mb-2&quot;&gt;\n",
       "                        &lt;div&gt;Variance&lt;/div&gt;\n",
       "                        &lt;div&gt;{{variance this}}&lt;/div&gt;\n",
       "                      &lt;/div&gt;\n",
       "                    &lt;/div&gt;\n",
       "                  &lt;/div&gt;\n",
       "                &lt;/div&gt;\n",
       "              &lt;/div&gt;\n",
       "            &lt;/div&gt;\n",
       "          &lt;/div&gt;\n",
       "        &lt;/div&gt;\n",
       "      &lt;/div&gt;\n",
       "      &lt;div class=&quot;no-responsive&quot;&gt;\n",
       "        &lt;div class=&quot;no-responsive__content&quot;&gt;\n",
       "          &lt;h1 class=&quot;no-responsive__title&quot;&gt;Hold on! :)&lt;/h1&gt;\n",
       "          &lt;p class=&quot;no-responsive__text&quot;&gt;\n",
       "            It looks like your current screen size or device is not yet supported by the WhyLabs Sandbox. The Sandbox is\n",
       "            best experienced on a desktop computer. Please try maximizing this window or switching to another device. We\n",
       "            are working on adding support for a larger variety of devices.\n",
       "          &lt;/p&gt;\n",
       "        &lt;/div&gt;\n",
       "      &lt;/div&gt;\n",
       "    \n",
       "  &lt;/script&gt;\n",
       "\n",
       "  &lt;script src=&quot;https://code.jquery.com/jquery-3.6.0.min.js&quot; integrity=&quot;sha256-/xUj+3OJU5yExlq6GSYGSHk7tPXikynS7ogEvDej/m4=&quot; crossorigin=&quot;anonymous&quot;&gt;&lt;/script&gt;\n",
       "\n",
       "  &lt;script src=&quot;https://cdnjs.cloudflare.com/ajax/libs/d3/6.7.0/d3.min.js&quot; integrity=&quot;sha512-cd6CHE+XWDQ33ElJqsi0MdNte3S+bQY819f7p3NUHgwQQLXSKjE4cPZTeGNI+vaxZynk1wVU3hoHmow3m089wA==&quot; crossorigin=&quot;anonymous&quot; referrerpolicy=&quot;no-referrer&quot;&gt;&lt;/script&gt;\n",
       "\n",
       "  &lt;script&gt;\n",
       "    function registerHandlebarHelperFunctions() {\n",
       "      //helper fun\n",
       "      // function formatLabelDate(timestamp) {\n",
       "      //   const date = new Date(timestamp);\n",
       "      //   const format = d3.timeFormat(&quot;%Y-%m-%d %I:%M:%S %p %Z&quot;);\n",
       "      //   return format(date);\n",
       "      // }\n",
       "\n",
       "      function fixNumberTo(number, decimals = 3) {\n",
       "        return parseFloat(number).toFixed(decimals);\n",
       "      }\n",
       "\n",
       "      Handlebars.registerHelper(&quot;variance&quot;, function (column) {\n",
       "        const feature = Object.values(column)[0]\n",
       "\n",
       "        if (feature.descriptive_statistics &amp;&amp; typeof feature.descriptive_statistics.variance === &#x27;number&#x27;) {\n",
       "          if (isNaN(feature.descriptive_statistics.variance)){return &quot;-&quot;}\n",
       "          if (feature.descriptive_statistics.variance==null){return &quot;-&quot;}\n",
       "          return fixNumberTo(feature.descriptive_statistics.variance,2);\n",
       "        }\n",
       "        return &quot;-&quot;;\n",
       "      });\n",
       "\n",
       "      Handlebars.registerHelper(&quot;coefficientOfVariation&quot;, function (column) {\n",
       "        const feature = Object.values(column)[0]\n",
       "\n",
       "        if (feature.descriptive_statistics &amp;&amp; typeof feature.descriptive_statistics.coefficient_of_variation === &#x27;number&#x27;) {\n",
       "          if (isNaN(feature.descriptive_statistics.coefficient_of_variation)){return &quot;-&quot;}\n",
       "          if (feature.descriptive_statistics.coefficient_of_variation==null){return &quot;-&quot;}\n",
       "          return fixNumberTo(feature.descriptive_statistics.coefficient_of_variation,2);\n",
       "        }\n",
       "        return &quot;-&quot;;\n",
       "      });\n",
       "\n",
       "      Handlebars.registerHelper(&quot;median&quot;, function (column) {\n",
       "        const feature = Object.values(column)[0]\n",
       "\n",
       "        if (feature.quantile_statistics &amp;&amp; typeof feature.quantile_statistics.median === &#x27;number&#x27;) {\n",
       "          if (isNaN(feature.quantile_statistics.median)){return &quot;-&quot;}\n",
       "          if (feature.quantile_statistics.median==null){return &quot;-&quot;}\n",
       "          return fixNumberTo(feature.quantile_statistics.median);\n",
       "        }\n",
       "        return &quot;-&quot;;\n",
       "      });\n",
       "\n",
       "      Handlebars.registerHelper(&quot;fifthPercentile&quot;, function (column) {\n",
       "        const feature = Object.values(column)[0]\n",
       "\n",
       "        if (feature.quantile_statistics &amp;&amp; typeof feature.quantile_statistics.fifth_percentile === &#x27;number&#x27;) {\n",
       "          if (isNaN(feature.quantile_statistics.fifth_percentile)){return &quot;-&quot;}\n",
       "          if (feature.quantile_statistics.fifth_percentile==null){return &quot;-&quot;}\n",
       "          return fixNumberTo(feature.quantile_statistics.fifth_percentile);\n",
       "        }\n",
       "        return &quot;-&quot;;\n",
       "      });\n",
       "\n",
       "      Handlebars.registerHelper(&quot;ninetyFifthPercentile&quot;, function (column) {\n",
       "        const feature = Object.values(column)[0]\n",
       "\n",
       "        if (feature.quantile_statistics &amp;&amp; typeof feature.quantile_statistics.ninety_fifth_percentile === &#x27;number&#x27;) {\n",
       "          if (isNaN(feature.quantile_statistics.ninety_fifth_percentile)){return &quot;-&quot;}\n",
       "          if (feature.quantile_statistics.ninety_fifth_percentile==null){return &quot;-&quot;}\n",
       "          return fixNumberTo(feature.quantile_statistics.ninety_fifth_percentile);\n",
       "        }\n",
       "        return &quot;-&quot;;\n",
       "      });\n",
       "\n",
       "      Handlebars.registerHelper(&quot;range&quot;, function (column) {\n",
       "        const feature = Object.values(column)[0]\n",
       "\n",
       "        if (feature.range &amp;&amp; typeof feature.range === &#x27;number&#x27;) {\n",
       "          if (isNaN(feature.range)){return &quot;-&quot;}\n",
       "          if (feature.range==null){return &quot;-&quot;}\n",
       "          return fixNumberTo(feature.range);\n",
       "        }\n",
       "        return &quot;-&quot;;\n",
       "      });\n",
       "\n",
       "      Handlebars.registerHelper(&quot;q3&quot;, function (column) {\n",
       "        const feature = Object.values(column)[0]\n",
       "\n",
       "        if (feature.quantile_statistics &amp;&amp; typeof feature.quantile_statistics.q3 === &#x27;number&#x27;) {\n",
       "          if (isNaN(feature.quantile_statistics.q3)){return &quot;-&quot;}\n",
       "          if (feature.quantile_statistics.q3==null){return &quot;-&quot;}\n",
       "          return fixNumberTo(feature.quantile_statistics.q3);\n",
       "        }\n",
       "        return &quot;-&quot;;\n",
       "      });\n",
       "\n",
       "      Handlebars.registerHelper(&quot;q1&quot;, function (column) {\n",
       "        const feature = Object.values(column)[0]\n",
       "\n",
       "        if (feature.quantile_statistics &amp;&amp; typeof feature.quantile_statistics.q1 === &#x27;number&#x27;) {\n",
       "          if (isNaN(feature.quantile_statistics.q1)){return &quot;-&quot;}\n",
       "          if (feature.quantile_statistics.q1==null){return &quot;-&quot;}\n",
       "          return fixNumberTo(feature.quantile_statistics.q1);\n",
       "        }\n",
       "        return &quot;-&quot;;\n",
       "      });\n",
       "\n",
       "      Handlebars.registerHelper(&quot;getSum&quot;, function (column) {\n",
       "        const feature = Object.values(column)[0]\n",
       "\n",
       "        if (feature.descriptive_statistics &amp;&amp; typeof feature.descriptive_statistics.sum === &#x27;number&#x27;) {\n",
       "          if (isNaN(feature.descriptive_statistics.sum)){return &quot;-&quot;}\n",
       "          if (feature.descriptive_statistics.sum==null){return &quot;-&quot;}\n",
       "          return fixNumberTo(feature.descriptive_statistics.sum,2);\n",
       "        }\n",
       "        return &quot;-&quot;;\n",
       "      });\n",
       "\n",
       "      Handlebars.registerHelper(&quot;iqr&quot;, function (column) {\n",
       "        const feature = Object.values(column)[0]\n",
       "\n",
       "        if (feature.quantile_statistics &amp;&amp; typeof feature.quantile_statistics.iqr === &#x27;number&#x27; ) {\n",
       "          if (isNaN(feature.quantile_statistics.iqr)){return &quot;-&quot;}\n",
       "          if (feature.quantile_statistics.iqr==null){return &quot;-&quot;}\n",
       "          return fixNumberTo(feature.quantile_statistics.iqr);\n",
       "        }\n",
       "        return &quot;-&quot;;\n",
       "      });\n",
       "\n",
       "\n",
       "      Handlebars.registerHelper(&quot;distinct&quot;, function (column) {\n",
       "        const feature = Object.values(column)[0]\n",
       "        const distinct_pct = feature.distinct\n",
       "\n",
       "        return fixNumberTo(distinct_pct,2);\n",
       "      });\n",
       "\n",
       "      Handlebars.registerHelper(&quot;missing&quot;, function (column) {\n",
       "        const feature = Object.values(column)[0]\n",
       "        if (feature.missing) {\n",
       "          return feature.missing;\n",
       "        }\n",
       "        return &quot;0&quot;;\n",
       "      });\n",
       "\n",
       "      Handlebars.registerHelper(&quot;mean&quot;, function (column) {\n",
       "        const feature = Object.values(column)[0]\n",
       "\n",
       "        if (feature.descriptive_statistics &amp;&amp; typeof feature.descriptive_statistics.mean === &#x27;number&#x27;) {\n",
       "          if (isNaN(feature.descriptive_statistics.mean)){return &quot;-&quot;}\n",
       "          if (feature.descriptive_statistics.mean==null){return &quot;-&quot;}\n",
       "          return fixNumberTo(feature.descriptive_statistics.mean);\n",
       "        }\n",
       "        return &quot;-&quot;;\n",
       "      });\n",
       "\n",
       "      Handlebars.registerHelper(&quot;stddev&quot;, function (column) {\n",
       "        const feature = Object.values(column)[0]\n",
       "\n",
       "        if (feature.descriptive_statistics &amp;&amp; typeof feature.descriptive_statistics.stddev === &#x27;number&#x27;) {\n",
       "          if (isNaN(feature.descriptive_statistics.stddev)){return &quot;-&quot;}\n",
       "          if (feature.descriptive_statistics.stddev==null){return &quot;-&quot;}\n",
       "          return fixNumberTo(feature.descriptive_statistics.stddev);\n",
       "        }\n",
       "        return &quot;-&quot;;\n",
       "      });\n",
       "\n",
       "      Handlebars.registerHelper(&quot;minimum&quot;, function (column) {\n",
       "        const feature = Object.values(column)[0]\n",
       "        if (typeof feature.min === &#x27;number&#x27;) {\n",
       "          if (isNaN(feature.min)){return &quot;-&quot;}\n",
       "          if (feature.min==null){return &quot;-&quot;}\n",
       "          return fixNumberTo(feature.min);\n",
       "        }\n",
       "        return &quot;-&quot;;\n",
       "      });\n",
       "\n",
       "      Handlebars.registerHelper(&quot;maximum&quot;, function (column) {\n",
       "        const feature = Object.values(column)[0]\n",
       "\n",
       "        if (typeof feature.max === &#x27;number&#x27;) {\n",
       "          if (isNaN(feature.max)){return &quot;-&quot;}\n",
       "          if (feature.max==null){return &quot;-&quot;}\n",
       "          return fixNumberTo(feature.max);\n",
       "        }\n",
       "        return &quot;-&quot;;\n",
       "      });\n",
       "\n",
       "      // Handlebars.registerHelper(&quot;getProfileTimeStamp&quot;, function (column) {\n",
       "      //   return formatLabelDate(+column.properties.dataTimestamp)\n",
       "      // });\n",
       "\n",
       "      // Handlebars.registerHelper(&quot;getProfileName&quot;, function (column) {\n",
       "      //   return column.properties.tags.name\n",
       "      // });\n",
       "\n",
       "      Handlebars.registerHelper(&quot;featureName&quot;, function (column) {\n",
       "        const featureName = Object.keys(column)[0]\n",
       "        return featureName\n",
       "      });\n",
       "    }\n",
       "\n",
       "    function initHandlebarsTemplate() {\n",
       "      // Replace this context with JSON from .py file\n",
       "      const context = {&quot;alcohol&quot;: {&quot;total_count&quot;: 408, &quot;missing&quot;: 0, &quot;distinct&quot;: 7.59803978178436, &quot;min&quot;: 11.066666666666698, &quot;max&quot;: 14.9, &quot;range&quot;: 3.833333333333302, &quot;quantile_statistics&quot;: {&quot;fifth_percentile&quot;: 11.1, &quot;iqr&quot;: 1.0, &quot;q1&quot;: 11.4, &quot;median&quot;: 11.8, &quot;q3&quot;: 12.4, &quot;ninety_fifth_percentile&quot;: 13.2}, &quot;descriptive_statistics&quot;: {&quot;stddev&quot;: 0.6824986635512768, &quot;coefficient_of_variation&quot;: 0.05725985668809312, &quot;sum&quot;: 4863.083333333334, &quot;variance&quot;: 0.4658044257492789, &quot;mean&quot;: 11.919321895424838}}};\n",
       "      // Config handlebars and pass data to HBS template\n",
       "      const source = document.getElementById(&quot;entry-template&quot;).innerHTML;\n",
       "      const template = Handlebars.compile(source);\n",
       "      const html = template(context);\n",
       "      const target = document.getElementById(&quot;generated-html&quot;);\n",
       "      target.innerHTML = html;\n",
       "    }\n",
       "\n",
       "    // Invoke functions -- keep in mind invokation order\n",
       "    registerHandlebarHelperFunctions();\n",
       "    initHandlebarsTemplate();\n",
       "  &lt;/script&gt;\n",
       "&lt;/html&gt;\n",
       "\" width=100% height=650px\n",
       "        frameBorder=0></iframe><br><div></div><iframe srcdoc=\"&lt;!DOCTYPE html&gt;\n",
       "&lt;html lang=&quot;en&quot;&gt;\n",
       "  &lt;head&gt;\n",
       "    &lt;meta charset=&quot;UTF-8&quot; /&gt;\n",
       "    &lt;meta http-equiv=&quot;X-UA-Compatible&quot; content=&quot;IE=edge&quot; /&gt;\n",
       "    &lt;meta name=&quot;viewport&quot; content=&quot;width=device-width, initial-scale=1.0&quot; /&gt;\n",
       "    &lt;meta name=&quot;description&quot; content=&quot;&quot; /&gt;\n",
       "    &lt;meta name=&quot;author&quot; content=&quot;&quot; /&gt;\n",
       "\n",
       "    &lt;title&gt;Profile Visualizer | whylogs&lt;/title&gt;\n",
       "\n",
       "    &lt;link rel=&quot;icon&quot; href=&quot;images/whylabs-favicon.png&quot; type=&quot;image/png&quot; sizes=&quot;16x16&quot; /&gt;\n",
       "    &lt;link rel=&quot;preconnect&quot; href=&quot;https://fonts.googleapis.com&quot; /&gt;\n",
       "    &lt;link rel=&quot;preconnect&quot; href=&quot;https://fonts.gstatic.com&quot; crossorigin /&gt;\n",
       "    &lt;link href=&quot;https://fonts.googleapis.com/css2?family=Asap:wght@400;500;600;700&amp;display=swap&quot; rel=&quot;stylesheet&quot; /&gt;\n",
       "    &lt;link rel=&quot;preconnect&quot; href=&quot;https://fonts.gstatic.com&quot; /&gt;\n",
       "    &lt;link rel=&quot;stylesheet&quot; href=&quot;https://cdn.jsdelivr.net/npm/bootstrap@5.1.0/dist/css/bootstrap.min.css&quot; /&gt;\n",
       "\n",
       "    &lt;script\n",
       "      src=&quot;https://cdnjs.cloudflare.com/ajax/libs/handlebars.js/4.7.7/handlebars.min.js&quot;\n",
       "      integrity=&quot;sha512-RNLkV3d+aLtfcpEyFG8jRbnWHxUqVZozacROI4J2F1sTaDqo1dPQYs01OMi1t1w9Y2FdbSCDSQ2ZVdAC8bzgAg==&quot;\n",
       "      crossorigin=&quot;anonymous&quot;\n",
       "      referrerpolicy=&quot;no-referrer&quot;\n",
       "    &gt;&lt;/script&gt;\n",
       "\n",
       "    &lt;style type=&quot;text/css&quot;&gt;\n",
       "\n",
       "      /* Screen on smaller screens */\n",
       "      .no-responsive {\n",
       "        display: none;\n",
       "        position: fixed;\n",
       "        top: 0;\n",
       "        left: 0;\n",
       "        z-index: 1031;\n",
       "        width: 100vw;\n",
       "        height: 100vh;\n",
       "        background-color: var(--tealBackground);\n",
       "        display: flex;\n",
       "        align-items: center;\n",
       "        justify-content: center;\n",
       "      }\n",
       "\n",
       "      @media screen and (min-width: 1000px) {\n",
       "        .desktop-content {\n",
       "          display: block;\n",
       "        }\n",
       "        .no-responsive {\n",
       "          display: none;\n",
       "        }\n",
       "      }\n",
       "\n",
       "      .no-responsive__content {\n",
       "        max-width: 600px;\n",
       "        width: 100%;\n",
       "        padding: 0 24px;\n",
       "      }\n",
       "\n",
       "      .no-responsive__title {\n",
       "        font-size: 96px;\n",
       "        font-weight: 300;\n",
       "        color: var(--brandSecondary900);\n",
       "        line-height: 1.167;\n",
       "      }\n",
       "\n",
       "      .no-responsive__text {\n",
       "        margin: 0;\n",
       "        font-size: 16px;\n",
       "        font-weight: 400;\n",
       "        color: var(--brandSecondary900);\n",
       "        line-height: 1.5;\n",
       "      }\n",
       "\n",
       "      .header-title {\n",
       "        font-size: 26px;\n",
       "        font-weight: 700;\n",
       "        color: #444444;\n",
       "      }\n",
       "\n",
       "      .statistics-header-title {\n",
       "        font-size: 20px;\n",
       "        font-weight: 700;\n",
       "        color: #444444;\n",
       "      }\n",
       "\n",
       "      .statistic-number-title {\n",
       "        font-family: Arial;\n",
       "        font-weight: normal;\n",
       "        font-size: 14px;\n",
       "        line-height: 20px;\n",
       "        color: #6C757D;\n",
       "      }\n",
       "\n",
       "      .statistic-number {\n",
       "        font-family: Arial;\n",
       "        font-weight: bold;\n",
       "        font-size: 20px;\n",
       "        line-height: 140%;\n",
       "        display: flex;\n",
       "        align-items: center;\n",
       "        color: #4F595B;\n",
       "      }\n",
       "\n",
       "      .full-summary-statistics-wrap {\n",
       "        padding: 20px;\n",
       "      }\n",
       "\n",
       "      .statistics {\n",
       "        width: 100%;\n",
       "      }\n",
       "\n",
       "      .statistics-list {\n",
       "        width: 49% ;\n",
       "      }\n",
       "\n",
       "      .notif-circle-container{\n",
       "        position: absolute;\n",
       "        top: -8px;\n",
       "        right: -8px;\n",
       "        padding: 5.3px;\n",
       "        border-radius: 50%;\n",
       "        background-color: var(--brandSecondary100);\n",
       "        cursor: pointer;\n",
       "      }\n",
       "\n",
       "      .notif-circle {\n",
       "        position: absolute;\n",
       "        top: 2px;\n",
       "        right: 2px;\n",
       "        height: 16px;\n",
       "        width: 16px;\n",
       "        border-radius: 50%;\n",
       "        font-size: 10px;\n",
       "        color: #fff;\n",
       "        background-color: #ECB100;\n",
       "      }\n",
       "\n",
       "      .border-solid-gray {\n",
       "        border: 1px solid #CED4DA;\n",
       "        border-radius: 4px;\n",
       "        padding: 10px;\n",
       "      }\n",
       "\n",
       "      .display-flex {\n",
       "        display: flex;\n",
       "      }\n",
       "\n",
       "      .justify-content-space-between {\n",
       "        justify-content: space-between;\n",
       "      }\n",
       "\n",
       "      .justify-content-center {\n",
       "        justify-content: center;\n",
       "      }\n",
       "\n",
       "      .align-items-center {\n",
       "        align-items: center;\n",
       "      }\n",
       "\n",
       "      .padding-right-30 {\n",
       "        padding-right: 30px;\n",
       "      }\n",
       "\n",
       "      @media screen and (min-width: 500px) {\n",
       "        .desktop-content {\n",
       "          display: block;\n",
       "        }\n",
       "        .no-responsive {\n",
       "          display: none;\n",
       "        }\n",
       "      }\n",
       "    &lt;/style&gt;\n",
       "  &lt;/head&gt;\n",
       "\n",
       "  &lt;body id=&quot;generated-html&quot;&gt;&lt;/body&gt;\n",
       "\n",
       "  &lt;script id=&quot;entry-template&quot; type=&quot;text/x-handlebars-template&quot;&gt;\n",
       "    \n",
       "      &lt;div class=&quot;desktop-content&quot;&gt;\n",
       "        &lt;div class=&quot;full-summary-statistics-wrap&quot;&gt;\n",
       "          &lt;div class=&quot;full-summary-statistics&quot;&gt;\n",
       "            &lt;div class=&quot;mb-4&quot;&gt;\n",
       "                &lt;strong class=&quot;header-title&quot;&gt;{{featureName this}}: Summary Statistics&lt;/strong&gt;\n",
       "            &lt;/div&gt;\n",
       "            &lt;div class=&quot;statistics-wrap border-solid-gray display-flex justify-content-center mb-5&quot;&gt;\n",
       "              &lt;div class=&quot;statistics display-flex justify-content-space-between&quot;&gt;\n",
       "                  &lt;div class=&quot;statistic-item padding-right-30&quot;&gt;\n",
       "                    &lt;div class=&quot;statistic-number-title&quot;&gt;Distinct (%)&lt;/div&gt;\n",
       "                    &lt;div class=&quot;statistic-number&quot;&gt;{{distinct this}}&lt;/div&gt;\n",
       "                  &lt;/div&gt;\n",
       "                  &lt;div class=&quot;statistic-item padding-right-30&quot;&gt;\n",
       "                    &lt;div class=&quot;statistic-number-title&quot;&gt;Missing&lt;/div&gt;\n",
       "                    &lt;div class=&quot;statistic-number&quot;&gt;{{missing this}}&lt;/div&gt;\n",
       "                  &lt;/div&gt;\n",
       "                  &lt;div class=&quot;statistic-item padding-right-30&quot;&gt;\n",
       "                    &lt;div class=&quot;statistic-number-title&quot;&gt;Mean&lt;/div&gt;\n",
       "                    &lt;div class=&quot;statistic-number&quot;&gt;{{mean this}}&lt;/div&gt;\n",
       "                  &lt;/div&gt;\n",
       "                  &lt;div class=&quot;statistic-item padding-right-30&quot;&gt;\n",
       "                    &lt;div class=&quot;statistic-number-title&quot;&gt;Minimum&lt;/div&gt;\n",
       "                    &lt;div class=&quot;statistic-number&quot;&gt;{{minimum this}}&lt;/div&gt;\n",
       "                  &lt;/div&gt;\n",
       "                  &lt;div class=&quot;statistic-item padding-right-30&quot;&gt;\n",
       "                    &lt;div class=&quot;statistic-number-title&quot;&gt;Maximum&lt;/div&gt;\n",
       "                    &lt;div class=&quot;statistic-number&quot;&gt;{{maximum this}}&lt;/div&gt;\n",
       "                  &lt;/div&gt;\n",
       "              &lt;/div&gt;\n",
       "            &lt;/div&gt;\n",
       "            &lt;div&gt;\n",
       "              &lt;div class=&quot;display-flex justify-content-space-between&quot;&gt;\n",
       "                &lt;div class=&quot;statistics-list border-solid-gray&quot;&gt;\n",
       "                  &lt;div&gt;\n",
       "                    &lt;div class=&quot;mb-3&quot;&gt;\n",
       "                      &lt;strong class=&quot;statistics-header-title&quot;&gt;Quantile statistics&lt;/strong&gt;\n",
       "                    &lt;/div&gt;\n",
       "                    &lt;div&gt;\n",
       "                      &lt;div class=&quot;display-flex justify-content-space-between mb-2&quot;&gt;\n",
       "                        &lt;div&gt;5-th percentile&lt;/div&gt;\n",
       "                        &lt;div&gt;{{fifthPercentile this}}&lt;/div&gt;\n",
       "                      &lt;/div&gt;\n",
       "                      &lt;div class=&quot;display-flex justify-content-space-between mb-2&quot;&gt;\n",
       "                        &lt;div&gt;Q1&lt;/div&gt;\n",
       "                        &lt;div&gt;{{q1 this}}&lt;/div&gt;\n",
       "                      &lt;/div&gt;\n",
       "                      &lt;div class=&quot;display-flex justify-content-space-between mb-2&quot;&gt;\n",
       "                        &lt;div&gt;median&lt;/div&gt;\n",
       "                        &lt;div&gt;{{median this}}&lt;/div&gt;\n",
       "                      &lt;/div&gt;\n",
       "                      &lt;div class=&quot;display-flex justify-content-space-between mb-2&quot;&gt;\n",
       "                        &lt;div&gt;Q3&lt;/div&gt;\n",
       "                        &lt;div&gt;{{q3 this}}&lt;/div&gt;\n",
       "                      &lt;/div&gt;\n",
       "                      &lt;div class=&quot;display-flex justify-content-space-between mb-2&quot;&gt;\n",
       "                        &lt;div&gt;95-th percentile&lt;/div&gt;\n",
       "                        &lt;div&gt;{{ninetyFifthPercentile this}}&lt;/div&gt;\n",
       "                      &lt;/div&gt;\n",
       "                      &lt;div class=&quot;display-flex justify-content-space-between mb-2&quot;&gt;\n",
       "                        &lt;div&gt;Range&lt;/div&gt;\n",
       "                        &lt;div&gt;{{range this}}&lt;/div&gt;\n",
       "                      &lt;/div&gt;\n",
       "                      &lt;div class=&quot;display-flex justify-content-space-between mb-2&quot;&gt;\n",
       "                        &lt;div&gt;Interquartile range (IQR)&lt;/div&gt;\n",
       "                        &lt;div&gt;{{iqr this}}&lt;/div&gt;\n",
       "                      &lt;/div&gt;\n",
       "                    &lt;/div&gt;\n",
       "                  &lt;/div&gt;\n",
       "                &lt;/div&gt;\n",
       "                &lt;div class=&quot;statistics-list border-solid-gray&quot;&gt;\n",
       "                  &lt;div&gt;\n",
       "                    &lt;div class=&quot;mb-3&quot;&gt;\n",
       "                      &lt;strong class=&quot;statistics-header-title&quot;&gt;Descriptive statistics&lt;/strong&gt;\n",
       "                    &lt;/div&gt;\n",
       "                    &lt;div&gt;\n",
       "                      &lt;div class=&quot;display-flex justify-content-space-between mb-2&quot;&gt;\n",
       "                        &lt;div&gt;Standard deviation&lt;/div&gt;\n",
       "                        &lt;div&gt;{{stddev this}}&lt;/div&gt;\n",
       "                      &lt;/div&gt;\n",
       "                      &lt;div class=&quot;display-flex justify-content-space-between mb-2&quot;&gt;\n",
       "                        &lt;div&gt;Coefficient of variation (CV)&lt;/div&gt;\n",
       "                        &lt;div&gt;{{coefficientOfVariation this}}&lt;/div&gt;\n",
       "                      &lt;/div&gt;\n",
       "                      &lt;div class=&quot;display-flex justify-content-space-between mb-2&quot;&gt;\n",
       "                        &lt;div&gt;Sum&lt;/div&gt;\n",
       "                        &lt;div&gt;{{getSum this}}&lt;/div&gt;\n",
       "                      &lt;/div&gt;\n",
       "                      &lt;div class=&quot;display-flex justify-content-space-between mb-2&quot;&gt;\n",
       "                        &lt;div&gt;Variance&lt;/div&gt;\n",
       "                        &lt;div&gt;{{variance this}}&lt;/div&gt;\n",
       "                      &lt;/div&gt;\n",
       "                    &lt;/div&gt;\n",
       "                  &lt;/div&gt;\n",
       "                &lt;/div&gt;\n",
       "              &lt;/div&gt;\n",
       "            &lt;/div&gt;\n",
       "          &lt;/div&gt;\n",
       "        &lt;/div&gt;\n",
       "      &lt;/div&gt;\n",
       "      &lt;div class=&quot;no-responsive&quot;&gt;\n",
       "        &lt;div class=&quot;no-responsive__content&quot;&gt;\n",
       "          &lt;h1 class=&quot;no-responsive__title&quot;&gt;Hold on! :)&lt;/h1&gt;\n",
       "          &lt;p class=&quot;no-responsive__text&quot;&gt;\n",
       "            It looks like your current screen size or device is not yet supported by the WhyLabs Sandbox. The Sandbox is\n",
       "            best experienced on a desktop computer. Please try maximizing this window or switching to another device. We\n",
       "            are working on adding support for a larger variety of devices.\n",
       "          &lt;/p&gt;\n",
       "        &lt;/div&gt;\n",
       "      &lt;/div&gt;\n",
       "    \n",
       "  &lt;/script&gt;\n",
       "\n",
       "  &lt;script src=&quot;https://code.jquery.com/jquery-3.6.0.min.js&quot; integrity=&quot;sha256-/xUj+3OJU5yExlq6GSYGSHk7tPXikynS7ogEvDej/m4=&quot; crossorigin=&quot;anonymous&quot;&gt;&lt;/script&gt;\n",
       "\n",
       "  &lt;script src=&quot;https://cdnjs.cloudflare.com/ajax/libs/d3/6.7.0/d3.min.js&quot; integrity=&quot;sha512-cd6CHE+XWDQ33ElJqsi0MdNte3S+bQY819f7p3NUHgwQQLXSKjE4cPZTeGNI+vaxZynk1wVU3hoHmow3m089wA==&quot; crossorigin=&quot;anonymous&quot; referrerpolicy=&quot;no-referrer&quot;&gt;&lt;/script&gt;\n",
       "\n",
       "  &lt;script&gt;\n",
       "    function registerHandlebarHelperFunctions() {\n",
       "      //helper fun\n",
       "      // function formatLabelDate(timestamp) {\n",
       "      //   const date = new Date(timestamp);\n",
       "      //   const format = d3.timeFormat(&quot;%Y-%m-%d %I:%M:%S %p %Z&quot;);\n",
       "      //   return format(date);\n",
       "      // }\n",
       "\n",
       "      function fixNumberTo(number, decimals = 3) {\n",
       "        return parseFloat(number).toFixed(decimals);\n",
       "      }\n",
       "\n",
       "      Handlebars.registerHelper(&quot;variance&quot;, function (column) {\n",
       "        const feature = Object.values(column)[0]\n",
       "\n",
       "        if (feature.descriptive_statistics &amp;&amp; typeof feature.descriptive_statistics.variance === &#x27;number&#x27;) {\n",
       "          if (isNaN(feature.descriptive_statistics.variance)){return &quot;-&quot;}\n",
       "          if (feature.descriptive_statistics.variance==null){return &quot;-&quot;}\n",
       "          return fixNumberTo(feature.descriptive_statistics.variance,2);\n",
       "        }\n",
       "        return &quot;-&quot;;\n",
       "      });\n",
       "\n",
       "      Handlebars.registerHelper(&quot;coefficientOfVariation&quot;, function (column) {\n",
       "        const feature = Object.values(column)[0]\n",
       "\n",
       "        if (feature.descriptive_statistics &amp;&amp; typeof feature.descriptive_statistics.coefficient_of_variation === &#x27;number&#x27;) {\n",
       "          if (isNaN(feature.descriptive_statistics.coefficient_of_variation)){return &quot;-&quot;}\n",
       "          if (feature.descriptive_statistics.coefficient_of_variation==null){return &quot;-&quot;}\n",
       "          return fixNumberTo(feature.descriptive_statistics.coefficient_of_variation,2);\n",
       "        }\n",
       "        return &quot;-&quot;;\n",
       "      });\n",
       "\n",
       "      Handlebars.registerHelper(&quot;median&quot;, function (column) {\n",
       "        const feature = Object.values(column)[0]\n",
       "\n",
       "        if (feature.quantile_statistics &amp;&amp; typeof feature.quantile_statistics.median === &#x27;number&#x27;) {\n",
       "          if (isNaN(feature.quantile_statistics.median)){return &quot;-&quot;}\n",
       "          if (feature.quantile_statistics.median==null){return &quot;-&quot;}\n",
       "          return fixNumberTo(feature.quantile_statistics.median);\n",
       "        }\n",
       "        return &quot;-&quot;;\n",
       "      });\n",
       "\n",
       "      Handlebars.registerHelper(&quot;fifthPercentile&quot;, function (column) {\n",
       "        const feature = Object.values(column)[0]\n",
       "\n",
       "        if (feature.quantile_statistics &amp;&amp; typeof feature.quantile_statistics.fifth_percentile === &#x27;number&#x27;) {\n",
       "          if (isNaN(feature.quantile_statistics.fifth_percentile)){return &quot;-&quot;}\n",
       "          if (feature.quantile_statistics.fifth_percentile==null){return &quot;-&quot;}\n",
       "          return fixNumberTo(feature.quantile_statistics.fifth_percentile);\n",
       "        }\n",
       "        return &quot;-&quot;;\n",
       "      });\n",
       "\n",
       "      Handlebars.registerHelper(&quot;ninetyFifthPercentile&quot;, function (column) {\n",
       "        const feature = Object.values(column)[0]\n",
       "\n",
       "        if (feature.quantile_statistics &amp;&amp; typeof feature.quantile_statistics.ninety_fifth_percentile === &#x27;number&#x27;) {\n",
       "          if (isNaN(feature.quantile_statistics.ninety_fifth_percentile)){return &quot;-&quot;}\n",
       "          if (feature.quantile_statistics.ninety_fifth_percentile==null){return &quot;-&quot;}\n",
       "          return fixNumberTo(feature.quantile_statistics.ninety_fifth_percentile);\n",
       "        }\n",
       "        return &quot;-&quot;;\n",
       "      });\n",
       "\n",
       "      Handlebars.registerHelper(&quot;range&quot;, function (column) {\n",
       "        const feature = Object.values(column)[0]\n",
       "\n",
       "        if (feature.range &amp;&amp; typeof feature.range === &#x27;number&#x27;) {\n",
       "          if (isNaN(feature.range)){return &quot;-&quot;}\n",
       "          if (feature.range==null){return &quot;-&quot;}\n",
       "          return fixNumberTo(feature.range);\n",
       "        }\n",
       "        return &quot;-&quot;;\n",
       "      });\n",
       "\n",
       "      Handlebars.registerHelper(&quot;q3&quot;, function (column) {\n",
       "        const feature = Object.values(column)[0]\n",
       "\n",
       "        if (feature.quantile_statistics &amp;&amp; typeof feature.quantile_statistics.q3 === &#x27;number&#x27;) {\n",
       "          if (isNaN(feature.quantile_statistics.q3)){return &quot;-&quot;}\n",
       "          if (feature.quantile_statistics.q3==null){return &quot;-&quot;}\n",
       "          return fixNumberTo(feature.quantile_statistics.q3);\n",
       "        }\n",
       "        return &quot;-&quot;;\n",
       "      });\n",
       "\n",
       "      Handlebars.registerHelper(&quot;q1&quot;, function (column) {\n",
       "        const feature = Object.values(column)[0]\n",
       "\n",
       "        if (feature.quantile_statistics &amp;&amp; typeof feature.quantile_statistics.q1 === &#x27;number&#x27;) {\n",
       "          if (isNaN(feature.quantile_statistics.q1)){return &quot;-&quot;}\n",
       "          if (feature.quantile_statistics.q1==null){return &quot;-&quot;}\n",
       "          return fixNumberTo(feature.quantile_statistics.q1);\n",
       "        }\n",
       "        return &quot;-&quot;;\n",
       "      });\n",
       "\n",
       "      Handlebars.registerHelper(&quot;getSum&quot;, function (column) {\n",
       "        const feature = Object.values(column)[0]\n",
       "\n",
       "        if (feature.descriptive_statistics &amp;&amp; typeof feature.descriptive_statistics.sum === &#x27;number&#x27;) {\n",
       "          if (isNaN(feature.descriptive_statistics.sum)){return &quot;-&quot;}\n",
       "          if (feature.descriptive_statistics.sum==null){return &quot;-&quot;}\n",
       "          return fixNumberTo(feature.descriptive_statistics.sum,2);\n",
       "        }\n",
       "        return &quot;-&quot;;\n",
       "      });\n",
       "\n",
       "      Handlebars.registerHelper(&quot;iqr&quot;, function (column) {\n",
       "        const feature = Object.values(column)[0]\n",
       "\n",
       "        if (feature.quantile_statistics &amp;&amp; typeof feature.quantile_statistics.iqr === &#x27;number&#x27; ) {\n",
       "          if (isNaN(feature.quantile_statistics.iqr)){return &quot;-&quot;}\n",
       "          if (feature.quantile_statistics.iqr==null){return &quot;-&quot;}\n",
       "          return fixNumberTo(feature.quantile_statistics.iqr);\n",
       "        }\n",
       "        return &quot;-&quot;;\n",
       "      });\n",
       "\n",
       "\n",
       "      Handlebars.registerHelper(&quot;distinct&quot;, function (column) {\n",
       "        const feature = Object.values(column)[0]\n",
       "        const distinct_pct = feature.distinct\n",
       "\n",
       "        return fixNumberTo(distinct_pct,2);\n",
       "      });\n",
       "\n",
       "      Handlebars.registerHelper(&quot;missing&quot;, function (column) {\n",
       "        const feature = Object.values(column)[0]\n",
       "        if (feature.missing) {\n",
       "          return feature.missing;\n",
       "        }\n",
       "        return &quot;0&quot;;\n",
       "      });\n",
       "\n",
       "      Handlebars.registerHelper(&quot;mean&quot;, function (column) {\n",
       "        const feature = Object.values(column)[0]\n",
       "\n",
       "        if (feature.descriptive_statistics &amp;&amp; typeof feature.descriptive_statistics.mean === &#x27;number&#x27;) {\n",
       "          if (isNaN(feature.descriptive_statistics.mean)){return &quot;-&quot;}\n",
       "          if (feature.descriptive_statistics.mean==null){return &quot;-&quot;}\n",
       "          return fixNumberTo(feature.descriptive_statistics.mean);\n",
       "        }\n",
       "        return &quot;-&quot;;\n",
       "      });\n",
       "\n",
       "      Handlebars.registerHelper(&quot;stddev&quot;, function (column) {\n",
       "        const feature = Object.values(column)[0]\n",
       "\n",
       "        if (feature.descriptive_statistics &amp;&amp; typeof feature.descriptive_statistics.stddev === &#x27;number&#x27;) {\n",
       "          if (isNaN(feature.descriptive_statistics.stddev)){return &quot;-&quot;}\n",
       "          if (feature.descriptive_statistics.stddev==null){return &quot;-&quot;}\n",
       "          return fixNumberTo(feature.descriptive_statistics.stddev);\n",
       "        }\n",
       "        return &quot;-&quot;;\n",
       "      });\n",
       "\n",
       "      Handlebars.registerHelper(&quot;minimum&quot;, function (column) {\n",
       "        const feature = Object.values(column)[0]\n",
       "        if (typeof feature.min === &#x27;number&#x27;) {\n",
       "          if (isNaN(feature.min)){return &quot;-&quot;}\n",
       "          if (feature.min==null){return &quot;-&quot;}\n",
       "          return fixNumberTo(feature.min);\n",
       "        }\n",
       "        return &quot;-&quot;;\n",
       "      });\n",
       "\n",
       "      Handlebars.registerHelper(&quot;maximum&quot;, function (column) {\n",
       "        const feature = Object.values(column)[0]\n",
       "\n",
       "        if (typeof feature.max === &#x27;number&#x27;) {\n",
       "          if (isNaN(feature.max)){return &quot;-&quot;}\n",
       "          if (feature.max==null){return &quot;-&quot;}\n",
       "          return fixNumberTo(feature.max);\n",
       "        }\n",
       "        return &quot;-&quot;;\n",
       "      });\n",
       "\n",
       "      // Handlebars.registerHelper(&quot;getProfileTimeStamp&quot;, function (column) {\n",
       "      //   return formatLabelDate(+column.properties.dataTimestamp)\n",
       "      // });\n",
       "\n",
       "      // Handlebars.registerHelper(&quot;getProfileName&quot;, function (column) {\n",
       "      //   return column.properties.tags.name\n",
       "      // });\n",
       "\n",
       "      Handlebars.registerHelper(&quot;featureName&quot;, function (column) {\n",
       "        const featureName = Object.keys(column)[0]\n",
       "        return featureName\n",
       "      });\n",
       "    }\n",
       "\n",
       "    function initHandlebarsTemplate() {\n",
       "      // Replace this context with JSON from .py file\n",
       "      const context = {&quot;chlorides&quot;: {&quot;total_count&quot;: 408, &quot;missing&quot;: 0, &quot;distinct&quot;: 21.813730257594944, &quot;min&quot;: 0.012, &quot;max&quot;: 0.23, &quot;range&quot;: 0.218, &quot;quantile_statistics&quot;: {&quot;fifth_percentile&quot;: 0.046, &quot;iqr&quot;: 0.025999999999999995, &quot;q1&quot;: 0.06, &quot;median&quot;: 0.071, &quot;q3&quot;: 0.086, &quot;ninety_fifth_percentile&quot;: 0.12}, &quot;descriptive_statistics&quot;: {&quot;stddev&quot;: 0.024213181268290383, &quot;coefficient_of_variation&quot;: 0.3226526212509791, &quot;sum&quot;: 30.618, &quot;variance&quot;: 0.0005862781471310883, &quot;mean&quot;: 0.07504411764705882}}};\n",
       "      // Config handlebars and pass data to HBS template\n",
       "      const source = document.getElementById(&quot;entry-template&quot;).innerHTML;\n",
       "      const template = Handlebars.compile(source);\n",
       "      const html = template(context);\n",
       "      const target = document.getElementById(&quot;generated-html&quot;);\n",
       "      target.innerHTML = html;\n",
       "    }\n",
       "\n",
       "    // Invoke functions -- keep in mind invokation order\n",
       "    registerHandlebarHelperFunctions();\n",
       "    initHandlebarsTemplate();\n",
       "  &lt;/script&gt;\n",
       "&lt;/html&gt;\n",
       "\" width=100% height=650px\n",
       "        frameBorder=0></iframe>"
      ],
      "text/plain": [
       "<IPython.core.display.HTML object>"
      ]
     },
     "execution_count": 19,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "visualization.feature_statistics(feature_name=[\"density\",\"alcohol\",\"chlorides\"], profile=\"target\")\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Looks like we have 72 distinct values for `citric acid`, ranging from 0 to 0.79. We can also see the 10 missing values injected earlier."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Downloading the Visualization Output"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "All of the previous visualizations can be downloaded in `HTML` format for further inspection. Just run:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {},
   "outputs": [],
   "source": [
    "import os\n",
    "os.getcwd()\n",
    "visualization.write(\n",
    "    rendered_html=visualization.profile_summary(),\n",
    "    html_file_name=os.getcwd() + \"/example\",\n",
    ")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "We're downloading the constraints report here, but you can simply replace it for your preferred visualization. "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## References"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "- https://www.kaggle.com/uciml/red-wine-quality-cortez-et-al-2009\n",
    "\n",
    "- https://www.kaggle.com/vishalyo990/prediction-of-quality-of-wine\n",
    "\n",
    "- https://medium.com/data-from-the-trenches/a-primer-on-data-drift-18789ef252a6"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3.8.10 ('.venv': poetry)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.8.10"
  },
  "orig_nbformat": 4,
  "vscode": {
   "interpreter": {
    "hash": "5dd5901cadfd4b29c2aaf95ecd29c0c3b10829ad94dcfe59437dbee391154aea"
   }
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}