示例#1
0
文件: Model.cs 项目: folterj/ProMISE2
        public VisOutSet updateVisOutVar(OutSet outSet, ViewParams viewParams)
        {
            VisOutSet       visOutSet = new VisOutSet();
            List <VisSerie> visSeries;
            List <VisSerie> visRawSeries = null;
            VisSerie        visSerie;
            List <VisPoint> visPoints;

            OutCell[][]   rawOutCells = outSet.rawOutCells;
            OutCell[]     compRawOutCells;
            OutCell       outCell;
            OutComp       outComp;
            VisComp       visComp;
            VisAxes       visAxes = new VisAxes();
            VisAxis       visAxis;
            Axes          axes  = outSet.axes;
            Axis          xaxis = new Axis();
            Axis          yaxis = new Axis();
            PhaseType     phase = new PhaseType();
            int           nphases;
            int           ncomps;
            int           npoints;
            int           nseries;
            int           ncells;
            bool          previewMode  = (viewParams.viewType == ViewType.Setup);
            bool          dispDualTime = (viewParams.phaseDisplay == PhaseDisplayType.UpperLowerTime);
            bool          dispDual     = (viewParams.phaseDisplay == PhaseDisplayType.UpperLower || dispDualTime);
            bool          usePrefixes  = (viewParams.exponentType == ExponentType.Prefixes);
            bool          scaleDrawReverse;
            bool          scaleSet;
            bool          sum;
            float         maxcon = 0;
            float         con    = 0;
            float         rangey = 0;
            float         rangex = 0;
            float         range;
            float         rangey0;
            float         scaleu, scalel;
            float         miny, maxy;
            float         minvx     = 0;
            float         maxvx     = 0;
            float         minxlabel = 0;
            float         maxxlabel = 0;
            float         k;
            float         flow;
            float         pos;
            float         vceff;
            RectangleF    allrect = new RectangleF(0, 0, 1, 1);
            RectangleF    vrect = allrect;
            RectangleF    rawvrect = allrect;
            float         unitsize = 0.025f;
            float         vx, vy;
            int           s = 0;
            int           c;
            string        label         = "";
            MassUnitsType prefMassUnits = inParams.massUnits;
            int           prefMassUnitsi;
            float         multiplier = 1;

            // general vars
            if (dispDual && !previewMode)
            {
                nphases = 2;
            }
            else
            {
                nphases = 1;
            }
            ncomps  = inParams.comps.Count;
            nseries = outSet.outCells.Length;

            if (ncomps == 0)
            {
                return(visOutSet);
            }

            // update outComps units
            foreach (OutComp outComp0 in outSet.comps)
            {
                outComp0.units     = inParams.viewUnits;
                outComp0.volUnits  = inParams.volUnits;
                outComp0.timeUnits = inParams.timeUnits;
                outComp0.massUnits = inParams.massUnits;
            }

            // convert out to units
            outSet.unitsOutCells = new OutCell[outSet.outCells.Length][];
            for (s = 0; s < nseries; s++)
            {
                c = s / nphases;
                if (viewParams.phaseDisplay == PhaseDisplayType.Lower)
                {
                    phase = PhaseType.Lower;
                }
                else
                {
                    phase = PhaseType.Upper;
                }
                if (nphases > 1)
                {
                    phase = (PhaseType)((s % nphases) + 1);
                }
                ncells = outSet.outCells[s].Length;

                outSet.unitsOutCells[s] = new OutCell[ncells];
                for (int i = 0; i < ncells; i++)
                {
                    pos = inParams.convertUnit(outSet.outCells[s][i].pos, inParams.natUnits, viewParams.viewUnits, phase);
                    con = outSet.outCells[s][i].con;
                    outSet.unitsOutCells[s][i] = new OutCell(pos, con);
                }
            }

            // initialise vis series
            visSeries = new List <VisSerie>(nseries);
            if (viewParams.showProbUnits)
            {
                visRawSeries = new List <VisSerie>(nseries);
            }

            if (viewParams.showProbUnits)
            {
                if (dispDual)
                {
                    rawvrect.Height = unitsize * 2;
                }
                else
                {
                    rawvrect.Height = unitsize;
                }

                vrect.Y      = rawvrect.Bottom;
                vrect.Height = 1 - vrect.Y;
            }

            // Axes
            axes = outSet.axes;
            // Set maxcon / rangey
            if (viewParams.yScale == YScaleType.Absolute)
            {
                // * not exactly correct; should use maxcon from first (time) step
                maxcon = 0;
                for (int i = 0; i < outSet.comps.Count; i++)
                {
                    if (outSet.comps[i].m > maxcon)
                    {
                        maxcon = outSet.comps[i].m;
                    }
                }
                rangey = maxcon;
            }
            else if (viewParams.yScale == YScaleType.Normalised)
            {
                rangey = 0;
            }
            else             // Auto or Log scale
            {
                maxcon = 0;
                for (int i = 0; i < axes.maxcon.Count; i++)
                {
                    if (axes.maxcon[i] > maxcon)
                    {
                        maxcon = axes.maxcon[i];
                    }
                }
                if (viewParams.yScale == YScaleType.Automatic)
                {
                    rangey = maxcon;
                }
                else if (axes.logScale)
                {
                    maxcon = (float)Math.Ceiling(Math.Log(maxcon));                     // Nearest E power
                    rangey = 5;
                    // Scale: E^maxcon ... E^(maxcon-rangey)
                }
            }

            // Column lines
            if (viewParams.showProbUnits)
            {
                visAxis           = new VisAxis();
                visAxis.drawColor = Colors.LightGray;
                visAxis.point1    = new VisPoint(vrect.Left, rawvrect.Top);
                visAxis.point2    = new VisPoint(vrect.Left, rawvrect.Bottom);
                visAxes.visAxes.Add(visAxis);

                visAxis           = new VisAxis();
                visAxis.drawColor = Colors.LightGray;
                visAxis.point1    = new VisPoint(vrect.Right, rawvrect.Top);
                visAxis.point2    = new VisPoint(vrect.Right, rawvrect.Bottom);
                visAxes.visAxes.Add(visAxis);

                visAxis        = new VisAxis();
                visAxis.point1 = new VisPoint(vrect.Left, rawvrect.Top);
                visAxis.point2 = new VisPoint(vrect.Right, rawvrect.Top);
                visAxes.visAxes.Add(visAxis);

                visAxis        = new VisAxis();
                visAxis.point1 = new VisPoint(vrect.Left, rawvrect.Bottom);
                visAxis.point2 = new VisPoint(vrect.Right, rawvrect.Bottom);
                visAxes.visAxes.Add(visAxis);
            }
            if (axes.showCol)
            {
                visAxis           = new VisAxis();
                visAxis.drawColor = Colors.LightGray;
                vx             = axes.colstart / axes.rangex * allrect.Width + allrect.Left;
                visAxis.point1 = new VisPoint(vx, allrect.Top);
                visAxis.point2 = new VisPoint(vx, allrect.Bottom);
                visAxes.visAxes.Add(visAxis);

                visAxis           = new VisAxis();
                visAxis.drawColor = Colors.LightGray;
                vx             = axes.colend / axes.rangex * allrect.Width + allrect.Left;
                visAxis.point1 = new VisPoint(vx, allrect.Top);
                visAxis.point2 = new VisPoint(vx, allrect.Bottom);
                visAxes.visAxes.Add(visAxis);
            }
            if (axes.showDeadvolstart)
            {
                visAxis        = new VisAxis();
                vx             = axes.deadvolstart / axes.rangex * vrect.Width + vrect.Left;
                visAxis.point1 = new VisPoint(vx, vrect.Top);
                visAxis.point2 = new VisPoint(vx, vrect.Bottom);
                visAxes.visAxes.Add(visAxis);
            }
            if (axes.showDeadvolend)
            {
                visAxis        = new VisAxis();
                vx             = axes.deadvolend / axes.rangex * vrect.Width + vrect.Left;
                visAxis.point1 = new VisPoint(vx, vrect.Top);
                visAxis.point2 = new VisPoint(vx, vrect.Bottom);
                visAxes.visAxes.Add(visAxis);
            }
            if (axes.showDeadvolinsert)
            {
                visAxis        = new VisAxis();
                vx             = axes.deadvolinjectstart / axes.rangex * vrect.Width + vrect.Left;
                visAxis.point1 = new VisPoint(vx, vrect.Top);
                visAxis.point2 = new VisPoint(vx, vrect.Bottom);
                visAxes.visAxes.Add(visAxis);

                visAxis        = new VisAxis();
                vx             = axes.deadvolinjectend / axes.rangex * vrect.Width + vrect.Left;
                visAxis.point1 = new VisPoint(vx, vrect.Top);
                visAxis.point2 = new VisPoint(vx, vrect.Bottom);
                visAxes.visAxes.Add(visAxis);
            }

            // X Axis
            if (viewParams.syncScales && viewParams.viewUnits != QuantityType.ReS)
            {
                minxlabel = inParams.convertUnit(axes.scaleminulabel, inParams.natUnits, viewParams.viewUnits, PhaseType.Upper);
                maxxlabel = inParams.convertUnit(axes.scalemaxulabel, inParams.natUnits, viewParams.viewUnits, PhaseType.Upper);
                scaleu    = Math.Abs(maxxlabel - minxlabel);

                minxlabel = inParams.convertUnit(axes.scaleminllabel, inParams.natUnits, viewParams.viewUnits, PhaseType.Lower);
                maxxlabel = inParams.convertUnit(axes.scalemaxllabel, inParams.natUnits, viewParams.viewUnits, PhaseType.Lower);
                scalel    = Math.Abs(maxxlabel - minxlabel);

                if (scaleu != 0 && scalel != 0)
                {
                    axes.sync(scaleu, scalel);
                }
            }
            label = "";
            for (int phasei = 0; phasei < 2; phasei++)
            {
                if (dispDual)
                {
                    vy = vrect.Top + 0.5f * vrect.Height;
                    scaleDrawReverse = ((PhaseType)(phasei + 1) == PhaseType.Lower);
                }
                else
                {
                    vy = vrect.Bottom;
                    scaleDrawReverse = false;
                }
                scaleSet = false;
                if ((PhaseType)(phasei + 1) == PhaseType.Upper && (inParams.runMode != RunModeType.LowerPhase || (inParams.eeMode != EEModeType.None && inParams.isPosEEdir())) && viewParams.phaseDisplay != PhaseDisplayType.Lower)
                {
                    // show Up axis
                    minvx     = vrect.Left + axes.scaleminu / axes.rangexu * vrect.Width;
                    maxvx     = vrect.Left + axes.scalemaxu / axes.rangexu * vrect.Width;
                    minxlabel = inParams.convertUnit(axes.scaleminulabel, inParams.natUnits, viewParams.viewUnits, PhaseType.Upper);
                    maxxlabel = inParams.convertUnit(axes.scalemaxulabel, inParams.natUnits, viewParams.viewUnits, PhaseType.Upper);
                    rangex    = Math.Abs(axes.scalemaxu - axes.scaleminu);
                    scaleSet  = true;
                }
                else if ((PhaseType)(phasei + 1) == PhaseType.Lower && (inParams.runMode != RunModeType.UpperPhase || (inParams.eeMode != EEModeType.None && !inParams.isPosEEdir())) && viewParams.phaseDisplay != PhaseDisplayType.Upper)
                {
                    // show Lp axis
                    minvx     = vrect.Left + axes.scaleminl / axes.rangexl * vrect.Width;
                    maxvx     = vrect.Left + axes.scalemaxl / axes.rangexl * vrect.Width;
                    minxlabel = inParams.convertUnit(axes.scaleminllabel, inParams.natUnits, viewParams.viewUnits, PhaseType.Lower);
                    maxxlabel = inParams.convertUnit(axes.scalemaxllabel, inParams.natUnits, viewParams.viewUnits, PhaseType.Lower);
                    rangex    = Math.Abs(axes.scalemaxl - axes.scaleminl);
                    scaleSet  = true;
                }
                if (scaleSet)
                {
                    range = maxxlabel - minxlabel;
                    // if syncScales: use same divs/stepsize as other axis
                    if (phasei == 0 || !viewParams.syncScales || viewParams.phaseDisplay == PhaseDisplayType.Upper || viewParams.phaseDisplay == PhaseDisplayType.Lower)
                    {
                        xaxis.calcScale(range);
                    }
                    if (label == "")
                    {
                        // only do first label
                        label = inParams.getXaxisLegend();
                    }
                    else
                    {
                        label = "";
                    }
                    visAxes.addAxis(label,
                                    minvx, vy, maxvx, vy,
                                    false, true, true, !previewMode, !dispDual, scaleDrawReverse, false,
                                    false, 1,
                                    Colors.Black, 1,
                                    minxlabel, maxxlabel, xaxis.nMajorDivs, xaxis.majorStepSize, xaxis.nMinorDivs, xaxis.minorStepSize);
                    if (viewParams.viewUnits == QuantityType.ReS)
                    {
                        // ReS (K-values) scale: overwrite labels
                        visAxis = visAxes.visAxes[visAxes.visAxes.Count - 1];
                        visAxis.clearLabels();
                        for (int i = 0; i <= 8; i++)
                        {
                            if (i > 4)
                            {
                                k = (float)4 / (8 - i);
                            }
                            else
                            {
                                k = (float)i / 4;
                            }
                            flow = Equations.calcFlow(inParams.kDefinition, inParams.fu, -inParams.fl, k);
                            if (flow < 0 && inParams.runMode == RunModeType.DualMode)
                            {
                                vceff = inParams.injectPos * inParams.vc;
                            }
                            else
                            {
                                vceff = (1 - inParams.injectPos) * inParams.vc;
                            }
                            if (flow != 0)
                            {
                                if (float.IsInfinity(k))
                                {
                                    pos = Equations.calcInfPos(inParams.kDefinition, vceff, inParams.lf, inParams.uf, inParams.fu, inParams.fl);
                                }
                                else
                                {
                                    pos = Equations.calcPos(inParams.kDefinition, vceff, inParams.lf, inParams.uf, flow, k);
                                }
                                if ((PhaseType)(phasei + 1) == PhaseType.Lower)
                                {
                                    pos = -pos;
                                }
                                pos = inParams.convertUnit(pos, QuantityType.Time, inParams.natUnits, (PhaseType)(phasei + 1));
                                if (pos > 0 && !float.IsInfinity(pos))
                                {
                                    vx = minvx + pos / rangex * (maxvx - minvx);
                                    visAxis.addLabel(Util.toString(k, 2), vx, vy);
                                }
                            }
                        }
                    }
                }
            }
            // Y Axis
            range = rangey;
            if (!axes.logScale)
            {
                // normal scale
                yaxis.calcScale(range);
                rangey = yaxis.scale;
                miny   = 0;
                maxy   = rangey;
            }
            else
            {
                // log scale
                yaxis.majorStepSize = 1;
                yaxis.nMajorDivs    = (int)rangey;
                yaxis.minorStepSize = 0;
                yaxis.nMinorDivs    = 0;
                miny = maxcon - rangey;
                maxy = maxcon;
            }
            if (usePrefixes)
            {
                prefMassUnitsi = (int)inParams.massUnits;
                rangey0        = rangey;
                while (rangey0 >= 1000 && prefMassUnitsi < Enum.GetValues(typeof(MassUnitsType)).Length)
                {
                    rangey0    /= 1000;
                    multiplier /= 1000;
                    prefMassUnitsi++;
                }
                while (rangey0 < 1 && prefMassUnitsi > 0)
                {
                    rangey0    *= 1000;
                    multiplier *= 1000;
                    prefMassUnitsi--;
                }
                prefMassUnits = (MassUnitsType)prefMassUnitsi;
                label         = inParams.getYaxisLegend(prefMassUnits);
            }
            else
            {
                label = inParams.getYaxisLegend(null);
            }
            if (dispDual)
            {
                vy = vrect.Top + 0.5f * vrect.Height;
                // positive y scale
                visAxes.addAxis("Upper Phase " + label,
                                vrect.Left, vy, vrect.Left, vrect.Top,
                                !previewMode, true, true, !previewMode, !axes.logScale, false, axes.logScale,
                                !usePrefixes, multiplier,
                                Colors.Black, 1,
                                miny, maxy, yaxis.nMajorDivs, yaxis.majorStepSize, yaxis.nMinorDivs, yaxis.minorStepSize);
                // negative y scale
                if (!axes.logScale)
                {
                    yaxis.inverse();
                    miny = -miny;
                    maxy = -maxy;
                }
                visAxes.addAxis("Lower Phase " + label,
                                vrect.Left, vy, vrect.Left, vrect.Bottom,
                                !previewMode, true, true, !previewMode, false, false, axes.logScale,
                                !usePrefixes, multiplier,
                                Colors.Black, 1,
                                miny, maxy, yaxis.nMajorDivs, yaxis.majorStepSize, yaxis.nMinorDivs, yaxis.minorStepSize);
            }
            else
            {
                visAxes.addAxis(label,
                                vrect.Left, vrect.Bottom, vrect.Left, vrect.Top,
                                !previewMode, true, true, !previewMode, true, false, axes.logScale,
                                !usePrefixes, multiplier,
                                Colors.Black, 1,
                                miny, maxy, yaxis.nMajorDivs, yaxis.majorStepSize, yaxis.nMinorDivs, yaxis.minorStepSize);
            }

            // Raw Series (units)
            if (viewParams.showProbUnits)
            {
                for (s = 0; s < rawOutCells.Length; s++)
                {
                    compRawOutCells = rawOutCells[s];
                    npoints         = compRawOutCells.Length;
                    c = s / nphases;

                    visSerie            = new VisSerie();
                    visSerie.type       = VisSerieType.Units;
                    visSerie.visRect    = new Rect(rawvrect.X, rawvrect.Y, rawvrect.Width, rawvrect.Height);
                    visSerie.compi      = c;
                    visSerie.drawSize   = unitsize;
                    visSerie.drawWeight = outSet.comps[c].m;

                    visPoints = new List <VisPoint>();

                    if (viewParams.phaseDisplay == PhaseDisplayType.Lower)
                    {
                        phase = PhaseType.Lower;
                    }
                    else
                    {
                        phase = PhaseType.Upper;
                    }
                    if (nphases > 1)
                    {
                        phase = (PhaseType)((s % nphases) + 1);
                    }
                    if (phase == PhaseType.Upper)
                    {
                        rangex = axes.rangexu;
                    }
                    else
                    {
                        rangex = axes.rangexl;
                    }
                    if (c < ncomps)
                    {
                        visSerie.drawColor = Util.colorRange(c, ncomps);
                    }
                    else
                    {
                        visSerie.drawColor = Colors.Gray;
                    }

                    for (int i = 0; i < npoints; i++)
                    {
                        outCell = compRawOutCells[i];
                        vx      = rawvrect.Left + outCell.pos / rangex * rawvrect.Width;
                        if (s % nphases == 0)
                        {
                            vy = rawvrect.Top;
                        }
                        else
                        {
                            vy = rawvrect.Top + 0.5f * rawvrect.Height;
                        }

                        visPoints.Add(new VisPoint(vx, vy));
                    }
                    visSerie.visPoints = visPoints.ToArray();
                    visRawSeries.Add(visSerie);
                }
                visOutSet.visRawSeries = visRawSeries.ToArray();

                if (dispDual)
                {
                    visAxis        = new VisAxis();
                    visAxis.point1 = new VisPoint(rawvrect.Left, 0.5f * rawvrect.Height);
                    visAxis.point2 = new VisPoint(rawvrect.Right, 0.5f * rawvrect.Height);
                    visAxes.visAxes.Add(visAxis);
                }
            }
            visOutSet.visAxes = visAxes;

            // Series
            if (viewParams.yScale == YScaleType.Automatic)
            {
                maxcon = rangey;
            }
            for (s = 0; s < nseries; s++)
            {
                npoints = outSet.outCells[s].Length;
                c       = s / nphases;

                visSerie         = new VisSerie();
                visSerie.type    = VisSerieType.Graph;
                visSerie.visRect = new Rect(vrect.X, vrect.Y, vrect.Width, vrect.Height);
                visSerie.compi   = c;

                visPoints = new List <VisPoint>();

                if (nphases > 1)
                {
                    phase = (PhaseType)((s % nphases) + 1);
                }
                else if (viewParams.phaseDisplay == PhaseDisplayType.Lower)
                {
                    phase = PhaseType.Lower;
                }
                else
                {
                    phase = PhaseType.Upper;
                }
                if (phase == PhaseType.Upper)
                {
                    rangex = axes.rangexu;
                }
                else
                {
                    rangex = axes.rangexl;
                }
                if (c < ncomps)
                {
                    visSerie.drawWeight = outSet.comps[c].m;
                    visSerie.multiColor = false;
                    visSerie.drawColor  = Util.colorRange(c, ncomps);
                    sum = false;
                }
                else
                {
                    visSerie.multiColor = true;
                    visSerie.drawColor  = Colors.Gray;
                    sum = true;
                }
                if (viewParams.peaksDisplay != PeaksDisplayType.Sum || sum)
                {
                    // Sum graph: multi color
                    if (viewParams.yScale == YScaleType.Normalised)
                    {
                        maxcon = axes.maxcon[c];
                    }
                    for (int i = 0; i < npoints; i++)
                    {
                        outCell = outSet.outCells[s][i];
                        vx      = vrect.Left + outCell.pos / rangex * vrect.Width;
                        if (viewParams.yScale == YScaleType.Logarithmic)
                        {
                            if (outCell.con != 0 && maxcon != 0)
                            {
                                con = (float)(1 + (Math.Log(Math.Abs(outCell.con)) - maxcon) / rangey);
                                if (con < 0)
                                {
                                    con = 0;
                                }
                                if (outCell.con < 0)
                                {
                                    con = -con;
                                }
                            }
                            else
                            {
                                con = 0;
                            }
                        }
                        else
                        {
                            if (maxcon != 0)
                            {
                                con = outCell.con / maxcon;
                            }
                        }
                        if (dispDual)
                        {
                            vy = vrect.Top + (1 - con) / 2 * vrect.Height;
                        }
                        else
                        {
                            vy = vrect.Bottom - con * vrect.Height;
                        }
                        if (c < ncomps)
                        {
                            visPoints.Add(new VisPoint(vx, vy));
                        }
                        else
                        {
                            visPoints.Add(new VisPoint(vx, vy, outCell.color));
                        }
                    }
                    visSerie.visPoints = visPoints.ToArray();
                    visSeries.Add(visSerie);
                }
            }
            visOutSet.visSeries = visSeries.ToArray();

            // Peaks
            for (int i = 0; i < outSet.comps.Count; i++)
            {
                outComp = outSet.comps[i];
                if (outComp.phase == PhaseType.Upper)
                {
                    vx = vrect.Left + outComp.drawPosition / axes.rangexu * vrect.Width;
                }
                else if (outComp.phase == PhaseType.Lower)
                {
                    vx = vrect.Left + outComp.drawPosition / axes.rangexl * vrect.Width;
                }
                else
                {
                    vx = vrect.Left + outComp.drawPosition / axes.rangex * vrect.Width;
                }
                if (dispDual && outComp.phase == PhaseType.Lower)
                {
                    vy = vrect.Bottom;
                }
                else
                {
                    vy = vrect.Top;
                }
                visComp = new VisComp(new VisPoint(vx, vy, Util.colorRange(i, ncomps, 0.5f)), outComp.label, Util.colorRange(i, ncomps, 2));
                visOutSet.comps.Add(visComp);
            }

            visOutSet.posUnits      = inParams.getXaxisUnits();
            visOutSet.useMultiplier = usePrefixes;
            if (usePrefixes)
            {
                visOutSet.conMultiplier = multiplier;
                visOutSet.conUnits      = inParams.getYaxisUnits(prefMassUnits);
            }
            else
            {
                visOutSet.conMultiplier = 1;
                visOutSet.conUnits      = inParams.getYaxisUnits(null);
            }
            visOutSet.timeUnits = inParams.timeUnits.ToString();

            return(visOutSet);
        }
