Leaving Spotfire

A Spotfire to Power BI migration scoped from your DXP files and scripts, not your page count

We open every DXP analysis file, inventory the Information Links behind it, list every IronPython script and TERR data function it depends on, then rebuild the survivors as a star-schema semantic model with DAX — with marking, filtering schemes and Web Player delivery replaced by cross-filtering, slicers, bookmarks and the Power BI Service.

  • Microsoft-certified
  • Prepaid hours that never expire
  • US-based senior engineers
  • Scripts and data functions counted first
  • You own everything
Data Model Sales Date Product Region Customer

Representative dashboard — sample data

Where the work really sits

The scripts and data functions are the project. The charts are the easy part.

Most teams estimate this move by counting analyses, then discover the count was measuring the wrong thing. A Spotfire estate hides its real complexity in three places, and none of them appear in a page count: the Information Links that quietly define what "revenue" or "batch yield" means, the IronPython scripts wired to text-area buttons and document properties, and the TERR data functions doing statistics nobody has looked at in four years.

So we scope from those outward. How many distinct Information Links do your DXP files actually touch? How many scripts exist, and how many still do something? Which data functions are real analytics and which are an aggregation someone wrote in R because it was easier than a custom expression? That inventory sets the timeline, and on a script-light estate it usually shortens it.

What we translate

  • DXP analysis → PBIX
  • Information Links → Power Query
  • Custom expressions → DAX
  • IronPython → bookmarks & buttons
  • TERR data functions → DAX or dataflows
  • Marking → cross-filtering
  • Web Player → Power BI Service

Try us risk-free for 4 hours

Start with a block of prepaid Flex hours and, if you're unhappy within the first 4 hours, we refund you in full — no questions asked. The analysis and script inventory is the natural first task: it tells you the real size of the job before you commit a budget to it.

How we approach it

Six things we do differently on a script-first rebuild

Anyone can redraw a bar chart. The value is in what the scripts, expressions and Information Links were really doing — and in what quietly disagreed with itself across them.

Every DXP read as a specification

We work through each analysis file page by page and write down its data tables, calculated columns, custom expressions, document properties and dependencies. The file is evidence of what the business agreed on — it is not something to be converted automatically.

Every script and data function counted

The inventory lists each IronPython script and each TERR or Python data function in the estate, with what triggers it, what it touches and whether anyone still relies on it. Dead scripts are the single most common reason these projects are over-estimated.

A star schema, not a pile of related tables

Spotfire relations connect data tables so marking and filtering travel between them; Power BI relationships propagate filters so measures aggregate correctly across them. Those are different jobs, so the model gets reshaped in transit rather than copied across.

The Information Designer model mined, not discarded

Information Links carry years of agreed joins, filters and column definitions. We extract them into one list, show you where two links define the same measure differently, and you approve a single definition before it becomes a DAX measure.

Marking behaviour designed, not assumed

Analysts who live in Spotfire mark rows constantly. We record where marking merely highlights and where it genuinely drives a calculation, then design the replacement for each — because only the first case is covered by cross-highlighting out of the box.

Reconciled against the live analysis

Every rebuilt page is compared with its Spotfire original on the same filters and date range. Differences get explained line by line — and a few of them turn out to be defects in the original that we have just found.

What actually happens to a DXP analysis file?

A DXP is a single container holding the visualization layout, the data table definitions, calculated columns, document properties, filtering schemes, scripts and — if the analysis was saved with embedded data — the data itself. Power BI splits that into two things: a semantic model that holds tables, relationships and DAX, and a report that holds pages and visuals. Nothing reads a DXP and writes a PBIX, so the file becomes a specification rather than an input.

That split is the first real change your team will feel, and it is a gain. One model can serve several reports, so the definition of a metric stops being re-entered in each analysis. Microsoft's guidance on star schema design (opens in new tab) explains why the reshape matters more than the chart work — a narrow, well-related model compresses and queries far better than the wide tables a long-lived analysis accumulates.

