<div id="app">
    <div>
        <mds-section bold :title="chartAriaLabel" :aria-label="chartAriaLabel" aria-describedby="aria-description">
            <span id="aria-description" class="accessibly-hidden"> {{ chartAriaDescription }}</span>

            <mce-hover-flag v-if="focusedData" :x="mousePosition.pageX" :y="mousePosition.pageY">
                <mce-legend hide-top-border hide-bottom-border>
                    <mce-legend-item :color="chartColors[mouseData._itemId]" :label="mouseData.label" :value="mouseData.value | format" key-type="donut"></mce-legend-item>
                </mce-legend>
            </mce-hover-flag>
            <mce-layout :plot-width="plotWidth" :plot-height="plotHeight" :legend-right-width="legendRightWidth">
                <template #legend-right>
                    <mce-legend>
                        <mce-legend-group title="Asset Allocation">
                            <mce-legend-item v-for="row in fullData" :key="row.id" :label="row.label" :value="row.value | format" :color="chartColors[row.id]" key-type="donut"></mce-legend-item>
                        </mce-legend-group>
                    </mce-legend>
                </template>

                <!-- Main plot (default slot) -->
                <mce-donut-plot :color="chartColors" :data="chartData" :data-focused="focusedData" :height="plotHeight" :width="plotWidth" @mousemove-plot="onMousemovePlot" @mouseleave-plot="onMouseleavePlot"></mce-donut-plot>
            </mce-layout>
        </mds-section>

        <!-- provide an accessible alternative for screen-readers -->
        <mds-table class="table">
            <div class="accessibly-hidden">
                {{
                    chartAriaDescription
                }}
            </div>
            <mds-thead>
                <mds-th>Asset Class</mds-th>
                <mds-th right-aligned>Allocation %</mds-th>
            </mds-thead>
            <mds-tbody>
                <mds-tr v-for="row in fullData" :key="row.id">
                    <mds-td> {{ row.label }} </mds-td>
                    <mds-td right-aligned> {{ row.value | format }} </mds-td>
                </mds-tr>
            </mds-tbody>
        </mds-table>
    </div>
</div>
// All mixins, constants, and typography from MDS are available for use

@mixin mds-accessibly-hidden() {
    clip: rect(0 0 0 0);
    left: 0;
    position: absolute;
    z-index: -1;
}

body {
    margin: $mds-space-1-x;
    padding: 0;
}

.accessibly-hidden {
    @include mds-accessibly-hidden();
}

.table {
    margin-top: $mds-space-4-x;
    max-width: 400px;
}
View Compiled
import * as d3 from "https://cdn.skypack.dev/d3@6.1.1";
const { assetAllocation } = window.utilities.color;

// Prepare chart source data
const rawData = [
    {
        id: "AssetAllocCash",
        label: "Cash",
        value: 4.74688,
    },
    {
        id: "AssetAllocNotClassified",
        label: "Not Classified",
        value: 1.53654,
    },
    {
        id: "AssetAllocNonUSEquity",
        label: "Non-U.S. Equity",
        value: 27.24799,
    },
    {
        id: "AssetAllocOther",
        label: "Other",
        value: 0.0,
    },
    {
        id: "AssetAllocUSEquity",
        label: "U.S. Equity",
        value: 37.11866,
    },
    {
        id: "AssetAllocBond",
        label: "Fixed Income",
        value: 29.34991,
    }
];

const chartColors = {
    AssetAllocCash: assetAllocation.cash,
    AssetAllocNotClassified: assetAllocation['not-classified'],
    AssetAllocNonUSEquity: assetAllocation.alternative,
    AssetAllocOther: assetAllocation.other,
    AssetAllocUSEquity: assetAllocation.equity,
    AssetAllocBond: assetAllocation['fixed-income'],
};

// Initialize and render chart
const app = new Vue({
    el: "#app",
    data() {
        return {
            // Descriptive Labels
            chartAriaLabel:
                "Vanguard Global Wellington Fund Admiral Shares (VGWAX)",
            chartAriaDescription:
                "The allocation breakdown across asset classes for the Vanguard Global Wellington Fund Admiral Shares (VGWAX) fund. The fund is well diversified across asset classes with 37% allocated to U.S. Equity, 29% Fixed Income, 27% Non-U.S. Equity, and around 5% Cash.",

            // Dimensions
            plotHeight: 350,
            plotWidth: 350,
            legendRightWidth: 170,
            chartColors,
            mouseData: {},
            mousePosition: {},
            focusedData: null
        };
    },
    computed: {
        fullData() {
            // Show all values, including zero, in the legend
            return rawData.sort((a, b) => b.value - a.value);
        },
        chartData() {
            // Ignore zero values to avoid unwanted pie padAngle slices
            return this.fullData.filter((d) => d.value > 0);
        },
    },
    filters: {
        format(value) {
            return d3.format(",.2%")(value / 100);
        }
    },
    methods: {
        onMousemovePlot(e) {            
            const { data, position } = e;

            this.mouseData = data;
            this.mousePosition = position;
            this.focusedData = [data._itemId];
        },
        onMouseleavePlot() {
            this.focusedData = null;
        }
    }
});
View Compiled

External CSS

  1. https://mds-static-assets.s3.amazonaws.com/sandbox/constants.scss
  2. https://mds-static-assets.s3.amazonaws.com/sandbox/fonts.scss
  3. https://mds-static-assets.s3.amazonaws.com/sandbox/typography_constants.scss
  4. https://mds-static-assets.s3.amazonaws.com/sandbox/typography.scss
  5. https://mds-static-assets.s3.amazonaws.com/sandbox/link.scss

External JavaScript

  1. https://cdnjs.cloudflare.com/ajax/libs/vue/2.6.14/vue.min.js
  2. https://mds-static-assets.s3.amazonaws.com/sandbox/components.js
  3. https://mds-static-assets.s3.amazonaws.com/mce-codepen/charts.js
  4. https://mds-static-assets.s3.amazonaws.com/mce-codepen/utilities.js