/// <summary>
        /// Creates a dummy chart to show an error message.
        /// </summary>
        /// <param name="viewer">The WPFChartViewer to display the error message.</param>
        /// <param name="msg">The error message</param>
        protected void errMsg(WPFChartViewer viewer, string msg)
        {
            MultiChart m = new MultiChart(400, 200);

            m.addTitle2(Chart.Center, msg, "Arial", 10).setMaxWidth(m.getWidth());
            viewer.Chart = m;
        }
        /// <summary>
        /// Creates a dummy chart to show an error message.
        /// </summary>
        /// <param name="msg">The error message.
        /// <returns>The BaseChart object containing the error message.</returns>
        protected BaseChart errMsg(string msg)
        {
            MultiChart m = new MultiChart(400, 200);

            m.addTitle2(Chart.Center, msg, "Arial", 10).setMaxWidth(m.getWidth());
            return(m);
        }
Exemplo n.º 3
0
        /// <summary>
        /// Creates a dummy chart to show an error message.
        /// </summary>
        /// <param name="msg">The error message.
        /// <returns>The BaseChart object containing the error message.</returns>
        protected void errMsg(WinChartViewer WebChartViewer1, string msg)
        {
            MultiChart m = new MultiChart(400, 200);

            m.addTitle2(Chart.Center, msg, "Arial", 10).setMaxWidth(m.getWidth());

            WebChartViewer1.Image = m.makeImage();
        }