Scope note: this page covers Spotfire analyses delivered through Spotfire Analyst and Web Player, whether you are on a self-hosted Spotfire Server or the hosted service. Bespoke applications built on the Spotfire JavaScript or .NET APIs are software projects rather than reporting work, and we would scope those separately rather than fold them into a report rebuild.

How do Spotfire concepts map to Power BI?

Here is the working map we build the plan from. It is deliberately dull — a good migration is one where nothing surprising happens after the estimate is signed.

Spotfire objects and their Power BI equivalents
Spotfire Power BI equivalent What changes in practice
DXP analysis file PBIX report plus a shared semantic model Layout and model separate, so one model can serve several reports instead of each analysis carrying its own
Spotfire Library folder Workspace and published app Library permissions become workspace roles and app audiences; folder structure usually simplifies on the way
Information Link Power Query query, or a Dataflow for shared logic A server-side reusable query becomes a documented transformation step you can see and version
Information Designer elements (columns, filters, joins, procedures) Star-schema tables, relationships and DAX measures The agreed semantic layer survives as a model; near-duplicate column elements collapse into one definition
In-database data connection DirectQuery, or a composite model Storage mode is decided per table rather than once for the whole analysis
Imported data table / SBDF file Import-mode table (VertiPaq) Loose SBDF extracts are usually traced back to the source and connected properly instead of re-imported
Calculated column and custom expression DAX measure, or a Power Query step Row-level logic moves to Power Query where it can; genuine aggregation becomes a measure instead of a column
OVER with node navigation (Previous, Parent, Intersect) DAX with CALCULATE and time intelligence Hierarchy-walking expressions become explicit filter context, which is more verbose but far easier to test
Document property and property control Slicer, field parameter or what-if parameter Text-area drop-downs that switched a measure become native field parameters with no script behind them
IronPython script (action control or property-change trigger) Bookmarks, buttons, field parameters, or DAX Power BI has no in-report scripting surface; each script is replaced by a native feature or declared out of scope
TERR or Python data function DAX measure, Power Query R/Python step, dataflow or Fabric notebook Aggregation moves to DAX; real statistics keep their code but run upstream of the report
Spotfire Statistics Services Scheduled dataflow or notebook writing results to a table A separate statistics server stops being infrastructure you run and patch
Marking Cross-highlighting, cross-filtering and drillthrough Highlighting is native; marking that feeds a calculation needs a designed replacement, usually a measure reading the selection
Filtering scheme Bookmarks over slicer and filter state Named filter states become named bookmarks; per-page filter scope becomes explicit rather than implicit
Filters panel (range, item, check box) Slicers and the filter pane The always-visible filter column usually becomes a smaller set of slicers people actually use
Spotfire Mod or custom visualization AppSource custom visual, or a native rebuild Each one is triaged individually; we never promise a like-for-like match we cannot ship
Information Link filtered by the current user Row-level security role Per-user filtering moves from the query to the model, where it can be tested by viewing as each role
Web Player Power BI Service Browser delivery without the Spotfire Server and node manager estate behind it
Automation Services job Scheduled refresh, subscriptions and paginated exports Scheduled opens and emailed PDFs become refresh schedules and subscriptions

The modeling half of that table is the same discipline covered on our Power BI data modeling and DAX page. Where Information Links are shared across many analyses, the reusable transformation layer is built once as a dataflow — Microsoft's introduction to dataflows (opens in new tab) covers how that reuse works. Where links are filtered per user today, our guide to Power BI row level security setup covers how we build and test the replacement roles.

What do we do with the IronPython scripts?

This is the question that decides whether your estate is a three-week job or a three-month one, and it is the reason a Spotfire migration is not interchangeable with a Tableau or Qlik one. Scripts in Spotfire are wired to text-area action controls and to document-property change triggers, and where a script has to react to a marking or filtering change it is normally reached indirectly — a data function or a property binding turns the interaction into a property change, and the property change fires the script. Untangling that chain is the work.

