Skip to content

Commit

Permalink
Chart label updates (metabase#12169)
Browse files Browse the repository at this point in the history
  • Loading branch information
paulrosenzweig authored Mar 23, 2020
1 parent 06fdd99 commit a219c78
Show file tree
Hide file tree
Showing 5 changed files with 64 additions and 29 deletions.
10 changes: 10 additions & 0 deletions frontend/src/metabase/css/dashboard.css
Original file line number Diff line number Diff line change
Expand Up @@ -366,6 +366,16 @@
background-color: color(var(--color-bg-white) alpha(-86%));
}

.Dashboard--night text.value-label-outline {
stroke: var(--night-mode-card);
}

.Dashboard text.value-label,
.Dashboard text.value-label-outline,
.Dashboard .LineAreaBarChart .dc-chart .axis text {
font-size: 12px;
}

.ScalarValue {
font-weight: 900;
font-size: 1.8rem;
Expand Down
20 changes: 0 additions & 20 deletions frontend/src/metabase/css/query_builder.css
Original file line number Diff line number Diff line change
Expand Up @@ -692,23 +692,3 @@
.ParameterValuePickerNoPopover input::-webkit-input-placeholder {
color: var(--color-text-medium);
}

text.value-label-outline {
font-weight: 900;
stroke-width: 4px;
stroke: var(--color-text-white);
}

text.value-label {
fill: var(--color-text-dark);
font-weight: 900;
}

text.value-label-outline,
text.value-label {
pointer-events: none;
}

.Dashboard--night text.value-label-outline {
stroke: var(--night-mode-card);
}
Original file line number Diff line number Diff line change
Expand Up @@ -206,3 +206,19 @@
.LineAreaBarChart .dc-chart .trend .line {
stroke-dasharray: 5, 5;
}

text.value-label-outline,
text.value-label {
pointer-events: none;
}

text.value-label-outline {
font-weight: 800;
stroke-width: 4px;
stroke: var(--color-text-white);
}

text.value-label {
fill: var(--color-text-dark);
font-weight: 800;
}
20 changes: 11 additions & 9 deletions frontend/src/metabase/visualizations/lib/LineAreaBarPostRender.js
Original file line number Diff line number Diff line change
Expand Up @@ -262,15 +262,17 @@ function onRenderValueLabels(chart, formatYValue, [data]) {

// Update `data` to use named x/y and include `showLabelBelow`.
// We need to do that before data is filtered to show every nth value.
data = data.map(([x, y], i) => {
const isLocalMin =
// first point or prior is greater than y
(i === 0 || data[i - 1][1] > y) &&
// last point point or next is greater than y
(i === data.length - 1 || data[i + 1][1] > y);
const showLabelBelow = isLocalMin && display === "line";
return { x, y, showLabelBelow };
});
data = data
.map(([x, y], i) => {
const isLocalMin =
// first point or prior is greater than y
(i === 0 || data[i - 1][1] > y) &&
// last point point or next is greater than y
(i === data.length - 1 || data[i + 1][1] > y);
const showLabelBelow = isLocalMin && display === "line";
return { x, y, showLabelBelow };
})
.filter(d => display !== "bar" || d.y !== 0);

const formattingSetting = chart.settings["graph.label_value_formatting"];
let compact;
Expand Down
27 changes: 27 additions & 0 deletions frontend/src/metabase/visualizations/lib/apply_axis.js
Original file line number Diff line number Diff line change
Expand Up @@ -369,6 +369,33 @@ export function applyChartYAxis(chart, series, yExtent, axisName) {
scale = d3.scale.linear();
}

// This makes non-zero bar values take up at least one pixel.
// Ideally, we would just pass a custom interpolate factory to `interpolate`.
// However, dc.js passes its own after we give it the scael, so instead we
// overwrite the scale's interpolate method. That let's us use theirs but
// special case values withing one pixel of the edge.
if (series.every(s => s.card.display === "bar")) {
const _interpolate = scale.interpolate.bind(scale);
scale.interpolate = customInterpolatorFactory =>
_interpolate((a, b) => {
// dc.js uses a rounding interpolator. We want to use the factory they
// pass in, but we also need to create d3's default interpolator. We use
// that to see when a value is between 0 and 1. If we just looked at the
// rounded value, 0.49 would round to 0 and we wouldn't bump it up to 1.
const custom = customInterpolatorFactory(a, b);
const unrounded = d3.interpolate(a, b);
return t => {
const value = unrounded(t);
const onePixelUp = custom(0) - 1;
// y goes from top to bottom, so "onePixelUp" is actually the largest value
if (onePixelUp < value && value < unrounded(0)) {
return onePixelUp;
}
return custom(t);
};
});
}

scale.clamp(true);

if (axis.setting("auto_range")) {
Expand Down

0 comments on commit a219c78

Please sign in to comment.