示例#2
0
        public void addAxis(string title,
                            float vx1, float vy1, float vx2, float vy2,
                            bool drawLines, bool drawLabels, bool drawMajorTicks, bool drawMinorTicks, bool drawZero, bool drawReverse, bool logScale,
                            bool expScale, float multiplier,
                            Color drawcolor, float drawsize,
                            float min, float max, int nlabeldiv, float labelstepsize, int ntickdiv, float tickstepsize)
        {
            VisAxis axis = new VisAxis();
            float   frac, f;
            float   vx, vy;
            string  l;
            int     exp  = 0;
            int     ndec = 0;

            axis.title          = title;
            axis.point1.vx      = vx1;
            axis.point1.vy      = vy1;
            axis.point2.vx      = vx2;
            axis.point2.vy      = vy2;
            axis.drawLines      = drawLines;
            axis.drawLabels     = drawLabels;
            axis.drawMajorTicks = drawMajorTicks;
            axis.drawMinorTicks = drawMinorTicks;
            axis.drawColor      = drawcolor;
            axis.drawSize       = drawsize;
            axis.negative       = (max < min);
            axis.drawReverse    = drawReverse;

            if (expScale)
            {
                exp  = Util.getExponent(string.Format("{0:E0}", max));
                ndec = Util.getNDecimals(Util.toString(labelstepsize / (float)Math.Pow(10, exp), 3));
            }

            for (int i = 0; i <= ntickdiv; i++)
            {
                if (max - min != 0)
                {
                    frac = i * tickstepsize / (max - min);
                    if (frac <= 1)
                    {
                        vx = vx1 + frac * (vx2 - vx1);
                        vy = vy1 + frac * (vy2 - vy1);
                        axis.scaletickpos.Add(new VisPoint(vx, vy));
                    }
                }
            }
            for (int i = 0; i <= nlabeldiv; i++)
            {
                if (max - min != 0)
                {
                    frac = i * labelstepsize / (max - min);
                    if (frac <= 1)
                    {
                        vx = vx1 + frac * (vx2 - vx1);
                        vy = vy1 + frac * (vy2 - vy1);
                        axis.scalelabelpos.Add(new VisPoint(vx, vy));
                        f = min + i * labelstepsize;
                        l = "";
                        if (logScale)
                        {
                            if (i != 0 || drawZero)
                            {
                                if (f < 0)
                                {
                                    l = string.Format("E{0:F0}", f);
                                }
                                else
                                {
                                    l = string.Format("E+{0:F0}", f);
                                }
                            }
                        }
                        else
                        {
                            if (f != 0 || drawZero)
                            {
                                if (expScale && f != 0)
                                {
                                    l = string.Format("{0:F" + ndec + "}", Math.Abs(f) / (float)Math.Pow(10, exp));
                                    if (exp != 0)
                                    {
                                        l += string.Format("E{0}", exp);
                                    }
                                }
                                else
                                {
                                    l = Util.toString(Math.Abs(f) * multiplier, 3);
                                }
                            }
                        }
                        axis.scalelabeltext.Add(l);
                    }
                }
            }
            visAxes.Add(axis);
        }