Exemplo n.º 4
0
    private static void OnSeriesSourceChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        IEnumerable newValue = (IEnumerable)e.NewValue;
        MultiChart  source   = (MultiChart)d;

        source.Series.Clear();
        foreach (LineSeries item in newValue)
        {
            source.Series.Add(item);
        }
    }
        public void MultiChartShouldConstructProperly()
        {
            MultiChartDefinition chartDefinition = new MultiChartDefinition {
                Name = "MultiChart"
            };

            MultiChart chart = new MultiChart(chartDefinition);

            chart.Should().BeOfType <MultiChart>();
            chart.ChartDefinition.Should().BeOfType <MultiChartDefinition>();
            chart.Name.Should().Be("MultiChart");
        }
        public void MultiChartShouldSerializeProperly()
        {
            MultiChartDefinition chartDefinition = new MultiChartDefinition {
                Name = "MultiChart"
            };

            MultiChart chart = new MultiChart(chartDefinition);

            IChartSerializer serializer = Mock.Create <IChartSerializer>(Behavior.Strict);

            serializer.Arrange(x => x.Serialize(Arg.IsAny <MultiChartDefinition>())).Returns("").OccursOnce();

            chart.Serialize(serializer);

            serializer.AssertAll();
        }
        public void MultiChartShouldCopyProperly()
        {
            MultiChartDefinition chartDefinition = new MultiChartDefinition {
                Name = "MultiChart"
            };

            MultiChart chart = new MultiChart(chartDefinition);

            VisualObject copy = chart.Copy("Copied MultiChart");

            copy.Should().BeOfType <MultiChart>();
            MultiChart copiedChart = ( MultiChart )copy;

            copiedChart.ChartDefinition.Should().BeOfType <MultiChartDefinition>();
            copiedChart.Name.Should().Be("Copied MultiChart");
        }
        private static DeclarationList CreateCurrentDeclarations()
        {
            DeclarationList declarationList = new DeclarationList();
            int             num             = 1;

            declarationList[num++] = IDOwner.GetDeclaration();
            declarationList[num++] = ReportItem.GetDeclaration();
            num++;
            declarationList[num++] = Report.GetDeclaration();
            declarationList[num++] = PageSection.GetDeclaration();
            declarationList[num++] = Line.GetDeclaration();
            declarationList[num++] = Rectangle.GetDeclaration();
            declarationList[num++] = Image.GetDeclaration();
            num++;
            declarationList[num++] = CheckBox.GetDeclaration();
            declarationList[num++] = TextBox.GetDeclaration();
            declarationList[num++] = SubReport.GetDeclaration();
            declarationList[num++] = ActiveXControl.GetDeclaration();
            declarationList[num++] = DataRegion.GetDeclaration();
            num++;
            declarationList[num++] = ReportHierarchyNode.GetDeclaration();
            declarationList[num++] = Grouping.GetDeclaration();
            declarationList[num++] = Sorting.GetDeclaration();
            declarationList[num++] = List.GetDeclaration();
            declarationList[num++] = Pivot.GetDeclaration();
            declarationList[num++] = Matrix.GetDeclaration();
            declarationList[num++] = PivotHeading.GetDeclaration();
            declarationList[num++] = MatrixHeading.GetDeclaration();
            declarationList[num++] = MatrixColumn.GetDeclaration();
            num++;
            declarationList[num++] = MatrixRow.GetDeclaration();
            num++;
            declarationList[num++] = Subtotal.GetDeclaration();
            declarationList[num++] = Table.GetDeclaration();
            declarationList[num++] = TableColumn.GetDeclaration();
            num++;
            declarationList[num++] = TableGroup.GetDeclaration();
            declarationList[num++] = TableRow.GetDeclaration();
            num++;
            declarationList[num++] = OWCChart.GetDeclaration();
            declarationList[num++] = ChartColumn.GetDeclaration();
            num++;
            declarationList[num++] = ReportItemCollection.GetDeclaration();
            declarationList[num++] = ReportItemIndexer.GetDeclaration();
            num++;
            declarationList[num++] = Style.GetDeclaration();
            num++;
            declarationList[num++] = AttributeInfo.GetDeclaration();
            declarationList[num++] = Visibility.GetDeclaration();
            declarationList[num++] = ExpressionInfo.GetDeclaration();
            num++;
            declarationList[num++] = DataAggregateInfo.GetDeclaration();
            num++;
            declarationList[num++] = RunningValueInfo.GetDeclaration();
            num++;
            num++;
            declarationList[num++] = Filter.GetDeclaration();
            num++;
            declarationList[num++] = DataSource.GetDeclaration();
            num++;
            declarationList[num++] = DataSet.GetDeclaration();
            num++;
            declarationList[num++] = ReportQuery.GetDeclaration();
            declarationList[num++] = Field.GetDeclaration();
            num++;
            declarationList[num++] = ParameterValue.GetDeclaration();
            num++;
            num++;
            num++;
            num++;
            declarationList[num++] = ReportSnapshot.GetDeclaration();
            declarationList[num++] = SenderInformation.GetDeclaration();
            declarationList[num++] = InstanceInfo.GetDeclaration();
            declarationList[num++] = ReceiverInformation.GetDeclaration();
            declarationList[num++] = InstanceInfo.GetDeclaration();
            declarationList[num++] = DocumentMapNode.GetDeclaration();
            declarationList[num++] = InfoBase.GetDeclaration();
            declarationList[num++] = OffsetInfo.GetDeclaration();
            declarationList[num++] = InstanceInfo.GetDeclaration();
            declarationList[num++] = ReportItemInstanceInfo.GetDeclaration();
            declarationList[num++] = ReportInstanceInfo.GetDeclaration();
            declarationList[num++] = ReportItemColInstanceInfo.GetDeclaration();
            declarationList[num++] = LineInstanceInfo.GetDeclaration();
            declarationList[num++] = TextBoxInstanceInfo.GetDeclaration();
            declarationList[num++] = RectangleInstanceInfo.GetDeclaration();
            declarationList[num++] = CheckBoxInstanceInfo.GetDeclaration();
            declarationList[num++] = ImageInstanceInfo.GetDeclaration();
            declarationList[num++] = SubReportInstanceInfo.GetDeclaration();
            declarationList[num++] = ActiveXControlInstanceInfo.GetDeclaration();
            declarationList[num++] = ListInstanceInfo.GetDeclaration();
            declarationList[num++] = ListContentInstanceInfo.GetDeclaration();
            declarationList[num++] = MatrixInstanceInfo.GetDeclaration();
            declarationList[num++] = MatrixHeadingInstanceInfo.GetDeclaration();
            declarationList[num++] = MatrixCellInstanceInfo.GetDeclaration();
            declarationList[num++] = TableInstanceInfo.GetDeclaration();
            declarationList[num++] = TableGroupInstanceInfo.GetDeclaration();
            declarationList[num++] = TableRowInstanceInfo.GetDeclaration();
            declarationList[num++] = OWCChartInstanceInfo.GetDeclaration();
            declarationList[num++] = ChartInstanceInfo.GetDeclaration();
            declarationList[num++] = NonComputedUniqueNames.GetDeclaration();
            declarationList[num++] = InstanceInfoOwner.GetDeclaration();
            declarationList[num++] = ReportItemInstance.GetDeclaration();
            num++;
            declarationList[num++] = ReportInstance.GetDeclaration();
            declarationList[num++] = ReportItemColInstance.GetDeclaration();
            declarationList[num++] = LineInstance.GetDeclaration();
            declarationList[num++] = TextBoxInstance.GetDeclaration();
            declarationList[num++] = RectangleInstance.GetDeclaration();
            declarationList[num++] = CheckBoxInstance.GetDeclaration();
            declarationList[num++] = ImageInstance.GetDeclaration();
            declarationList[num++] = SubReportInstance.GetDeclaration();
            declarationList[num++] = ActiveXControlInstance.GetDeclaration();
            declarationList[num++] = ListInstance.GetDeclaration();
            declarationList[num++] = ListContentInstance.GetDeclaration();
            num++;
            declarationList[num++] = MatrixInstance.GetDeclaration();
            declarationList[num++] = MatrixHeadingInstance.GetDeclaration();
            num++;
            declarationList[num++] = MatrixCellInstance.GetDeclaration();
            num++;
            num++;
            declarationList[num++] = TableInstance.GetDeclaration();
            declarationList[num++] = TableRowInstance.GetDeclaration();
            declarationList[num++] = TableColumnInstance.GetDeclaration();
            declarationList[num++] = TableGroupInstance.GetDeclaration();
            num++;
            declarationList[num++] = OWCChartInstance.GetDeclaration();
            declarationList[num++] = ParameterInfo.GetDeclaration();
            num++;
            num++;
            num++;
            declarationList[num++] = InstanceInfo.GetDeclaration();
            num++;
            declarationList[num++] = RecordSetInfo.GetDeclaration();
            declarationList[num++] = RecordRow.GetDeclaration();
            declarationList[num++] = RecordField.GetDeclaration();
            declarationList[num++] = ValidValue.GetDeclaration();
            num++;
            declarationList[num++] = ParameterDataSource.GetDeclaration();
            declarationList[num++] = ParameterDef.GetDeclaration();
            num++;
            declarationList[num++] = ParameterBase.GetDeclaration();
            num++;
            declarationList[num++] = ProcessingMessage.GetDeclaration();
            declarationList[num++] = MatrixSubtotalHeadingInstanceInfo.GetDeclaration();
            declarationList[num++] = MatrixSubtotalCellInstance.GetDeclaration();
            declarationList[num++] = CodeClass.GetDeclaration();
            num++;
            declarationList[num++] = TableDetail.GetDeclaration();
            declarationList[num++] = TableDetailInstance.GetDeclaration();
            num++;
            declarationList[num++] = TableDetailInstanceInfo.GetDeclaration();
            num++;
            declarationList[num++] = Action.GetDeclaration();
            declarationList[num++] = ActionInstance.GetDeclaration();
            declarationList[num++] = Chart.GetDeclaration();
            declarationList[num++] = ChartHeading.GetDeclaration();
            declarationList[num++] = ChartDataPoint.GetDeclaration();
            num++;
            declarationList[num++] = MultiChart.GetDeclaration();
            declarationList[num++] = MultiChartInstance.GetDeclaration();
            num++;
            declarationList[num++] = Axis.GetDeclaration();
            declarationList[num++] = AxisInstance.GetDeclaration();
            declarationList[num++] = ChartTitle.GetDeclaration();
            declarationList[num++] = ChartTitleInstance.GetDeclaration();
            declarationList[num++] = ThreeDProperties.GetDeclaration();
            declarationList[num++] = PlotArea.GetDeclaration();
            declarationList[num++] = Legend.GetDeclaration();
            declarationList[num++] = GridLines.GetDeclaration();
            declarationList[num++] = ChartDataLabel.GetDeclaration();
            declarationList[num++] = ChartInstance.GetDeclaration();
            declarationList[num++] = ChartHeadingInstance.GetDeclaration();
            declarationList[num++] = ChartHeadingInstanceInfo.GetDeclaration();
            num++;
            declarationList[num++] = ChartDataPointInstance.GetDeclaration();
            declarationList[num++] = ChartDataPointInstanceInfo.GetDeclaration();
            num++;
            num++;
            declarationList[num++] = RenderingPagesRanges.GetDeclaration();
            num++;
            declarationList[num++] = IntermediateFormatVersion.GetDeclaration();
            declarationList[num++] = ImageInfo.GetDeclaration();
            declarationList[num++] = ActionItem.GetDeclaration();
            declarationList[num++] = ActionItemInstance.GetDeclaration();
            num++;
            num++;
            declarationList[num++] = DataValue.GetDeclaration();
            declarationList[num++] = DataValueInstance.GetDeclaration();
            num++;
            num++;
            declarationList[num++] = Tablix.GetDeclaration();
            declarationList[num++] = TablixHeading.GetDeclaration();
            declarationList[num++] = CustomReportItem.GetDeclaration();
            declarationList[num++] = CustomReportItemInstance.GetDeclaration();
            declarationList[num++] = CustomReportItemHeading.GetDeclaration();
            declarationList[num++] = CustomReportItemHeadingInstance.GetDeclaration();
            num++;
            num++;
            num++;
            num++;
            declarationList[num++] = CustomReportItemCellInstance.GetDeclaration();
            num++;
            num++;
            declarationList[num++] = DataValueCRIList.GetDeclaration();
            declarationList[num++] = BookmarkInformation.GetDeclaration();
            declarationList[num++] = InstanceInfo.GetDeclaration();
            declarationList[num++] = DrillthroughInformation.GetDeclaration();
            declarationList[num++] = InstanceInfo.GetDeclaration();
            num++;
            declarationList[num++] = CustomReportItemInstanceInfo.GetDeclaration();
            declarationList[num++] = ImageMapAreaInstanceList.GetDeclaration();
            declarationList[num++] = ImageMapAreaInstance.GetDeclaration();
            num++;
            declarationList[num++] = InstanceInfo.GetDeclaration();
            declarationList[num++] = SortFilterEventInfo.GetDeclaration();
            declarationList[num++] = EndUserSort.GetDeclaration();
            num++;
            num++;
            declarationList[num++] = RecordSetPropertyNames.GetDeclaration();
            num++;
            num++;
            num++;
            declarationList[num++] = PageSectionInstance.GetDeclaration();
            num++;
            declarationList[num++] = PageSectionInstanceInfo.GetDeclaration();
            declarationList[num++] = SimpleTextBoxInstanceInfo.GetDeclaration();
            declarationList[num++] = ScopeLookupTable.GetDeclaration();
            num++;
            declarationList[num++] = ReportDrillthroughInfo.GetDeclaration();
            declarationList[num++] = InstanceInfo.GetDeclaration();
            Global.Tracer.Assert(declarationList.Count == num, "(current.Count == index)");
            return(declarationList);
        }
