How to generate 12 different Brush Colors at run time (12 is a number that may vary) - wpf

I want to generate 12 different visible Brush Colors in WPF in my code behind and the number of colors which is initially 12 may vary as the application evolves i.e. I want to generate as many different visible Brush Colors depending on a given count?
I would explain it a little more:
I am creating Rectangles in a for loop and for each rectangle created at run time I have to assign a Fill Color e.g.
for (i=0; i<12; i++)
{
Rectangle rect = new Rectangle();
rect.Fill = <I want to assign a unique visible color>;
rect.Stroke = Brushes.Black;
rect.StrokeThickness = 1;
}

What you probably need is an RGB to HSL, and HSL to RGB converter. You can then divide the total hue (usually represented as degrees in a circle, but sometimes a percent value) by the number of colors required. Incrementing the hue value by the segment amount should produce the most differentiated colors possible.
Most examples use the WinForms Color object since it was able to provide H S and L values. There are lots of online examples:
https://web.archive.org/web/20141023005253/http://bobpowell.net/RGBHSB.aspx
how to use HSL in Asp.net

Brushes can be assigned colors, This SO question should help you in getting the colors, and then assign them each time you create a new brush for any number of brushes.
Just for reference:
Brush Class
Brushes class

Use a random number generator to create the RGB triple for the colour. Save it in a list. Then the next time round the loop check the newly generated colour against the list. If it's not in the list use it, if it is choose again.
Potentially this could run into trouble if you have a lot of colours so you're more and more likely to hit an existing colour, but for 12 (or so) colours it should be OK.
Alternatively create a list of 100's of colours and remove each one from the list when it's picked randomly. This will ensure you don't get any clashes but would require you extend the list if you needed more colours.

Related

How to remove xTextLabel in a barChart?

The code to draw a bar chart as follows:
XYMultipleSeriesRenderer renderer = buildBarRenderer(colors);
renderer.setXLabels(4);
renderer.setYLabels(4);
ChartLabel chartLabel = getChartLabelfromString(dateL);
for (int i=0; i<chartLabel.labelIdxs.size(); i++){
renderer.addXTextLabel(chartLabel.labelIdxs.get(i),chartLabel.labelStrs.get(i));
}
BarChart chart = new BarChart(buildBarDataset(titles, valueDDL), renderer, BarChart.Type.DEFAULT);
chartLabel.labelIdxs.size() = 4
There are two strange values in the xlabels marked as red color. How do I remove the values 5,10 in the Xaxis?
Barchart Sample Code Output with labels A B C D
There are a number of ways to remove a symbol from your Watchlist.
Using the Links Column
Click on the Links icon.
Select "Delete from Watchlist". The symbol is immediately removed.
It seems you're setting the font size to be relatively large with long labels so they override each other. You can set the angle of the text to fit longer text or you can shrink the font size but there's a limit to what can physically fit under a chart. I suggest just using the month denominator in the labels.
There might be other options since the renderer class includes a lot of them.

OxyPlot WPF Muliple LinearBarSeries with same X-Axis Values

I currently have the need to be able to display multiple bars that may have the same X-Axis value. I used the WPF LinearBarSeries example in the source code.
The issue I am having is if the series with the smaller Y value is selected first, the series with the bigger Y value hides the smaller one. If I select the series with the bigger Y value first and then the smaller Y value, they both are displayed.
I am putting a small border around my bars to make them more readable.
Bigger First
Smaller First
Admittedly, I'm not an expert with OxyPlot and I haven't done a whole lot of charting in the past. Is there a better approach I should be taking? Maybe a different Series to use?
I did not find the way to display LinearBarSeries side by side either. I finally used the RectangleBarSeries where the bar is defined between two points x,y, and so you can manually define an offset between them.
var serie = new RectangleBarSeries { Title = "Example"};
serie.Items.Add(new RectangleBarItem(x1, 0, x2, y2));

How do I calculate the required size for a CheckedListBox?

I have written some code to automatically scale a CheckedListBox to its contents using mListBox.ItemHeight and mListBox.CreateGraphics().MeasureString(...).
The output from the string measurements is a bit dubious but what really puzzles me is how much to add for borders and such.
I tried both SystemInformation.Border3DSize (= 2) as well as the difference between ClientSize and Size (= 4).
But taking mListBox.ItemHeight * mListBox.Items.Count + 4 for the height makes it one pixel too small and a scrollbar appears.
For the width it does not work at all because it does not take the size of the checkboxes into account for which I can't seem to find a source.
How should I determine the size of the control?
In cases like this, it is typically easier to set the ClientSize rather than the whole Size. One thing to note about ItemHeight is that it does not include the margins of the item. Using a CheckedListBox with default settings, I had an ItemHeight of 13. But the ItemRectangle property had a height of 15.
So here is what I did. I added 9 items to the CheckedListBox (the first Item was longer than the rest), keeping the default size of the control as set by the designer. Then in the constructor of the form, I set the ClientSize like so:
this.checkedListBox1.ClientSize = new Size(TextRenderer.MeasureText(checkedListBox1.Items[0].ToString(), checkedListBox1.Font).Width + 20, checkedListBox1.GetItemRectangle(0).Height * checkedListBox1.Items.Count);
Notice I used TextRenderer.MeasureText to measure the text. It will typically give you better values than Graphics.MeasureString. By default, TextRenderer included a bit of padding in it's measurement. I also included a 20 pixel padding to account for the checkbox. Anyway, with TextRenderer.MeasureText, and the 20 pixel padding for width, and ItemRectangle * Items.Count for the height, that gave me a CheckedListBox that was sized to its contents without ScrollBars.
EDIT: If item widths vary, it may complicate setting the width, as you'll want to set the width based on the longest item. In this case you'll need to measure each item and keep track of which one was the longest.
EDIT 2: Ok so I dug around in the CheckedListBox source code. They use a default size of 13 plus a 3 pixel padding for the width and height of the checkbox. But, if VisualStyles is enabled, they call CheckBoxRenderer.GetGlyphSize to get the size to use because it takes into account the DPI settings. Most machines are set at 96 DPI so that method will still return a size of (13,13). So when you're measuring the text of the item, you can also pass the Graphics object and a CheckBoxState enum to the CheckBoxRenderer.GetGlyphSize to get a size. I used System.Windows.Forms.VisualStyles.CheckBoxState.CheckedNormal for the state, but I'm not sure that the state matters. I tried CheckBoxState.MixedDisabled as well and it returned the same size, (13,13).
So to summarize, you can use CheckBoxRenderer to get the size of the checkbox, but you will still probably need to use some padding. This reduces the need for hardcoding a magic number to account for the checkbox. Since the checkbox is drawn and isn't an actual control, its size can't be determined like sizes of controls can.
Here is a link to the source of CheckedListBox. It wouldn't hurt to look at it. Specifically, look at the protected override void OnDrawItem method.
CheckedListBox Source

I want to have a set of patches overlay onto an image and want to control their color range?

I have a set of patches I am overlaying onto an image. The below patches draw a grid of boxes over the image. This works when I dont try and restrict the colormap range. But when I try and set it with caxis it does not allow me to use the array of hpatch as a handle. How can I get this to work? or is there a better approach then what I am doing? Also the image is grayscale but I would like the patches to use the jet colormap. Is this possible to do?
hFig = figure;
hAx = axes('Parent',hFig);
for i = 1:256
hpatch(i) = patch([x2(i+17) x2(i+18) x2(i+1) x2(i)],[y2(i+17) y2(i+18) y2(i+1) y2(i)],[0 0 0 0],'Parent',hAx, 'FaceColor','flat','CData',cdata(i),'CDataMapping','scaled', 'FaceAlpha',(0.5));
end
caxis(hpatch,[0 25])
Here's one problem: the colormap is a figure-level property. When using the CAXIS function, you have to pass it an axes handle, not a patch handle, and specify a range that determines how the color data values in that set of axes are mapped to the colormap.
If your axes have an indexed-color image or other objects with their 'CDataMapping' property set to 'direct' or 'scaled', then it may get quite messy trying to make one colormap to accommodate them all. You would have to concatenate their colormaps into one to use for the figure, then adjust their color value indices accordingly. Changing the scaling for any one object would be more involved than just using CAXIS: you'd have to modify the corresponding section of the colormap for that object or modify its colormap indices stored in the 'CData' property.
However, you can simplify the problem by making sure only one object (or related set of objects) uses the colormap, setting all the other objects to use fixed RGB values for their 'CData'. Since you mention that your image is grayscale, it would be best to make it a Truecolor (i.e. RGB) image (if it isn't already) so that only your patches use the colormap. Here's how you can convert your image:
If the image you're plotting is an M-by-N-by-3 matrix, it's already an RGB image.
If the image is an M-by-N matrix and has an associated colormap, use the IND2RGB function to convert it to an RGB image.
If the image is an M-by-N matrix with no colormap, then IMSHOW will still display it using the figure colormap. To convert it to an RGB image, first apply whatever windowing you want to the 2-D image data, then replicate the data in the third dimension to make it an M-by-N-by-3 matrix. Here's an example (assuming img is your image data):
limits = [0.05 0.4]; %# The window you want to apply to the data
img = (img-limits(1))./diff(limits); %# Scale the data
img(img < 0) = 0; %# Clip the data outside 0 and 1 (even without these two
img(img > 1) = 1; %# steps, IMSHOW should display the data properly)
img = repmat(img,[1 1 3]); %# Replicate the image so it is 3-D
imshow(img); %# Display the image
Once you've converted and plotted the image and plotted your patches as above, you should be able to use a jet colormap for the patches like so:
colormap(jet);
caxis(hAx,[0 25]);

Masking image data using values generate from a histogram in OpenCV

Given a generated histogram that I got from an image I was wondering if there was any optimized way to generate a mask. Below I have added in 3 different images: the reference to use, the histogram data of the reference, and the main image that I would like to mask. I know that I could do this by each pixel and vary the color information by a certain percentage so that I would be able to get colors with lighting changes as well.
The basic idea is to find a color, given by the histogram data and within a certain range, and if it finds anything then to make it black. If it doesn't find anything then the color will be white.
Any advice would be greatly appreciated.
Reference image:
Histogram values:
Image to mask:
What you want is to mask a color in a certain range, this is what you should try with the code i posted here :
In my example, it is used to make it transparent, if you want to make it black, just skip the cvNot() step...
Making a color completely transparent in OpenCV
Hope it helped,
Julien
PS : i've just seen that you were the one who asked the question I answered about how to make a color transparent: the problem here is exactly the same... just adapt a lil bit the answer..
1) Convert your image RGB -> HSV : cvtColor()
2) Generate your histogram : calcHist()
3) Find the maximum in your Hue histogram : minMaxLoc()
4) Select thresholds around this maximum : your function
5) Use them to select only the color you want : inRange()
6) Put this mask in black : your function (a very simple way would be to remove all the RGB components on the mask) : your function
Try to use template matching approaches instead of histogram, for example, normalized cross correlation http://www.mathworks.com/products/demos/image/cross_correlation/imreg.html.

Resources