http://jsfiddle.net/BhrpA/1/embedded/result/
Why does the graph not extend the full 789px? (width of the black container div)
The SVG element is 789 but there is 100px or so of black space at the far right.
Thanks!
Your x-domain isn't set up correctly. Since arrays are 0 based, your maximum index is length-1 not length. So if you change it to:
x=d3.scale.linear().domain([0,data.length-1]).range([0,w])
You'll see that it now goes the full length as expected.
Related
By default there is a lot of space between the text of the label and the boundary of the node. How to reduce that spacing? This would usually be called padding but pad means something else for the graphviz - the overall spacing between the graph and the boundary of the figure. What is the name of the attribute?
You are probably looking for margin, but be also aware of height and width which actually specify min-height and min-width
example
digraph G {
node[shape=rect]
A
"B0123456789\n0\n1"
"C0123456789\n0\n1"[margin=0]
}
I tried everything, but I still can't solve this problem without brute force:
I get N blocks with a known height and width. I can rotate them (height become width and width become height) and I have to build the tallest possible pyramid from them (of course I can change the order of blocks).
The problem is that you can't put a block of width X onto a block with width smaller than X.
EDIT:
The problem is, that you can't put a block onto a block of the same width.
Any ideas?
What I understand reading your problem statement and comments is that you want to build tallest pyramid with width from bottom to top in decreasing order.
If this is the case, then what we can do is simply the following steps:
Loop over blocks and swap width and height only if width > height.
Now, sort the array of blocks in decreasing order of width which is the order used for stacking blocks from bottom to top in pyramid.
Answer is summation of all heights.
Note: step -2 is only needed if you want to display order of blocks
from bottom to top in pyramid.
I have two arrays of strings: these two arrays contain the labels that are to be inserted on the x and y axis (these labels will be those of a heatmap).
nutsNames corresponds to the x axis (left to right) and the yearsNames corresponds to the y axis (top to bottom).
As the data may vary, I would like to create a way that fits the data.
So the problem is the positioning of the elements on the axes and the svg size.
What I would like to get is something like this:
The image shows two examples of different data.
(I don't want to show axes, I put them only to understand what is their direction).
Here is the plunker.
I thought about finding the longest string in nutsNames and multiplying it by a constant (which I don't know how to define) to create the minimum necessary width of the svg.
A similar thing I did it for years.
Obviously the code doesn't work.
What you can do is input some dummy numbers for the width,height and margins and let it draw the elements first. Now since all your axis labels are in a g , you can get the width of gs for x and y labels.
The group<g> tag wraps the contents inside it so getting its width/height will automatically give you the width/height of the largest text inside it.
Now you have the width and height of those gs, all that's left is to change the dimensions of the svg accordingly.
Try adding or removing labels in your data. Here's your Plunker
(this should probably be in another community but I couldn't find how to move the question)
I was told for an SVG I have that one of the transformations in it is an illegal or invalid transformation. I believe I have found the offending transformation and am trying to understand what it did.
The transformation is:
<image transform="matrix(0.773723,0,0,0,860,182)" width="137" height="2" xlink:href="someImage.png" />
From my understanding, the SVG notation of the matrix (0.773723,0,0,0,860,182) is the equivalent of (pretend its one big bracket not 3 on each side):
[.773723,0,0860]
[0,0,182 ]
[0,0,1 ]
My research has lead me to believe I am to use the width and height after the matrix, convert it into matrix notation and multiply the two to understand how it was transformed. If that is correct, I'm trying to understand how to convert the height and width to the matrix notation []. If it is not correct, any pointers in the right direction would be greatly appreciated!
That looks like a legal transform (technically). but it's incorporating a 0% vertical scale: that "0" in the fourth position of the matrix, so it's making your element disappear. Height and width are the "before" height and width, not the "after" height and width. You can't specify absolute dimensions in a matrix, just scaling factor. (You can specify offset or translate in absolute dimensions).
I am writing a small image analysis program just for fun. Image analysis has always fascinated me. I am trying to locate regions on a scanned document. These regions are going to be marked by clearly defined filled black rectangles (pre-printed on the page).
My problem is locating the rectangles. I know SIFT\SURF find "features" but I am trying to find something specific. Here is what I was thinking of doing. I am not sure if this is the "right" way or there is a better idea.
First off using some library I will turn the image into greyscale, perhaps a PGM since that is what I'm used to working with in school. For the analysis I first plan to run the image through a state of the art deskew algorithm in OpenCV or something else that I find. Once I have my deskewed image I will then threshhold it at some pretty high thresshold. The rectangles are going to be straight black hence me using a pretty high threshhold. I will then experimentally determine a good size black rectangle to slide across the image. While sliding my rectangle across the image I will determine the areas where the greatest percentage of pixles are the same. I will have a cutoff, say 90%. If 90% of the pixles contained in my window are black I must have found a rectangle. My reasoning is that a true black rectangle slid over something that is "pretty much" a black rectangle is most likely a black rectangle. Since I deskewed the image I can assume that the rectangles are straight up and down "enough". I can then track the (x,y) offsets where the rectangles are found on the image and mark them.
Would anyone suggest a better approach?
There are many approaches that might work. (One can easily come up with 10 or more approaches.)
Idea #1 - Canny edge detection; find rectangle fit to contours
cv::Canny
cv::findContours
cv::minAreaRect, or
cv::boundingRect might also work, if the deskewing works as advertised.
Idea #2 - Find all lines using Hough transform; Iterates through all regions created from line intersections.
Idea #3 - (Improvement on #2) Restrict the Hough transform to horizontal and vertical lines by pre-processing.
Idea #4 - Compute Horizontal and Vertical profiles on the entire image; find dips; iterate through all candidate regions.
This idea is based on the assumption that the black rectangles are large enough that they leave a "depression" in both the horizontal and vertical projection profiles, which would be detectable despite other noise objects in the image.
cv::reduce
With dim = 0 or 1 for reducing to a row or column respectively,
With CV_REDUCE_AVG flag
Apply cv::threshold to the horizontal and vertical projection profiles, separately.
For each profile now thresholded into zero/non-zero, find runs of zeroes. These are the possible row ranges and column ranges that could contain the dark rectangles.
For each combination of candidate row range and column range, calculate the average pixel value to decide if it is a true dark rectangle.
Idea #5 - Use integral image (summed area table) to quickly calculate the average pixel value in arbitrary rectangles
cv::integral
To compute the sum (and average) of a rectangle from an integral image, see the Wikipedia article on Summed Area Table
Preprocessing idea - use morphological dilation (or erosion) to "erase" things that cannot be the large continuous black box.
Preprocessing idea - use pre-processing to enhance horizontal and vertical edges; suppress edges in other directions.
I don't know if it is a better approach, but the first thing that came to mind would be a scan-line solution (assuming black or white pixels): I'd check each scanline from top to bottom. In each scanline I'd check each pixel from left to right. A "first" black pixel would be a possible upperleft corner of a rect. If there were enough following contiguous black pixels on the line to meet my desired minimum width, keep the [left, width] in a list of possible rects. Find all possible rect starts and widths on the line.
For a rect to stay in the list and grow in height, the next scanline would have to have the same [left, width] occurrence, otherwise the rect is finished (if its height meets my desired minimum height) or discarded or ignored as too short in height.
You can easily add logic for situations like two rectangles too close to one another vertically or horizontally. Overlapping rectangles would be trickier but still possible to detect with added code.
Here's some pseudocode:
for s := 1 to scanlinecount do
begin
pixel := 1
while pixel <= scanlinewidth do
if black(s, pixel) then // possible rect
begin
left := pixel
repeat
inc(pixel)
until (pixel > scanlinewidth) or white(s, pixel)
width := pixel - left
if width >= MINWIDTH then // wide enough
rememberrect(s, left, width) // bumps height if already in list
end
else inc(pixel)
end
Your list of found rects stores the starting scanline, leftmost pixel, width, and height for each rect found. The "rememberrect" routine checks each rect in the list:
rememberrect(currentline, left, width):
for r := 1 to rectlist.count do
if rectlist[r].left = left
& rectlist[r].width = width
& rectlist[r].y + rectlist[r].height = currentline then
begin // found rect continuing on scanline
inc(rectlist[r].height)
exit
end
inc(rectlist.count) // add new rect to list
rectlist[rectlist.count].left := left
rectlist[rectlist.count].width := width
rectlist[rectlist.count].y := currentline
rectlist[rectlist.count].height := 1
If the group of black pixels on the current scanline has the same leftmost pixel and width as a group on the previous scanline (you'll know they're vertically contiguous because the starting scanline of the rect in the list plus its height will equal the current scanline) then rememberrect bumps the height of the found and remembered rect by 1. Otherwise, remember the new rect with initial height 1.
After the last scanline you'll have a long list of rect candidates, many of them only 1 pixel high. Delete or ignore any rects in the list that aren't high enough. To avoid growing a long list of futile candidates: at the start of each scanline mark all rects found so far as "finished". If rememberrect grows an existing rect or adds a new rect, mark that rect as "grown". At the end of each scanline, any rect still marked as finished that isn't tall enough can be deleted from the list.