Issues with Data Visualization Project 1 Bar Chart Tests

I’m encountering some errors that I’m having difficulty troubleshooting and nailing down. One is with the y-axis and the second is with the tooltip functionality.

1 - Y-Axis Issues - When I run the tests, I fail test cases 9 and 11. #9 is “Each bar element’s height should accurately represent the data’s corresponding GDP.” Result = Expected ‘infinity’ to equal '2743.413". #11 is "The data-gdp attribute and its corresponding bar element should align with the corresponding value on the y-axis. Result = "Cannot read property ‘length’ of null.

I’m guessing this are related to eachother, and if I solve one, the other will resolve. When I comb through my data line by line via the tooltip, there’s no odd values appearing. The graph curves visually as I would expect. The only thing I can come up with is that there’s a rounding error due to floating point, but that doesn’t explain why the value being received is “infinity.”

2 - I’m failing both tooltip tests (mouse over to show more info via a tooltip with id=tooltip and tooltip should have a “data-date” property that corresponds to the “data-date” of the active area). I handled the mouse over the same way it was taught in the lessons via combining “title” with “text”. I was reading through other posts that there may be bugs with the test case where it only accepts the mouse over being done via a .on(function(d)…). This leads me to believe the second test case may be failing due to a bug as well.

My CodePen link: https://codepen.io/bloo0178/pen/mGRgaa

Any help is appreciated!

1 Like

For those of you reading, I got the tooltip tests working with information and inspiration provided thanks to a separate post by @javineya . Data Vis Projects - Bar Chart Test 9

Essentially, the tests will not pass if you intend to create a tooltip the way it was demonstrated in the lessons (using “title” with “text”). You need to first create a tooltip element that is appended as a div to the body.

let tooltip = d3
      .select("body")
      .append("div")
      .attr("class", "tooltip")
      .attr("id", "tooltip")
      .style("opacity", 0);

Then, you must add .on(“mouseover”, function(d)…) and .on(“mouseout”, function(d)…) to your “rect” elements as follows (note: I’m still playing with what I’m actually going to display, thus the “testTest”…:

.on("mouseover", function(d) {
        tooltip
          .transition()
          .duration(200)
          .style("opacity", 0.9);
        tooltip
          .html("testTest: " + d)
          .style("left", d3.event.pageX + 20 + "px")
          .style("top", d3.event.pageY + 20 + "px");
        tooltip.attr("data-date", d[0]);
      })
      .on("mouseout", function(d) {
        tooltip
          .transition()
          .duration(400)
          .style("opacity", 0);
      });

Finally, make sure you have the CSS in place to support the styling and placement of your tooltip. I will be modifying the code in my Codepen, but again, current styling credit in the code below goes to @javineya:

.tooltip 
{	
    position: absolute;			
    text-align: center;			
    width: 60px;					
    height: auto;					
    padding: 2px;				
    font: 12px sans-serif;		
    background: lavender;	
    border: 0px;		
    border-radius: 8px;			
    pointer-events: none;			
}

.bar:hover
{
  fill: purple;
}

I hope this helps others who get stuck on this piece as well. Now, onto working through my Y-Axis issues. I will post a solution to that once I find it.

5 Likes

In working through my Y-axis issue, I’m noticing something odd. For certain data points, the bar spills over into subsequent columns. Also, I’m unable to mouseover the final column/ datapoint. Now attempting to figure out what’s causing that issue…

FCC%20DV%20Proj%201%20Issue

You see that in the picture because the bar is very big and it’s being partially hidden by the next one.

1 Like

Ah, so that’s not an issue with my code? Also, any thoughts on why I’m unable to mouseover the final column? I’m thinking something is off in my xScale.

I should note that if I change the maxXVal in the xScale domain to a literal date that exceeds the JSON data (new Date(2016, 0, 1)), I’m able to mouseover the final datapoint. However, when I set the maxXVal of the domain to the literal last date provided in the JSON data, I’m unable to mouseover the final data point. I’d prefer to have my max domain value dynamically set by my dataset, as that seems like a better practice if this were a dynamic, changing dataset or intended to be a reusable chunk of code.

To fix you code you just need to tweak two lines:

.domain([0,maxYVal])
.range([h, 0]);
1 Like

That did the trick - thanks! The solution now passes all tests. However, I’m still seeing that issue outside of the tests with not being able to 1) highlight the final data point and 2) having some columns spilling over into parts of subsequent columns.

