Public
Edited
May 15
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
portfolioData = d3.csv("https://docs.google.com/spreadsheets/d/e/2PACX-1vQSz2gGUW3Sgq0hrcpaKM3ToNgEGImWgwJthfp3b9OUmxiEcEN6kMZygz1HZuq1cbbPcxcWXGUicurY/pub?gid=0&single=true&output=csv")
Insert cell
Insert cell
Insert cell
Insert cell
render({
mark: "arc",
data: { values: portfolioData },
transform: [
{ calculate: "datum.Shares*datum.Price", as: "Total Value" }
],
encoding: {
row: { field: "Date", type: "T" },
column: { field: "Investor", type: "N" },
color: { field: "Symbol", type: "N" },
theta: { field: "Total Value", type: "Q" },
tooltip: [
{ field: "Symbol", type: "N" },
{ field: "Price", type: "Q" },
{ field: "Shares", type: "Q" },
{ field: "Total Value", type: "Q" }
]
},
width: 150,
height: 200
})
Insert cell
Insert cell
render({
mark: "bar",
data: { values: portfolioData },
transform: [
{ calculate: "datum.Shares * datum.Price", as: "Total Value" }
],
encoding: {
x: { field: "Investor", type: "N" },
y: { aggregate: "sum", field: "Total Value", type: "Q" },
color: { field: "Symbol", type: "N" },
tooltip: [
{ field: "Symbol", type: "N" },
{ field: "Price", type: "Q" },
{ field: "Shares", type: "Q" },
{ field: "Total Value", type: "Q" }
]
}
})
Insert cell
Insert cell
render({
mark: { type: "line", point: true },
data: { values: portfolioData },
transform: [
{ calculate: "datum.Shares * datum.Price", as: "Total Value" }
],
encoding: {
x: { field: "Date", type: "T" },
y: { aggregate: "sum", field: "Total Value", type: "Q" },
column: { field: "Investor", type: "N" },
tooltip: [
{ field: "Date", type: "T" },
{ aggregate: "sum", field: "Total Value", type: "Q" }
],
},
width: 190,
height: 200
})
Insert cell
Insert cell
render({
mark: { type: "bar", bar: { size: 40 } },
data: { values: portfolioData },
transform: [
{ calculate: "datum.Shares * datum.Price", as: "Total Value" },
{
window: [{ op: "sum", field: "Total Value", as: "sum" }],
frame: [null, null],
groupby: ["Date", "Investor"]
},
{
calculate: "datum['Total Value'] / datum['sum']",
as: "Percent"
}
],
encoding: {
column: { field: "Date", type: "T" },
row: { field: "Investor", type: "N" },
color: { field: "Symbol", type: "N" },
theta: { field: "Total Value", type: "Q" },

tooltip: [
{ field: "Symbol", type: "N" },
{ field: "Price", type: "Q" },
{ field: "Shares", type: "Q" },
{ field: "Total Value", type: "Q" },
],

x: {
field: "Percent",
type: "Q",
axis: { title: "Percent", format: ".0%" }
},
},
width: 1000,
height: 100,
column: 4
});

Insert cell
Insert cell
Insert cell
Insert cell
render({
mark: { type: "bar", bar: { size: 40 } },
data: { values: portfolioData },
transform: [
{ calculate: "datum.Shares * datum.Price", as: "Total Value" },
{
window: [{ op: "sum", field: "Total Value", as: "sum" }],
frame: [null, null],
groupby: ["Date", "Investor"]
},


{
calculate: "datum['Total Value'] / datum['sum']",
as: "percent"
},



//Rank the bar chart and make it easier for readers to get the statistical information
{
window: [{ op: "rank", as: "rank" }],
sort: [{ field: "Total Value", order: "descending" }],
groupby: ["Date", "Investor"]
},

],




encoding: {
column: { field: "Investor", type: "N" },
row: { field: "Date", type: "T" },


color: { field: "Symbol", type: "N" },
tooltip: [
{ field: "Symbol", type: "N" },
{ field: "Price", type: "Q" },
{ field: "Shares", type: "Q" },
{ field: "Total Value", type: "Q" },
],

// show it horizontally, and the readers can directly know the percentage of each stock symbol
x: {
field: "rank",
type: "O",
axis: null
},
y: {
field: "percent",
type: "Q",
axis: { format: ".0%", title: "Percentage" }
},
},
width: 150,
height: 200
});
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell

Purpose-built for displays of data

Observable is your go-to platform for exploring data and creating expressive data visualizations. Use reactive JavaScript notebooks for prototyping and a collaborative canvas for visual data exploration and dashboard creation.
Learn more