I need help trying to achieve the first in the second image. Not the monocolor because the image and the text in the middle.
You can use a renderer which allows to add custom image / text anywhere.
chart.renderer.image('http://highcharts.com/demo/gfx/sun.png', 100, 100, 30, 30)
.add();
image (String source, Number x, Number y, Number width, Number height)Since 2.0 Add an image from an external resource.
Parameters
source: String The URL of the image. x: String The x position of the
image's upper left corner. y: String The y position of the image's
upper left corner. width: String The width of the image. height:
String The height of the image.
Related
I'm looking at drawing a custom theme element onto a device content.
For example's sake, i will use the HeaderItem from the Windows XP header/listview:
(18×18 px)
Which we can blow up to see a little easier:
Note: I am not using the Theme API, nor am i asking about using the Theme API.
If i have my bitmap, like the one above, how can i draw it in practice?
Stretch draw ruins the style
The important problem that needs solving is how to maintain the important details. You can see the actual Windows XP Header draws the right-edge vertical line nice and crisp:
But if i were to blindly StretchBlt the image, the details become fuzzy:
The issue also happens with theme elements with crisp horizontal feature when the image is stretched vertically. In this case it also messes up the vertical gradient. But some other element have it even more pronounced.
So what is the technique that can be used to address this?
Should i cut 6 px off the top, left, bottom, and right?:
And then rather than drawing 1 image, i draw nine?:
And draw them with various horizontal or vertical stretch rules depending where it is?:
Unstretched
Horizontally stretched
Unstretched
Vertically stretched
Horizontally and vertically stretched
Vertically stretched
Unstretched
Horizontally stretched
Unstretched
This must be a solved problem already; since Windows already solved it, and who knows how many more Widget libraries that support themes.
Microsoft's solution to this problem can be reverse engineered by looking at the NormalBlue.ini file inside Luna.msstyles. Looking at the entry for Header.HeaderItem:
NormalBlue.ini:
[Header.HeaderItem]
bgtype = imagefile
SizingMargins = 8, 8, 3, 4
ContentMargins = 3, 0, 0, 0
ImageFile = Blue\ListViewHeader.bmp
imageCount=5
imageLayout=vertical
sizingType = tile
transparent=true
transparentcolor=255 0 0
FillColorHint = 250 248 243; Average fill color (light beige)
AccentColorHint = 252 194 71; Rollover hilite color (orange)
First we see it references the \Blue\ListViewHeader.bmp:
ImageFile = Blue\ListViewHeader.bmp
Which is:
And then there's the magic piece:
SizingMargins = 8, 8, 3, 4
This corresponds to TMT_SIZINGMARGINS:
TMT_SIZINGMARGINS: The margins used for sizing a non-true-size image.
where you can see some more hints in TmSchema.h:
//---- rendering MARGIN properties ----
TM_PROP(3601, TMT, SIZINGMARGINS, MARGINS) // margins used for 9-grid sizing
"Margins used for 9-grid sizing". This is a reference to the idea that you split up the image into 3x3 grid, and size the chunks independently as appropriate.
And the final piece is the documentation of the MARGINS type in UxTheme.h:
typedef struct _MARGINS
{
int cxLeftWidth; // width of left border that retains its size
int cxRightWidth; // width of right border that retains its size
int cyTopHeight; // height of top border that retains its size
int cyBottomHeight; // height of bottom border that retains its size
} MARGINS, *PMARGINS;
and its documentation:
cxLeftWidth: int - Width of the left border that retains its size.
cxRightWidth: int - Width of the right border that retains its size.
cyTopHeight: int - Height of the top border that retains its size.
cyBottomHeight: int - Height of the bottom border that retains its size.
Chop and Paint
The Luna theme is telling us that when we draw ListViewHeader.bmp, we need to use the sizing margins:
SizingMargins = 8, 8, 3, 4
And cut the image up into 9 pieces (3x3). But rather than using 6px all around (like i said in my question), we need to use the sizes that the designer of the image intended:
Left: 8
Right: 8
Top: 3
Bottom: 4
So given the 18×18 theme element image created in Photoshop by a designer:
The person who created the image said that my drawing code needs to cut off:
left 8 pixels
right 8 pixels
top 3 pixels
bottom 4 pixels
Meaning i then have to draw each of the nine images:
And then stretch draw some parts in certain directions:
Top-left: draw unstretched
Left: stretch vertically
Bottom-left: draw unstretched
Top: draw stretch horizontally
Middle: draw stretched horizontally and vertically
Bottom: draw stretched horizontally
Top-right: draw unstretched
Right: draw stretched vertically
Bottom-right: draw unstretched
I am trying to find the width of the bounding box of the output image in pixels:
In this article, it says YOLO v3 extracts coordinates and dimensions of the bounding box (line 82). YOLO returns bounding box coordinates in the form:
(centerX, centerY, width, and height)
Are these coordinates, width and height, real pixel values? Or do they perform scaling on them?
Can I print out the value of width and consider it as a real pixel value for the width of the aforementioned box?
Please note that my question is about YOLO v3.
Those are what are called normalized coordinates. To get the width in pixels you would need to multiply by the width of the images. For example if your image 640x480 than multiple the width values outputted by Yolo by the width of the image.
If the numbers in your screenshot are the width:
Dog width = .98 * 640 = 627 px
Cat width = .88 * 563 = 563 px
I have a dc.js heatmap working:
But I want to add grid lines to it, like so:
You can see that the lines to not match up with the bottom edges of the rects. Inserting the lines themselves is easy, you just start at zero and add 11 lines based on the height of the rects, which in this case will always be 11 / chart.effectiveHeight().
The reason they do not match up, seems to be that the top rect row does not always start at 0, instead, there seems to be a random(?) y position that the chart starts at, this will change with the height of the chart container, eg this y position starts at 5:
If it was consistent, then I could just start appending lines from that number instead of 0, but it is not. I have tried a couple of hacky work arounds, however I am unsure as to how to get the y position of all the rects after they are available in the DOM.
Interestingly the demo heatmap does not have this issue:
Here is the code for the heatmap:
const heat_map = dc.heatMap('#heatmap');
heat_map
.width(0)
.height(0)
.margins(margins)
.dimension(hm_dim)
.group(hm_group)
.keyAccessor(function(d) { return +d.key[0]; })
.valueAccessor(function(d) { return +d.key[1]; })
.colorAccessor(function(d) { return +d.value; })
.colors(color_scale)
.calculateColorDomain()
.yBorderRadius(0)
.xBorderRadius(0)
heat_map.render();
Is there a way to force the rects to begin at 0? Or get the random y position for the top rows? I did have a look at the source code but got a bit lost. Also I thought about creating a false group that would include each rect in the grid, and the grid lines could then be rect borders, but I thought that was a bit heavy handed.
Outlining the cells using CSS
It's easy to outline the cells using CSS:
rect.heat-box {
stroke-width: 1;
stroke: black;
}
Example fiddle.
However, as you point out, this only works if all the cells have values; crossfilter will not create the empty ones and I agree it would be absurd fill them in using a fake group just for some lines.
So, to answer your original question...
Why is there a gap at the top of the chart?
The heatmap calculates an integer size for the cells, and there may be space left over (since the space doesn't divide perfectly).
It's kind of nasty but the heatmap example avoids having extra space by calculating the width and height for the chart using the count of cells in each dimension:
chart
.width(45 * 20 + 80)
.height(45 * 5 + 40)
The default margins are {top: 10, right: 50, bottom: 30, left: 30} so this allocates 45x45 pixels for each cell and adds on the margins to get the right chart size.
Since the heatmap in this example draws 20 columns by 5 rows, it will calculate the cell width and height as 45.
Alternative Answer for Responsive/Resizable Charts
I am revisiting this question after rewriting my heatmap chart to be responsive - using the "ResizeObserver" method outlined in the dc.js resizing examples and Gordon's answer to this question
While specifying the chart width and height for the heatmap in Gordon's answer still works, it does not combine well with the resizing method because resized charts will have their .width and .height set to 'null'. Which means that this rounding issue will reoccur and the heat boxes will be again be offset by a random integer x or y value of anywhere between 0 and 5 (unless you want to write a custom resizing function for heatmaps).
The alternative answer is relatively simple and can be determined by selecting just one heat-box element in the heatmap.
The vertical offset value for the heat boxes is the remainder value when the heat-box y attribute is divided by the heat-box height attribute.
const heatbox_y = heat_map.select('.heat-box').attr('y);
const heatbox_height = heat_map.select('.heat-box').attr('height')
const vertical_offset = heatbox_y % heatbox_height
The modulus % will return the remainder.
The horizontal offset can be determined in the same way.
Thus you can append lines to the chart at regular intervals determined by the heatbox_height + the vertical_offset values.
This will work if you pick any heat-box in the chart, and so it is suitable for instances like this where you cannot guarantee that there will be a heat-box at each x or y level. And it means that you are free to set your chart height and width to 'null' if needed.
I have a problem with iTextSharp. I have an image of 20000x1000 and I have to put it in a PDF with page size A1 horizontal. The tricky thing is that I need to adjust the height of the image to the PDF and print multiple pages wide in relation to the image.
I tried with this but it generates a PDF with a single page and the image adjusted both width and height.
Rectangle pageSize = PageSize.A1;
Document doc = new Document(pageSize.Rotate(), 10f, 10f, 10f, 10f);
PdfWriter writer = PdfWriter.GetInstance(doc, new FileStream(#"C:\TestFiles\Default.pdf", FileMode.Create));
doc.Open();
Image image = Image.GetInstance(#"C:\TestFiles\image.png");
PdfPTable table = new PdfPTable(1);
table.WidthPercentage = 100;
PdfPCell c = new PdfPCell(image, true);
c.Border = PdfPCell.NO_BORDER;
c.Padding = 5;
c.Image.ScaleAbsoluteHeight(pageSize.Height);
table.AddCell(c);
doc.Add(table);
doc.Close();
Thank you in advance for your help.
Using a table is not the way to go for your requirement.
First let's take a look at how you can scale the image so that the height is adapted to the height of a rotated A1 document:
Image image = Image.GetInstance(#"C:\TestFiles\image.png");
image.ScaleToFit(image.ScaledWidth, PageSize.A1.Width);
The ScaleToFit() method scales an image so that it fits into a rectangle. In this case, we don't want the width to be reduced, so we define the width of that rectangle as equal to the width of the original image. We do want to scale the height so that it fits the height of a rotated A1 page. As we rotate the A1 page, we have to use PageSize.A1.Width instead of PageSize.A1.Height.
Suppose that you have an image that measures 500 x 1500, then the scaled image will have size 500 by 2000 because that image fits a rectangle of 500 by 1684.
Suppose that you have an image that measures 500 x 2000, then the scaled image will be 421 x 1684. The height will be reduced to fit the rotated A1 page, and the width will be reduced accordingly.
Suppose that you have an image of 5000 by 2000, then the scaled image will be 4210 x 1684.
Now we have to add the same image as many times as needed until the complete image is rendered. Note that the image bytes will only be stored once in the PDF: those bytes are reused for every page.
Float offset = 0;
while (offset <= img.ScaledWidth) {
document.NewPage();
img.SetAbsolutePosition(-offset, 0);
document.Add(img);
offset += PageSize.A1.HEIGHT;
}
What happens in the above code snippet? On the first page, we add the image at position (0, 0) which is means that the lower-left corner of the image will coincide with the lower left corner of the page.
If the image fits the page, e.g. in case the width was scaled smaller than the new offset (2384), no new page will be triggered. If the image doesn't fit the page (e.g. because the scaled width is 4210 which is greater than 2384) a new page will be created, and the same image will be added with a new offset (e.g. (-2384, 0)).
Suppose that the width of the scaled image is indeed 4210 and the width of the page is 2384, then the offset after a second page is added will be 4768. That is greater than 4210, so there will be no third page.
I have a four element position vector [xmin ymin width hight] that specifies the size and position of crop rectangle from image I. How can i find the new position and size for the resized image I?
It is not entirely clear, what you want, as we don't know your coordinate system. Assuming x is the horizontal axis and y is the vertical axis and your point (1,1) is at the top left corner, you can use the following snippet:
p = [xmin ymin width height];
I = I_orig(p(2):p(2)+p(4)-1,p(1):p(1)+p(3)-1);
The size is of course your specified width and height.
You can convert your original bounding box to relative values (that is assuming the image size is 1x1)
[origH origW] = size( origI(:,:,1) );
relativeBB = [xmin / origW, ymin / origH, width / origW, hight / origH];
Now, no matter how you resized your origI, you can recover the bounding box w.r.t the new size from the relative representation:
[currH currW] = size(I(:,:,1));
currBB = relativeBB .* [currW, currH, currW, currH];
You might need to round things a bit: you might find floor better for xmin and ymin and ceil more suitable for width and height.