Let's create a pie chart component that takes the following inputs in the Embeddable no-code builder:
And produces the following chart on the canvas:
For simplicity we’ll use the react wrapper for Chart.js to render the chart:
import React from 'react';
import { Line } from 'react-chartjs-2';
import { Dimension, Measure, Dataset } from "@embeddable.com/core";
import { DataResponse } from "@embeddable.com/react";
import Loading from '../util/Loading'
import Error from '../util/Error'
...
type Props = {
ds: Dataset;
slice: Dimension; // { name, title }
metric: Measure; // [{ name, title }]
results: DataResponse; // { isLoading, error, data: [{ <name>: <value>, ... }] }
};
export default (props: Props) => {
const { slice, metric, results } = props;
const { isLoading, data, error } = results;
if(isLoading) {
return <Loading />
}
if(error) {
return <Error msg={error}/>;
}
/*
E.g:
data = [
{ country: "US", count: 23 },
{ country: "UK", count: 10 },
{ country: "Germany", count: 5 },
]
slice = { name: 'country' }
metric = { name: 'count' }
*/
// Chart.js pie expects labels like so: ['US', 'UK', 'Germany']
const labels = data.map(d => d[slice.name]);
// Chart.js pie expects counts like so: [23, 10, 5]
const counts = data.map(d => d[metric.name]);
return <Pie options={chartOptions()}
data={chartData(labels, counts)} />
};
There is nothing Embeddable-specific about this code. It is just standard React, using the Pie chart from Chart.js.
Then all we need to do is tell Embeddable what are the inputs for our component, and how do they map to the props for our React component:
import { defineComponent } from '@embeddable.com/react';
import { loadData } from '@embeddable.com/core';
import Component from './index'; // this is our React component (index.tsx, above)
export const meta = {
name: 'BasicPieComponent', // unique name for this component (must match file name)
label: 'Basic Pie', // human readable name for showing in the no-code builder
inputs: [ // the inputs the no-code builder user will be asked to enter
{
name: "ds", // unique name for this input
type: "dataset", // tells Embeddable to render a dropdown containing available datasets
label: "Dataset to display", // human readable name for this input (shown in UI above)
},
{
name: "slice",
type: "dimension", // renders a dropdown containing available dimensions
label: "Slice",
config: {
dataset: "ds", // only show dimensions from dataset "ds" (defined above)
},
},
{
name: "metric",
type: "measure", // renders a dropdown containing available measures
label: "Metric",
config: {
dataset: "ds", //only show measures from dataset "ds" (defined above)
},
}
],
};
export default defineComponent(Component, meta, {
props: (inputs) => {
return {
// pass ds, slice and metric directly to the React component
...inputs,
// request data to populate our chart
results: loadData({
from: inputs.ds,
dimensions: [inputs.slice],
measures: [inputs.metric],
})
};
}
});
Some things to notice:
dataset
dimension
measure
loadData
function.
As you can see, creating components in Embeddable is as simple as: