-
Really enjoying learning JavaScript through Observable -- thank you!! However, I can't figure out how to add a slider to this histogram to select rows corresponding to a year in a parquet file/database (https://jaanli.github.io/american-community-survey/): ![]() Specifically, I read through the documentation here: https://observablehq.com/framework/lib/duckdb And modified the above example to try to refresh the data via the following DuckDB SQL query every time the slider value changes:
The The resulting Plot is blank: https://jaanli.github.io/american-community-survey/income ![]() The code is here: https://github.com/jaanli/american-community-survey/blob/main/docs/income.md And if I comment out the above lines, then I see the chart in the screenshot (as expected). I am likely missing something basic about JavaScript and promises. |
Beta Was this translation helpful? Give feedback.
Replies: 7 comments 3 replies
-
You need an await in your |
Beta Was this translation helpful? Give feedback.
This comment has been minimized.
This comment has been minimized.
-
Got it, thank you @Fil & @mbostock ! Made the change, but now I don't think I'm calling Observable Plot correctly, as it shows There's likely something simple I'm still missing, will keep digging around the documentation 🙏 P.S. Think I tried this initially but got confused after it showed "Promise" on the frontend and I reading the docs - was going by the documentation's first example: https://observablehq.com/framework/lib/duckdb
Also tried reading about Promises on Observable's documentation: https://observablehq.com/@observablehq/introduction-to-promises |
Beta Was this translation helpful? Give feedback.
-
I suggest that you define ```js
const income = db.query(`
SELECT income, count, sector FROM data
WHERE year = ${selectedYear}
`);
``` Then you pass the already-computed ```js
function incomeChart(income, width) {
return Plot.plot({
width,
marginLeft: 60,
x: { type: "log" },
color: { legend: "swatches", columns: 6, domain: orderSectors },
marks: [
Plot.rectY(
income,
Plot.binX(
{ y: "sum" },
{
x: "income",
y: "count",
fill: "sector",
order: orderSectors,
thresholds: d3
.ticks(Math.log10(2_000), Math.log10(1_000_000), 40)
.map((d) => +(10 ** d).toPrecision(3)),
tip: true,
}
)
),
],
});
}
``` Then lastly you render the chart like so: ${resize((width) => incomeChart(income, width))} |
Beta Was this translation helpful? Give feedback.
-
Thank you @mbostock ! Trying that now - that is much cleaner than what GPT-4 suggested, which was replacing
function renderChart(selectedYear) {
incomeChart(db, selectedYear, window.innerWidth * 0.9) // Assuming you want to use 90% of the window width for the chart
.then(chart => {
document.querySelector("#chartContainer").appendChild(chart); // Append the new chart
})
.catch(error => console.error("Failed to render chart:", error));
} // Assuming yearInput is already defined and set up as shown in your code.
// Listen for changes on the yearInput to update the chart accordingly.
yearInput.addEventListener('change', () => {
// Retrieve the current selected year from the input.
const selectedYear = yearInput.value;
// Call renderChart with the selected year.
renderChart(selectedYear);
});
// Call renderChart initially to render the chart for the first time with the most recent year or a default year.
renderChart(yearInput.value);
function renderChart(selectedYear) {
incomeChart(db, selectedYear, window.innerWidth * 0.9) // Adjust width as needed
.then(chart => {
const chartContainer = document.querySelector("#chartContainer");
if (chartContainer) {
chartContainer.innerHTML = ''; // Clear the container before appending new content
chartContainer.appendChild(chart); // Append the chart
} else {
console.error("Chart container not found");
}
})
.catch(error => console.error("Failed to render chart:", error));
} Diff here: jaanli/american-community-survey@e8f27c9 At least got that working now: https://jaanli.github.io/american-community-survey/income ![]() Pretty wild to see data from 38033488 Americans like this! Excited for more exploration given what this enables with geospatial. |
Beta Was this translation helpful? Give feedback.
-
That was indeed much cleaner - thank you @mbostock & @Fil for bearing with my learning about best practices for asynchronous functions !! Very cool to see this demo... happy to contribute it back somehow. Final result: https://jaanli.github.io/american-community-survey/income |
Beta Was this translation helpful? Give feedback.
-
GIF of the result: |
Beta Was this translation helpful? Give feedback.
I suggest that you define
income
as a top-level variable so that you can use implicit await across code blocks, and also so you only recomputeincome
when theselectedYear
changes (and not also on resize):Then you pass the already-computed
income
data to yourincomeChart
function, rather than querying within the chart (and once again theincomeChart
function doesn’t need to be async, which makes it compatible withresize
):