{"id":31652,"date":"2026-10-01T06:51:20","date_gmt":"2026-10-01T06:51:20","guid":{"rendered":"urn:uuid:6cf2694c-2465-40ec-a56d-b05ae3c606f1"},"modified":"2026-10-01T06:51:21","modified_gmt":"2026-10-01T06:51:21","slug":"creating-your-first-chart-from-morningstar-funds-data","status":"publish","type":"post","link":"https:\/\/www.highcharts.com\/blog\/post\/creating-your-first-chart-from-morningstar-funds-data\/","title":{"rendered":"Creating Your First Chart from Morningstar Funds Data"},"content":{"rendered":"\n<p><b>Guest post by&nbsp;J\u0119drzej Ruta<\/b>: Developer Highcharts Support Engineer.<\/p><br>\n\n<p>Morningstar is one of the most trusted names in financial data. But getting that data onto a screen has traditionally meant handling complex requests, and a mapping layer that someone has to maintain forever.<\/p>\n\n<p>The Highcharts connectors for Morningstar Direct Web Services (DWS) remove that detour. You configure your credentials once, pick the data you want, and the connector hands you a formatted data table that Highcharts can render directly, with easy access to raw data as well.<\/p>\n\n<p>In this tutorial we will go from an empty HTML file to a working chart built on Morningstar data. We will use the DWS bundle, which targets Morningstar&#8217;s newer API, and we will finish by looking at how the same few lines of setup unlock the rest of the DWS data catalogue.<\/p>\n\n<h2>What we will build<\/h2>\n\n<p>An equity sector chart showing how a fund&#8217;s stock holdings are spread across sectors &#8211; built with the <strong>Investment Details Connector<\/strong> and Highcharts, in three steps from an empty file.<\/p>\n\n<p>The connectors ship in two flavours, and they are not interchangeable:<\/p>\n\n<ul>\n    <li><strong><code>connectors-morningstar<\/code><\/strong> &#8211; the legacy Enterprise Component API, covering Security Details, Screeners, X-Ray, Risk Score, Performance, and more.<\/li>\n    <li><strong><code>connectors-morningstar-dws<\/code><\/strong> &#8211; the newer DWS API, covering the <strong>Investment Details API<\/strong> and the <strong>Time Series API<\/strong>, with more to come.<\/li>\n<\/ul>\n\n<p>This tutorial uses the DWS bundle throughout. Its connectors live under the <code>HighchartsConnectors.MorningstarDWS<\/code> namespace, while the legacy ones live under <code>HighchartsConnectors.Morningstar<\/code>.<\/p>\n\n<p>DWS is a broad service. Morningstar currently lists APIs, covering screeners, scenario analysis, portfolio X-Ray, performance, optimisation, risk scoring, and more. The connectors reach two of them: the Investment Details Connector we are about to use, which returns data views for a single investment, and the Time Series Connector for historical data such as performance and fees.<\/p>\n\n<h2>Building the sector breakdown chart<\/h2>\n\n<h3>Step 1: Load Highcharts and the DWS connectors<\/h3>\n\n<p>Create an <code>index.html<\/code> file. A sector breakdown is a snapshot rather than a time series, so Highcharts Core is all we need here:<\/p>\n\n<pre><code class=\"language-html\">&lt;!DOCTYPE html&gt;\n&lt;html&gt;\n    &lt;head&gt;\n        &lt;meta charset=\"UTF-8\" \/&gt;\n        &lt;title&gt;My First Morningstar Chart&lt;\/title&gt;\n        &lt;script src=\"https:\/\/code.highcharts.com\/highcharts.js\"&gt;&lt;\/script&gt;\n        &lt;script src=\"https:\/\/code.highcharts.com\/connectors\/morningstar\/connectors-morningstar-dws.js\"&gt;&lt;\/script&gt;\n    &lt;\/head&gt;\n    &lt;body&gt;\n        &lt;div id=\"container\"&gt;&lt;\/div&gt;\n        &lt;script src=\".\/demo.js\"&gt;&lt;\/script&gt;\n    &lt;\/body&gt;\n&lt;\/html&gt;<\/code><\/pre>\n\n<p>Loading the bundle registers the connectors with Highcharts as a side effect and exposes them on the global <code>HighchartsConnectors<\/code> object. That is all the wiring there is.<\/p>\n\n<p>If you are working in an app project rather than a plain HTML page, install the package and import it instead:<\/p>\n\n<pre><code class=\"language-bash\">npm install @highcharts\/connectors-morningstar<\/code><\/pre>\n\n<pre><code class=\"language-js\">import Highcharts from 'highcharts';\nimport { InvestmentsConnector } from '@highcharts\/connectors-morningstar\/dws';<\/code><\/pre>\n\n<p>One difference to keep in mind as you read on. The <code>&lt;script&gt;<\/code> tag exposes everything on the global <code>HighchartsConnectors<\/code> object, which is why this tutorial writes <code>new HighchartsConnectors.MorningstarDWS.InvestmentsConnector({ ... })<\/code>. An ES module sets no such global, so there you write <code>new InvestmentsConnector({ ... })<\/code> with whatever you imported. Everything else is the same. See <a href=\"https:\/\/www.highcharts.com\/docs\/getting-started\/installation\">Installation<\/a> for more on the two loading methods.<\/p>\n\n<h3>Step 2: Configure the Investment Details Connector<\/h3>\n\n<p>Now create <code>demo.js<\/code>. Because loading data is asynchronous, we will build the chart inside an <code>async<\/code> function and call it at the end of the file. The <code>InvestmentsConnector<\/code> describes a single security, and you choose what you want to know about it by naming one or more of the available <a href=\"https:\/\/www.highcharts.com\/docs\/morningstar\/dws\/investments-details-connector#available-data-converters\">converters<\/a>:<\/p>\n\n<pre><code class=\"language-js\">async function createChart () {\n    const connector = new HighchartsConnectors.MorningstarDWS.InvestmentsConnector({\n        api: {\n            access: {\n                token: 'your_access_token'\n            }\n        },\n        security: {\n            id: '0P00000FIA'\n        },\n        converters: {\n            EquitySectorsBreakdown: {}\n        }\n    });\n    ...<\/code><\/pre>\n\n<p>Three of those options deserve a closer look.<\/p>\n\n<p><strong><code>security<\/code><\/strong> takes a single <code>id<\/code> &#8211; the Investment Details API describes one investment at a time. The identifier above is a Morningstar <code>performanceId<\/code>.<\/p>\n\n<p><strong><code>converters<\/code><\/strong> is the heart of this connector. Rather than one connector per data type, a single instance can request several converters at once, and each one populates its own named data tables. Here we ask for just <code>EquitySectorsBreakdown<\/code>; the empty object is not a placeholder to fill in, since most converters need no options at all. Some accept <code>startDate<\/code> and <code>endDate<\/code> to bound a historical series:<\/p>\n\n<pre><code class=\"language-js\">converters: {\n    EquitySectorsBreakdown: {},\n    AssetAllocationBreakdown: {},\n    EquityStyleBox: {\n        startDate: '2025-01-01',\n        endDate: '2025-12-01'\n    }\n}<\/code><\/pre>\n\n<p>That is one request block and one <code>load()<\/code> for three datasets &#8211; a fund profile page with six panels needs one connector with six converters, not six connectors.<\/p>\n\n<p><strong><code>api.access<\/code><\/strong> carries your credentials. The <code>token<\/code> is a Morningstar access token, which the connector sends as an <code>Authorization: Bearer<\/code> header on every request. Issue it from your own backend rather than hard-coding it in the page, so the credentials never reach the browser. To learn more about authenticating yourself in Morningstar API, see the <a href=\"https:\/\/developer.morningstar.com\/direct-web-services\/documentation\/documentation\/get-started\/authentication\">authentication page<\/a>.<\/p>\n\n<pre><code class=\"language-js\">const { token } = await getToken();\n\nconst connector = new HighchartsConnectors.MorningstarDWS.InvestmentsConnector({\n    api: {\n        access: { token }\n    },\n    \/\/ ...security and converters as above\n});<\/code><\/pre>\n\n<h3>Step 3: Load the data and render the chart<\/h3>\n\n<p>This is the step where the connector&#8217;s design pays off. <code>EquitySectorsBreakdown<\/code> populates three data tables, already shaped for Highcharts, each retrieved by name:<\/p>\n\n<pre><code class=\"language-js\">await connector.load();<\/code><\/pre>\n\n<pre><code class=\"language-js\">const superSectorsTable = connector.getTable('EqSuperSectors'),\n    sectorsTable = connector.getTable('EqSectors'),\n    industriesTable = connector.getTable('EqIndustries');<\/code><\/pre>\n\n<p>The three tables are the same breakdown at increasing detail. <code>EqSuperSectors<\/code> groups holdings into Morningstar&#8217;s three super sectors &#8211; cyclical, defensive, and sensitive. <code>EqSectors<\/code> splits those into the eleven sectors most readers will recognise, and <code>EqIndustries<\/code> goes one level deeper.<\/p>\n\n<p>Every table has a <code>Type<\/code> column naming its categories, plus one column per measure: <code>PercLong<\/code>, <code>PercLongRescaled<\/code>, <code>PercNet<\/code>, and <code>PercShort<\/code>.<\/p>\n\n<p>Hand the table to the chart with the <code>dataTable<\/code> option, then let each series pick its columns through <code>dataMapping<\/code>: <code>name<\/code> for the category label, <code>y<\/code> for the value. The series name defaults to the column it maps to, so there is nothing else to wire up:<\/p>\n\n<pre><code class=\"language-js\">    ...\n    Highcharts.chart('container', {\n        chart: {\n            type: 'column'\n        },\n        title: {\n            text: 'Equity Sectors Breakdown'\n        },\n        dataTable: sectorsTable,\n        xAxis: {\n            type: 'category'\n        },\n        yAxis: {\n            title: {\n                text: 'Sector weight'\n            },\n            labels: {\n                format: '{value}%'\n            }\n        },\n        tooltip: {\n            valueSuffix: '%',\n            valueDecimals: 2\n        },\n        series: [{\n            dataMapping: { name: 'Type', y: 'PercLong' }\n        }, {\n            dataMapping: { name: 'Type', y: 'PercNet' }\n        }]\n    });\n}\n\ncreateChart();<\/code><\/pre>\n\n<p>That is your first chart from Morningstar data: one connector, one converter, and no mapping layer in between.<\/p>\n\n<p><a href=\"https:\/\/jsfiddle.net\/BlackLabel\/fayw7q0o\/\">Check the live outcome here.<\/a><\/p>\n\n<p><a href=\"https:\/\/api.highcharts.com\/highcharts\/dataTable\"><code>dataTable<\/code><\/a> and <a href=\"https:\/\/api.highcharts.com\/highcharts\/plotOptions.series.dataMapping\"><code>dataMapping<\/code><\/a> need Highcharts 13 or newer. On Highcharts 12, read the columns yourself and assign them to <code>series.data<\/code> instead &#8211; e.g. <code>sectorsTable.getColumn('PercLong')<\/code> in place of the mapping above.<\/p>\n\n<p>One more detail worth knowing: the connector exposes the security&#8217;s <code>performanceId<\/code> through its metadata, which is handy for a subtitle:<\/p>\n\n<pre><code class=\"language-js\">subtitle: {\n    text: `Performance ID: ${connector.metadata.EquitySectorsBreakdown.performanceId}`\n}<\/code><\/pre>\n\n<h2>What else DWS gives you<\/h2>\n\n<p><code>EquitySectorsBreakdown<\/code> is one of eight converters currently available on the Investment Details Connector. The rest follow the identical pattern &#8211; name the converter, read its tables:<\/p>\n\n<ul>\n    <li><strong>Asset Allocation Breakdown<\/strong> &#8211; allocation across asset classes, with general, Canadian, and underlying-instrument views.<\/li>\n    <li><strong>Country and Regional Exposure Breakdown<\/strong> &#8211; geographic exposure by region and country, for equity, fixed income, and revenue.<\/li>\n    <li><strong>Equity Sectors Breakdown<\/strong> &#8211; sector exposure at super-sector, sector, and industry levels, in the <code>EqSuperSectors<\/code>, <code>EqSectors<\/code>, and <code>EqIndustries<\/code> tables.<\/li>\n    <li><strong>Fixed Income Sectors Breakdown<\/strong> &#8211; fixed-income sector exposure across super, primary, and secondary sectors, plus per-region tables.<\/li>\n    <li><strong>Equity Style Box<\/strong> &#8211; Morningstar&#8217;s proprietary style box and stock grades, as both a current grid and a historical series.<\/li>\n    <li><strong>Equity Residual Risk and Return Sensitivity<\/strong> &#8211; Alpha, Beta, and RSquare at daily and monthly granularity.<\/li>\n    <li><strong>Equity Aggregates Residual Risk and Return Sensitivity<\/strong> &#8211; aggregate residual-risk statistics with their company counts.<\/li>\n    <li><strong>Prospectus Fees<\/strong> &#8211; management, administration, and distribution fees, sales loads, and expense ratios.<\/li>\n<\/ul>\n\n<h2>The other connector: Time Series<\/h2>\n\n<p>Investment details are one half of what the connectors cover. The other is the <code>TimeSeriesConnector<\/code>, which targets Morningstar&#8217;s Time Series API and returns historical data for up to 25 securities in a single request.<\/p>\n\n<p>It follows the same three beats you just used &#8211; and, like the code above, it belongs inside an <code>async<\/code> function. Two things differ: instead of converters you pick data with a <code>category<\/code> and a <code>dataPoint<\/code>, and instead of one security you pass a list:<\/p>\n\n<pre><code class=\"language-js\">const growthConnector = new HighchartsConnectors.MorningstarDWS.TimeSeriesConnector({\n    api: {\n        access: {\n            token: 'your_access_token'\n        }\n    },\n    ids: [{\n        id: '0P00000FIA',\n        idType: 'performanceId'\n    }, {\n        id: '0P00002PB8',\n        idType: 'performanceId'\n    }],\n    category: 'performance',\n    dataPoint: 'growth',\n    startDate: '2024-10-30',\n    endDate: '2025-10-30',\n    currencyId: 'EUR'\n});\n\nawait growthConnector.load();<\/code><\/pre>\n\n<p><code>category<\/code> and <code>dataPoint<\/code> map directly onto Morningstar&#8217;s Time Series API paths: take the two segments immediately after <code>time-series\/v1\/<\/code>, so <code>...\/time-series\/v1\/performance\/growth\/<\/code> becomes <code>category: 'performance'<\/code> and <code>dataPoint: 'growth'<\/code>. Categories include <code>performance<\/code>, <code>fees-expenses<\/code>, <code>portfolio-holdings<\/code>, and many others with more to come in the future. <code>performanceId<\/code> is the default <code>idType<\/code>, so you can omit it, and <code>currencyId<\/code> takes an ISO 4217 code &#8211; worth setting explicitly when you compare funds domiciled in different markets, since it otherwise defaults to each investment&#8217;s own base currency.<\/p>\n\n<p>Reading the result differs from the tables above. There is a single table whose first column is <code>Date<\/code>, holding <code>yyyy-MM-dd<\/code> strings sorted ascending. Request one security and the values land in a <code>Value<\/code> column; request several and each is suffixed with that security&#8217;s <code>performanceId<\/code> &#8211; always the <code>performanceId<\/code>, whatever <code>idType<\/code> you asked with. The same pairing works here, with <code>x<\/code> taking the date column instead of <code>name<\/code>:<\/p>\n\n<pre><code class=\"language-js\">Highcharts.stockChart('container', {\n    dataTable: growthConnector.getTable(),\n    series: [{\n        name: 'Capital Group Global Equity Fund (LUX) B',\n        dataMapping: { x: 'Date', y: 'Value_0P00000FIA' }\n    }, {\n        name: 'Dodge &amp; Cox Stock Fund Class I (DODGX)',\n        dataMapping: { x: 'Date', y: 'Value_0P00002PB8' }\n    }]\n});<\/code><\/pre>\n\n<p>Both securities share one table, so each series names its own value column, and Highcharts Stock parses the <code>yyyy-MM-dd<\/code> strings into dates for you. Note the different bundle: a time series wants <code>highstock.js<\/code> rather than the <code>highcharts.js<\/code> we loaded in Step 1.<\/p>\n\n<h2>Two things that will save you time<\/h2>\n\n<p><strong>Develop against pre-fetched JSON.<\/strong> Both DWS connectors accept an <code>api.json<\/code> option that bypasses authentication and the network entirely, using a payload you supply. It takes priority over <code>postman<\/code> and online API settings, which makes it ideal for local development, demos, and tests where you do not want to burn API calls:<\/p>\n\n<pre><code class=\"language-js\">const connector = new HighchartsConnectors.MorningstarDWS.InvestmentsConnector({\n    api: {\n        json: {\n            AssetAllocationBreakdown: {\n                assetAllocationBreakdown: {\n                    assetAllocCashPercLong: 4.49556,\n                    assetAllocEquityPercLong: 95.50442\n                },\n                identifiers: {\n                    performanceId: '0P00000FIA'\n                },\n                metadata: {}\n            }\n        }\n    },\n    security: {\n        id: '0P00000FIA'\n    },\n    converters: {\n        AssetAllocationBreakdown: {}\n    }\n});<\/code><\/pre>\n\n<p>For multi-converter requests, key the object by converter name, exactly as above.<\/p>\n\n<p><strong>Set the region explicitly.<\/strong> Unless you say otherwise, the DWS connectors send their requests to Morningstar&#8217;s Americas endpoint. If your account is served by another region, set <code>api.url<\/code>:<\/p>\n\n<pre><code class=\"language-js\">api: {\n    url: 'https:\/\/www.emea-api.morningstar.com\/',\n    access: {\n        token: 'your_access_token'\n    }\n}<\/code><\/pre>\n\n<p>The three regional endpoints are <code>https:\/\/www.us-api.morningstar.com\/<\/code> (Americas, the default), <code>https:\/\/www.emea-api.morningstar.com\/<\/code>, and <code>https:\/\/www.apac-api.morningstar.com\/<\/code>.<\/p>\n\n<h2>Using the connectors with Dashboards<\/h2>\n\n<p>Everything above creates connectors by hand, which is the pattern for Highcharts Core and Stock. With Highcharts Dashboards you do not have to: loading a bundle registers the connectors with the Dashboards registry automatically, and they become available in the data pool like any other connector type. Reference them as <code>MorningstarDWSInvestments<\/code> and <code>MorningstarDWSTimeSeries<\/code>:<\/p>\n\n<pre><code class=\"language-js\">Dashboards.board('container', {\n    dataPool: {\n        connectors: [{\n            id: 'equity-sectors',\n            type: 'MorningstarDWSInvestments',\n            api: {\n                access: {\n                    token: 'your_access_token'\n                }\n            },\n            security: {\n                id: '0P00000FIA'\n            },\n            converters: {\n                EquitySectorsBreakdown: {}\n            }\n        }]\n    }\n    \/\/ ...gui and components\n});<\/code><\/pre>\n\n<p>Components then bind to a table by name through <code>dataTableKey<\/code>, so a Grid or chart reads the connector&#8217;s output the same way the chart above did &#8211; here you would get tables named <code>EqSuperSectors<\/code>, <code>EqSectors<\/code>, or <code>EqIndustries<\/code>.<\/p>\n\n<h2>More details and licensing<\/h2>\n\n<p>The full option reference for every connector and converter lives in the <a href=\"https:\/\/www.highcharts.com\/docs\/morningstar\/morningstar\">Morningstar connectors documentation<\/a>, and each converter page lists the demos that go with it.<\/p>\n\n<p>Using the connectors requires a Highcharts Partner Data License and a Morningstar Direct Web Services account. If you would like to talk through your specific use case, or see the connectors running against your own data, <a href=\"https:\/\/shop.highcharts.com\/contact\/partner-data\">reach out to our team<\/a>.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Guest post by&nbsp;J\u0119drzej Ruta: Developer Highcharts Support Engineer. Morningstar is one of the most trusted names in financial data. But getting that data onto a screen has traditionally meant handling complex requests, and a mapping layer that someone has to maintain forever. The Highcharts connectors for Morningstar Direct Web Services (DWS) remove that detour. You [&hellip;]<\/p>\n","protected":false},"author":32,"featured_media":31673,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"meta_title":"Create Your First Morningstar Funds Chart with Highcharts","meta_description":"Learn how to connect Morningstar DWS data to Highcharts and build your first fund chart using the Investment Details and Time Series connectors.","hc_selected_options":[],"footnotes":"","_members_access_role":[],"_members_access_error":""},"categories":[224],"tags":[788,1094,883,1122,824],"coauthors":[699],"class_list":["post-31652","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-post","tag-finance","tag-highcharts-core","tag-highcharts-stock","tag-morningstar","tag-react"],"_links":{"self":[{"href":"https:\/\/www.highcharts.com\/blog\/wp-json\/wp\/v2\/posts\/31652","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.highcharts.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.highcharts.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.highcharts.com\/blog\/wp-json\/wp\/v2\/users\/32"}],"replies":[{"embeddable":true,"href":"https:\/\/www.highcharts.com\/blog\/wp-json\/wp\/v2\/comments?post=31652"}],"version-history":[{"count":3,"href":"https:\/\/www.highcharts.com\/blog\/wp-json\/wp\/v2\/posts\/31652\/revisions"}],"predecessor-version":[{"id":31676,"href":"https:\/\/www.highcharts.com\/blog\/wp-json\/wp\/v2\/posts\/31652\/revisions\/31676"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.highcharts.com\/blog\/wp-json\/wp\/v2\/media\/31673"}],"wp:attachment":[{"href":"https:\/\/www.highcharts.com\/blog\/wp-json\/wp\/v2\/media?parent=31652"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.highcharts.com\/blog\/wp-json\/wp\/v2\/categories?post=31652"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.highcharts.com\/blog\/wp-json\/wp\/v2\/tags?post=31652"},{"taxonomy":"author","embeddable":true,"href":"https:\/\/www.highcharts.com\/blog\/wp-json\/wp\/v2\/coauthors?post=31652"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}