1

I am currently creating a Legend component that maps text onto a gradient-looking legend that looks like this:

enter image description here

The central piece of code looks like the below (omitting the graphics declaration code snippets, as that's not the main piece):

        int numberOfItems = 10;
        int increment = (int) Math.Round((max - min), 0);
        int step = increment / numberOfItems;

Array that stores the step into an integer array the size of 10.

        int[] legend = new int[numberOfItems];
        for (int i = 0; i < legend.Length; i++) {
            legend[i] = step * i;
        }

String Reversal Code Snippet

        for (int i = (legend.Length - 1); i >= 0; i--) {
            g.DrawString(legend[i].ToString(), drawFontX, Brushes.White, ((newWidth / 2) - 5), (newHeight / 10) + (verticalDistance * i), stringFormatTimes);
        }

I have also tried:

        legend.Reverse();
        for (int i = 0; i < numberOfItems; i++) {
            g.DrawString(legend[i].ToString(), drawFontX, Brushes.White, ((newWidth / 2) - 5), (newHeight / 10) + (verticalDistance * i), stringFormatTimes);    
        }

As you can tell, I am trying to have the graph render the text from the largest value to the lowest, instead of what it is doing now, which is 0 - 1080.

My issue is, despite using both array reversal methods, I have been unable to reverse the legend array. I'm not quite sure what I am doing wrong.

3 Answers 3

3

legend.Reverse binds to Enumerable.Reverse which returns you a copy. This should teach you not to mutate state if you don't have to. Instead, create new data from old data.

var legendContents =
 Enumerable.Range(0, numberOfItems)
 .Select(i => step * i)
 .Reverse()
 .Select(i => new { Text = i.ToString(), Y = (newHeight / 10) + (verticalDistance * i) }
 .ToArray();

//at this point you can easily examine all draw operations in the debugger

var xPos = ((newWidth / 2) - 5);
foreach (var legendItem in legendContents)
 g.DrawString(legendItem.Text, drawFontX, Brushes.White, xPos, legendItem.Y, stringFormatTimes);    

Use a functional programming style. Much code saved, very readable now and easy to change.

Sign up to request clarification or add additional context in comments.

4 Comments

Are there any benefits to your solution and the ones Dan and Dave Bish suggested?
There are multiple Reverse methods in the framework. Which one is picked depends on the exact type of the receiver. You might accidentally call List.Reverse for example. This is a design flaw in the BCL.
Excuse me but did you look at my previous question's code snippets to implement the things below the array reversal =P?
That's rather funny actually, unless I'm not in on the joke. I also named my items xPos and stringFormatTimes. Anyways - thanks for the help!
2

You missed your assignment:

legend = legend.Reverse().ToArray();

Comments

2

Try this:

legend = legend.Reverse().ToArray();

The problem is that the Reverse method you are using doesn't change the original object; it creates a new object with the items from the original in reverse order. But you weren't saving the result of the Reverse method. It was just being ignored. If you reassign the value of the legend variable to the result of the Reverse method, this should fix your problem.

Another option would be to use a List<int>:

List<int> legend = new List<int>(numberOfItems);
for (int i = 0; i < numberOfItems; i++) {
    legend.Add(step * i);
}

//...

legend.Reverse();

Here you would be calling the Reverse method on the List<T> class which does change the order of the calling list instead of returning a new instance.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.