Skip to content

What-If Scenario Forecasting, Live Demo ​

A what-if simulator is a forecast whose input data is a function of a few user-controlled drivers. Datastripes doesn't need a special API for this: derive the scenario dataset from the drivers, hand it to executeForecast() (or to a component), and the engine re-forecasts in the browser.

The demo below uses daily sales with two exogenous columns (marketing spend and discount rate). Each slider rewrites the historical rows before they reach the engine, and the KPI deck and chart from @datastripes/forecast/vue re-render from the new forecast.

How it works ​

  1. Drivers are plain state. The three sliders are ordinary reactive values, nothing Datastripes-specific.
  2. The scenario is derived data. A computed value rewrites each historical row (Marketing_Spend, Discount_Pct, and the Gross_Sales it implies) from the current drivers. The data can stay a CSV string: the engine parses it and auto-discovers Date as the time column and Gross_Sales as the target.
  3. Re-forecast on change. Whenever the scenario changes, call executeForecast() again and render the newest result. Because runs are asynchronous, keep only the latest one so a slow run can't overwrite a newer scenario.

The scenario formula in this demo (sales × trend + Δspend × 2.2) is an illustrative assumption for the demo, not something the library computes.

Source (Vue) ​

vue
<script setup>
import { computed, onMounted, ref, shallowRef, watch } from 'vue';
import { executeForecast } from '@datastripes/forecast';
import { DatastripesKpiDeck, DatastripesForecastChart } from '@datastripes/forecast/vue';

const adSpendShockPct = ref(25);
const scenarioCsv = computed(() => applyScenario(RAW_CSV_SALES, adSpendShockPct.value));

const result = shallowRef(null);
let latestRun = 0;

async function runScenario() {
  const run = ++latestRun;
  const output = await executeForecast({ data: scenarioCsv.value, algorithm: 'prophet_lite', horizon: 35 });
  if (run === latestRun) result.value = output;
}

onMounted(() => {
  runScenario();
  watch(scenarioCsv, runScenario);
});
</script>

<template>
  <input v-model.number="adSpendShockPct" type="range" min="-50" max="100" step="5" />
  <template v-if="result">
    <DatastripesKpiDeck :forecast="result" />
    <DatastripesForecastChart :points="result.points" :license-status="result.licenseStatus" />
  </template>
</template>

Source (React) ​

In React, DatastripesForecast re-runs the forecast whenever its data prop changes, so the scenario only has to be memoized:

tsx
import { useMemo, useState } from 'react';
import { DatastripesForecast } from '@datastripes/forecast/react';

export function WhatIfScenario() {
  const [adSpendShockPct, setAdSpendShockPct] = useState(25);
  const scenarioCsv = useMemo(
    () => applyScenario(RAW_CSV_SALES, adSpendShockPct),
    [adSpendShockPct]
  );

  return (
    <>
      <input
        type="range" min={-50} max={100} step={5}
        value={adSpendShockPct}
        onChange={(e) => setAdSpendShockPct(Number(e.target.value))}
      />
      <DatastripesForecast
        data={scenarioCsv}
        algorithm="prophet_lite"
        horizon={35}
        customOptions={{ chart: { yAxisFormat: 'currency', yAxisPrefix: '€' } }}
      />
    </>
  );
}