A Quadrant Chart displays data as a scatter or bubble series, divided into four independently styled regions around a pivot point.
Simple Quadrant Chart Copy Link
import { createApp, defineComponent, ref } from "vue";
import { AgQuadrantChart } from "ag-charts-vue3";
import type { AgChartOptions } from "ag-charts-types";
import { ModuleRegistry, QuadrantChartModule } from "ag-charts-enterprise";
import { getData } from "./data";
ModuleRegistry.registerModules([QuadrantChartModule]);
const ChartExample = defineComponent({
template: `
<ag-quadrant-chart
:options="options"
/>
`,
components: {
"ag-quadrant-chart": AgQuadrantChart,
},
setup(props) {
const options = ref<AgQuadrantChartOptions>({
data: getData(),
title: { text: "Product Portfolio Review" },
subtitle: {
text: "Year-on-year revenue growth against change in gross margin",
},
xKey: "revenueGrowth",
xName: "Revenue growth",
yKey: "marginChange",
yName: "Margin change",
labelKey: "category",
labelName: "Category",
xAxis: { title: { text: "Revenue growth (%)" } },
yAxis: { title: { text: "Margin change (% points)" } },
});
return {
options,
};
},
});
createApp(ChartExample).mount("#app");
export function getData() {
return [
{ category: "Wireless Earbuds", revenueGrowth: 24.6, marginChange: 3.8 },
{ category: "Smart Home", revenueGrowth: 18.2, marginChange: 2.4 },
{ category: "Fitness Trackers", revenueGrowth: 11.4, marginChange: 5.2 },
{ category: "E-Readers", revenueGrowth: 6.8, marginChange: 1.6 },
{ category: "VR Headsets", revenueGrowth: 27.4, marginChange: -1.4 },
{ category: "Gaming Consoles", revenueGrowth: 21.8, marginChange: -4.2 },
{ category: "Streaming Devices", revenueGrowth: 14.2, marginChange: -2.6 },
{ category: "Tablets", revenueGrowth: 8.4, marginChange: -5.8 },
{ category: "Printers", revenueGrowth: -8.6, marginChange: 4.4 },
{ category: "Landline Phones", revenueGrowth: -22.8, marginChange: 3.6 },
{ category: "Desktop PCs", revenueGrowth: -12.4, marginChange: 2.8 },
{ category: "Digital Cameras", revenueGrowth: -19.2, marginChange: 1.2 },
{ category: "Sat Nav", revenueGrowth: -9.4, marginChange: -1.8 },
{ category: "Feature Phones", revenueGrowth: -18.6, marginChange: -4.8 },
{ category: "MP3 Players", revenueGrowth: -15.8, marginChange: -6.4 },
{ category: "DVD Players", revenueGrowth: -26.2, marginChange: -3.2 },
];
}
To create a Quadrant Chart, use the createQuadrantChart() API with an AgQuadrantChartOptions object.
template: `<ag-quadrant-chart :options="options" />`,
components: {
'ag-quadrant-chart': AgQuadrantChart,
},
data() {
return {
options: {
data: getData(),
title: { text: 'Product Portfolio Review' },
xKey: 'revenueGrowth',
yKey: 'marginChange',
labelKey: 'category',
xAxis: { title: { text: 'Revenue growth (%)' } },
yAxis: { title: { text: 'Margin change (% points)' } },
},
};
}In this configuration:
datais an array of objects, each representing a point on the chart.xKeyandyKeymap the two measures being compared, with the optionallabelKeyproviding a third measure for the marker text.xAxisandyAxisoptions can be used to set titles, labels and other axis features.- Marker labels are shown by default when
labelKeyor alabelobject is set, and hidden otherwise; setlabel.enabledto override either way.
Marker Size Copy Link
To vary the size of the markers to visualise a third dimension, provide a sizeKey.
import { createApp, defineComponent, ref } from "vue";
import { AgQuadrantChart } from "ag-charts-vue3";
import type { AgChartOptions } from "ag-charts-types";
import { ModuleRegistry, QuadrantChartModule } from "ag-charts-enterprise";
import { getData } from "./data";
ModuleRegistry.registerModules([QuadrantChartModule]);
const ChartExample = defineComponent({
template: `
<ag-quadrant-chart
:options="options"
/>
`,
components: {
"ag-quadrant-chart": AgQuadrantChart,
},
setup(props) {
const options = ref<AgQuadrantChartOptions>({
data: getData(),
title: { text: "Product Portfolio Review" },
subtitle: { text: "Marker size shows annual revenue" },
xKey: "revenueGrowth",
xName: "Revenue growth",
yKey: "marginChange",
yName: "Margin change",
sizeKey: "revenue",
sizeName: "Revenue",
minSize: 8,
maxSize: 40,
labelKey: "category",
labelName: "Category",
xAxis: { title: { text: "Revenue growth (%)" } },
yAxis: { title: { text: "Margin change (% points)" } },
});
return {
options,
};
},
});
createApp(ChartExample).mount("#app");
export function getData() {
return [
{
category: "Wireless Earbuds",
revenueGrowth: 24.6,
marginChange: 3.8,
revenue: 412,
},
{
category: "Smart Home",
revenueGrowth: 18.2,
marginChange: 2.4,
revenue: 268,
},
{
category: "Fitness Trackers",
revenueGrowth: 11.4,
marginChange: 5.2,
revenue: 143,
},
{
category: "E-Readers",
revenueGrowth: 6.8,
marginChange: 1.6,
revenue: 61,
},
{
category: "VR Headsets",
revenueGrowth: 27.4,
marginChange: -1.4,
revenue: 96,
},
{
category: "Gaming Consoles",
revenueGrowth: 21.8,
marginChange: -4.2,
revenue: 674,
},
{
category: "Streaming Devices",
revenueGrowth: 14.2,
marginChange: -2.6,
revenue: 187,
},
{
category: "Tablets",
revenueGrowth: 8.4,
marginChange: -5.8,
revenue: 528,
},
{
category: "Printers",
revenueGrowth: -8.6,
marginChange: 4.4,
revenue: 224,
},
{
category: "Landline Phones",
revenueGrowth: -22.8,
marginChange: 3.6,
revenue: 38,
},
{
category: "Desktop PCs",
revenueGrowth: -12.4,
marginChange: 2.8,
revenue: 596,
},
{
category: "Digital Cameras",
revenueGrowth: -19.2,
marginChange: 1.2,
revenue: 112,
},
{
category: "Sat Nav",
revenueGrowth: -9.4,
marginChange: -1.8,
revenue: 74,
},
{
category: "Feature Phones",
revenueGrowth: -18.6,
marginChange: -4.8,
revenue: 156,
},
{
category: "MP3 Players",
revenueGrowth: -15.8,
marginChange: -6.4,
revenue: 29,
},
{
category: "DVD Players",
revenueGrowth: -26.2,
marginChange: -3.2,
revenue: 47,
},
];
}
{
sizeKey: 'revenue',
minSize: 8,
maxSize: 40,
}In this configuration:
sizeKeymaps to the data field determining the size of each marker.minSizesets the size of the marker for the smallest data point. This defaults to thesizeproperty when not set.maxSizesets the size for the largest data point.
When sizeKey is not set, the size property sets a fixed size for every marker.
Pivot Copy Link
The pivot option determines the data values at which the regions are divided. It defaults to { x: 0, y: 0 }.
import { createApp, defineComponent, ref } from "vue";
import { AgQuadrantChart } from "ag-charts-vue3";
import type { AgChartOptions } from "ag-charts-types";
import { ModuleRegistry, QuadrantChartModule } from "ag-charts-enterprise";
import { getData } from "./data";
import clone from "clone";
const MIN = 0;
const MAX = 10;
let pivotX = 4;
let pivotY = 6;
ModuleRegistry.registerModules([QuadrantChartModule]);
const ChartExample = defineComponent({
template: `
<div class="example-controls">
<div class="controls-row">
<button id="pivot-left" v-on:click="movePivot(-1, 0)">Move Pivot Left</button>
<button id="pivot-right" v-on:click="movePivot(1, 0)">Move Pivot Right</button>
<button id="pivot-down" v-on:click="movePivot(0, -1)">Move Pivot Down</button>
<button id="pivot-up" v-on:click="movePivot(0, 1)">Move Pivot Up</button>
</div>
</div>
<ag-quadrant-chart
:options="options"
/>
`,
components: {
"ag-quadrant-chart": AgQuadrantChart,
},
setup(props) {
const options = ref<AgQuadrantChartOptions>({
data: getData(),
title: { text: "Roadmap Prioritisation" },
// subtitle: { text: 'Expected impact against implementation effort' },
xKey: "effort",
xName: "Effort",
yKey: "impact",
yName: "Impact",
labelKey: "initiative",
labelName: "Initiative",
label: { enabled: true },
xAxis: { min: MIN, max: MAX, title: { text: "Effort" } },
yAxis: { min: MIN, max: MAX, title: { text: "Impact" } },
pivot: { x: 4, y: 6 },
});
const updatePivotButtons = () => {
document.getElementById("pivot-left").disabled = pivotX <= MIN;
document.getElementById("pivot-right").disabled = pivotX >= MAX;
document.getElementById("pivot-down").disabled = pivotY <= MIN;
document.getElementById("pivot-up").disabled = pivotY >= MAX;
};
const movePivot = (dx, dy) => {
const optionsCopy = clone(options.value);
pivotX = Math.min(MAX, Math.max(MIN, pivotX + dx));
pivotY = Math.min(MAX, Math.max(MIN, pivotY + dy));
optionsCopy.pivot = { x: pivotX, y: pivotY };
updatePivotButtons();
options.value = optionsCopy;
};
return {
options,
movePivot,
};
},
});
createApp(ChartExample).mount("#app");
export function getData() {
return [
{ initiative: "Online co-op", effort: 8.4, impact: 9.1 },
{ initiative: "Invert camera axis", effort: 1.4, impact: 6.2 },
{ initiative: "VR support", effort: 7.2, impact: 1.4 },
{ initiative: "Weapon skins", effort: 3.6, impact: 4.4 },
{ initiative: "Seamless open world", effort: 9.6, impact: 8.8 },
{ initiative: "Checkpoint autosave", effort: 3.8, impact: 8.2 },
{ initiative: "Mod marketplace", effort: 9.4, impact: 4.2 },
{ initiative: "Emote wheel", effort: 2.2, impact: 2.4 },
{ initiative: "Combat overhaul", effort: 6.8, impact: 9.4 },
{ initiative: "Level editor", effort: 8.6, impact: 3.8 },
{ initiative: "Photo mode", effort: 3.4, impact: 7.8 },
{ initiative: "New game plus", effort: 4.2, impact: 4.8 },
{ initiative: "Remappable controls", effort: 2.6, impact: 7.1 },
{ initiative: "Daily login rewards", effort: 6.8, impact: 2.8 },
{ initiative: "Main menu parallax", effort: 0.6, impact: 0.9 },
{ initiative: "Dynamic weather", effort: 6.2, impact: 7.2 },
];
}
{
pivot: { x: 4, y: 6 },
}In this configuration:
pivot.xandpivot.ydivide the chart into regions at an effort of4and an impact of6.- The
pivotuses a data value tied to both the x- and y-axis, allowing full control over the size of the regions.
Regions Copy Link
The fill and stroke of each region, as well as the style of their markers and labels is configured under the region specific properties within the regions options. There is also a shared regions.label property which each region can override as necessary.
Callbacks such as itemStyler, tooltip.renderer and label callbacks receive the region of each point to allow for region specific styling.
Labels Copy Link
import { createApp, defineComponent, ref } from "vue";
import { AgQuadrantChart } from "ag-charts-vue3";
import type { AgChartOptions } from "ag-charts-types";
import { ModuleRegistry, QuadrantChartModule } from "ag-charts-enterprise";
import { getData } from "./data";
import clone from "clone";
ModuleRegistry.registerModules([QuadrantChartModule]);
const ChartExample = defineComponent({
template: `
<div class="example-controls">
<div class="controls-row">
<label for="label-position">Label Position:</label>
<select id="label-position" v-on:change="updateLabelPosition($event.target.value)">
<option value="outside-outer">outside-outer</option>
<option value="outside-center">outside-center</option>
<option value="outside-inner">outside-inner</option>
<option value="inside-outer-outer" selected="">inside-outer-outer</option>
<option value="inside-outer-center">inside-outer-center</option>
<option value="inside-outer-inner">inside-outer-inner</option>
<option value="inside-center-outer">inside-center-outer</option>
<option value="inside-center">inside-center</option>
<option value="inside-center-inner">inside-center-inner</option>
<option value="inside-inner-outer">inside-inner-outer</option>
<option value="inside-inner-center">inside-inner-center</option>
<option value="inside-inner-inner">inside-inner-inner</option>
</select>
</div>
</div>
<ag-quadrant-chart
:options="options"
/>
`,
components: {
"ag-quadrant-chart": AgQuadrantChart,
},
setup(props) {
const options = ref<AgQuadrantChartOptions>({
data: getData(),
title: { text: "Product Portfolio Review" },
xKey: "revenueGrowth",
xName: "Revenue growth",
yKey: "marginChange",
yName: "Margin change",
labelKey: "category",
labelName: "Category",
xAxis: { title: { text: "Revenue growth (%)" } },
yAxis: { title: { text: "Margin change (% points)" } },
padding: { top: 30, right: 30, bottom: 10, left: 10 },
regions: {
label: { position: "inside-outer-outer" },
topLeft: { label: { text: "Shrinking, Wider Margins" } },
topRight: { label: { text: "Growing, Wider Margins" } },
bottomLeft: { label: { text: "Shrinking, Thinner Margins" } },
bottomRight: { label: { text: "Growing, Thinner Margins" } },
},
tooltip: {
renderer: (params) => {
return {
data: [
{ label: "Category", value: params.datum.category },
{
label: "Revenue growth",
value: `${params.datum.revenueGrowth}%`,
},
{
label: "Margin change",
value: `${params.datum.marginChange}%`,
},
],
};
},
},
});
const updateLabelPosition = (position) => {
const optionsCopy = clone(options.value);
optionsCopy.regions.label = { position };
options.value = optionsCopy;
};
return {
options,
updateLabelPosition,
};
},
});
createApp(ChartExample).mount("#app");
export function getData() {
return [
{ category: "Wireless Earbuds", revenueGrowth: 24.6, marginChange: 3.8 },
{ category: "Smart Home", revenueGrowth: 18.2, marginChange: 2.4 },
{ category: "Fitness Trackers", revenueGrowth: 11.4, marginChange: 5.2 },
{ category: "E-Readers", revenueGrowth: 6.8, marginChange: 1.6 },
{ category: "VR Headsets", revenueGrowth: 27.4, marginChange: -1.4 },
{ category: "Gaming Consoles", revenueGrowth: 21.8, marginChange: -4.2 },
{ category: "Streaming Devices", revenueGrowth: 14.2, marginChange: -2.6 },
{ category: "Tablets", revenueGrowth: 8.4, marginChange: -5.8 },
{ category: "Printers", revenueGrowth: -8.6, marginChange: 4.4 },
{ category: "Landline Phones", revenueGrowth: -22.8, marginChange: 3.6 },
{ category: "Desktop PCs", revenueGrowth: -12.4, marginChange: 2.8 },
{ category: "Digital Cameras", revenueGrowth: -19.2, marginChange: 1.2 },
{ category: "Sat Nav", revenueGrowth: -9.4, marginChange: -1.8 },
{ category: "Feature Phones", revenueGrowth: -18.6, marginChange: -4.8 },
{ category: "MP3 Players", revenueGrowth: -15.8, marginChange: -6.4 },
{ category: "DVD Players", revenueGrowth: -26.2, marginChange: -3.2 },
];
}
{
regions: {
label: { position: 'inside-outer-outer' },
topLeft: { label: { text: 'Shrinking, Wider Margins' } },
topRight: { label: { text: 'Growing, Wider Margins' } },
bottomLeft: { label: { text: 'Shrinking, Thinner Margins' } },
bottomRight: { label: { text: 'Growing, Thinner Margins' } },
},
}In this example:
- Use the dropdown to change the
label.position, moving a region label to any corner, any edge or the center of each region. - All regions use the shared
labeloption. - Each region has its own
label.textto set the text for that region.
Customisation Copy Link
import { createApp, defineComponent, ref } from "vue";
import { AgQuadrantChart } from "ag-charts-vue3";
import type { AgChartOptions } from "ag-charts-types";
import { ModuleRegistry, QuadrantChartModule } from "ag-charts-enterprise";
import { getData } from "./data";
function formatRegion(region) {
return region
.split("-")
.map((word) => word[0].toUpperCase() + word.slice(1))
.join(" ");
}
ModuleRegistry.registerModules([QuadrantChartModule]);
const ChartExample = defineComponent({
template: `
<ag-quadrant-chart
:options="options"
/>
`,
components: {
"ag-quadrant-chart": AgQuadrantChart,
},
setup(props) {
const options = ref<AgQuadrantChartOptions>({
data: getData(),
title: { text: "Climate Anomalies" },
xKey: "tempAnomaly",
xName: "Temperature anomaly (°C)",
yKey: "precipAnomaly",
yName: "Precipitation anomaly (%)",
labelKey: "country",
labelName: "Country",
xAxis: {
title: { text: "Temperature anomaly (°C)" },
label: { formatter: (params) => `${params.value} °C` },
line: { enabled: false, width: 0 },
gridLine: { enabled: false },
},
yAxis: {
title: { text: "Precipitation anomaly (%)" },
label: { formatter: (params) => `${params.value}%` },
max: 20,
line: { enabled: false },
gridLine: { enabled: false },
},
pivot: { x: 1.35, y: 0 },
regions: {
label: {
fontSize: 14,
fontWeight: "bold",
},
topLeft: {
fill: {
type: "gradient",
rotation: 315,
colorStops: [
{ color: "rgba(56, 189, 248, 0)" },
{ color: "#38bdf8" },
],
},
fillOpacity: 0.45,
stroke: "#0284c7",
strokeOpacity: 0.4,
strokeWidth: 1.5,
marker: { fill: "#38bdf8", strokeWidth: 0 },
label: {
text: "Slower Warming, Wetter",
color: "#0284c7",
},
},
topRight: {
fill: {
type: "gradient",
rotation: 45,
colorStops: [
{ color: "rgba(168, 85, 247, 0)" },
{ color: "#a855f7" },
],
},
fillOpacity: 0.45,
stroke: "#9333ea",
strokeOpacity: 0.4,
strokeWidth: 1.5,
marker: { fill: "#a855f7", strokeWidth: 0, size: 14 },
label: {
text: "Faster Warming, Wetter",
color: "#9333ea",
},
},
bottomLeft: {
fill: {
type: "gradient",
rotation: 225,
colorStops: [
{ color: "rgba(20, 184, 166, 0)" },
{ color: "#14b8a6" },
],
},
fillOpacity: 0.45,
stroke: "#0d9488",
strokeOpacity: 0.4,
strokeWidth: 1.5,
marker: {
fill: "#14b8a6",
stroke: "#0d9488",
strokeWidth: 2,
shape: "cross",
},
label: {
text: "Slower Warming, Drier",
color: "#0d9488",
},
},
bottomRight: {
fill: {
type: "gradient",
rotation: 135,
colorStops: [
{ color: "rgba(249, 115, 22, 0)" },
{ color: "#f97316" },
],
},
fillOpacity: 0.45,
stroke: "#ea580c",
strokeOpacity: 0.4,
strokeWidth: 1.5,
marker: { fill: "#f97316", strokeWidth: 0 },
label: {
text: "Faster Warming, Drier",
color: "#ea580c",
},
},
},
tooltip: {
renderer: ({ region }) => ({
title: formatRegion(region),
}),
},
});
return {
options,
};
},
});
createApp(ChartExample).mount("#app");
// Illustrative values following documented regional patterns, not measured station records.
export function getData() {
return [
{ country: "Iceland", tempAnomaly: 1.43, precipAnomaly: 8.2 },
{ country: "Norway", tempAnomaly: 1.68, precipAnomaly: 9.9 },
{ country: "Sweden", tempAnomaly: 1.8, precipAnomaly: 8.4 },
{ country: "Finland", tempAnomaly: 1.98, precipAnomaly: 9.3 },
{ country: "Estonia", tempAnomaly: 1.93, precipAnomaly: 8.2 },
{ country: "Denmark", tempAnomaly: 1.61, precipAnomaly: 7.3 },
{ country: "United Kingdom", tempAnomaly: 1.27, precipAnomaly: 6.3 },
{ country: "Ireland", tempAnomaly: 1.09, precipAnomaly: 5.3 },
{ country: "Netherlands", tempAnomaly: 1.59, precipAnomaly: 7.3 },
{ country: "Belgium", tempAnomaly: 1.69, precipAnomaly: 4.6 },
{ country: "France", tempAnomaly: 1.74, precipAnomaly: 1.8 },
{ country: "Germany", tempAnomaly: 1.8, precipAnomaly: 3.8 },
{ country: "Poland", tempAnomaly: 1.78, precipAnomaly: 3.4 },
{ country: "Czechia", tempAnomaly: 1.89, precipAnomaly: 2.1 },
{ country: "Austria", tempAnomaly: 1.98, precipAnomaly: 2.8 },
{ country: "Hungary", tempAnomaly: 1.83, precipAnomaly: -0.8 },
{ country: "Romania", tempAnomaly: 1.71, precipAnomaly: -1.8 },
{ country: "Ukraine", tempAnomaly: 1.64, precipAnomaly: 1.2 },
{ country: "Russia", tempAnomaly: 1.9, precipAnomaly: 5.7 },
{ country: "Spain", tempAnomaly: 1.59, precipAnomaly: -8.9 },
{ country: "Portugal", tempAnomaly: 1.4, precipAnomaly: -9.9 },
{ country: "Italy", tempAnomaly: 1.71, precipAnomaly: -6.3 },
{ country: "Greece", tempAnomaly: 1.47, precipAnomaly: -8.6 },
{ country: "Turkey", tempAnomaly: 1.53, precipAnomaly: -8.1 },
{ country: "Morocco", tempAnomaly: 1.29, precipAnomaly: -13.6 },
{ country: "Algeria", tempAnomaly: 1.43, precipAnomaly: -12.2 },
{ country: "Egypt", tempAnomaly: 1.36, precipAnomaly: -11.4 },
{ country: "Iran", tempAnomaly: 1.71, precipAnomaly: -15.1 },
{ country: "Iraq", tempAnomaly: 1.8, precipAnomaly: -16.2 },
{ country: "Saudi Arabia", tempAnomaly: 1.92, precipAnomaly: -9.8 },
{ country: "Senegal", tempAnomaly: 1.11, precipAnomaly: 6.6 },
{ country: "Mali", tempAnomaly: 1.31, precipAnomaly: 6.1 },
{ country: "Nigeria", tempAnomaly: 1.02, precipAnomaly: 5.3 },
{ country: "Ghana", tempAnomaly: 1.03, precipAnomaly: 6.1 },
{ country: "Ethiopia", tempAnomaly: 1.11, precipAnomaly: -3.0 },
{ country: "Kenya", tempAnomaly: 1.06, precipAnomaly: -3.7 },
{ country: "South Africa", tempAnomaly: 1.19, precipAnomaly: -6.1 },
{ country: "Zimbabwe", tempAnomaly: 1.23, precipAnomaly: -5.2 },
{ country: "India", tempAnomaly: 0.88, precipAnomaly: -2.3 },
{ country: "Pakistan", tempAnomaly: 1.09, precipAnomaly: 2.9 },
{ country: "Bangladesh", tempAnomaly: 0.98, precipAnomaly: 3.9 },
{ country: "Sri Lanka", tempAnomaly: 0.86, precipAnomaly: 2.0 },
{ country: "Thailand", tempAnomaly: 0.99, precipAnomaly: 3.9 },
{ country: "Vietnam", tempAnomaly: 1.03, precipAnomaly: 2.9 },
{ country: "Indonesia", tempAnomaly: 0.91, precipAnomaly: 5.3 },
{ country: "Philippines", tempAnomaly: 0.87, precipAnomaly: 6.0 },
{ country: "China", tempAnomaly: 1.53, precipAnomaly: 2.9 },
{ country: "Mongolia", tempAnomaly: 2.11, precipAnomaly: -7.0 },
{ country: "Japan", tempAnomaly: 1.38, precipAnomaly: 4.9 },
{ country: "South Korea", tempAnomaly: 1.49, precipAnomaly: 6.0 },
{ country: "Australia", tempAnomaly: 1.46, precipAnomaly: -5.1 },
{ country: "New Zealand", tempAnomaly: 1.13, precipAnomaly: 3.4 },
{ country: "United States", tempAnomaly: 1.3, precipAnomaly: 4.0 },
{ country: "Canada", tempAnomaly: 1.81, precipAnomaly: 7.1 },
{ country: "Mexico", tempAnomaly: 1.4, precipAnomaly: -6.3 },
{ country: "Brazil", tempAnomaly: 1.1, precipAnomaly: -3.0 },
{ country: "Argentina", tempAnomaly: 1.02, precipAnomaly: 4.9 },
{ country: "Chile", tempAnomaly: 1.09, precipAnomaly: -17.7 },
{ country: "Peru", tempAnomaly: 1.04, precipAnomaly: -1.6 },
];
}
{
regions: {
label: { fontSize: 14, fontWeight: 'bold' },
topLeft: {
fill: {
type: 'gradient',
rotation: 315,
colorStops: [{ color: 'rgba(56, 189, 248, 0)' }, { color: '#38bdf8' }],
},
stroke: '#0284c7',
marker: { fill: '#38bdf8', strokeWidth: 0 },
label: { text: 'Slower Warming, Wetter', color: '#0284c7' },
},
topRight: {
// ... other options
marker: { fill: '#a855f7', strokeWidth: 0, size: 14 },
},
bottomLeft: {
// ... other options
marker: { fill: '#14b8a6', stroke: '#0d9488', strokeWidth: 2, shape: 'cross' },
},
// ... other regions
},
tooltip: {
renderer: ({ region }) => ({
title: formatRegion(region),
}),
},
}In this configuration:
filltakes a colour, gradient, pattern or image;strokeoutlines the region.markerstyles the points inside that region, includingsizeandshape.labelsets the region label text and colour. Styling shared by every region goes onregions.label.- A
regionproperty is also passed toitemStyler,tooltip.rendererand label callbacks. It is used here to set the tooltiptitle.
Axes Copy Link
By default the axis lines cross at the pivot, while the axis titles, labels and crosshair labels stay at the edge of the chart.
import { createApp, defineComponent, ref } from "vue";
import { AgQuadrantChart } from "ag-charts-vue3";
import type { AgChartOptions } from "ag-charts-types";
import { ModuleRegistry, QuadrantChartModule } from "ag-charts-enterprise";
import { getData } from "./data";
import clone from "clone";
let alignAxesToPivot = true;
ModuleRegistry.registerModules([QuadrantChartModule]);
const ChartExample = defineComponent({
template: `
<div class="example-controls">
<div class="controls-row">
<button id="alignAxesToPivotToggle" aria-pressed="true" v-on:click="toggleAlignAxesToPivot()">
Align Axes to Pivot
</button>
<fieldset id="placementGroup" class="control-group">
<label for="title-placement">Title:</label>
<select id="title-placement" v-on:change="updateTitlePlacement($event.target.value)">
<option value="edge" selected="">edge</option>
<option value="crossing">crossing</option>
</select>
<label for="label-placement">Label:</label>
<select id="label-placement" v-on:change="updateLabelPlacement($event.target.value)">
<option value="edge" selected="">edge</option>
<option value="crossing">crossing</option>
</select>
<label for="crosshair-label-placement">Crosshair Label:</label>
<select id="crosshair-label-placement" v-on:change="updateCrosshairLabelPlacement($event.target.value)">
<option value="edge" selected="">edge</option>
<option value="crossing">crossing</option>
</select>
</fieldset>
</div>
</div>
<ag-quadrant-chart
:options="options"
/>
`,
components: {
"ag-quadrant-chart": AgQuadrantChart,
},
setup(props) {
const options = ref<AgQuadrantChartOptions>({
data: getData(),
title: { text: "Roadmap Prioritisation" },
xKey: "effort",
xName: "Effort",
yKey: "impact",
yName: "Impact",
// labelKey: 'initiative',
// labelName: 'Initiative',
label: { enabled: false },
pivot: { x: 4, y: 6 },
xAxis: { min: 0, max: 10, title: { text: "Effort" } },
yAxis: { min: 0, max: 10, title: { text: "Impact" } },
});
const updatePlacementSelects = () => {
document.getElementById("placementGroup").disabled = !alignAxesToPivot;
};
const toggleAlignAxesToPivot = () => {
const optionsCopy = clone(options.value);
alignAxesToPivot = !alignAxesToPivot;
optionsCopy.alignAxesToPivot = alignAxesToPivot;
document
.getElementById("alignAxesToPivotToggle")
.setAttribute("aria-pressed", String(alignAxesToPivot));
updatePlacementSelects();
options.value = optionsCopy;
};
const updateTitlePlacement = (placement) => {
const optionsCopy = clone(options.value);
optionsCopy.axisPlacement = {
...optionsCopy.axisPlacement,
title: placement,
};
options.value = optionsCopy;
};
const updateLabelPlacement = (placement) => {
const optionsCopy = clone(options.value);
optionsCopy.axisPlacement = {
...optionsCopy.axisPlacement,
label: placement,
};
options.value = optionsCopy;
};
const updateCrosshairLabelPlacement = (placement) => {
const optionsCopy = clone(options.value);
optionsCopy.axisPlacement = {
...optionsCopy.axisPlacement,
crosshairLabel: placement,
};
options.value = optionsCopy;
};
return {
options,
toggleAlignAxesToPivot,
updateTitlePlacement,
updateLabelPlacement,
updateCrosshairLabelPlacement,
};
},
});
createApp(ChartExample).mount("#app");
export function getData() {
return [
{ initiative: "Online co-op", effort: 8.4, impact: 9.1 },
{ initiative: "Invert camera axis", effort: 1.4, impact: 6.2 },
{ initiative: "VR support", effort: 7.2, impact: 1.4 },
{ initiative: "Weapon skins", effort: 1.2, impact: 4.6 },
{ initiative: "Seamless open world", effort: 9.6, impact: 8.8 },
{ initiative: "Checkpoint autosave", effort: 3.8, impact: 8.2 },
{ initiative: "Mod marketplace", effort: 9.4, impact: 4.2 },
{ initiative: "Emote wheel", effort: 2.2, impact: 2.4 },
{ initiative: "Combat overhaul", effort: 6.8, impact: 9.4 },
{ initiative: "Level editor", effort: 8.6, impact: 3.8 },
{ initiative: "Photo mode", effort: 3.4, impact: 7.8 },
{ initiative: "New game plus", effort: 1.8, impact: 3.2 },
{ initiative: "Remappable controls", effort: 2.6, impact: 7.1 },
{ initiative: "Daily login rewards", effort: 6.8, impact: 2.8 },
{ initiative: "Main menu parallax", effort: 0.6, impact: 0.9 },
{ initiative: "Dynamic weather", effort: 6.2, impact: 7.2 },
];
}
{
alignAxesToPivot: true,
axisPlacement: {
title: 'crossing',
label: 'crossing',
crosshairLabel: 'crossing',
},
xAxis: {
title: { text: 'Effort' },
},
yAxis: {
title: { text: 'Impact' },
},
}In this configuration:
alignAxesToPivottoggles whether the axis lines to cross at the pivot point or remain at the edge.axisPlacement.title,.labeland.crosshairLabeleach default to'edge'. Set any to'crossing'to move them to the pivot whilealignAxesToPivotistrue.- The
xAxisandyAxisproperties allow customising the axes which are both Number Axes.
Quadrant Chart Examples Copy Link
See more Quadrant Chart examples in the AG Charts Gallery.
API Reference Copy Link
Properties available on the AgQuadrantChartOptions interface.
- xKey required
DatumKey - The key to use to retrieve x-values from the data.
- yKey required
DatumKey - The key to use to retrieve y-values from the data.
- theme
AgChartTheme | AgChartThemeName - A predefined theme name or an object containing theme overrides. See: [Themes Reference](/themes-api/)
- data
DatumDefault[] - The data to render the chart from. If this is not specified, it must be set on individual series instead.
- dataIdKey
DatumKey - The key of the property on each datum that contains its unique identifier. When specified, transactions will match items by this field instead of by object reference. The values of this field must be unique across the dataset.
- container
HTMLElement | null - The element to place the rendered chart into.
- initialState
AgInitialStateOptions - The initial state of the chart. This must be a serialisable value.
- width
PixelSize - The width of the chart in pixels.
- height
PixelSize - The height of the chart in pixels.
- minHeight
PixelSizedefault: 300 - Sets the minimum height of the chart. Ignored if `height` is specified.
- minWidth
PixelSizedefault: 300 - Sets the minimum width of the chart. Ignored if `width` is specified.
- padding
Padding - Configuration for the padding of the chart. A number applies uniform padding; an object sets each side.
- title
AgChartCaptionOptions - Configuration for the title shown at the top of the chart.
- subtitle
AgChartSubtitleOptions - Configuration for the subtitle shown beneath the chart title.
- footnote
AgChartFooterOptions - Configuration for the footnote shown at the bottom of the chart.
- animation
AgAnimationOptions - Configuration for chart animations.
- contextMenu
AgContextMenuOptions - Configuration for the context menu.
- locale
AgLocaleOptions - Configuration for localisation.
- selection
AgChartSelectionOptions - Data selection options
- listeners
AgBaseChartListeners - A map of event names to event listeners.
- formatter
FormatterConfiguration - Global formatter configuration.
- enableRtl
boolean - Set to `true` to render the chart in right-to-left mode. If not specified, the chart will detect the `dir` attribute on the container or its ancestors.
- alignAxesToPivot
booleandefault: true - Whether to move the axis lines so that they cross at the pivot. When `false`, the axes stay at the bottom and left of the chart.
- axisPlacement
AgQuadrantAxisPlacementOptions - Configuration for placement of axis titles and labels.
- errorBar
AgErrorBarOptions - Configuration for the Error Bars.
- itemStyler
Styler - Function used to return formatting for individual markers, based on the supplied information.
- label
AgQuadrantLabelOptions - Configuration for the labels shown on top of data points.
- pivot
AgQuadrantPivotOptions - The data values at which the chart is divided into four regions.
- regions
AgQuadrantRegionsOptions - Configuration for each of the four regions the pivot divides the chart into.
- sizeKey
DatumKey - The key to use to retrieve size values from the data, used to control the size of the markers.
- sizeName
string - A human-readable description of the size values. If supplied, this will be shown in the default tooltip and passed to the tooltip renderer as one of the parameters.
- minSize
PixelSize - Determines the smallest size a marker can be in pixels when `sizeKey` is present. Defaults to `size` when not set.
- maxSize
PixelSize - Determines the largest size a marker can be in pixels when `sizeKey` is present.
- tooltip
AgSeriesTooltip - Series-specific tooltip configuration.
- xAxis
AgQuadrantAxisOptions - Configuration for the horizontal axis, which is always a number axis. Its ticks are hidden by default.
- yAxis
AgQuadrantAxisOptions - Configuration for the vertical axis, which is always a number axis. Its ticks are hidden by default.
- labelKey
DatumKey - The key to use to retrieve values from the data to use as labels for the markers.
- xName
string - A human-readable description of the x-values. If supplied, this will be shown in the default tooltip and passed to the tooltip renderer as one of the parameters.
- yName
string - A human-readable description of the y-values. If supplied, this will be shown in the default tooltip and passed to the tooltip renderer as one of the parameters.
- labelName
string - A human-readable description of the label values. If supplied, this will be shown in the default tooltip and passed to the tooltip renderer as one of the parameters.
- maxRenderedItems
numberdefault: 2000 - Determines the largest number of items that can be rendered at once. If there are more items, they will be aggregated to resemble similar visual appearance.
- styler
Styler - Function used to return formatting for entire series, based on the given parameters.
- highlight
AgMultiSeriesHighlightOptions - Configuration for highlighting when a series or legend item is hovered over.
- cursor
string - The cursor to use for hovered markers. This config is identical to the CSS `cursor` property.
- context
ContextDefault - Context object to use in callbacks.
- nodeClickRange
InteractionRange - Range from a node that a click triggers the listener.
- size
PixelSize - The size in pixels of the markers.
- shape
AgMarkerShape - The shape to use for the markers. You can also supply a custom marker by providing a `AgMarkerShapeFn` function.
- fill
AgColorType - The colour for filling shapes. A colour string, or an object for a gradient, pattern, or image fill.
- fillOpacity
Opacity - The opacity of the fill colour.
- stroke
AgCssColorOrRef - The colour for the stroke.
- strokeWidth
PixelSize - The width of the stroke in pixels.
- strokeOpacity
Opacity - The opacity of the stroke colour.
- lineDash
PixelSize[] - An array specifying the length in pixels of alternating dashes and gaps.
- lineDashOffset
PixelSize - The initial offset of the dashed line in pixels.
Properties available on the AgQuadrantChartOptions interface.
- xKey required
DatumKey - The key to use to retrieve x-values from the data.
- yKey required
DatumKey - The key to use to retrieve y-values from the data.
- theme
AgChartTheme | AgChartThemeName - A predefined theme name or an object containing theme overrides. See: [Themes Reference](/themes-api/)
- data
DatumDefault[] - The data to render the chart from. If this is not specified, it must be set on individual series instead.
- dataIdKey
DatumKey - The key of the property on each datum that contains its unique identifier. When specified, transactions will match items by this field instead of by object reference. The values of this field must be unique across the dataset.
- container
HTMLElement | null - The element to place the rendered chart into.
- initialState
AgInitialStateOptions - The initial state of the chart. This must be a serialisable value.
- width
PixelSize - The width of the chart in pixels.
- height
PixelSize - The height of the chart in pixels.
- minHeight
PixelSizedefault: 300 - Sets the minimum height of the chart. Ignored if `height` is specified.
- minWidth
PixelSizedefault: 300 - Sets the minimum width of the chart. Ignored if `width` is specified.
- padding
Padding - Configuration for the padding of the chart. A number applies uniform padding; an object sets each side.
- title
AgChartCaptionOptions - Configuration for the title shown at the top of the chart.
- subtitle
AgChartSubtitleOptions - Configuration for the subtitle shown beneath the chart title.
- footnote
AgChartFooterOptions - Configuration for the footnote shown at the bottom of the chart.
- animation
AgAnimationOptions - Configuration for chart animations.
- contextMenu
AgContextMenuOptions - Configuration for the context menu.
- locale
AgLocaleOptions - Configuration for localisation.
- selection
AgChartSelectionOptions - Data selection options
- listeners
AgBaseChartListeners - A map of event names to event listeners.
- formatter
FormatterConfiguration - Global formatter configuration.
- enableRtl
boolean - Set to `true` to render the chart in right-to-left mode. If not specified, the chart will detect the `dir` attribute on the container or its ancestors.
- alignAxesToPivot
booleandefault: true - Whether to move the axis lines so that they cross at the pivot. When `false`, the axes stay at the bottom and left of the chart.
- axisPlacement
AgQuadrantAxisPlacementOptions - Configuration for placement of axis titles and labels.
- errorBar
AgErrorBarOptions - Configuration for the Error Bars.
- itemStyler
Styler - Function used to return formatting for individual markers, based on the supplied information.
- label
AgQuadrantLabelOptions - Configuration for the labels shown on top of data points.
- pivot
AgQuadrantPivotOptions - The data values at which the chart is divided into four regions.
- regions
AgQuadrantRegionsOptions - Configuration for each of the four regions the pivot divides the chart into.
- sizeKey
DatumKey - The key to use to retrieve size values from the data, used to control the size of the markers.
- sizeName
string - A human-readable description of the size values. If supplied, this will be shown in the default tooltip and passed to the tooltip renderer as one of the parameters.
- minSize
PixelSize - Determines the smallest size a marker can be in pixels when `sizeKey` is present. Defaults to `size` when not set.
- maxSize
PixelSize - Determines the largest size a marker can be in pixels when `sizeKey` is present.
- tooltip
AgSeriesTooltip - Series-specific tooltip configuration.
- xAxis
AgQuadrantAxisOptions - Configuration for the horizontal axis, which is always a number axis. Its ticks are hidden by default.
- yAxis
AgQuadrantAxisOptions - Configuration for the vertical axis, which is always a number axis. Its ticks are hidden by default.
- labelKey
DatumKey - The key to use to retrieve values from the data to use as labels for the markers.
- xName
string - A human-readable description of the x-values. If supplied, this will be shown in the default tooltip and passed to the tooltip renderer as one of the parameters.
- yName
string - A human-readable description of the y-values. If supplied, this will be shown in the default tooltip and passed to the tooltip renderer as one of the parameters.
- labelName
string - A human-readable description of the label values. If supplied, this will be shown in the default tooltip and passed to the tooltip renderer as one of the parameters.
- maxRenderedItems
numberdefault: 2000 - Determines the largest number of items that can be rendered at once. If there are more items, they will be aggregated to resemble similar visual appearance.
- styler
Styler - Function used to return formatting for entire series, based on the given parameters.
- highlight
AgMultiSeriesHighlightOptions - Configuration for highlighting when a series or legend item is hovered over.
- cursor
string - The cursor to use for hovered markers. This config is identical to the CSS `cursor` property.
- context
ContextDefault - Context object to use in callbacks.
- nodeClickRange
InteractionRange - Range from a node that a click triggers the listener.
- size
PixelSize - The size in pixels of the markers.
- shape
AgMarkerShape - The shape to use for the markers. You can also supply a custom marker by providing a `AgMarkerShapeFn` function.
- fill
AgColorType - The colour for filling shapes. A colour string, or an object for a gradient, pattern, or image fill.
- fillOpacity
Opacity - The opacity of the fill colour.
- stroke
AgCssColorOrRef - The colour for the stroke.
- strokeWidth
PixelSize - The width of the stroke in pixels.
- strokeOpacity
Opacity - The opacity of the stroke colour.
- lineDash
PixelSize[] - An array specifying the length in pixels of alternating dashes and gaps.
- lineDashOffset
PixelSize - The initial offset of the dashed line in pixels.