Skip to main content
Version: Current

Creating cross-connected charts

In this tutorial, we will show how you can make multiple charts cross interactive. We will show how you can enable cross filtering between charts.

Create a Bar Chart and a Pie Chart

Let's first create a bar chart, which shows the Average Horsepower of Cylinders of Cars.

const barChart = muze.canvas().rows(["Horsepower"]).columns(["Cylinders"]);
const pieChart = muze
.canvas()
.rows([])
.columns([])
.color("Origin")
.layers([
{
mark: "arc",
encoding: {
angle: "CountVehicle",
},
},
]);

Here, we set the mark type as arc for a pie chart and set rows and columns to an empty array as there are no x and y axis in polar charts. The color field Origin splits the pie chart into multiple slices and the angle of each slice is derived by the CountVehicle field.

const { muze, getDataFromSearchQuery, env } = viz;
const data = getDataFromSearchQuery();

const dmWithCount = dm.calculateVariable(
{
name: "CountVehicle",
type: "measure",
defAggFn: "count",
numberFormat: (val) => parseInt(val, 10),
},
["Cylinders"],
() => 1,
);

const barChart = muze
.canvas()
.data(dmWithCount)
.color("Origin")
.rows(["Acceleration"])
.columns(["Cylinders"])
.title("Cylinders vs. Acceleration")
.mount("#bar");

const pieChart = muze
.canvas()
.data(dmWithCount)
.rows([])
.columns([])
.color("Origin")
.layers([
{
mark: "arc",
encoding: {
angle: "CountVehicle",
},
},
])
.title("Count of cars by Origin")
.mount("#pie");

Make both charts cross interactive

Now we will learn how you can make both of the charts cross interactive using a simple api of Muze.

Here is the code for enabling cross interactivity,

muze.ActionModel.for(barChart, pieChart).enableCrossInteractivity();

Here, ActionModel is the interaction registry which registers interactions and enables cross interactions between multiple canvases.

ActionModel.for api takes any array of canvas instances and enableCrossInteractivity api enables cross interactions among all the canvases. This enables all the default interactions like tooltips and highlighting.

Next, we will add crossfiltering between canvases.

muze.ActionModel.for(barChart, pieChart).enableCrossInteractivity({
[barChart.alias()]: {
select: {
target: {
[pieChart.alias()]: {
filter: {
sideEffects: ["filter"],
},
},
},
},
},
});

This tells muze to filter other pieChart canvas whenever an select even occurs on the barChart.

const { muze, getDataFromSearchQuery, env } = viz;
const data = getDataFromSearchQuery();

const dmWithCount = dm.calculateVariable(
{
name: "CountVehicle",
type: "measure",
defAggFn: "count",
numberFormat: (val) => parseInt(val, 10),
},
["Cylinders"],
() => 1,
);

const barChart = muze
.canvas()
.data(dmWithCount)
.rows(["Acceleration"])
.columns(["Cylinders"])
.color("Origin")
.title("Cylinders vs. Acceleration")
.mount("#bar");

const pieChart = muze
.canvas()
.data(dmWithCount)
.rows([])
.columns([])
.color("Origin")
.layers([
{
mark: "arc",
encoding: {
angle: "CountVehicle",
},
},
])
.title("Count of cars by Origin")
.mount("#pie");

muze.ActionModel.for(barChart, pieChart).enableCrossInteractivity({
[barChart.alias()]: {
select: {
target: {
[pieChart.alias()]: {
filter: {
sideEffects: ["filter"],
},
},
},
},
},
});