Skip to content
Snippets Groups Projects
Unverified Commit a4bec904 authored by Emmad Usmani's avatar Emmad Usmani Committed by GitHub
Browse files

automatically use compact formatting for pie chart total (#46505)

* automatically use compact formatting for pie chart total

* add story and snapshots
parent cf7a09e3
No related branches found
No related tags found
No related merge requests found
.loki/reference/chrome_laptop_Visualizations_ChartSkeleton_Pie.png

8.23 KiB

.loki/reference/chrome_laptop_static_viz_PieChart_Auto_Compact_Total.png

45.6 KiB

......@@ -49,6 +49,13 @@ AllSettings.args = {
renderingContext,
};
export const AutoCompactTotal = Template.bind({});
AutoCompactTotal.args = {
rawSeries: data.autoCompactTotal as any,
dashcardSettings: {},
renderingContext,
};
export const Colors = Template.bind({});
Colors.args = {
rawSeries: data.colors as any,
......
[
{
"card": {
"original_card_id": 404,
"can_delete": false,
"public_uuid": null,
"parameter_usage_count": 0,
"created_at": "2024-08-05T20:30:10.651932Z",
"parameters": [],
"metabase_version": "v0.2.0-SNAPSHOT (69588cf)",
"collection": {
"authority_level": null,
"description": null,
"archived": false,
"trashed_from_location": null,
"slug": "pie",
"archive_operation_id": null,
"name": "Pie",
"personal_owner_id": null,
"type": null,
"is_sample": false,
"id": 23,
"archived_directly": null,
"entity_id": "hy98llXqY3i_uwtm5ISY_",
"location": "/5/",
"namespace": null,
"is_personal": false,
"created_at": "2024-06-03T19:59:20.91934Z"
},
"visualization_settings": {
"pie.percent_visibility": "legend",
"column_settings": {
"[\"name\",\"sum\"]": {
"number_style": "currency",
"scale": 1000000000
}
}
},
"last-edit-info": {
"id": 1,
"email": "emmad@metabase.com",
"first_name": "Emmad",
"last_name": "Usmani",
"timestamp": "2024-08-05T20:57:14.264199Z"
},
"collection_preview": true,
"entity_id": "nrUcr1BhxR1jlJyMjTjIn",
"archived_directly": false,
"display": "pie",
"parameter_mappings": [],
"id": 404,
"dataset_query": {
"database": 1,
"type": "query",
"query": {
"source-table": 2,
"joins": [
{
"alias": "Products",
"condition": [
"=",
[
"field",
40,
{
"base-type": "type/Integer"
}
],
[
"field",
62,
{
"base-type": "type/BigInteger",
"join-alias": "Products"
}
]
],
"source-table": 1
}
],
"aggregation": [
[
"sum",
[
"field",
42,
{
"base-type": "type/Float"
}
]
]
],
"breakout": [
[
"field",
59,
{
"base-type": "type/Float",
"join-alias": "Products",
"binning": {
"strategy": "default"
}
}
]
]
}
},
"cache_ttl": null,
"embedding_params": null,
"made_public_by_id": null,
"updated_at": "2024-08-05T20:57:54.323277Z",
"moderation_reviews": [],
"can_restore": false,
"creator_id": 1,
"average_query_time": 392.625,
"type": "question",
"last_used_at": "2024-08-05T20:57:36.657574Z",
"dashboard_count": 2,
"last_query_start": "2024-08-05T20:57:36.586596Z",
"name": "Pie - auto compact total",
"query_type": "query",
"collection_id": 23,
"enable_embedding": false,
"database_id": 1,
"trashed_from_collection_id": null,
"can_write": true,
"initially_published_at": null,
"creator": {
"email": "emmad@metabase.com",
"first_name": "Emmad",
"last_login": "2024-08-01T22:52:19.345702Z",
"is_qbnewb": false,
"is_superuser": true,
"id": 1,
"last_name": "Usmani",
"date_joined": "2023-11-21T21:25:41.062104Z",
"common_name": "Emmad Usmani"
},
"result_metadata": [
{
"description": "The list price of the product. Note that this is not always the price the product sold for due to discounts, promotions, etc.",
"semantic_type": null,
"coercion_strategy": null,
"name": "PRICE",
"settings": null,
"fk_target_field_id": null,
"field_ref": [
"field",
59,
{
"base-type": "type/Float",
"join-alias": "Products",
"binning": {
"strategy": "num-bins",
"min-value": 12.5,
"max-value": 100,
"num-bins": 8,
"bin-width": 12.5
}
}
],
"effective_type": "type/Float",
"id": 59,
"visibility_type": "normal",
"display_name": "Products → Price",
"fingerprint": {
"global": {
"distinct-count": 170,
"nil%": 0
},
"type": {
"type/Number": {
"min": 15.691943673970439,
"q1": 37.25154462926434,
"q3": 75.45898071609447,
"max": 98.81933684368194,
"sd": 21.711481557852057,
"avg": 55.74639966792074
}
}
},
"base_type": "type/Float"
},
{
"display_name": "Sum of Total",
"semantic_type": null,
"settings": null,
"field_ref": ["aggregation", 0],
"base_type": "type/Float",
"effective_type": "type/Float",
"name": "sum",
"fingerprint": {
"global": {
"distinct-count": 7,
"nil%": 0
},
"type": {
"type/Number": {
"min": 28736.694011055744,
"q1": 174576.8862639765,
"q3": 271320.6692900193,
"max": 392735.2694337764,
"sd": 111670.79255772682,
"avg": 215803.0975786616
}
}
}
}
],
"can_run_adhoc_query": true,
"table_id": 2,
"collection_position": null,
"view_count": 4,
"archived": false,
"description": null,
"cache_invalidated_at": null,
"displayIsLocked": true
},
"data": {
"rows": [
[12.5, 28736.694011055744],
[25, 169910.41361932785],
[37.5, 257168.1884902365],
[50, 197456.6504083654],
[62.5, 276038.1628899469],
[75, 392735.2694337764],
[87.5, 188576.30419792255]
],
"cols": [
{
"description": "The list price of the product. Note that this is not always the price the product sold for due to discounts, promotions, etc.",
"database_type": "DECFLOAT",
"semantic_type": null,
"table_id": 1,
"coercion_strategy": null,
"binning_info": {
"min_value": 12.5,
"max_value": 100,
"num_bins": 8,
"bin_width": 12.5,
"binning_strategy": "num-bins"
},
"name": "PRICE",
"settings": null,
"source": "breakout",
"fk_target_field_id": null,
"field_ref": [
"field",
59,
{
"base-type": "type/Float",
"join-alias": "Products",
"binning": {
"strategy": "num-bins",
"min-value": 12.5,
"max-value": 100,
"num-bins": 8,
"bin-width": 12.5
}
}
],
"effective_type": "type/Float",
"nfc_path": null,
"parent_id": null,
"id": 59,
"position": 5,
"visibility_type": "normal",
"display_name": "Products → Price",
"fingerprint": {
"global": {
"distinct-count": 170,
"nil%": 0
},
"type": {
"type/Number": {
"min": 15.691943673970439,
"q1": 37.25154462926434,
"q3": 75.45898071609447,
"max": 98.81933684368194,
"sd": 21.711481557852057,
"avg": 55.74639966792074
}
}
},
"base_type": "type/Float",
"source_alias": "Products"
},
{
"database_type": "DECFLOAT",
"semantic_type": null,
"name": "sum",
"settings": null,
"source": "aggregation",
"field_ref": ["aggregation", 0],
"effective_type": "type/Float",
"aggregation_index": 0,
"display_name": "Sum of Total",
"base_type": "type/Float"
}
],
"native_form": {
"query": "SELECT (FLOOR(((\"Products\".\"PRICE\" - 12.5) / 12.5)) * 12.5) + 12.5 AS \"Products__PRICE\", SUM(\"PUBLIC\".\"ORDERS\".\"TOTAL\") AS \"sum\" FROM \"PUBLIC\".\"ORDERS\" LEFT JOIN \"PUBLIC\".\"PRODUCTS\" AS \"Products\" ON \"PUBLIC\".\"ORDERS\".\"PRODUCT_ID\" = \"Products\".\"ID\" GROUP BY (FLOOR(((\"Products\".\"PRICE\" - 12.5) / 12.5)) * 12.5) + 12.5 ORDER BY (FLOOR(((\"Products\".\"PRICE\" - 12.5) / 12.5)) * 12.5) + 12.5 ASC",
"params": null
},
"format-rows?": true,
"results_timezone": "America/Los_Angeles",
"results_metadata": {
"columns": [
{
"description": "The list price of the product. Note that this is not always the price the product sold for due to discounts, promotions, etc.",
"semantic_type": null,
"coercion_strategy": null,
"name": "PRICE",
"settings": null,
"fk_target_field_id": null,
"field_ref": [
"field",
59,
{
"base-type": "type/Float",
"join-alias": "Products",
"binning": {
"strategy": "num-bins",
"min-value": 12.5,
"max-value": 100,
"num-bins": 8,
"bin-width": 12.5
}
}
],
"effective_type": "type/Float",
"id": 59,
"visibility_type": "normal",
"display_name": "Products → Price",
"fingerprint": {
"global": {
"distinct-count": 170,
"nil%": 0
},
"type": {
"type/Number": {
"min": 15.691943673970439,
"q1": 37.25154462926434,
"q3": 75.45898071609447,
"max": 98.81933684368194,
"sd": 21.711481557852057,
"avg": 55.74639966792074
}
}
},
"base_type": "type/Float"
},
{
"display_name": "Sum of Total",
"semantic_type": null,
"settings": null,
"field_ref": ["aggregation", 0],
"base_type": "type/Float",
"effective_type": "type/Float",
"name": "sum",
"fingerprint": {
"global": {
"distinct-count": 7,
"nil%": 0
},
"type": {
"type/Number": {
"min": 28736.694011055744,
"q1": 174576.8862639765,
"q3": 271320.6692900193,
"max": 392735.2694337764,
"sd": 111670.79255772682,
"avg": 215803.0975786616
}
}
}
}
]
},
"insights": null
}
}
]
import allNegative from "./all-negative.json";
import allSettings from "./all-settings.json";
import allZeroMetric44847 from "./all-zero-metric-44847.json";
import autoCompactTotal from "./auto-compact-total.json";
import binnedDimension from "./binned-dimension.json";
import booleanDimension from "./boolean-dimension.json";
import colors from "./colors.json";
......@@ -77,6 +78,7 @@ export const data = {
invalidDimensionSetting44085,
percentagesOnChartBooleanDimensionCrashes44085,
allZeroMetric44847,
autoCompactTotal,
noSingleColumnLegend45149,
numericSQLColumnCrashes28568,
missingLabelLargeSlice38424,
......
......@@ -20,6 +20,7 @@ export const DIMENSIONS = {
minWidth: 120,
valueFontSize: 22,
labelFontSize: 14,
fontWeight: 700,
},
};
......
......@@ -8,7 +8,7 @@ import type { PieChartModel } from "./model/types";
export interface PieChartFormatters {
formatDimension: (value: unknown) => string;
formatMetric: (value: unknown) => string;
formatMetric: (value: unknown, isCompact?: boolean) => string;
formatPercent: (value: unknown, location: "legend" | "chart") => string;
}
......@@ -34,9 +34,10 @@ export function getPieChartFormatters(
...dimensionColSettings,
});
const formatMetric = (value: unknown) =>
const formatMetric = (value: unknown, isCompact: boolean = false) =>
renderingContext.formatValue(value, {
...metricColSettings,
compact: isCompact,
});
const formatPercent = (value: unknown, location: "legend" | "chart") => {
......
......@@ -40,13 +40,21 @@ function getTotalGraphicOption(
const hasSufficientWidth = outerRadius * 2 >= DIMENSIONS.total.minWidth;
if (hasSufficientWidth && settings["pie.show_total"]) {
const sliceValueOrTotal =
hoveredIndex != null
? chartModel.slices[hoveredIndex].data.displayValue
: chartModel.total;
const valueWillOverflow =
renderingContext.measureText(formatters.formatMetric(sliceValueOrTotal), {
size: DIMENSIONS.total.valueFontSize,
family: renderingContext.fontFamily,
weight: DIMENSIONS.total.fontWeight,
}) > outerRadius; // innerRadius technically makes more sense, but looks too narrow in practice
valueText = truncateText(
formatters.formatMetric(
hoveredIndex != null
? chartModel.slices[hoveredIndex].data.displayValue
: chartModel.total,
),
outerRadius, // innerRadius technically makes more sense, but looks too narrow in practice
formatters.formatMetric(sliceValueOrTotal, valueWillOverflow),
outerRadius,
DIMENSIONS.total.valueFontSize,
);
labelText = truncateText(
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment