示例#1
0
        void performPaintLegend(Graphics g, ChartRegion region_legend)
        {
            if (0 == region_legend.Height)
            {
                return;
            }

            double cumulative_legend_text_width = 0.0;

            // Resize the font of the legend as more series are added
            int legendFontSize = 14 - series_list.Count / 2;

            legendFontSize = Math.Max(legendFontSize, 4);
            if (font_legend.Size != legendFontSize)
            {
                font_legend = new Font(FontFamily.GenericSansSerif, legendFontSize);
            }

            // Count the space for the text labels
            SizeF[] measurements = new SizeF[series_list.Count];
            for (int i = 0; i < series_list.Count; ++i)
            {
                Series series = (Series)series_list[i];
                measurements[i] = g.MeasureString(series.name, font_legend);
                cumulative_legend_text_width += measurements[i].Width;
            }

            // Add in the space for the gaps and the indicators
            cumulative_legend_text_width += legend_gap_width * (series_list.Count - 1);
            cumulative_legend_text_width += legend_indicator_size * series_list.Count;
            cumulative_legend_text_width += legend_indicator_gap_width * series_list.Count;

            double left_offset = region_legend.Left + (region_legend.Width - cumulative_legend_text_width) / 2;

            // Now write out the labels
            double current_offset = left_offset;

            for (int i = 0; i < series_list.Count; ++i)
            {
                Series series = (Series)series_list[i];

                brush_legend.Color = series.color;
                pen_legend.Color   = series.color;

                double indicator_top = region_legend.Top + (region_legend.Height - legend_indicator_size) / 2.0;
                double text_top      = region_legend.Top + (region_legend.Height - measurements[i].Height) / 2.0;

                renderSeriesLegend(i, series, g, pen_legend, brush_legend, (float)(current_offset + legend_indicator_size / 2.0), (float)(indicator_top + legend_indicator_size / 2.0), (float)legend_indicator_size);
                current_offset += legend_indicator_size;
                current_offset += legend_indicator_gap_width;
                g.DrawString(series.name, font_legend, brush_legend, (float)current_offset, (float)text_top);
                current_offset += measurements[i].Width;
                current_offset += legend_gap_width;
            }
        }
示例#2
0
        void performPaintY1Axis(Graphics g, ChartRegion region_chart, ChartRegion region_y1_axis, Point2D min, Point2D max)
        {
            // Check that we have at least one series of our kind
            if (!haveSeriesForChartAxis(ChartAxis.Primary))
            {
                return;
            }

            // Draw in the ticks
            double y_extent     = region_y1_axis.Height;
            int    tick_divisor = determineTickDivisor(y_extent, axis_tick_gap_min);

            // Calculate the space between ticks
            double notch_spacing = (y_extent / tick_divisor);

            // Draw in the ticks
            int parity = -1;

            for (double y_pos = region_y1_axis.Top; y_pos <= region_y1_axis.Bottom && notch_spacing > 0; y_pos += notch_spacing)
            {
                parity = -parity;
                if (parity > 0 && y_pos < region_y1_axis.Bottom)
                {
                    g.FillRectangle(brush_background_axisguide, region_chart.Left, (float)y_pos, region_chart.Width, (float)notch_spacing);
                }

                g.DrawLine(pen_axis_guide, region_chart.Left, (float)y_pos, region_chart.Right, (float)y_pos);
                g.DrawLine(pen_axis, region_y1_axis.Right - axis_notch_height, (float)y_pos, region_y1_axis.Right, (float)y_pos);
            }

            // Used to make text vertical
            StringFormat string_format = new StringFormat(StringFormatFlags.DirectionVertical);

            // Draw in the values
            int precision = Precision.estimateMeaningfulChartRoundingPrecision(max.y - min.y);

            for (double y_pos = region_y1_axis.Top; y_pos <= region_y1_axis.Bottom && notch_spacing > 0; y_pos += notch_spacing)
            {
                double y_value = max.y - (max.y - min.y) * (y_pos - region_y1_axis.Top) / region_y1_axis.Height;
                y_value = Math.Round(y_value, precision);
                string y_text      = "" + y_value;
                SizeF  y_text_size = g.MeasureString(y_text, font_axis, (int)region_y1_axis.Width, string_format);
                g.DrawString(y_text, font_axis, brush_axis, region_y1_axis.Right - 5.0f - y_text_size.Width, (float)(y_pos - y_text_size.Height / 2.0), string_format);
            }

            // Draw in the title
            SizeF y1_axis_title_text_size = g.MeasureString(y1_axis_title, font_axis, (int)region_y1_axis.Width, string_format);

            g.DrawString(y1_axis_title, font_axis, brush_axis, 0, (float)(region_y1_axis.Top + (region_y1_axis.Height - y1_axis_title_text_size.Height) / 2.0), string_format);
        }