So every script gets read and sorted into one of four buckets. Interface behaviour — resetting filters, switching a page, showing and hiding visuals, toggling a measure — becomes bookmarks, buttons and field parameters, and Microsoft's documentation on report bookmarks (opens in new tab) covers most of what that bucket needs. Calculation becomes a DAX measure. Data preparation moves to Power Query or a dataflow. What is left is genuine application logic — writing back to a database, calling an external system, orchestrating a process — and that belongs in an application, not in a report. We name those explicitly in the inventory rather than discovering them in week three, because Power BI deliberately has no in-report scripting surface and pretending otherwise is how these projects go wrong.

And the TERR data functions?

Data functions are triaged on what they actually compute. A surprising share are aggregations, rankings or variance calculations written in R because a custom expression felt harder at the time; those become DAX measures and get faster in the process. The genuine analytics — forecasting, clustering, regression, design-of-experiments work — keeps its code, but the code moves out of the report and upstream, into a Power Query R or Python step, a scheduled dataflow, or a Fabric notebook that writes its results to a table the model reads. Either way the dependency on TERR and on Spotfire Statistics Services ends with the migration, which is usually a stated goal rather than a side effect.

Where the analytics workload is substantial enough to deserve its own platform rather than a refresh step, our Microsoft Fabric consulting work picks that up as a separate workstream with its own scope.

What does it cost and how long does it take?

Work runs on prepaid Flex hours that never expire: Starter $2,500, Growth $4,600, or Power $8,000, with hourly rates from $100 on the largest block. The analysis, script and data-function inventory usually fits inside a Starter block, and it is the task we recommend buying first, because it converts a vague replatform into a list of scoped items with hours against each one.

After that, cost follows script and data-function density far more than page count — forty clean analyses over three Information Links is a different job from twelve analyses carrying sixty scripts. Individual analyses typically ship within 3–5 business days of approval, and the migration runs as a sequence of those rather than one big-bang cutover. Running both platforms in parallel for a single reporting cycle is worth the overlap: people compare old and new on live data, and the Spotfire licences get handed back with nothing left stranded.

Who this is for

Analytics, engineering and finance teams running Spotfire — commonly in life sciences, energy, manufacturing and process industries, where it took hold for good reasons — with a renewal in sight and a Microsoft 365 or Azure estate already paid for. It is a poor fit for anyone wanting a like-for-like copy with no decisions made, because the duplicated expressions and the abandoned scripts are precisely the things worth resolving in transit. Mixed estates are normal, and each source platform has its own page for a reason: Tableau to Power BI migration is scoped from workbook triage and LOD expressions, Qlik to Power BI migration from the load script and the associative model, and SAP BusinessObjects to Power BI migration from the Universe outward. None of those estates hide their logic in a scripting layer the way a Spotfire estate does, which is why the plans genuinely differ. The broader Power BI migration service covers the Excel and SSRS routes on the same prepaid model.

What you get

  • A page-by-page inventory of every DXP analysis
  • Every IronPython script and data function listed with its trigger
  • Information Link logic captured as a single agreed definition set
  • A star-schema semantic model with tested DAX
  • Per-user Information Link filters rebuilt as RLS roles
  • Reconciliation against the live Spotfire output
3–5

business days per analysis

Phased

not big-bang

You

own everything

Start with the inventory and decide the rest once the real scope is visible. See Flex pricing.

How it works

From a folder of analyses to a model your team trusts

  1. 1

    Inventory the analyses, links and scripts

    We catalogue every DXP file page by page, trace the Information Links and data connections behind it, and list each IronPython script and TERR data function with its trigger and its dependants. You approve a rebuild, merge or retire call on each item before anything is built.

  2. 2

    Rebuild the model, then the pages

    Surviving content is rebuilt on one star-schema semantic model, with custom expressions rewritten as DAX measures and Information Link logic re-expressed in Power Query or a dataflow. Report pages, slicers and bookmarks follow the model, not the other way round.

  3. 3

    Reconcile, publish and hand over

    We compare each page to its Spotfire original, explain every variance, publish to your workspace with row-level security tested role by role, and walk your analysts through what marking, filtering schemes and property controls became.

Representative perspective

