-
Notifications
You must be signed in to change notification settings - Fork 14
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
base: main
Are you sure you want to change the base?
Evelyn zheng assignment 6 #51
Conversation
.transition() | ||
.duration(1500) | ||
.call(d3.scaleBottom(xScale)) | ||
.selectAll('text') // rotate and adjust text labels |
There was a problem hiding this comment.
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!
There was a problem hiding this comment.
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
There was a problem hiding this comment.
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) { |
There was a problem hiding this comment.
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
<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"> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
great job!!
<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> |
There was a problem hiding this comment.
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))]; |
There was a problem hiding this comment.
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
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); | ||
} | ||
} |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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
Promise.all([ | ||
d3.json('us-states.json'), | ||
d3.csv('NSRDB_StationsMeta.csv', d3.autoType) | ||
]).then(function ([geoJSONData, stationData]) { | ||
geoJson = geoJSONData; | ||
stations = stationData; | ||
draw(); | ||
}); |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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!
overall, great job! Couple things to improve on that I tried to highlight but very nice |
No description provided.