Exemplo n.º 9
0
        //Main code for creating chart.
        //Note: the argument img is unused because this demo only has 1 chart.
        public void createChart(WinChartViewer viewer, string img)
        {
            // The age groups
            string[] labels = { "0 - 4",   "5 - 9",   "10 - 14", "15 - 19", "20 - 24",
                                "24 - 29", "30 - 34", "35 - 39", "40 - 44", "44 - 49","50 - 54",
                                "55 - 59", "60 - 64", "65 - 69", "70 - 74", "75 - 79","80+" };

            // The male population (in thousands)
            double[] male = { 215, 238, 225, 236, 235, 260, 286, 340, 363, 305, 259,
                              164, 135, 127, 102,  68, 66 };

            // The female population (in thousands)
            double[] female = { 194, 203, 201, 220, 228, 271, 339, 401, 384, 304, 236,
                                137, 116, 122, 112,  85, 110 };


            //=============================================================
            //    Draw the right bar chart
            //=============================================================

            // Create a XYChart object of size 320 x 300 pixels
            XYChart c = new XYChart(320, 300);

            // Set the plotarea at (50, 0) and of size 250 x 255 pixels. Use pink
            // (0xffdddd) as the background.
            c.setPlotArea(50, 0, 250, 255, 0xffdddd);

            // Add a custom text label at the top right corner of the right bar chart
            c.addText(300, 0, "Female", "Times New Roman Bold Italic", 12, 0xa07070
                      ).setAlignment(Chart.TopRight);

            // Add the pink (0xf0c0c0) bar chart layer using the female data
            BarLayer femaleLayer = c.addBarLayer(female, 0xf0c0c0, "Female");

            // Swap the axis so that the bars are drawn horizontally
            c.swapXY(true);

            // Set the bar to touch each others
            femaleLayer.setBarGap(Chart.TouchBar);

            // Set the border style of the bars to 1 pixel 3D border
            femaleLayer.setBorderColor(-1, 1);

            // Add a Transparent line layer to the chart using the male data. As it
            // is Transparent, only the female bar chart can be seen. We need to put
            // both male and female data in both left and right charts, because we
            // want auto-scaling to produce the same scale for both chart.
            c.addLineLayer(male, Chart.Transparent);

            // Set the y axis label font to Arial Bold
            c.yAxis().setLabelStyle("Arial Bold");

            // Set the labels between the two bar charts, which can be considered as
            // the x-axis labels for the right chart
            ChartDirector.TextBox tb = c.xAxis().setLabels(labels);

            // Use a fix width of 50 for the labels (height = automatic) with center
            // alignment
            tb.setSize(50, 0);
            tb.setAlignment(Chart.Center);

            // Set the label font to Arial Bold
            tb.setFontStyle("Arial Bold");

            // Disable ticks on the x-axis by setting the tick length to 0
            c.xAxis().setTickLength(0);

            //=============================================================
            //    Draw the left bar chart
            //=============================================================

            // Create a XYChart object of size 280 x 300 pixels with a transparent
            // background.
            XYChart c2 = new XYChart(280, 300, Chart.Transparent);

            // Set the plotarea at (20, 0) and of size 250 x 255 pixels. Use pale
            // blue (0xddddff) as the background.
            c2.setPlotArea(20, 0, 250, 255, 0xddddff);

            // Add a custom text label at the top left corner of the left bar chart
            c2.addText(20, 0, "Male", "Times New Roman Bold Italic", 12, 0x7070a0);

            // Add the pale blue (0xaaaaff) bar chart layer using the male data
            BarLayer maleLayer = c2.addBarLayer(male, 0xaaaaff, "Male");

            // Swap the axis so that the bars are drawn horizontally
            c2.swapXY(true);

            // Reverse the direction of the y-axis so it runs from right to left
            c2.yAxis().setReverse();

            // Set the bar to touch each others
            maleLayer.setBarGap(Chart.TouchBar);

            // Set the border style of the bars to 1 pixel 3D border
            maleLayer.setBorderColor(-1, 1);

            // Add a Transparent line layer to the chart using the female data. As it
            // is Transparent, only the male bar chart can be seen. We need to put
            // both male and female data in both left and right charts, because we
            // want auto-scaling to produce the same scale for both chart.
            c2.addLineLayer(female, Chart.Transparent);

            // Set the y axis label font to Arial Bold
            c2.yAxis().setLabelStyle("Arial Bold");

            // Set the x-axis labels for tool tip purposes.
            c2.xAxis().setLabels(labels);

            // Hide the x-axis labels by setting them to Transparent. We only need to
            // display the x-axis labels for the right chart.
            c2.xAxis().setColors(0x000000, Chart.Transparent, -1, Chart.Transparent);

            //=============================================================
            //    Use a MultiChart to contain both bar charts
            //=============================================================

            // Create a MultiChart object of size 590 x 320 pixels.
            MultiChart m = new MultiChart(590, 320);

            // Add a title to the chart using Arial Bold Italic font
            m.addTitle("Demographics Hong Kong Year 2002", "Arial Bold Italic");

            // Add another title at the bottom using Arial Bold Italic font
            m.addTitle2(Chart.Bottom, "Population (in thousands)",
                        "Arial Bold Italic", 10);

            // Put the right chart at (270, 25)
            m.addChart(270, 25, c);

            // Put the left chart at (0, 25)
            m.addChart(0, 25, c2);

            // Output the chart
            viewer.Image = m.makeImage();

            //include tool tip for the chart
            viewer.ImageMap = m.getHTMLImageMap("clickable", "",
                                                "title='{dataSetName} (Age {xLabel}): Population {value}K'");
        }
