Skip to content
This repository was archived by the owner on Feb 18, 2025. It is now read-only.
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 8 additions & 10 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@
},
"devDependencies": {
"@embeddable.com/core": "^2.8.1",
"@embeddable.com/react": "^2.9.1",
"@embeddable.com/react": "^2.9.2",
"@embeddable.com/sdk-core": "^3.12.4",
"@embeddable.com/sdk-react": "^3.10.4",
"@trivago/prettier-plugin-sort-imports": "^4.3.0",
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
import {defineComponent, EmbeddedComponentMeta, Inputs} from '@embeddable.com/react';
import { loadData } from '@embeddable.com/core';

import Component from './BasicPieComponent';

export const meta = {
name: 'BasicPieComponent', // unique name for this component (must match file name)
label: 'Basic Pie',
category: 'Ailo: components',
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)
},
},
{
name: 'showLegend',
type: 'boolean',
label: 'Turn on the legend',
defaultValue: true,
category: 'Chart settings',
},
]
} as const satisfies EmbeddedComponentMeta;

export default defineComponent(Component, meta, {
props: (inputs: Inputs<typeof meta>) => {
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],
})
};
}
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
import React from 'react';
import { Pie } from 'react-chartjs-2';
import {Dimension, Measure, Dataset, DataResponse} from "@embeddable.com/core";
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>, ... }] }
showLegend: boolean;
};

const COLORS = [
'#A9DBB0',
'#F59E54',
'#F77A5F',
'#8FCBCF',
'#C3B0EA',
];

const chartOptions = (showLegend: boolean) => ({
responsive: true,
maintainAspectRatio: false,
plugins: {
legend: {
display: showLegend
}
},
});

const chartData = (labels: string[] | undefined, counts: number[] | undefined) => {
return {
labels,
datasets: [
{
data: counts,
backgroundColor: COLORS,
borderColor: COLORS,
}
]
};
}

export default (props: Props) => {
const { slice, metric, results, showLegend } = 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: string[] |undefined = data?.map(d => d[slice.name] as string);

// Chart.js pie expects counts like so: [23, 10, 5]
const counts = data?.map(d => d[metric.name] as number);

return <Pie options={chartOptions(showLegend)}
data={chartData(labels, counts)} />
};
1 change: 1 addition & 0 deletions src/components/ailo-components/BasicPieComponent/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * as BasicPieComponent from "./BasicPieComponent.emb";
Original file line number Diff line number Diff line change
@@ -0,0 +1,190 @@
import { OrderBy, loadData } from '@embeddable.com/core';
import { EmbeddedComponentMeta, Inputs, defineComponent } from '@embeddable.com/react';

import Component from './BasicStackedBarChart';

export const meta = {
name: 'BasicStackedBarChart',
label: 'Basica stacked bar chart',
classNames: ['inside-card'],
category: 'Ailo: components',
inputs: [
{
name: 'ds',
type: 'dataset',
label: 'Dataset to display',
category: 'Chart data',
},
{
name: 'xAxis',
type: 'dimension',
label: 'X-Axis',
config: {
dataset: 'ds',
},
category: 'Chart data',
},
{
name: 'segment',
type: 'dimension',
label: 'Grouping',
config: {
dataset: 'ds',
},
category: 'Chart data',
},
{
name: 'metric',
type: 'measure',
label: 'Metric',
config: {
dataset: 'ds',
},
category: 'Chart data',
},
{
name: 'sortBy',
type: 'dimensionOrMeasure',
label: 'Sort by (optional)',
config: {
dataset: 'ds',
},
category: 'Chart data',
},
{
name: 'title',
type: 'string',
label: 'Title',
description: 'The title for the chart',
category: 'Chart settings',
},
{
name: 'description',
type: 'string',
label: 'Description',
description: 'The description for the chart',
category: 'Chart settings',
},
{
name: 'stackBars',
type: 'boolean',
label: 'Stack bars',
defaultValue: true,
category: 'Chart settings',
},
{
name: 'showLegend',
type: 'boolean',
label: 'Show legend',
defaultValue: true,
category: 'Chart settings',
},
{
name: 'maxSegments',
type: 'number',
label: 'Max Legend Items',
defaultValue: 8,
category: 'Chart settings',
},
{
name: 'otherSegmentsName',
type: 'string',
label: 'Other segments grouped name',
defaultValue: 'Other',
category: 'Chart settings',
},
{
name: 'maxLabelsToShow',
type: 'number',
label: 'Max number of labels to show',
defaultValue: 8,
category: 'Chart settings',
},
{
name: 'otherLabelsName',
type: 'string',
label: 'Other labels grouped name',
defaultValue: 'Other',
category: 'Chart settings',
},
{
name: 'showLabels',
type: 'boolean',
label: 'Show Labels',
defaultValue: false,
category: 'Chart settings',
},
{
name: 'showTotals',
type: 'boolean',
label: 'Show Totals Above Stacked Bars',
defaultValue: false,
category: 'Chart settings',
},
{
name: 'displayHorizontally',
type: 'boolean',
label: 'Display Horizontally',
defaultValue: false,
category: 'Chart settings',
},
{
name: 'reverseXAxis',
type: 'boolean',
label: 'Reverse X Axis',
category: 'Chart settings',
defaultValue: false,
},
{
name: 'displayAsPercentage',
type: 'boolean',
label: 'Display as Percentages',
defaultValue: false,
category: 'Chart settings',
},
{
name: 'dps',
type: 'number',
label: 'Decimal Places',
category: 'Formatting',
},
{
name: 'enableDownloadAsCSV',
type: 'boolean',
label: 'Show download as CSV',
category: 'Export options',
defaultValue: true,
},
{
name: 'enableDownloadAsPNG',
type: 'boolean',
label: 'Show download as PNG',
category: 'Export options',
defaultValue: true,
},
],
} as const satisfies EmbeddedComponentMeta;

export default defineComponent(Component, meta, {
props: (inputs: Inputs<typeof meta>) => {
const orderProp: OrderBy[] = [];

if (inputs.sortBy) {
orderProp.push({
property: inputs.sortBy,
direction: inputs.sortBy.nativeType == 'string' ? 'asc' : 'desc',
});
}

return {
...inputs,
isGroupedBar: true,
results: loadData({
from: inputs.ds,
dimensions: [inputs.xAxis, inputs.segment],
measures: [inputs.metric],
orderBy: orderProp,
}),
};
},
});
Loading