<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-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
// Locally we would import from the d3 package, e.g.
// import * as d3 from 'd3';
// In CodePen, we'll pull from cdn.skypack.dev instead.
import * as d3 from "https://cdn.skypack.dev/d3@6.1.1";
// Locally we would import from the @mce/color package, e.g.
// import { assetAllocation } from '@mce/color';
// In CodePen, we'll pull from window.utilities.color instead.
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,
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 } = e;
this.focusedData = [data._itemId];
},
onMouseleavePlot() {
this.focusedData = null;
}
}
});
View Compiled