1 Like

Spamming my own thread unintentionally…

An easy fix for the columns spilling over into subsequent columns was to set the width of my “rect” elements dynamically - that is, to my static defined width (w) divided by the length of my dataArray.

  .attr("width", w / dataArray.length)

Still working on the issue of showing that final column tooltip on mouseover…

Well, an easy and dirty fix would be incrementing the width of the SVG by… 5px? :smiley:

Sorry I can’t have a look at it right now. I hope someone help you with a clean solution to that problem :slight_smile:

1 Like

Thank you for the help! That does the trick for now. I’ll post back once I figure out why I’m seeing the issue without that fix.

1 Like

Messed around with this a bit more and think I’m understanding what’s happening…

I believe the issue (feature?) that’s causing my problem is that when you combine the max value of a scale domain with a D3 Axes method (in this case, axisBottom()), the axis generates up to the max value of the domain. Since the bars are technically being generated on that value as the start point, the last bar spills off the SVG x-axis and is therefore not able to be moused over.

I’ve noticed on a number of other project examples that the final data point was either missing entirely from the graph or spilled off the x-axis (as was the case on mine).

One workaround that technically works to fit all the data within the x-axis is to set the max domain to exceed the max data value from the data set. You can do this by either setting a static value (example: new Date(2016, 1, 1)), or dynamically incrementing the Date object associated with the final value by another arbitrary value (example: 1 month) and setting that as your domain max.

I’d be curious to get others’ feedback on this. Is this best practice? Am I missing something? etc. etc.

1 Like

Hi again,

Honestly, I never had such a problem. I think it’s because in all my projects using D3 I always clean up the code before passing it to D3.

On line 54 of my Barchart project you can see what I’m talking about.

Anyways, it’s good to know that you already solved the problem.

Happy coding!

2 Likes

Your implementation of the solution looks amazing! Very well done. Aside from the pleasing aesthetics, I do like how you cleansed the input data into more intuitive objects. I will do something like that moving forward.

That being said, I did notice that your bars were having some of the same display issues as mine. They spill over into subsequent columns in the exact same spots mine did before I changed the width of the rect elements to be equal to the width of the SVG canvas / the number of items in my data array.

2018-09-01%2020_00_30-Window

Also, I saw a similar thing happening to your final data point that was happening to mine as I was trying to figure out how to get everything to display properly. If you look closely, you’ll see your final bar is twice the width of the other bars.

2018-09-01%2020_01_02-Window

It really seems to me that there are some very subtle nuances with D3 (or perhaps my implementation of it) that are causing some unexpected results. Certainly not glaring problems and the solutions indeed pass the tests, but unexpected behavior nonetheless.

1 Like

Thank you very much for the feedback and, of course, for the kind word. I really appreciate it :slight_smile:

In your screenshots, the problem is in both cases the same. In the first one, as you already noticed, the blue bar is behind the one in the right. In the second screenshot, the same happens: the blue bar is “behind” the last bar and that does it look like the last bar is about twice the size of the blue one, but it is not. But that was intentional, though.

If you go to line 137 into my code, you will see the following code:

.attr( 'width', this.innerWidth / this.data.length + 1 )

Pay close attention to the + 1 there. I intentionally made a quick —and dirty— fix by adding 1 pixel to the width of each bar so the bar chart won’t have those weird, extremely thin, blue lines between each bar. I found it a little ugly so I decided to get rid of the space between the bars by incrementing their width by one pixel.

See the chart with the extra pixel added:

And the chart without the extra pixel. Notice the thin blue vertical lines:

1 Like

Oh, I almost forgot. And if, like me, you want to test your bar chart with an updated dataset, I made a quick API on Glitch to fetch the latest US GDP data (so far, the available data is up to April this year).

This is the API:
https://gdp-api.glitch.me/

Its absurdly simple code:

And a forked pen where I use this API:

1 Like

Thanks a ton for the responses, advice, and continued dialogue! I sincerely appreciate it!

1 Like

This is exactly the problem I am encountering with the bar chart project. Thanks for your post.

2 Likes

Aha! I got my tooltips working. Thanks again.

2 Likes

Thanks a ton. This was the exact problem in which I was stuck for (seemingly) a really long time. Really cool solution.

Thanks a lot.

Thanks a lot! I had exactly the same issues.