|
code
newsgroups
|
|||||||||||||||||||||||
|
|||||||||||||||||||||||
Graphic Time LabelingI have my own graph routine which labels time on the X Axis.
The problem I'm having is labeling different compression periods based on the time of the compression period. The amount of space between X points is variable, so I need to somehow adjust the labeling (more or less labels) based on the space available while keeping the correct time associated with the X point when the label is placed. Anyone have a suggestion? Thanks David: "David" <dw85745***@earthlink.net> wrote That amounts to a bit of math, but without context, it would be difficult> I have my own graph routine which labels time on the X Axis. > The problem I'm having is labeling different compression periods based on > the time of the compression period. > > The amount of space between X points is variable, so I need to somehow > adjust the labeling (more or less labels) based on the space available > while keeping the correct time associated with the X point when the label is > placed. > > Anyone have a suggestion? to explain. If you post example code of what you've tried, that would add context to the problem so that others might fill in the missing details. LFS "David" <dw85745***@earthlink.net> wrote in message So you have an X axis that that represents time, it's assumed you know how news:uyr02EukJHA.1248@TK2MSFTNGP03.phx.gbl... >I have my own graph routine which labels time on the X Axis. > The problem I'm having is labeling different compression periods based on > the time of the compression period. > > The amount of space between X points is variable, so I need to somehow > adjust the labeling (more or less labels) based on the space available > while keeping the correct time associated with the X point when the label > is placed. > > Anyone have a suggestion? much time to represent, maybe a few seconds or a thousand days from left to right, and you would know how wide (in scale units ) the disply area is and where the leftmost point (StartTime) is, It's best (but not compulsory to work in Pixels). You would need to calc a ScalueUnitToTime varible of how much time per scale unit. ScaleUnits divided by total display time Then the X point of where to put your 'Lable' is So: Label1.Left = TimeZeroX + AmountOfTime * ScaleUnitToTime If the total display time is 3 minutes and is 600 Pixels wide then ScaleUnitToTime would be 600 / 180, so each second is 3.33 pixels. So 47 seconds would be 47 * 3.33 = 156 pixels from the zero position. Clear as mud? Ivar Take a look at the MeasureString graphics method.
http://msdn.microsoft.com/en-us/library/6xe5hazb.aspx This will give the size of each label. You might work with the sizes of specific labels, or you might work with a 'typical' label size. Once you have the size, start from the left edge of the graph and place the first label (or the first one where the text can be positioned to match the point you are labelling) and note where the label ends. Continue to the right, only labelling those points where the the label position (starting point) is a certain distance beyond the end of the previous label. In other words, for each point find the width of its label. and subtract half that from the point to find the label start (assuming you want the label centred under the point). The first label is the first point which has a label start of 0 or greater. The next point is the first point that has a label start of the end of the previous label plus an allowance for spacing. For instance Pt W 0.5 Start End Spc Next 10 50 25 -15 20 50 25 -5 40 45 22 18 * 62 3 65 50 40 20 30 65 50 25 40 80 40 20 60 110 35 17 93 * 127 3 130 120 40 20 100 150 40 20 130 * 170 3 173 etc Show quoteHide quote "David" <dw85745***@earthlink.net> wrote in message news:uyr02EukJHA.1248@TK2MSFTNGP03.phx.gbl... >I have my own graph routine which labels time on the X Axis. > The problem I'm having is labeling different compression periods based on > the time of the compression period. > > The amount of space between X points is variable, so I need to somehow > adjust the labeling (more or less labels) based on the space available > while keeping the correct time associated with the X point when the label > is placed. > > Anyone have a suggestion? > > Thanks > David: > > "James Hahn" <jh***@yahoo.com> wrote in message That's dotnet stuff and judging by the fact that the OP posted to the news:O2pMMPvkJHA.4132@TK2MSFTNGP04.phx.gbl... > Take a look at the MeasureString graphics method. > http://msdn.microsoft.com/en-us/library/6xe5hazb.aspx Classic VB newsgroup he is almost certainly using Classic VB (VB6 or earlier), in which case the dotnet solution you posted will be of no use to him. In VB6 he can use the TextWidth function on a DC set to the same font, or he can use or he can simply read the Label's width (if it has Autosize set to True). Mike Thanks for responses guys.
I'm currently using TextWidth and doing what Mr. Hahn has posted. My labels show up, but as compression time increases the X label value tends to get cut off when the next label is placed. I need to somehow set up a variable which is a function of compression so labels are increase along with compression. For example. Say you are posting minute data so that each point represents one minute. The time value would be a textwidth of 5 (hh:mm). and would need to be space every so often to look good. Now lets say every point repsented every 153 minutes. You would still have a textwidth of 5 (hh:mm) but the label spacing would need to increase accordingly. So without some form of select/case with every possible minute, some variable relationship needs to be established between the compression and label spacing. Thanks David Show quoteHide quote "James Hahn" <jh***@yahoo.com> wrote in message news:O2pMMPvkJHA.4132@TK2MSFTNGP04.phx.gbl... > Take a look at the MeasureString graphics method. > http://msdn.microsoft.com/en-us/library/6xe5hazb.aspx > > This will give the size of each label. You might work with the sizes of > specific labels, or you might work with a 'typical' label size. > > Once you have the size, start from the left edge of the graph and place > the first label (or the first one where the text can be positioned to > match the point you are labelling) and note where the label ends. Continue > to the right, only labelling those points where the the label position > (starting point) is a certain distance beyond the end of the previous > label. > > In other words, for each point find the width of its label. and subtract > half that from the point to find the label start (assuming you want the > label centred under the point). The first label is the first point which > has a label start of 0 or greater. The next point is the first point that > has a label start of the end of the previous label plus an allowance for > spacing. > > For instance > Pt W 0.5 Start End Spc Next > 10 50 25 -15 > 20 50 25 -5 > 40 45 22 18 * 62 3 65 > 50 40 20 30 > 65 50 25 40 > 80 40 20 60 > 110 35 17 93 * 127 3 130 > 120 40 20 100 > 150 40 20 130 * 170 3 173 > etc > > "David" <dw85745***@earthlink.net> wrote in message > news:uyr02EukJHA.1248@TK2MSFTNGP03.phx.gbl... >>I have my own graph routine which labels time on the X Axis. >> The problem I'm having is labeling different compression periods based on >> the time of the compression period. >> >> The amount of space between X points is variable, so I need to somehow >> adjust the labeling (more or less labels) based on the space available >> while keeping the correct time associated with the X point when the label >> is placed. >> >> Anyone have a suggestion? >> >> Thanks >> David: >> >> > If the procedure I suggested is not working then your problem is not clear
to me. "David" <dw85745***@earthlink.net> wrote in message I assume this case is OK because each minute is positioned more than 5 news:OZmp3M2kJHA.5732@TK2MSFTNGP05.phx.gbl... > Thanks for responses guys. > I'm currently using TextWidth and doing what Mr. Hahn has posted. > > My labels show up, but as compression time increases the X label value > tends to get cut off when the next label is placed. > I need to somehow set up a variable which is a function of compression so > labels are increase along with compression. > > For example. Say you are posting minute data so that each point > represents one minute. The time value would be a textwidth of 5 > (hh:mm). and would need to be space every so often to look good. characters apart, so the labels do not overlap. > Now lets say every point repsented every 153 minutes. You would still Now (I assume), each minute point is very close together and to print a > have a textwidth of 5 (hh:mm) but the label spacing would need to increase > accordingly. label for each one would make them unreadable. Therefore you want to print labels for only some of the minute points, but you need to work out which ones. If my assumption is correct then the process I described will do what you want - it will print labels only for those points where the position of the first character of the label is beyond the end of the last character of the previous printed label. You would use a loop that calculates the numbers I listed in the table for each minute, but print the label only when the start position for the label is greater than the end of the previous one - the labels I have marked with an asterisk in the example. > So without some form of select/case with every possible minute, There is an alternative procedure which calculates the number of labels that > some variable relationship needs to be established between the compression > and label spacing. > > Thanks > David can fit on the X axis (assuming they are all the same size) and then divides that number into the range of values to determine the value increment at which each label is placed. For instance- Width = 100, Label width = 5 + 2 spaces --> room for 14 labels X-Scale = 0 to 8000 minutes --> print a label every 570 minutes Mr Hahn:
Thanks for response. I am using VB6 not Net but the logic should be the same whether you are using TextWidth or MeasureString. The key area I'm trying to address is the "Number of Labels" placed across the screen. In your original post you aptly point out: A. Continue to the right, only labelling those points where the the label position (starting point) is a certain distance beyond the end of the previous label. and The first label is the first point which has a label start of 0 or greater. The next point is the first point that has a label start of the end of the previous label plus an allowance for spacing. I do the above as noted. ------------------- Where the issue lies is this. As I spin through my display loop I put down my datapoint, then I check to see if that point is the beginning of a day, if so I place "mm/dd" at that location, determine the width of those characters (5) and calculate where the next label can be placed. I then lay down datapoints until I'm => that spacing, then place another label for the next point "hh:mm". I then calculate that that label width(5), determine where the next label point can be placed and continue to loop. This places a lot of labels. If display time period changes to days for example, I mark every month and then label every seventh day. I could have a variable which adjusts the number of dependent labels "hh:mm" or "day", but I'm looking for some way to adjust this automatically Any ideas? Show quoteHide quote "James Hahn" <jh***@yahoo.com> wrote in message news:epP9Ar$kJHA.3380@TK2MSFTNGP04.phx.gbl... > If the procedure I suggested is not working then your problem is not clear > to me. > > "David" <dw85745***@earthlink.net> wrote in message > news:OZmp3M2kJHA.5732@TK2MSFTNGP05.phx.gbl... >> Thanks for responses guys. >> I'm currently using TextWidth and doing what Mr. Hahn has posted. >> >> My labels show up, but as compression time increases the X label value >> tends to get cut off when the next label is placed. >> I need to somehow set up a variable which is a function of compression so >> labels are increase along with compression. >> >> For example. Say you are posting minute data so that each point >> represents one minute. The time value would be a textwidth of 5 >> (hh:mm). and would need to be space every so often to look good. > > I assume this case is OK because each minute is positioned more than 5 > characters apart, so the labels do not overlap. > >> Now lets say every point repsented every 153 minutes. You would still >> have a textwidth of 5 (hh:mm) but the label spacing would need to >> increase accordingly. > > Now (I assume), each minute point is very close together and to print a > label for each one would make them unreadable. Therefore you want to print > labels for only some of the minute points, but you need to work out which > ones. > > If my assumption is correct then the process I described will do what you > want - it will print labels only for those points where the position of > the first character of the label is beyond the end of the last character > of the previous printed label. > > You would use a loop that calculates the numbers I listed in the table for > each minute, but print the label only when the start position for the > label is greater than the end of the previous one - the labels I have > marked with an asterisk in the example. > >> So without some form of select/case with every possible minute, >> some variable relationship needs to be established between the >> compression and label spacing. >> >> Thanks >> David > > There is an alternative procedure which calculates the number of labels > that can fit on the X axis (assuming they are all the same size) and then > divides that number into the range of values to determine the value > increment at which each label is placed. > > For instance- > Width = 100, Label width = 5 + 2 spaces --> room for 14 labels > X-Scale = 0 to 8000 minutes --> print a label every 570 minutes >
Show quote
Hide quote
"David" <dw85745***@earthlink.net> wrote To advance that same idea a little further, you might add an array (or two)> The key area I'm trying to address is the "Number of Labels" placed > across the screen. In your original post you aptly point out: > ------------------- > Where the issue lies is this. > > As I spin through my display loop I put down my datapoint, then I check to > see if that point is the beginning of a day, if so I place "mm/dd" at that > location, determine the width of those characters (5) and calculate where > the next label can be placed. I then lay down datapoints until I'm => that > spacing, then place another label for the next point "hh:mm". I then > calculate that that label width(5), determine where the next label point can > be placed and continue to loop. > This places a lot of labels. If display time period changes to days for > example, I mark every month and then label every seventh day. > > I could have a variable which adjusts the number of dependent labels > "hh:mm" or "day", but I'm looking for some way to adjust this automatically > > Any ideas? that denotes the lable format associated with a convenient unit measurement. If, for example the scale is in seconds, your format might be "nn:ss" with the convenient measurement at 30 seconds. If the scale is minutes, the format might be "hh:nn" with the unit measurement again at 30. Hours might be "hh:nn" with units at 1 or 12 (depending on size of display). For scales up past days and months added tests would be needed to align to Sundays and to the beginning of the month. But the idea is that in addition to your test for the next possible location, you could include a test for the convenient measurement (a Mod operation) such that seconds and/or minutes labels appear at 0 and 30, and hours would have labels (depending on display size) each hour or at midnight and noon. Any way you go at it, it sounds like a healthy chunk of decision making code.... <g> LFS I think your original comment might be correct - you will need a different
function for each case: The cases are something like: hh:mm mm:ss mm:ss mm:ss... dd:hh hh:mm hh:mm hh:mm... mm/dd dd:hh dd:hh dd:hh... yy/mm mm/dd mm/dd mm/dd... Not quite as you described it, but if you wanted a single function to do the job then the description would have to be something like that. While adjusting the labels for the different cases would be relatively easy, the test for start of hour/day/month, and the calculation of the value for each label would be different enough to suggest that the simplest solution is to get a routine that works at one scale then duplicate it at the others, with changes for both the labels and the calculations. This assumes that each display can be categorized into one of the above formats. If you need to (for instance) mark the start of a new day when you are displaying hours and minutes, so that it could be something like: 23:30 23:50 02/23 00:10 00:30 00:50 01:10 then the approaches I suggested won't work. The only way I could think of to do that would require a routine that processed the whole range for month markers, then each month (sub)range for day markers then each day (sub)range for hour markers and each hour (sub)range for minute markers and finally each minute (sub)range for seconds markers. This is a typical recursive routine. At any level there may be only one sub-range - ie, the span is less than one unit of the current range. Or, there could be several sub-ranges, each one of which is then processed recursively to see if it needs intermediate markers. Recursion would stop as soon as there was no room for a marker, or when it got to the seconds level. The original algorithm would work for placing the markers, as each subrange would appear to be a complete graph. Doing it from the top down (months, then days then hours etc) can also take care of the problem that (for example) an hour:minute marker of 00:00 should actually be promoted to a mm/dd marker, as this marker will have already been inserted at the higher recursion level. But this is becoming very complex code. Because it considers the whole range it could not be done as points are placed, but only after the extent of the graph was known. I don't think you could do this if it was a moving graph without having the labels jump around unexpectedly. Show quoteHide quote "David" <dw85745***@earthlink.net> wrote in message news:uEdINiRlJHA.1288@TK2MSFTNGP02.phx.gbl... > Mr Hahn: > > Thanks for response. I am using VB6 not Net but the logic should be the > same whether you are using TextWidth or MeasureString. > > The key area I'm trying to address is the "Number of Labels" placed > across the screen. In your original post you aptly point out: > > A. Continue to the right, only labelling those points where the the label > position (starting point) is a certain distance beyond the end of the > previous label. > > and > > The first label is the first point which has a label start of 0 or > greater. The next point is the first point that has a label start of the > end of the previous label plus an allowance for spacing. > > I do the above as noted. > > ------------------- > Where the issue lies is this. > > As I spin through my display loop I put down my datapoint, then I check to > see if that point is the beginning of a day, if so I place "mm/dd" at that > location, determine the width of those characters (5) and calculate where > the next label can be placed. I then lay down datapoints until I'm => > that spacing, then place another label for the next point "hh:mm". I then > calculate that that label width(5), determine where the next label point > can be placed and continue to loop. > This places a lot of labels. If display time period changes to days for > example, I mark every month and then label every seventh day. > > I could have a variable which adjusts the number of dependent labels > "hh:mm" or "day", but I'm looking for some way to adjust this > automatically > > Any ideas? > Thanks Mr. Hahn and Mr. Serflaten for your time and input.
Mr Serflaten I liked your idea of picking a "specific" subperiod time on which to place the label. This would force the sublabels to occur less frequently. Will give it a go. Please consider this thread closed unless anyone has other suggestions. David Show quoteHide quote "James Hahn" <jh***@yahoo.com> wrote in message news:evQzzQVlJHA.2384@TK2MSFTNGP04.phx.gbl... >I think your original comment might be correct - you will need a different >function for each case: > > The cases are something like: > hh:mm mm:ss mm:ss mm:ss... > dd:hh hh:mm hh:mm hh:mm... > mm/dd dd:hh dd:hh dd:hh... > yy/mm mm/dd mm/dd mm/dd... > > Not quite as you described it, but if you wanted a single function to do > the job then the description would have to be something like that. While > adjusting the labels for the different cases would be relatively easy, the > test for start of hour/day/month, and the calculation of the value for > each label would be different enough to suggest that the simplest solution > is to get a routine that works at one scale then duplicate it at the > others, with changes for both the labels and the calculations. This > assumes that each display can be categorized into one of the above > formats. > > If you need to (for instance) mark the start of a new day when you are > displaying hours and minutes, so that it could be something like: > 23:30 23:50 02/23 00:10 00:30 00:50 01:10 > then the approaches I suggested won't work. The only way I could think of > to do that would require a routine that processed the whole range for > month markers, then each month (sub)range for day markers then each day > (sub)range for hour markers and each hour (sub)range for minute markers > and finally each minute (sub)range for seconds markers. This is a typical > recursive routine. At any level there may be only one sub-range - ie, the > span is less than one unit of the current range. Or, there could be > several sub-ranges, each one of which is then processed recursively to see > if it needs intermediate markers. Recursion would stop as soon as there > was no room for a marker, or when it got to the seconds level. The > original algorithm would work for placing the markers, as each subrange > would appear to be a complete graph. Doing it from the top down (months, > then days then hours etc) can also take care of the problem that (for > example) an hour:minute marker of 00:00 should actually be promoted to a > mm/dd marker, as this marker will have already been inserted at the higher > recursion level. But this is becoming very complex code. Because it > considers the whole range it could not be done as points are placed, but > only after the extent of the graph was known. I don't think you could do > this if it was a moving graph without having the labels jump around > unexpectedly. > > "David" <dw85745***@earthlink.net> wrote in message > news:uEdINiRlJHA.1288@TK2MSFTNGP02.phx.gbl... >> Mr Hahn: >> >> Thanks for response. I am using VB6 not Net but the logic should be the >> same whether you are using TextWidth or MeasureString. >> >> The key area I'm trying to address is the "Number of Labels" placed >> across the screen. In your original post you aptly point out: >> >> A. Continue to the right, only labelling those points where the the >> label position (starting point) is a certain distance beyond the end of >> the previous label. >> >> and >> >> The first label is the first point which has a label start of 0 or >> greater. The next point is the first point that has a label start of the >> end of the previous label plus an allowance for spacing. >> >> I do the above as noted. >> >> ------------------- >> Where the issue lies is this. >> >> As I spin through my display loop I put down my datapoint, then I check >> to see if that point is the beginning of a day, if so I place "mm/dd" at >> that location, determine the width of those characters (5) and calculate >> where the next label can be placed. I then lay down datapoints until I'm >> => that spacing, then place another label for the next point "hh:mm". I >> then calculate that that label width(5), determine where the next label >> point can be placed and continue to loop. >> This places a lot of labels. If display time period changes to days for >> example, I mark every month and then label every seventh day. >> >> I could have a variable which adjusts the number of dependent labels >> "hh:mm" or "day", but I'm looking for some way to adjust this >> automatically >> >> Any ideas? >> >
how to reposition desktop icons
WTF happened to my typelibs? lifecyle? How to Link ADO control to DATAGRID? how to check an ADO recordset status? How to switch the monitor off through vb6 code? Common Dialog Font - Color Choices More Regional Setting Woes Visual Basic 6 ActivexDLLs are not registering under Windows Vista Adding a right-click function to a control |
|||||||||||||||||||||||