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

Evelyn zheng assignment 6 #51

Open
wants to merge 4 commits into
base: main
Choose a base branch
from

Conversation

evelynzhengg
Copy link
Collaborator

No description provided.

.transition()
.duration(1500)
.call(d3.scaleBottom(xScale))
.selectAll('text') // rotate and adjust text labels

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks like there's an error here -- I think you're trying to call axisBottom not scaleBottom, which is resulting in the x-axis not updating. Otherwise, looks great here!

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

then I guess the second question is how to get each of the a axis labels to move individually as well! I'm not sure if that was your goal but it looks like it was. It's tricky because calling the axisBottom function will make each title update immediately. this is a little more funky

Copy link

@KaiElwood KaiElwood Jul 30, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

basically you can do something like this:

data.sort(findComp(this.id));
const oldXScale = xScale.copy(); // here, we can make a copy of the old scale

xScale.domain(data.map(d => d.State)); // here, the normal scale has been updated to the new scale, but has not taken effect in the dom

Then basically we can update each tick individually based on the new and old positions:

              g.selectAll('g.x-axis g.tick')
                .each(function(d, i) {
                  const tick = d3.select(this);
                  const oldPosition = oldXScale(d);
                  const newPosition = xScale(d);
              
                  // Set initial position
                  tick.attr('transform', `translate(${oldPosition},0)`);
              
                  // Animate to new position
                  tick.transition()
                    .duration(1500)
                    .attr('transform', `translate(${newPosition},0)`)
                    .delay(i * delay);  // Staggered delay
                });

It's kinda weird tbh but it works I think how you wanted


// read in air quality data
// Read in air quality data
d3.csv('air_quality.csv').then(function (data) {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I know you didn't do this, but you can do "(data) =>." instead of what is here

Comment on lines +7 to +16
<label for="sort-states">Sort By State</label>
<input class="sortTypes" type="radio" id="sort-states" name="sort-by">
</div>
<div>
<label for="sort-emissions-asc">Sort By Emissions Ascending</label>
<input class="sortTypes" type="radio" id="sort-emissions-asc" name="sort-by">
</div>
<div>
<label for="sort-emissions-des">Sort By Emissions Descending</label>
<input class="sortTypes" type="radio" id="sort-emissions-des" name="sort-by">

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

great job!!

Comment on lines +27 to +31
<label for="min-elevation">Min Elevation:</label>
<input type="number" id="min-elevation" name="min-elevation">
<label for="max-elevation">Max Elevation:</label>
<input type="number" id="max-elevation" name="max-elevation">
<button id="filter-button">Filter Stations</button>

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think some sort of indication that there must be a value in both boxes might be nice

loc: [+d.longitude, +d.latitude]
})).filter(s => projection(s.loc) != null);

const stationClasses = [...new Set(nonNullStations.map(d => d.stationClass))];

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

excellent use of a set

Comment on lines +159 to 189
function updateStations() {
const selectedClasses = new Set(
d3.selectAll("#checkbox-container input:checked").nodes().map(d => +d.value)
);

const minElev = +d3.select("#min-elevation").property("value") || d3.min(nonNullStations, d => d.elevation);
const maxElev = +d3.select("#max-elevation").property("value") || d3.max(nonNullStations, d => d.elevation);

const filteredStations = nonNullStations.filter(d =>
selectedClasses.has(d.stationClass) && d.elevation >= minElev && d.elevation <= maxElev
);

drawStationsCheckbox(filteredStations);
}

function handleFilter() {
const minElev = +d3.select("#min-elevation").property("value");
const maxElev = +d3.select("#max-elevation").property("value");

if (isNaN(minElev) || isNaN(maxElev)) {
alert('Input elevations must be numbers.');
return;
}

const filteredStations = nonNullStations.filter(d =>
d.elevation >= minElev && d.elevation <= maxElev
);

drawStations(filteredStations);
}
}

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it looks like if no value is provided when clicking filter stations, the default is "". You're turning that into a number, which I believe in weird js sorcery will turn the value to false and then to 0. you may want to provide a default value of d3 max/min in order to avoid this.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the line +d3.select("#max-elevation").property("value"); is what turns it into a number. You have the alert below it, but I don't think that will ever hit because if there's any invalid number it will be coerced into a number by the "+". If it's not a number I belive it will be false, then 0

Comment on lines +32 to 39
Promise.all([
d3.json('us-states.json'),
d3.csv('NSRDB_StationsMeta.csv', d3.autoType)
]).then(function ([geoJSONData, stationData]) {
geoJson = geoJSONData;
stations = stationData;
draw();
});

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is well done! I do think that you could potentially seperate the draw function into a base layers function and then also a content layer. This might allow you to just utilize one function for the content layer and reuse it.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

oh ok i see that's kinda what you've done. looks pretty good!

@KaiElwood
Copy link

overall, great job! Couple things to improve on that I tried to highlight but very nice

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants