Measurement Studio for .NET Languages

cancel
Showing results for 
Search instead for 
Did you mean: 

The unit type is not in pixels

Solved!
Go to solution

While I'm trying to use the following code in my webform:

 

trendScatterGraph.Width = new Unit(80, UnitType.Percentage);

 

 

It raised a System.ArgumentException in NationalInstruments.UI.WebForms.dll.

The exception message said "The unit type is not in pixels.".

Is there any way that I could use the width property with percentage?

 

 

 

0 Kudos
Message 1 of 4
(4,842 Views)
Solution
Accepted by topic author gump996

Hi, gump996

 

The help topic for the Width property explains that this is expected behavior: http://zone.ni.com/reference/en-XX/help/372636F-01/mstudiowebhelp/html/96e4115f/ . For convenience, I have provided the help topic inline as follows:

 

Property Value

A Unit that specifies the width of the control. The default value is 200 pixels.

Exceptions

ExceptionCondition
ArgumentException The Type of the Unit is not Pixel.
ArgumentOutOfRangeException The Value of the Unit is less than 0.
ObjectDisposedException The object is disposed.

Remarks

Images created on a Web server must have an explicit size. Therefore, the only Type that is allowed on Unit is Pixel.

 

You can make this change on the client side of your web application using JavaScript. For example, if you were to make the change on page load, you could do something like the following:

 

window.onload = function () {
   var xyGraph = document.getElementById('exampleContentHolder_xyDataGraph');
   xyGraph.style.width = '80%';
};

 

 

Daniel Dorroh
National Instruments
0 Kudos
Message 2 of 4
(4,597 Views)

Thanks Daniel, this really helped me. But there comes a new problem when I was trying to use the following code to move a cursor on the Web ScatterGraph. If the browser's window size does not change, the code works perfectly. However, I am using the Responsive Web Design. Once the browser's windows size changes, the following code can not work because the PlotAreaBound of the ScatterGraph does not resize to the size as it should be. It still keeps its initital value. Is there any way to solve this problem?

 

	protected void TrendScatterGraph_PlotAreaClick(object sender, ClickEventArgs e)
        {
            double xValue, yValue;
            XAxis xAxis1;
            YAxis yAxis1;

            TrendScatterGraph.Cursors[0].LabelXFormat = new NationalInstruments.UI.FormatString(NationalInstruments.UI.FormatStringMode.DateTime, "yyyy/MM/dd HH:mm:ss");
            TrendScatterGraph.Cursors[0].LabelYFormat = new NationalInstruments.UI.FormatString(NationalInstruments.UI.FormatStringMode.Numeric, "F1");
            TrendScatterGraph.Cursors[0].LabelVisible = true;
            TrendScatterGraph.Cursors[0].Visible = true;

            xAxis1 = TrendScatterGraph.XAxes[0];
            yAxis1 = TrendScatterGraph.YAxes[0];
                        
            InverseMap(TrendScatterGraph.PlotAreaBounds, e.X, e.Y, xAxis1, yAxis1, out xValue, out yValue);
            TrendScatterGraph.Cursors[0].MoveCursor(xValue, yValue);

        }

        private void InverseMap(System.Drawing.Rectangle plotAreaBounds, int x, int y, XAxis xAxis, YAxis yAxis, out double xValue, out double yValue)
        {
            xValue = ((xAxis.Range.Maximum - xAxis.Range.Minimum) *
            ((x - plotAreaBounds.Left) / (double)(plotAreaBounds.Right - plotAreaBounds.Left))) + xAxis.Range.Minimum;

            yValue = ((yAxis.Range.Maximum - yAxis.Range.Minimum) *
            ((plotAreaBounds.Bottom - y) / (double)(plotAreaBounds.Bottom - plotAreaBounds.Top))) + yAxis.Range.Minimum;
        }
0 Kudos
Message 3 of 4
(4,556 Views)

Hi, gump996

 

If you would like to interact with the graph using PlotAreaClick, you probably won't be able to resize the graph this way. The reason is that a click event on the control posts back to the server with the coordinates of the click (this is the behavior of input DOM elements with type image). The Measurement Studio ASP.NET control uses the (x, y) coordinate information to determine whether the click occurred within the client area of the graph, and since the server does not know about the resize that happens on the client side this calculation doesn't work properly.

 

One work around you might be able to implement is to resize the graph in pixels based on the size of its parent container. The components required here are:

  • Client side function that calculates parent container size and posts information to the server if the graph isn't the correct size.
  • A hidden input on your form to store the calculated ideal width of the graph.
  • A server side value changed event attached to the hidden input which sets the graph width to the supplied value.

The components might look as follows:

JavaScript file sent with your ASPX page

 

function InvalidArgumentException(argumentName) {
    this.message = "Parameter '" + argumentName + "' caused an invalid argument exception.";
    this.name = "InvalidArgumentException";
}

function MakeGraphDesiredSizeInPercent(graph_id, form_id, hidden_width_input_id, percentWidth) {
    var graph,
        graphWidth,
        graphParentWidth,
        checkSize,
        percentWidth,
        hiddenWidthInput,
        form;

    // This implementation does not support fractions of percent or values larger than 100%.
    checkSize = parseInt(percentWidth, 10);
    if (checkSize !== percentWidth
        || percentWidth > 100) {
        throw new InvalidArgumentException('percentWidth');
    }

    graph = document.getElementById(graph_id);

    if (typeof (graph) === 'object') {
        // Extract width information from the computed styles for the graph and its parent.
        graphWidth = parseInt(window.getComputedStyle(graph, null)['width'], 10);
        graphParentWidth = parseInt(window.getComputedStyle(graph.parentNode, null)['width'], 10);

        // Resize the graph to have approximately the specified percentage width of its parent.
        if (percentWidth !== Math.floor(100 * graphWidth / graphParentWidth)
            && percentWidth !== Math.ceil(100 * graphWidth / graphParentWidth)) {

            // Set the value property of the hidden input to the desired graph width in pixels.
            hiddenWidthInput = document.getElementById(hidden_width_input_id);
            hiddenWidthInput.value = Math.floor(graphParentWidth * percentWidth / 100);

            // Submit the form containing the hidden input to trigger the value changed event on the server.
            form = document.getElementById(form_id);
            form.submit();

        } else {
            console.log(graph_id + " looks good! It's " + 100 * graphWidth / graphParentWidth + "% of its parent container.");
        }
    } else {
        console.log(graph_id + " doesn't exist!");
    }
}

window.onload = function () {
    MakeGraphDesiredSizeInPercent('MainContent_graph', 'ctl01', 'MainContent_desiredWidth', 80);
};

 

ASPX page

 

<div class="parent-area">
    <ni:WaveformGraph ID="graph" runat="server" InteractionMode="PlotAreaClick" OnPlotAreaClick="graph_PlotAreaClick">
        <Plots>
            <ni:WaveformPlot DataStateManagement="ServerCache" XAxis="XAxes[0]" YAxis="YAxes[0]" FillMode="Lines" LineStyle="None" LineToBaseWidth="5" />
        </Plots>
        <XAxes>
            <ni:XAxis>
            </ni:XAxis>
        </XAxes>
        <YAxes>
            <ni:YAxis>
            </ni:YAxis>
        </YAxes>
    </ni:WaveformGraph>
    <asp:HiddenField ID="desiredWidth" runat="server" OnValueChanged="desiredWidthValueChanged" />
</div>

 

ASPX page code behind

 

protected void desiredWidthValueChanged(object sender, EventArgs e)
{
    var widthField = sender as HiddenField;
    if (widthField != null)
        graph.Width = new Unit(widthField.Value);
}

 

Instead of my previous suggestion, in the window's load event you should just call MakeGraphDesiredSizeInPercent, and set the percentage that way.

 

Hope this helps!

Daniel Dorroh
National Instruments
0 Kudos
Message 4 of 4
(4,477 Views)