示例#3
0
        void performPaintXAxis(Graphics g, ChartRegion region_chart, ChartRegion region_x_axis, Point2D min, Point2D max)
        {
            if (0 == this.series_list.Count)
            {
                return;
            }

            double x_extent     = region_x_axis.Width;
            int    tick_divisor = determineTickDivisor(x_extent, axis_tick_gap_min);

            // Calculate the space between ticks
            double notch_spacing = (x_extent / tick_divisor);

            // Draw in the ticks
            for (double x_pos = region_x_axis.Left; x_pos <= region_x_axis.Right && notch_spacing > 0; x_pos += notch_spacing)
            {
                g.DrawLine(pen_axis_guide, (float)x_pos, region_chart.Top, (float)x_pos, region_chart.Bottom);
                g.DrawLine(pen_axis, (float)x_pos, region_x_axis.Top, (float)x_pos, region_x_axis.Top + axis_notch_height);
            }

            // Draw in the values
            int precision = Precision.estimateMeaningfulChartRoundingPrecision(max.x - min.x);

            for (double x_pos = region_x_axis.Left; x_pos <= region_x_axis.Right && notch_spacing > 0; x_pos += notch_spacing)
            {
                double x_value = min.x + (max.x - min.x) * (x_pos - region_x_axis.Left) / region_x_axis.Width;
                x_value = Math.Round(x_value, precision);
                string x_text      = "" + x_value;
                SizeF  x_text_size = g.MeasureString(x_text, font_axis);
                g.DrawString(x_text, font_axis, brush_axis, (float)(x_pos - x_text_size.Width / 2.0), region_x_axis.Top + 5.0f);
            }

            // Draw in the axis title
            SizeF x_axis_title_text_size = g.MeasureString(x_axis_title, font_axis);

            g.DrawString(x_axis_title, font_axis, brush_axis, (float)(region_x_axis.Left + (region_x_axis.Width - x_axis_title_text_size.Width) / 2.0), (float)(region_x_axis.Bottom - x_axis_title_text_size.Height));
        }
示例#4
0
        protected override void OnPaint(PaintEventArgs e)
        {
            if (series_list.Count == 0)
            {
                ChartTools.renderNoDatasetMessage(e.Graphics);
                return;
            }

            ChartRegion region_fullscreen = new ChartRegion(0, 0, this.Width, this.Height);

            ChartRegion region_title; ChartRegion region_title_remainder;

            region_fullscreen.splitHorizontal(title_height, out region_title, out region_title_remainder);

            ChartRegion region_legend; ChartRegion region_legend_remainder;

            region_title_remainder.splitHorizontal(region_title_remainder.Height - legend_height, out region_legend_remainder, out region_legend);
            region_legend.Top += 10;

            ChartRegion region_chart; ChartRegion region_x_axis; ChartRegion region_y1_axis; ChartRegion region_y2_axis;

            region_legend_remainder.splitAxes(axis_height, out region_chart, out region_x_axis, out region_y1_axis, out region_y2_axis);

            Point2D min_pri; Point2D max_pri; Point2D min_sec; Point2D max_sec;

            getSeriesExtents(out min_pri, out max_pri, out min_sec, out max_sec);

            // Set the axis overrides
            if (!double.IsNaN(x_axis_max))
            {
                max_pri.x = x_axis_max;
            }
            if (!double.IsNaN(x_axis_max))
            {
                max_sec.x = x_axis_max;
            }
            if (!double.IsNaN(x_axis_min))
            {
                min_pri.x = x_axis_min;
            }
            if (!double.IsNaN(x_axis_min))
            {
                min_sec.x = x_axis_min;
            }
            if (!double.IsNaN(y1_axis_max))
            {
                max_pri.y = y1_axis_max;
            }
            if (!double.IsNaN(y1_axis_min))
            {
                min_pri.y = y1_axis_min;
            }
            if (!double.IsNaN(y2_axis_max))
            {
                max_sec.y = y2_axis_max;
            }
            if (!double.IsNaN(y2_axis_min))
            {
                min_sec.y = y2_axis_min;
            }

            // Check that our series are beautifully coloured
            for (int i_series = 0; i_series < series_list.Count; ++i_series)
            {
                Series series = (Series)series_list[i_series];
                if (series.color == Color.Black)
                {
                    series.color = ChartColours.getOrderedColour(i_series);
                }
            }

            // Draw the various bits of the chart
            try
            {
                performPaintBackground(e.Graphics, region_chart);
                performPaintTitle(e.Graphics, region_title);
                performPaintLegend(e.Graphics, region_legend);

                if (region_chart.Height > 0 && region_chart.Width > 0)
                {
                    performPaintXAxis(e.Graphics, region_chart, region_x_axis, min_pri, max_pri);
                    performPaintY1Axis(e.Graphics, region_chart, region_y1_axis, min_pri, max_pri);
                    performPaintY2Axis(e.Graphics, region_chart, region_y2_axis, min_sec, max_sec);
                    performPaintSeries(e.Graphics, region_chart, min_pri, max_pri, min_sec, max_sec);
                }

                performPaintBorders(e.Graphics, region_chart);
            }

            catch (Exception)
            {
            }
        }
