WPF graph children z-order

I have a canvas added to a WPF graph's children in XAML to drawing various text blocks and lines. Later in code I add RangeCursors. The RangeCursors paint on top of the canvas, but I'd like the canvas on top. Is there a way to control this? I've tried both adding the RangeCursors at the end of the children collection and inserting at position 0, but the result is the same (RangeCursors on top).
Solved!
Go to Solution.

Set the ZIndex of the canvas to a value above the default of zero:
    <ni:Graph.Children>
        <Canvas Panel.ZIndex="1" ... />
        <ni:RangeCursor ... />
    </ni:Graph.Children>
~ Paul H

Similar Messages

  • Change order of wpf graph plots

    I'm trying to solve following issue. Let's say I'm sampling data once per second and showing it on the graph. I want to show history of the data, say last 20 plots using the same color with fading. What I do now:
    - create 21 plots, say Plots[0]..Plots[20] 
    - at meas 1, set Data[0] = data
    - set Plots[0] opacity to 1
    - at meas 2, set Data[1] = data
    - set Plots[1] opacity to 1, Plots[0] opacity to 0.5
    - at meas 3, set Data[2] = data
    - set Plots[2] opacity to 1, Plots[1] opacity to 0.6, Plots[0] opacity to 0.3
    - at meas 21, set Data[20] = data
    - set opacity to 0.1..1
    // we're fine as of now, here comes the tricky part
    - at meas 22 I need to remove the data of meas 0 (stored at Data[0]) and replace it with the new data
    - so I set Data[0] = data
    - set Plots[0] opacity to 1 (it's the newest result)
    - set other plots opacity 0.1..0.9
    // and here is the problem: Plots[0] is now at the bottom of the plot stack and is covered by 20 other plots, thus is barely visible
    so I somehow need to move Plots[0] to the top of the stack
    I've tried removing Plot and Data of the farthest plot and adding creating plot with the most recent data, but it leads to incorrect indices (Plot.Index grows all the time, but Data array stays the same)
    Another option would be to fix plots order and opacity in advance, and change data for all plots all the time. But I assume this would be very slow (think of 20-50 copies of the plot with say 1000 points).
    So, any bright ideas here?

    Idea 1) Pre-allocate all of the fade plots, use BeginInit/EndInit when updating the Data collection, and always apply the newest data to the last plot. In pseudo-code:
        // initial setup
        for( opacity = 0..1 )
            var renderer = new Renderer( opacity )
            graph.Plots.Add( new Plot { Renderer = renderer } )
        // on data update
        graph.BeginInit()
        for( i = 1..graph.Data.Count )
            graph.Data[i - 1] = graph.Data[i] /* shift old data down */
        graph.Data[20] = /* assign new data to the last plot */
        graph.EndInit()
    Idea 2) If you just want the historic data visible in the graph (i.e. you do not need to query or interact with the old data through the graph), and if your range is stable, then you could have one plot in the graph and use a PhosphorColorRamp to get the visual fade effect. In pseudo-code:
        // initial setup
        var brush = new SolidColorBrush( C )
        Graph.SetPhosphorMode( brush, Immediate )
        graph.Plots.Add( new Plot { Renderer = new Renderer( brush ) } )
        graph.RenderMode = Raster
        graph.PhosphorColorRamp = new FadeRamp { Color = C, Duration = 20, DurationKind = Frames }
        // on data update
        graph.Data[0] = /* assign new data to first plot */
    (Note that the phosphor effect is one of the areas being updated, so the syntax will be changing in the next release of Measurement Studio.)
    ~ Paul H

  • Wpf graph Measurement studio

    Bonjour,
    Je vous expose mon  probleme.
    J'ai developpe une application  sous Win7 et VS2010 environnement C# et wpf.
    Je dois afficher une courbe en temps réel sur une periode d'une heure avec un nouveau point toutes les 100ms (soit max 36000).
    J'utilise l'objet graph NI et je dois également afficher le temps sur l'axe des abcisses. les graph sont "databinder" 
    1er methode : J'ai utilser un analogWaveform mais au bout de 20000 points le rafraichissement commence a ralentir.  
    2eme methode : J'ai vu sur le site la page optimisation des graph donc je passe par un objet ChartCollectionAnalogWaveform. Je le dimensionne a 36000 et effectue un append toutes les 100ms 
    //ChartcollectionAnalogWaveform[] LengthCurveChart ;
    //toutes les 100 ms
    NationalInstruments.AnalogWaveform<double> __waveLength = new AnalogWaveform<double>(1);
    DateTime[] __time =new DateTime[1];
    __waveLength.Timing = WaveformTiming.CreateWithRegularInterval(new TimeSpan(0, 0, 0, 0, 100), new DateTime(2000, 1, 1, 0, 0, 0));
    LengthCurveChart[0].Append(__waveLength);
    Mais sur cette derniere methode j'ai un plantage au bout de quelques minutes ("Tha data store was modified ... Buffer<DateTime>".
    Je n'ai pas trouver d'exemple sur le net avec des chartCollectionAnalogWaveform et/ou des affichage avec l'horodatage en abcisses.
    J'aimerais savoir comment faire quel objet ou quellle methode utiliser ?
    Merci
    Johan

    My data are of type of double and I send the data to graph using the steps below (a simplified example):
    int N=35;
    Point[] pt = new Point[N];
    for (int i = 0; i < N; i++)
         pt[i].X = i+1;
         pt[i].Y = 2.1e-1 * (i + 1) * (i + 1);
    Plot plt = new Plot("Total ");
    plt.Label = "Total ";
    PointPlotRenderer pltr = new PointPlotRenderer();
    SolidColorBrush br = new SolidColorBrush(Colors.Red);
    pltr.Stroke = br;
    pltr.Fill = br;
    plt.Renderer = (PlotRenderer)pltr;
    plt.HorizontalScale = xAxis;
    plt.VerticalScale = yAxis;
    niGraph.Plots.Add(plt);
    niGraph.Data[0] = pt;
    I send new data each time to the plot and also I have created my own usercontrol chart using the Measurement Studio graph as the starting point in case that is useful for debugging.
    Thank you for the asnwer about the next version of measurement studio.

  • Wpf export graph to image problem

    My problem is I have created a new custom custom using the NI wpf graph as the basis. The control consist mainly of the graph,its axes and legends on a grid. To allow the legend to be moved around, I put it in a child grid. My problem is while trying to export the control as an image I am using the code below (similar to wpf graph export to image):
    Rect bounds = LayoutInformation.GetLayoutSlot(MainGrid);
    var bitmap = new RenderTargetBitmap((int)bounds.Width + 1, (int)bounds.Height + 1, 96, 96, PixelFormats.Default);
    bitmap.Render(MainGrid);
    My problem is the axes and the edges of the image exported to clipboard is dark as shown below. Is saved to image, the edges are instead transparent but better (not visible in the photos app but visible in paint). My question is why is this behavior and how can it be avoided?
    Thanks.
    Solved!
    Go to Solution.

    I did a bit of research and it seems the dark color is due to the trasnparency of the axes and edges of the image: the clipboard in windows does not support transparent image. The question is how can this transparency be removed from the axes and edges of the image?
    Thanks.

  • Position Cursor on GRAPH either by dragging it OR entering the dsired position in the Cursor legend

    I've written a VI that allows the user to import a dataset, view it on a graph, and then use cursors to "filter" the range of data that I'm interested in, by sending the cursor.index values from the first graph to an array subset function which feeds a second graph.  The problem is that I'd like to provide the user the ability to position the cursors on the first graph both visually - by dragging - (for "course" control) AND by entering the desired values directly into the cursor legend (for fine control).  The problem is that I cannot find a way to do this, since I have to have the Lock Ring set to “Lock to Plot” in order to capture the index information. According to the documentation, the only way to be able to position the cursors via the Cursor legend is to set the Lock Ring to “Free”, which means the index values are rendered useless, since the cursor is no longer locked to the plot.  If I leave the Lock Ring in "Lock to Plot", and enter a value in the cursor legend, it does move the cursor, but not to where it should.  If I enter a value an x value of 9.0 for cursor 1, the cursor goes to 10.2638.  The next time I enter 9.0, it goes to 9.82794.  I don't understand what the issue is.  Is there a way around this?
    Attachments:
    ppv data filter 3.vi ‏366 KB

    Yes Rudi:  What I want is for the operator to place the cursors by dragging them (just eye-balling it).  The, if they see that the Y cursor (horizontal) is at 10.234, and they want to make it 10, they could simply enter that value in the cursor legend, and the cursor would be placed exactly at 10.  The only way to do this seems to be to select the “Free” option for the cursor.  However, in order to use the first graph to set the boundaries of the second graph, I have to use the Cursor Index from the first as an input to the Array Subset that feeds the second graph.  In order to use the Cursor Index, the first graph has to have its cursor Lock Rings set to “Lock to Plot”.  Am I making this any more understandable, or just rambling?

  • How do I determine the best Order to run my butterwort​h filter at?

    I'm lowpass filtering a signal that was sampled at 200hz through a 40Hz butterworth. I need to determine the optimal filter order. How do i create a quantitative comparison of the effects of the butterworth filter on the frequencies above 40Hz based on varying order?
    I have tried using the FFT to create a chart in the frequency space, but am not sure how to proceed. Any help would be greatly appreciated. What I want to compare is the path immediately before and immediately after the butterworth filter.
    Also is there an alternate way to read in a column of numbers from a text file without using the Read from Measurement file Express VI?
    Solved!
    Go to Solution.
    Attachments:
    frequencydomain.JPG ‏131 KB

    I have my filter working correctly now. I just need a quantifiable way to justify picking any one order of filtering over another.
    Here is my front panel, How can I compare the (After/ Before) graphs of varying orders (in a quantifiable way)? How can one tell which is the best?
    I was thinking I could compare the (Integral from 0 to 40)/40 and the (Integral from 40-inf). The order that yeilds the closest to 1 and 0 respectively should be the one I go with. Does that sound logical?
    How do I compute a definite integral with a lower bound and an upper bound?
    Attachments:
    order2.JPG ‏240 KB
    order5.JPG ‏240 KB
    order10.JPG ‏240 KB

  • Different custom colors for a WPF line plot

    Dear Sir,
    I am trying to create a WPF graph with different colors for different points of time , example  Black 0-10,red 11-20, green 21-30...
    I saw the nifty video and download the range masking cursor but got stuck. 
    Thank you
    George MAsiello

    Here's a quick mockup of the custom renderer version (sorry I did not have time to translate it to VB myself):
        public class CustomRenderer : PlotRenderer {
            private static readonly DataRequirements _dataRequirements = new DataRequirements(
                DataCulling.PreserveLines, DataDecimation.CoLinear,
                new DataDimension( DataDimensionSource.IndexData, DataDimensionScale.IndependentScale ),
                new DataDimension( DataDimensionSource.SampleData, DataDimensionScale.DependentScale ) );
            // The color ranges we want to show on the plot.
            private readonly Tuple<Color, double>[] _colorRanges = new[] {
                Tuple.Create( Colors.Black, 10.0 ),
                Tuple.Create( Colors.Red, 20.0 ),
                Tuple.Create( Colors.Green, 30.0 ),
            private readonly RenderTargetOptions[] _rangeOptions;
            public CustomRenderer( ) {
                // Create render options for each range color.
                _rangeOptions = _colorRanges.Select( colorRange => new RenderTargetOptions( this,
                    RenderTargetOption.CreateValue( RenderTargetOptionsProperty.Stroke, new SolidColorBrush( colorRange.Item1 ) ),
                    RenderTargetOption.CreateValue( RenderTargetOptionsProperty.StrokeThickness, 1.0 ) ) )
                .ToArray( );
            public override SupportedRenderModes SupportedRenderModes {
                get { return SupportedRenderModes.VectorAndRaster; }
            public override DataRequirements GetDataRequirements( ) {
                return _dataRequirements;
            protected override Freezable CreateInstanceCore( ) {
                return new CustomRenderer( );
            protected override void RenderLegendCore( LegendRenderArgs renderArgs ) { }
            protected override void RenderGraphCore( PlotRenderArgs renderArgs ) {
                // Get the time axis for the renderer.
                Plot plot = (Plot)renderArgs.Plot;
                var timeAxis = plot.GraphParent.GetAxis( plot, Orientation.Horizontal );
                var dataMapper = (IDataMapper<double>)timeAxis.GetDataMapper( plot.GraphParent );
                int startIndex = 0;
                var xData = renderArgs.RelativeData[0];
                var yData = renderArgs.RelativeData[1];
                var renderTarget = renderArgs.RenderTarget;
                for( int i = 0; i < _colorRanges.Length - 1; ++i ) {
                    // Draw all data below the current range with the associated color.
                    int endIndex = startIndex;
                    double range = _colorRanges[i].Item2;
                    double offset = dataMapper.Map( range );
                    while( endIndex < xData.Size && xData[endIndex] <= offset )
                        ++endIndex;
                    RenderSegment( startIndex, endIndex, xData, yData, renderTarget, _rangeOptions[i] );
                    startIndex = endIndex;
                // Draw all remaining data with the last color range.
                RenderSegment( startIndex, xData.Size, xData, yData, renderTarget, _rangeOptions.Last( ) );
            private static void RenderSegment( int startIndex, int endIndex, Buffer<double> xData, Buffer<double> yData, IRenderTarget renderTarget, RenderTargetOptions options ) {
                int length = endIndex - startIndex;
                if( length <= 0 )
                    return;
                // Join current range with previous.
                if( startIndex > 0 ) {
                    --startIndex;
                    ++length;
                using( Buffer<double> xSegment = xData.Slice( startIndex, length ) )
                using( Buffer<double> ySegment = yData.Slice( startIndex, length ) )
                    renderTarget.DrawLines( options, xSegment, ySegment );
    ~ Paul H

  • Automatic Cursor Movement in one Graph, in accordance to the cursor in another graph

    I am using two XY graphs each with 4 cursors. I want to assign each cursor of graph A to each cursor of graph B such that the corresponding cursors in graph B moves in accordance to the cursors in graph A.
     I have used Active cursor, Cursor.PosX and it works for one cursor. However when I use the same concept to change the active cursor value and faciliate the automatic movement for all cursors they do not work.
    Message Edited by Chathuri on 08-13-2009 06:26 AM
    Solved!
    Go to Solution.

    Hi,
    As requested I would like to post the solution as to how I tacked the problem. It was actually small mistake on my part. When I connect the two property nodes for each XY graphs I should connect ActiveCursor to ActiveCursor and Cursor.PosX to Cursor.PosX. What I did was connect the Active cursor of A graph to the cursor.index of B graph. I have attached a small screen shot of connecting the first cursor of A graph to the 1st cursor of B graph so that the cursor in B graph follows the cursor in A graph.
    In order to connect more cursors as in my case, the only change to be made is the change in the Acitve cursor constant to, 1,2,......
    Chathuri
    Attachments:
    CursorMovement.JPG ‏7 KB

  • Grapher 2.0 bug nr. 23 ?

    April 2008, Grapher 1.1, OS X 10.4.11 Tiger : I could get graphs of sixth order differential equations, use y', y", y"' or d^n/dx^ (tried untill n=6) which Grapher 1.1 recognized.
    May 2008, Grapher 2.0, OS X 10.5.2 Leopard : only first order differential equations can be entered in Grapher ; y", y''', d^2/dx^2 or more are unknown expressions for Grapher 2.0.
    Is this nr. 23 bug, a new one ? Does anybody else get it ?
    Thanks for the replies yes or no. Regards, YB24

    I'm afraid this bug is a true one, nr. 23 of my bugs list (Curvus Pro X 1.3.2, Grapher 1.1, Grapher 2.0) ; it was confirmed by my son with OS X 10.5.3 and Grapher 2.0 in english, as well on my Mac OS X 10.5.2 & 10.5.3 and Grapher in french. So :
    — I found 7 bugs in Curvus Pro X 1.3.2 working in Tiger ;
    — Grapher 1.1 = Curvus Pro X 1.3.2 + 14 new bugs, total 21 bugs ;
    — Grapher 2.0 = Grapher 1.1 - 6 (from v. 1.1) + 2 new bugs, total 17 bugs.
    Shame on Apple developer in charge of Grapher !
    Is anybody concern with Grapher in the Honourable Apple inc. ?
    Please do the job ! YB24

  • How to using ni:Graph Control draw more than 500000 points

    this is my test code:
    ChartCollection<DateTime, double> chartCollection  = new ChartCollection<DateTime, double>();
    chartCollection.Append(dateTimeList, doubleList);     //dateTimeList and doubleList has 500000 points
     graph.DataSource = chartCollection ;
    but a System.OutOfMemoryException  throwed in mscorlib.dll when I  zoom the graph.

    Based on the data types involved, I believe you are hitting the same issue as the question WPF graph AxisDateTime crash. To avoid the crash, change the Mode of the MajorDivisions and MinorDivisions of your axes. For example, the XAML below reduces the number of major divisions to three and hides the minor divisions:
        <ni:AxisDateTime Orientation="Horizontal" MinorDivisions="{x:Null}">
             <ni:AxisDateTime.MajorDivisions>
                 <ni:RangeLabeledDivisions Mode="Count: 3" />
             </ni:AxisDateTime.MajorDivisions>
         </ni:AxisDateTime>
    ~ Paul H

  • References from nested clusters

    Hi,
    Currently our station can test only one product at the time, but we modified the wiring so now we can attach 2 units to the same station. A new application must be written to handle the new scenario. The test has to be executed several times on both the units. The execution is sequential so unit1 first then unit2.
    I have created a CONTROL cluster with the following elements
    - bool: boolean button (means unit enabled/disabled)
    - PARAMS cluster: various text rings. This cluster is disabled and greyed out once the user enabled the starter.
    - MEASUREMENT graph
    Rules:
    - the unit can not be enabeled if any of the text rings is unconfigured.
    - the test must be interrupted immediately for the given unit if the enabled button is pressed during the test (when the user disable the unit runtime). So a reference to this button must be used and continously monitored.
    - the test must be interrupted immediately for both the units if the stop button is pressed during thet test
    - after a test is completed the results must be evaluated and the unit must be disabled if the measured values are outside of the limits.
    now... This would be a very easy task if I would have one unit only. I would just create the neccessary control references drive them to the measurement VI and here we go.
    But its getting inconveniently complex when I have control 2 units. I can not treat the control elements in an array (so like an array with 2 CONTROL clusters) because then I can not disable the PARAMS clusters independently.
    I dont see an easy way to add 2 of the CONTROL clusters to a new cluster (so treat them as one cluster), I am not sure how to get the references in this way. (if I combine them into one cluster its pretty easy to get propertynode/value for any of the elements, but I need control refs)
    So I handle both clusters as an independent control on the front panel, so I have add lot of duplicatinos to handle both units in the same way. I find this very inconvenient and error prone, plus it complicates the block diagram 
    I am wondering what would be right approach to handle these type of problems.
    (I have tried to create reentrant VIs but I gave up because I had to communicate too much between my main VI and the reentrant VIs. That made the code hard to follow)
    I use LV2012, but the attachment in LV8 so hopefully everybody can open it
    Thanks
    Attachments:
    Cluster.vi ‏16 KB

    Well... if I create a reference to the main cluster then I can use the controls[] property which will give me back 3 references in an array. First the button, second the params clusters, third the graph (maybe the order is different, it doesnt matter for now). But when I drive the params cluster reference to another property node it does not offer me a controls[] property, so I can not access the contents of the cluster itself. I may could use some sort of a cast function, but its really counter-intuitive.
    I always have to know the order of any of the given clusters and if I change the order my code will mess up instantly. And hell, should why should I refer to my objects as control[][0], control[][1] etc instead of a real name.
    Not sure if this can be resolved in the current LabVIEW environment...
    The workaround I made is that I have created a cluster in which each element are references. I drive the button, graph and params cluster references into it and as I have two units to control I made an array of this cluster.
    Not sure if you agree but this is overcomplicating the code and I had to create an extra cluster just to access to the references of my original clusters. Pain in the back.
    Let me know your thoughts!
    thx.

  • Distinct Count Calculation

    Hello everybody,
    I have a cube with appointments including dimensions for companies and dates.
    One of my measures is "Appointments" which is the count of all appointments. Another calculated member is "Visits" which is the count of appointments with the type of "Visits".
    This is my MDX epxression for "Visits":
    AGGREGATE([Appointment].[Type].&[Visit], [Measures].[Appointments])
    Now I would like to create a new calculated member "Company Visits" which should be the distinct count of "Visits" by company and date.
    Example: 2 "Visits" in one company on the same day should be 1 "Company Visit"
    In T-SQL this query works:
    COUNT(
    DISTINCT(
    CASE [Type]
    WHEN "Visit" THEN CAST([CompanyID] AS NVARCHAR) + CONVERT(NCHAR(8), CAST([Date] AS NVARCHAR))
    ELSE NULL
    END
    ) AS [Company Visits]
    How can I do this with MDX in calculations?
    Additionally I would like to have a calculated member "Days in Field" as distinct count of dates with "Visits".
    Thanks in advance and best regards
    Lars

    Hi Lars,
    Based on your description, you want to create a new calculated member to calculate the distinct count of "Visit" for each company, right? In this case, you can use DistinctCount to achieve your requirement, here is a sample query about DistinctCount function
    for your reqerence.
    with member [DistCount] as
    distinctcount(exists(Employee.Employee.children,,"Reseller Orders"))
    Select {[Measures].[Reseller Order Count],
    [Measures].[DistCount]} on 0,
    ([Employee].[Gender].children) on 1
    From [AdventureWorks]
    Reference:DistinctCount (MDX)
    Regards,
    Charlie Liao
    TechNet Community Support

  • Multiple signal types in one chart

    Hi there!
    I need some help to understand if it is possible to do what I intend to do using SignalExpress LE.
    The task is actually quite simple. I need to start a measurement of 2 analog, 2 digital and 1 frequency channels. The sampling speed is moderate, 5kHz. During logging I wish to be able to see the signals "live" and afterwards I want to compare signals and measure time between signal events in the graph.
    I tried with a simulated device (since I have not yet one), the USB-6211. This failed due to the model only being able to poll the frequency channel (I think so since I was not able to select continuous samples). Therefore I tested by simulating with USB-6341 and made this setup:
    Now I have some questions:
    Are the steps (on the left) performed in sequence or in parallel?
    Can I plot all signals in one graph so I can correlate them and zoom and measure all together?
    I wanted to log the signals but I couldn’t include the frequency channel (see the little dialog box). Shouldn’t that be possible?
    I’m also confused by the fact that the frequency plot has Volts on y-axis and not Hz.
    Do I really need HW timing on digital I/O to perform this “simple” task? Which means a more expensive HW…
    Many thanks for any input!
    Regards,
    Nicke
    Attachments:
    MyTest.jpg ‏563 KB
    MyTest.seproj ‏131 KB

    I've figured it out. Like everything to do with Illustrator's horrible ancient neglected graph tool, it's absurdly clumsy and involves tiptoeing around what is shamefully bad programming for an expensive professional product.
    It's all about timing - you have to do things in one rigid counter-intuitive order that appears to not be working then comes together at the end:
    Create the graph but, for now, keep it all the same graph type. If you've already set it to have different graph types, set them to be the same for now.
    Select the whole graph, and in Graph Types main window, set Value Axis to 'Both sides'
    In the drop-down there should be a Left and Right Axis (or top and bottom...). Set Value Axis settings for these now. It'll look like it only works for one axis, because the other axis won't change - bare with it...
    Select the data series you want to use the other axis using Group Selection. Go to Graph Type and set the Value Axis to the other one, and set the graph type to the one you want. It should suddenly all fall into place.
    If you need to edit one of the Value Axis settings, select the whole graph, set the whole graph to one graph type, edit the appropriate value axis by choosing it from the drop down, and the re-apply the graph types as above.
    (the bug is - you shouldn't need to set the graph object to have only one graph type in order to access the value axis options for the two seperate value axis)

  • Why im getting too long time in getting response from server in RMI???

    I'm using RMI architecture. On my server side I put this method getRubricHierarchy() which returns the ArrayList of Test class objects. everything is working properly fine.
    Im getting response properly, problem is its taking very long time in getting the response. method populate and create ArrayList in 0 second at server side but its taking more than 20 seconds to get response at client side.
    My arraylist size is 30,000.
    Any suggestions to reduce the time.
    below you can see the code.
    public List<Test> getRubricHierarchy(String strTree,String gblCombinedRepSectionID,String gblCompleteRepSectionID,String gblCompleteRepertoryID,Map authMap) {
            Connection con=null;
              ResultSet rs = null;
              List<Test> l = new ArrayList<Test>();
              List allList = new ArrayList();
              con = createDBCon();
              rs = con.createStatement().executeQuery("select * from rubric where sectionid='"+gblCombinedRepSectionID+"' order by orders");
              Map parentMap = new HashMap();
              while (rs.next()) {
                   Test rNode = new Test();
                String rubrid = rs.getString("id");
                   final String desc = rs.getString("name");
                   rNode.setRubricName(desc);
                   rNode.setRubricID(rubrid);
                   rNode.setAuthor(rs.getString("repid"));
                   final int levlId = rs.getInt("levelid");
                   rNode.setRubLevel(levlId);
                   rNode.setCrossRef(rs.getString("CROSSREFERENCE"));
                   final String parentID = rs.getString("PARENTID");
                   rNode.setParentID(parentID);
                   rNode.setSectionID(rs.getString("sectionid"));
                   if (parentID.equals("0")) {
                        l.add(rNode);
                   allList.add(rNode);
                   List rmdyLst = (List) parentMap.get(parentID);
                   if (rmdyLst == null) {
                        rmdyLst = new ArrayList();
                        parentMap.put(parentID, rmdyLst);
                   rmdyLst.add(rNode);
              rs.close();
              for (Iterator iterator = allList.iterator(); iterator.hasNext();) {
                   Test rNodes = (Test) iterator.next();
                   List remdyLst = (List) parentMap.get(rNodes.getRubricID());
                   if (remdyLst != null) {
                        rNodes.setChildren(remdyLst);
                        for (Iterator iterator2 = remdyLst.iterator(); iterator2.hasNext();) {
                             Test rn = (Test) iterator2.next();
                             rn.setParent(rNodes);
            }catch(Exception e){
                e.printStackTrace();
              return l;
         }here is my Test Class
    public class Test implements  Serializable,Cloneable , MutableTreeNode{
            private String strRubricID,strOldRubricID,strRubricName,strCrossRef,Author,strParentID,strSectionID;
            private int rubLevel;
            private List remedyList;
            private List children = new ArrayList();
            private Test parent;
            private int order;
            private String AuthorName="";
            private String abbr;
            private String treeType="";
            private int noRem=-1;
            private boolean isAddAsChild=false;
            private String strRubricHie="";
            private String user="";
            public static final Enumeration<TreeNode> EMPTY_ENUMERATION = new Enumeration() {
                public boolean hasMoreElements() {
                    return false;
                public TreeNode nextElement() {
                    throw new NoSuchElementException("No more elements");
            public Test(){
            public void setUser(String user){
                this.user = user;
            public String getUser(){
                return user;
            public void setRubricHierarchy(String s){
                this.strRubricHie=s;
            public String getRubricHierarchy(){
                return strRubricHie;
            public Test(String treeType){
                this.treeType = treeType;
            public void setAddAsChild(boolean b){
                this.isAddAsChild=b;
            public boolean isAddAsChild(){
                return isAddAsChild;
            public Test getUserObject(){
                return this;
            public  void setRubricID(String id){
                this.strRubricID = id;
            public  String getRubricID(){
                return strRubricID ;
            public  void setOldRubricID(String id){
                this.strOldRubricID = id;
            public  String getOldRubricID(){
                return strOldRubricID ;
            public  void setParent(Test r){
                this.parent = r;
            public  Test getParent(){
                return parent;
            public  void setParentID(String id){
                this.strParentID = id;
            public  String getParentID(){
                return strParentID;
            public  void setSectionID(String id){
                this.strSectionID= id;
            public  String getSectionID(){
                return strSectionID;
            public  void setRubricName(String name){
                this.strRubricName = name;
            public  String getRubricName(){
                return strRubricName;
            public  void setAuthorName(String name){
                this.AuthorName = name;
            public  String getAuthorName(){
                return AuthorName;
            public  void setAuthorAbbrivation(String a){
                this.abbr = a;
            public  String getAuthorAbbrivation(){
                return abbr;
            public void setRubLevel(int rubLevel) {
                this.rubLevel = rubLevel;
            public int getRubLevel() {
                return rubLevel;
            public void setCrossRef(String strCrossRef) {
                this.strCrossRef = strCrossRef;
            public String getCrossRef() {
                return strCrossRef ;
            public void setRemedyList(List remedyList) {
                this.remedyList = remedyList;
            public List getRemedyList() {
                return remedyList;
            public void setAuthor(String Author) {
                this.Author = Author;
            public String getAuthor() {
                return Author;
            public void setChildren(List list) {
                this.children = list;
            public List getChildren() {
                return children;
            public void setOrder(int o){
                this.order = o;
            public int getOrder(){
                return order;
            public void setNumberOfRemedies(int no)
                this.noRem = no;
            public int getNumberOfRemedies()
                return noRem;
            public String toString() {
                String value="";
                value=strRubricName+ " ("+abbr+")";
                return value;
            public Object clone(){
                Test rubric = new Test();
                rubric.Author = Author;
                rubric.children = children;
                rubric.order = order;
                rubric.parent = parent;
                rubric.remedyList = remedyList;
                rubric.rubLevel = rubLevel;
                rubric.strCrossRef = strCrossRef;
                rubric.strParentID = strParentID;
                rubric.strRubricID = strRubricID;
                rubric.strRubricName = strRubricName;
                rubric.strSectionID = strSectionID;
                return rubric;
         @Override
         public TreeNode getChildAt(int paramInt) {
              if (this.children == null) {
                   throw new ArrayIndexOutOfBoundsException("node has no children");
              final TreeNode node = (TreeNode) children.get(paramInt);
              return node;
         @Override
         public int getChildCount() {
              if (this.children == null) {
                   return 0;
              return children.size();
         @Override
         public int getIndex(TreeNode paramTreeNode) {
              // TODO Auto-generated method stub
              return 0;
         @Override
         public boolean getAllowsChildren() {
              return true;
         @Override
         public boolean isLeaf() {
              return children.isEmpty();
         @Override
         public Enumeration children() {
              if (this.children == null) {
                   return EMPTY_ENUMERATION;
              Vector v = new Vector(this.children);
              return v.elements();
         @Override
         public void insert(MutableTreeNode newChild, int paramInt) {
              if (newChild == null) {
                   throw new IllegalArgumentException("new child is null");
              MutableTreeNode oldParent = (MutableTreeNode) newChild.getParent();
              if (oldParent != null) {
                   oldParent.remove(newChild);
              newChild.setParent(this);
              if (children == null) {
                   children = new ArrayList();
              children.add(paramInt, newChild);
         @Override
         public void remove(int childIndex) {
              MutableTreeNode child = (MutableTreeNode) getChildAt(childIndex);
              children.remove(childIndex);
              child.setParent(null);
         @Override
         public void remove(MutableTreeNode aChild) {
              if (aChild == null) {
                   throw new IllegalArgumentException("argument is null");
              if (!isNodeChild(aChild)) {
                   throw new IllegalArgumentException("argument is not a child");
              remove(getIndex(aChild)); // linear search
         public boolean isNodeChild(TreeNode aNode) {
              boolean retval;
              if (aNode == null) {
                   retval = false;
              } else {
                   if (getChildCount() == 0) {
                        retval = false;
                   } else {
                        retval = (aNode.getParent() == this);
              return retval;
         @Override
         public void setUserObject(Object paramObject) {
              // TODO Auto-generated method stub
         @Override
         public void removeFromParent() {
              MutableTreeNode parent = (MutableTreeNode) getParent();
              if (parent != null) {
                   parent.remove(this);
         @Override
         public void setParent(MutableTreeNode paramMutableTreeNode) {
              parent = (Test) paramMutableTreeNode;
          * Returns the path from the root, to get to this node. The last element in
          * the path is this node.
          * @return an array of TreeNode objects giving the path, where the first
          *         element in the path is the root and the last element is this
          *         node.
         public TreeNode[] getPath() {
              return getPathToRoot(this, 0);
          * Builds the parents of node up to and including the root node, where the
          * original node is the last element in the returned array. The length of
          * the returned array gives the node's depth in the tree.
          * @param aNode
          *            the TreeNode to get the path for
          * @param depth
          *            an int giving the number of steps already taken towards the
          *            root (on recursive calls), used to size the returned array
          * @return an array of TreeNodes giving the path from the root to the
          *         specified node
         protected TreeNode[] getPathToRoot(TreeNode aNode, int depth) {
              TreeNode[] retNodes;
               * Check for null, in case someone passed in a null node, or they passed
               * in an element that isn't rooted at root.
              if (aNode == null) {
                   if (depth == 0)
                        return null;
                   else
                        retNodes = new TreeNode[depth];
              } else {
                   depth++;
                   retNodes = getPathToRoot(aNode.getParent(), depth);
                   retNodes[retNodes.length - depth] = aNode;
              return retNodes;
        }

    You have an O(N**2) algorithm at the end that is rather ill-considered. It seems to me at first glance that it could be combined int the previous loop.

  • How to use analog Triggering and External clock scan

    Hi, there. I want to measure the engine cylinder pressure with an PXI6070-E card and BEI encoder. I have tried using Cont Acq&Graph ExtScanClk D-Trig.vi and Cont Acq&Graph ExtScanClk Soft A-Trig.vi , but they don't work. What I did was to connect a 50HZ pulse to PFI0 (analog triggering, I changed the code from digital triggering to analog triggering), and a 100K pulse to PFI7 (startscan), and an 50 HZ analog signal to ACH0. But the code always says: timeout. If I use internal clock, it works fine. Could you please give me some help? THANKS A LOT!

    Hey Wyuan,
    I tested the Cont Acq&Graph ExtScanClk Soft A-Trig.vi and it worked fine. However, the Cont Acq&Graph ExtScanClk D-Trig.vi has a small error in its logic that will prevent the data from ever being displayed to the graph. In order to run the examples you need to connect a trigger to pin 11 and a scan clock to pin 38. A 10kHz square wave would be fine for the clock signal and just a single pulse would work for the digital trigger.
    One additional think to keep in mind is the grounding. You might need to connect you ground from your signals to a DGND pin. I am including the two programs that I used for the test.
    I hope this helps,
    Joshua
    Attachments:
    Cont_Acq&Graph_ExtScanClk_D-Trig.vi ‏121 KB
    Cont_Acq&Graph_ExtScanClk_Soft_A-Trig.vi ‏153 KB

Maybe you are looking for