The script list was the uncomfortable part. We had sixty-one IronPython scripts across the estate and could account for maybe fifteen of them — the rest were from people who left years ago.
Analytics manager, specialty chemicals manufacturer

Representative perspective

Half our data functions turned out to be sums and rankings written in R. Knowing that before we scoped the work changed the budget conversation completely.
Director of data science, life sciences company

Find out what your analyses are really carrying

Tell us roughly how many DXP files you have, whether anyone still writes IronPython or data functions, and when the renewal lands. We'll scope the inventory task in hours so you know the size before committing.

FAQ

Questions teams ask before committing

No, and we would not trust a tool that claimed otherwise. A DXP packages the visualization layout, the data table definitions, calculated columns, document properties, scripts and often embedded data in Spotfire's own format. We read it as a specification instead: every page, expression, script and data function is listed, you decide what survives, and each surviving item is rebuilt deliberately in Power BI and reconciled against the Spotfire original.

Most of them stop existing, which is usually the right outcome. We inventory every script across the estate and sort each one into four buckets: user-interface behaviour that becomes bookmarks, buttons and field parameters; calculation that becomes a DAX measure; data preparation that moves to Power Query or a dataflow; and genuine application logic that belongs upstream of the report entirely. Power BI has no equivalent scripting surface inside a report, so anything left in the fourth bucket is called out before the estimate, not after.

Partly. Data functions that compute an aggregate, a ranking or a variance are almost always cheaper and faster as DAX measures. Ones doing real statistics — forecasting, clustering, regression — keep their R or Python code, but the code moves out of the report: into a Power Query R or Python step, a scheduled dataflow, or a Fabric notebook that writes results to a table the model reads. The result is that the maths keeps running without Spotfire Statistics Services under it.

Cross-highlighting and cross-filtering cover the everyday case: click a bar, every other visual on the page responds. Where marking does more than that — driving a details visualization, feeding a data function, or propagating across related data tables — the replacement is designed rather than assumed, usually as a drillthrough page or a DAX measure that reads the current selection. We identify those uses during the inventory because they are the ones that surprise people.

The databases stay exactly where they are. The Information Links do not, because they are a Spotfire Server construct that Power BI cannot read. What they contain is valuable, though: the joins, filters and column definitions your analysts agreed on over years. We treat the Information Designer model as the specification for the Power Query layer and the star schema, so the agreed logic survives even though the artefact does not.

The inventory takes days, not weeks, and it is what sets the rest. After approval, individual analyses typically ship within three to five business days each, running as a sequence rather than a single cutover. Estates heavy in data functions and scripts take longer than their page count suggests, which is exactly why we count scripts and data functions before we count pages.

Related work

This page covers the Spotfire path specifically — the DXP files, the Information Designer layer, the scripts and the data functions. Vendor webinars often bundle Spotfire with Tableau and Qlik as one "legacy visual analytics" story, but the three estates are scoped from completely different artefacts, so the plans are not interchangeable: see Tableau to Power BI migration for workbook and published-data-source triage, and Qlik to Power BI migration for load scripts, set analysis and Section Access. Estates whose governed layer is a vendor semantic model rather than a scripting layer are closer to SAP BusinessObjects to Power BI migration, which starts at the Universe. The broader migration to Power BI service handles Excel and SSRS on the same prepaid model. The rebuild itself leans on data modeling and DAX and report design, and once the estate is live a Power BI health check keeps refresh and performance honest. Every task is scoped before work begins from your prepaid block of senior-led hours — no project minimums, no change-order surprises, and hours are deducted only for work you approve.

Book a free demo

Get senior Power BI help, on demand

Tell us the task. We scope it, you approve, and a senior consultant delivers — typically in 3–5 business days. Prepaid hours that never expire.

  • Prepaid hours from $100/hour — and they never expire
  • Senior-led delivery — 20+ years on the Microsoft platform
  • Typical 3–5 business day turnaround
  • Full refund if you’re unhappy in your first 4 hours

The fastest way to reach us is the form — tell us the task and we'll reply within one business day.

All fields are required.

We reply within one business day. No newsletters, no drip campaigns.

Book a Free Demo