Exemplo n.º 10
0
        //
        // Draw finance chart track line with legend
        //
        private void trackFinance(MultiChart m, int mouseX)
        {
            // Clear the current dynamic layer and get the DrawArea object to draw on it.
            DrawArea d = m.initDynamicLayer();

            // It is possible for a FinanceChart to be empty, so we need to check for it.
            if (m.getChartCount() == 0)
            {
                return;
            }

            // Get the data x-value that is nearest to the mouse
            int xValue = (int)(((XYChart)m.getChart(0)).getNearestXValue(mouseX));

            // Iterate the XY charts (main price chart and indicator charts) in the FinanceChart
            XYChart c = null;

            for (int i = 0; i < m.getChartCount(); ++i)
            {
                c = (XYChart)m.getChart(i);

                // Variables to hold the legend entries
                string    ohlcLegend    = "";
                ArrayList legendEntries = new ArrayList();

                // Iterate through all layers to find the highest data point
                for (int j = 0; j < c.getLayerCount(); ++j)
                {
                    Layer layer        = c.getLayerByZ(j);
                    int   xIndex       = layer.getXIndexOf(xValue);
                    int   dataSetCount = layer.getDataSetCount();

                    // In a FinanceChart, only layers showing OHLC data can have 4 data sets
                    if (dataSetCount == 4)
                    {
                        double highValue  = layer.getDataSet(0).getValue(xIndex);
                        double lowValue   = layer.getDataSet(1).getValue(xIndex);
                        double openValue  = layer.getDataSet(2).getValue(xIndex);
                        double closeValue = layer.getDataSet(3).getValue(xIndex);

                        if (closeValue != Chart.NoValue)
                        {
                            // Build the OHLC legend
                            ohlcLegend = "Open: " + c.formatValue(openValue, "{value|P4}") + ", High: " +
                                         c.formatValue(highValue, "{value|P4}") + ", Low: " + c.formatValue(lowValue,
                                                                                                            "{value|P4}") + ", Close: " + c.formatValue(closeValue, "{value|P4}");

                            // We also draw an upward or downward triangle for up and down days and the %
                            // change
                            double lastCloseValue = layer.getDataSet(3).getValue(xIndex - 1);
                            if (lastCloseValue != Chart.NoValue)
                            {
                                double change  = closeValue - lastCloseValue;
                                double percent = change * 100 / closeValue;
                                string symbol  = ((change >= 0) ?
                                                  "<*font,color=008800*><*img=@triangle,width=8,color=008800*>" :
                                                  "<*font,color=CC0000*><*img=@invertedtriangle,width=8,color=CC0000*>");

                                ohlcLegend = ohlcLegend + "  " + symbol + " " + c.formatValue(change,
                                                                                              "{value|P4}") + " (" + c.formatValue(percent, "{value|2}") + "%)<*/font*>"
                                ;
                            }

                            // Use a <*block*> to make sure the line does not wrap within the legend entry
                            ohlcLegend = "<*block*>" + ohlcLegend + "      <*/*>";
                        }
                    }
                    else
                    {
                        // Iterate through all the data sets in the layer
                        for (int k = 0; k < layer.getDataSetCount(); ++k)
                        {
                            ChartDirector.DataSet dataSet = layer.getDataSetByZ(k);

                            string name  = dataSet.getDataName();
                            double value = dataSet.getValue(xIndex);
                            if ((!string.IsNullOrEmpty(name)) && (value != Chart.NoValue))
                            {
                                // In a FinanceChart, the data set name consists of the indicator name and its
                                // latest value. It is like "Vol: 123M" or "RSI (14): 55.34". As we are
                                // generating the values dynamically, we need to extract the indictor name
                                // out, and also the volume unit (if any).

                                // The unit character, if any, is the last character and must not be a digit.
                                string unitChar = name.Substring(name.Length - 1);
                                if (unitChar.CompareTo("0") >= 0 && unitChar.CompareTo("9") <= 0)
                                {
                                    unitChar = "";
                                }

                                // The indicator name is the part of the name up to the colon character.
                                int delimiterPosition = name.IndexOf(":");
                                if (delimiterPosition != -1)
                                {
                                    name = name.Substring(0, delimiterPosition);
                                }

                                // In a FinanceChart, if there are two data sets, it must be representing a
                                // range.
                                if (dataSetCount == 2)
                                {
                                    // We show both values in the range in a single legend entry
                                    value = layer.getDataSet(0).getValue(xIndex);
                                    double value2 = layer.getDataSet(1).getValue(xIndex);
                                    name = name + ": " + c.formatValue(Math.Min(value, value2), "{value|P3}")
                                           + " - " + c.formatValue(Math.Max(value, value2), "{value|P3}");
                                }
                                else
                                {
                                    // In a FinanceChart, only the layer for volume bars has 3 data sets for
                                    // up/down/flat days
                                    if (dataSetCount == 3)
                                    {
                                        // The actual volume is the sum of the 3 data sets.
                                        value = layer.getDataSet(0).getValue(xIndex) + layer.getDataSet(1
                                                                                                        ).getValue(xIndex) + layer.getDataSet(2).getValue(xIndex);
                                    }

                                    // Create the legend entry
                                    name = name + ": " + c.formatValue(value, "{value|P3}") + unitChar;
                                }

                                // Build the legend entry, consist of a colored square box and the name (with
                                // the data value in it).
                                legendEntries.Add("<*block*><*img=@square,width=8,edgeColor=000000,color=" +
                                                  dataSet.getDataColor().ToString("x") + "*> " + name + "<*/*>");
                            }
                        }
                    }
                }

                // Get the plot area position relative to the entire FinanceChart
                PlotArea plotArea      = c.getPlotArea();
                int      plotAreaLeftX = plotArea.getLeftX() + c.getAbsOffsetX();
                int      plotAreaTopY  = plotArea.getTopY() + c.getAbsOffsetY();

                // The legend is formed by concatenating the legend entries.
                legendEntries.Reverse();
                string legendText = String.Join("      ", (string[])legendEntries.ToArray(typeof(string)));

                // Add the date and the ohlcLegend (if any) at the beginning of the legend
                legendText = "<*block,valign=top,maxWidth=" + (plotArea.getWidth() - 5) +
                             "*><*font=Arial Bold*>[" + c.xAxis().getFormattedLabel(xValue, "mmm dd, yyyy") +
                             "]<*/font*>      " + ohlcLegend + legendText;

                // Draw a vertical track line at the x-position
                d.vline(plotAreaTopY, plotAreaTopY + plotArea.getHeight(), c.getXCoor(xValue) +
                        c.getAbsOffsetX(), d.dashLineColor(0x000000, 0x0101));

                // Display the legend on the top of the plot area
                TTFText t = d.text(legendText, "Arial", 8);
                t.draw(plotAreaLeftX + 5, plotAreaTopY + 3, 0x000000, Chart.TopLeft);
            }
        }