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
//achieving the highest percentage gain in portfolio value from the initial investment made on November 8, 2019, to its value on November 8, 2023.
//增值/投资
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
Insert cell
render({
data: { values: portfolioData },

transform: [
{ calculate: "year(datum.Date)", as: "Year" },
{ calculate: "datum.Shares * datum.Price", as: "TotalValue" },
{
aggregate: [
{ op: "sum", field: "TotalValue", as: "YearValue" }
],
groupby: ["Investor", "Year"]
},
{ pivot: "Year", value: "YearValue", groupby: ["Investor"] },
{
calculate: "(datum['2023'] - datum['2019']) / datum['2019'] * 100",
as: "PctGain"
}
],

mark: { type: "bar", cornerRadiusEnd: 3 },
encoding: {
x: { field: "Investor", type: "nominal", sort: "-y" },
y: { field: "PctGain", type: "quantitative", title: "% Gain (2019–2023)" },
color: {
field: "PctGain",
type: "quantitative",
scale: { scheme: "blues" }
},
tooltip: [
{ field: "Investor", type: "nominal" },
{ field: "PctGain", type: "quantitative", format: ".2f", title: "% Gain" },
{ field: "2019", type: "quantitative", title: "Value 2019 ($)" },
{ field: "2023", type: "quantitative", title: "Value 2023 ($)" }
]
},

title: "Portfolio % Gain by Investor (2019 → 2023)"
});

Insert cell
Insert cell
Insert cell
// write the code for your revised visualization here
// or add a screenshot in a new 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