Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

google-analytics edits #759

Merged
merged 11 commits into from
Feb 14, 2024
21 changes: 21 additions & 0 deletions examples/google-analytics/docs/components/formatTrend.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import {html} from "npm:htl";

export function formatTrend(
value,
{
locale,
format = {},
positive = "green",
negative = "red",
base = "muted",
positiveSuffix = " ↗︎",
negativeSuffix = " ↘︎",
baseSuffix = ""
} = {}
) {
if (format.signDisplay === undefined) format = {...format, signDisplay: "always"};
return html`<span class="small ${value > 0 ? positive : value < 0 ? negative : base}">${value.toLocaleString(
locale,
format
)}${value > 0 ? positiveSuffix : value < 0 ? negativeSuffix : baseSuffix}`;
}
14 changes: 14 additions & 0 deletions examples/google-analytics/docs/components/lineChart.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import * as Plot from "npm:@observablehq/plot";

export function lineChart(data, {width, height = 94, x = "date", y, percent} = {}) {
return Plot.plot({
width,
height,
axis: null,
insetTop: 10,
insetLeft: -15,
insetRight: -17,
y: {zero: true, percent, domain: percent ? [0, 100] : undefined},
marks: [Plot.areaY(data, {x, y, fillOpacity: 0.25}), Plot.lineY(data, {x, y, tip: true})]
});
}
29 changes: 0 additions & 29 deletions examples/google-analytics/docs/components/marimekko.js

This file was deleted.

89 changes: 89 additions & 0 deletions examples/google-analytics/docs/components/marimekkoChart.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
import * as Plot from "npm:@observablehq/plot";
import * as d3 from "npm:d3";

export function marimekkoChart(data, {width, height, xDim, yDim, metric, title, caption, color}) {
const xy = (options) => Marimekko({...options, x: xDim, y: yDim, value: metric});
return Plot.plot({
width,
height,
subtitle: title,
caption,
label: null,
x: {percent: true, ticks: 10, tickFormat: (d) => (d === 100 ? `100%` : d)},
y: {percent: true, ticks: 10, tickFormat: (d) => (d === 100 ? `100%` : d)},
color,
marks: [
Plot.text(
data,
xy({
text: (d) => d[metric].toLocaleString("en"),
fontSize: 14,
fontWeight: 600,
stroke: yDim,
fill: "var(--theme-background)"
})
),
Plot.rect(data, xy({fill: yDim, fillOpacity: 1})),
Plot.frame({fill: "var(--theme-background)", fillOpacity: 0.2}),
Plot.text(
data,
xy({
text: yDim,
fontSize: 11,
dy: -16,
fill: "var(--theme-background)"
})
),
Plot.text(
data,
xy({
text: (d) => d[metric].toLocaleString("en"),
fontSize: 14,
fontWeight: 600,
fill: "var(--theme-background)"
})
),
Plot.text(
data,
Plot.selectMaxY(
xy({
z: xDim,
text: (d) => `${d[xDim].slice(0, 1).toUpperCase()}${d[xDim].slice(1)}`,
anchor: "top",
lineAnchor: "bottom",
fontSize: 12,
dy: -6
})
)
)
]
});
}

// TODO attribution
function Marimekko({x, y, z, value = z, anchor = "middle", inset = 0.5, ...options} = {}) {
const stackX = /\bleft$/i.test(anchor) ? Plot.stackX1 : /\bright$/i.test(anchor) ? Plot.stackX2 : Plot.stackX;
const stackY = /^top\b/i.test(anchor) ? Plot.stackY2 : /^bottom\b/i.test(anchor) ? Plot.stackY1 : Plot.stackY;
const [X, setX] = Plot.column(x);
const [Y, setY] = Plot.column(y);
const [Xv, setXv] = Plot.column(value);
const {x: Xs, x1, x2, transform: tx} = stackX({offset: "expand", y: Y, x: Xv, z: X, order: "appearance"});
const {y: Ys, y1, y2, transform: ty} = stackY({offset: "expand", x, y: value, z: Y, order: "appearance"});
return Plot.transform({x: Xs, x1, x2, y: Ys, y1, y2, z, inset, frameAnchor: anchor, ...options}, (data, facets) => {
const X = setX(Plot.valueof(data, x));
setY(Plot.valueof(data, y));
const Xv = setXv(new Float64Array(data.length));
const Z = Plot.valueof(data, value);
for (const I of facets) {
const sum = d3.rollup(
I,
(J) => d3.sum(J, (i) => Z[i]),
(i) => X[i]
);
for (const i of I) Xv[i] = sum.get(X[i]);
}
tx(data, facets);
ty(data, facets);
return {data, facets};
});
}
52 changes: 52 additions & 0 deletions examples/google-analytics/docs/components/punchcardChart.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
import * as Plot from "npm:@observablehq/plot";
import * as d3 from "npm:d3";

export function punchcardChart(data, {width, height, label, metric} = {}) {
const aggregatedValues = d3
.rollups(
data,
(v) => d3.median(v, (d) => d[metric]),
(d) => d.hour,
(d) => d.dayOfWeek
)
.flatMap((d) => d[1].map((d) => d[1]));

return Plot.plot({
width,
height,
inset: 12,
padding: 0,
marginBottom: 10,
grid: true,
round: false,
label: null,
x: {
axis: "top",
domain: d3.range(24),
interval: 1,
tickFormat: (d) => (d % 12 || 12) + (d === 0 ? " AM" : d === 12 ? " PM" : "")
},
y: {
domain: ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"],
tickFormat: (d) => d.substr(0, 3)
},
r: {label, range: [1, 15], domain: d3.extent(aggregatedValues)},
marks: [
Plot.dot(
data,
Plot.group(
{r: "median"},
{
y: "dayOfWeek",
x: "hour",
r: metric,
fill: "currentColor",
stroke: "var(--theme-background)",
sort: null,
tip: true
}
)
)
]
});
}
31 changes: 0 additions & 31 deletions examples/google-analytics/docs/components/trend.js

This file was deleted.

7 changes: 0 additions & 7 deletions examples/google-analytics/docs/data/countries-110m.json.ts

This file was deleted.

This file was deleted.

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,16 @@ import {runReport} from "./google-analytics.js";
const response = await runReport({
dateRanges: [{startDate: "2023-04-01", endDate: "2023-12-31"}],
dimensions: [{name: "hour"}, {name: "dayOfWeekName"}],
metrics: [{name: "activeUsers"}]
metrics: [{name: "activeUsers"}, {name: "newUsers"}]
});

process.stdout.write(
csvFormat(
response.rows.map((d) => ({
hour: d.dimensionValues[0].value,
dayOfWeek: d.dimensionValues[1].value,
activeUsers: d.metricValues[0].value
activeUsers: d.metricValues[0].value,
newUsers: d.metricValues[1].value
}))
)
);
4 changes: 3 additions & 1 deletion examples/google-analytics/docs/data/google-analytics.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,9 @@ const defaultDimensionFilter = {
filter: {
fieldName: "fullPageUrl",
stringFilter: {
value: "observablehq.com/plot/"
value: "observablehq.com/plot",
matchType: "BEGINS_WITH",
caseSensitive: false
}
}
};
Expand Down
Loading