示例#5
0
        void performPaintSeries(Graphics g, ChartRegion region_chart, Point2D min_pri, Point2D max_pri, Point2D min_sec, Point2D max_sec)
        {
            if (0 == this.series_list.Count)
            {
                return;
            }

            for (int i_series = 0; i_series < series_list.Count; ++i_series)
            {
                Series series = (Series)series_list[i_series];

                Point2D min = series.chartaxis == ChartAxis.Primary ? min_pri : min_sec;
                Point2D max = series.chartaxis == ChartAxis.Primary ? max_pri : max_sec;

                // Skip any series with bad values
                if (Double.IsNaN(min.x))
                {
                    continue;
                }
                if (Double.IsNaN(min.y))
                {
                    continue;
                }
                if (Double.IsNaN(max.x))
                {
                    continue;
                }
                if (Double.IsNaN(max.y))
                {
                    continue;
                }

                pen_series.Color   = series.color;
                brush_series.Color = series.color;

                pen_series.DashStyle = pickSeriesDashStyle(i_series, series.charttype);

                if (series.charttype == ChartType.Point)
                {
                    for (int i_point = 0; i_point < series.Count; ++i_point)
                    {
                        Point2D point = (Point2D)series[i_point];

                        float x_pos = (float)(region_chart.Left + region_chart.Width * (point.x - min.x) / (max.x - min.x));
                        float y_pos = (float)(region_chart.Bottom - region_chart.Height * (point.y - min.y) / (max.y - min.y));
                        renderSeriesPoint(i_series, g, pen_series, brush_series, x_pos, y_pos, point_size);
                    }
                }

                else if (series.charttype == ChartType.Line || series.charttype == ChartType.SmoothLine || series.charttype == ChartType.LineAndPoint || series.charttype == ChartType.SmoothLineAndPoint)
                {
                    Point[] points = new Point[series.Count];
                    for (int i = 0; i < series.Count; ++i)
                    {
                        Point2D point = (Point2D)series[i];

                        float x_pos = (float)(region_chart.Left + region_chart.Width * (point.x - min.x) / (max.x - min.x));
                        float y_pos = (float)(region_chart.Bottom - region_chart.Height * (point.y - min.y) / (max.y - min.y));

                        if (series.charttype == ChartType.LineAndPoint || series.charttype == ChartType.SmoothLineAndPoint)
                        {
                            renderSeriesPoint(i_series, g, pen_series, brush_series, x_pos, y_pos, point_size);
                        }

                        points[i] = new Point((int)x_pos, (int)y_pos);
                    }

                    if (series.charttype == ChartType.Line || series.charttype == ChartType.LineAndPoint)
                    {
                        if (points.Length > 1)
                        {
                            g.DrawLines(pen_series, points);
                        }
                    }
                    else if (series.charttype == ChartType.SmoothLine || series.charttype == ChartType.SmoothLineAndPoint)
                    {
                        if (points.Length > 1)
                        {
                            g.DrawCurve(pen_series, points);
                        }
                    }
                }

                else if (series.charttype == ChartType.Bar)
                {
                    for (int i = 0; i < series.Count; ++i)
                    {
                        Point2D point = (Point2D)series[i];

                        float x_pos = (float)(region_chart.Left + region_chart.Width * (point.x - min.x) / (max.x - min.x));
                        float y_pos = (float)(region_chart.Bottom - region_chart.Height * (point.y - min.y) / (max.y - min.y));

                        g.DrawLine(pen_series, x_pos, y_pos, x_pos, region_chart.Bottom);
                    }
                }

                else
                {
                    throw new GenericException("Unknown chart type " + series.charttype);
                }
            }
        }
示例#6
0
 void performPaintBorders(Graphics g, ChartRegion region_chart)
 {
     g.DrawRectangle(pen_border, region_chart.Left, region_chart.Top, region_chart.Width, region_chart.Height);
 }
示例#7
0
        void performPaintTitle(Graphics g, ChartRegion region_title)
        {
            SizeF title_text_size = g.MeasureString(title, font_title);

            g.DrawString(title, font_title, brush_title, (float)(region_title.Left + (region_title.Width - title_text_size.Width) / 2.0), (float)(region_title.Top + (region_title.Height - title_text_size.Height) / 2.0));
        }
示例#8
0
 void performPaintBackground(Graphics g, ChartRegion region_chart)
 {
     g.FillRectangle(brush_background, region_chart.Left, region_chart.Top, region_chart.Width, region_chart.Height);
 }