С# Масштабирование осей диаграммы

У меня проблема с диаграммами в моем приложении. Я хочу использовать диаграммы для отображения гистограмм изображений. Я хочу добавить градиентный прямоугольник под диаграмму с цветами от черного до R/G/B/белого, поэтому я рисую его как фоновое изображение каждой диаграммы. Когда значения на AxisY превышают 1k, все в порядке, но когда эти значения содержат менее 4 цифр, возникает проблема экран. Кто-нибудь знает, как предотвратить расширение AxisX? введите здесь описание изображения

Начальные графики:

    for(int i = 0; i < 3; i++)
        {
            ca = new ChartArea();
            ca.AxisX.Interval = 1D;
            ca.AxisX.IntervalOffsetType = System.Windows.Forms.DataVisualization.Charting.DateTimeIntervalType.Number;
            ca.AxisX.LabelAutoFitStyle = System.Windows.Forms.DataVisualization.Charting.LabelAutoFitStyles.WordWrap;
            ca.AxisX.MajorGrid.Enabled = false;
            ca.AxisY.MajorGrid.LineColor = System.Drawing.Color.DarkGray;
            ca.BackColor = System.Drawing.Color.Transparent;
            ca.BackSecondaryColor = System.Drawing.Color.Transparent;
            ca.BorderWidth = 0;
            ca.Name = "ChartArea" + i.ToString();
            ca.AxisY.LabelAutoFitStyle = LabelAutoFitStyles.DecreaseFont;
            ca.AxisX.Minimum = 0;
            ca.AxisX.Interval = 256;
            ca.AxisY.IntervalAutoMode = IntervalAutoMode.VariableCount;

            s = new Series();
            s.BorderWidth = 0;
            s.ChartArea = "ChartArea" + i.ToString();
            s.IsVisibleInLegend = false;
            s.Name = "Series" + i.ToString(); ;
            s.Color = Colors[i];
            s["PointWidth"] = "1";

            HistCharts[i] = new Chart();
            HistCharts[i].Anchor = AnchorStyles.Top | AnchorStyles.Right;
            HistCharts[i].BackColor = Color.Transparent;
            HistCharts[i].BackgroundImageLayout = ImageLayout.None;
            HistCharts[i].BorderlineWidth = 0;
            HistCharts[i].ChartAreas.Add(ca);
            HistCharts[i].Location = new System.Drawing.Point(405, (i + 3) * Form.Height / 6 - 28);
            HistCharts[i].Name = "Chart" + i.ToString();
            HistCharts[i].Series.Add(s);
            HistCharts[i].Size = new System.Drawing.Size(297, Form.Height / 6 - 27);
            HistCharts[i].TabIndex = 6;
            HistCharts[i].Text = "chart" + i.ToString();
            HistCharts[i].Visible = false;
            HistCharts[i].SendToBack();
        }

        SetChartImage();
        for(int i = 0; i < 3; i++)
            HistCharts[i].BackgroundImage = HistImages[i];

Установите новую серию и раскрасьте:

        if(Hists == null)
            {
                HistCharts[0].Visible = false;
                HistCharts[1].Visible = false;
                HistCharts[2].Visible = false;
                UpdateStatTimer(Time);
                return;
            }

            HistCharts[0].BackgroundImage = HistImages[Hists.Length > 1 ? 1 : 0];

            if(Hists[0].SequenceEqual(Hists[1]) && Hists[0].SequenceEqual(Hists[2]))
            {
                HistCharts[0].Series[0].Color = Color.Black;
                HistCharts[0].BackgroundImage = HistImages[0];
                HistCharts[0].Visible = true;
                HistCharts[1].Visible = false;
                HistCharts[2].Visible = false;
            }
            else
            {
                HistCharts[0].Series[0].Color = Color.Red;
                HistCharts[0].BackgroundImage = HistImages[1];
                HistCharts[0].Visible = true;
                HistCharts[1].Visible = true;
                HistCharts[2].Visible = true;
            }

            int Max = 0;
            for(int i = 0; i < 3; i++)
            {
                HistCharts[i].Series[0].Points.Clear();
                HistCharts[i].ChartAreas[0].AxisY.Maximum = Double.NaN;
                for(int j = 0; j < Hists[i].Length; j++)
                    HistCharts[i].Series[0].Points.AddXY(j + 0.5, Hists[i][j]);
                HistCharts[i].Update();
                if(HistCharts[i].ChartAreas[0].AxisY.Maximum > Max)
                    Max = (int) HistCharts[i].ChartAreas[0].AxisY.Maximum;
            }
            if(StatisticsItemCheck.Checked == false)
            {
                for(int i = 0; i < 3; i++)
                    HistCharts[i].ChartAreas[0].AxisY.Maximum = Max;
            }

если все гистограммы равны, зеленая и синяя гистограммы невидимы, а красная гистограмма становится гистограммой в оттенках серого.


person legier    schedule 23.10.2015    source источник
comment
Добро пожаловать в Stack Overflow! Вы должны включить соответствующий код в свои вопросы, если хотите получить помощь быстрее. Мы здесь программисты, и без кода мы мало что можем для вас сделать. В нынешнем виде я могу порекомендовать некоторые фотошопы, которые могли бы исправить эту картинку, которую вы включили.   -  person leigero    schedule 23.10.2015
comment
Я должен согласиться с leigero: нам нужно увидеть хотя бы код краски. Я предполагаю, что все изображения и все диаграммы имеют одинаковый размер?   -  person TaW    schedule 23.10.2015


Ответы (1)


На самом деле это не касается масштабирования..:

Причина, по которой ваши изображения не всегда совпадают с осью Y, заключается в том, что легенда оси Y в различных случаях занимает больше или меньше места. Это делает внутренняя область графика перемещается вправо, и ваше тщательно выровненное изображение больше не помещается.

Когда ось Y перемещается вправо, вся область графика сжимается, по крайней мере, если значения по умолчанию Auto все еще действительны для различных элементов.

Самый простой обходной путь — установить для позиции Auto фиксированное значение, подходящее для всех ваших данных:

chart1.ChartAreas[0].InnerPlotPosition.X = someValue;

Обратите внимание, что все позиция элемента значения указаны в процентах от всей диаграммы! Так что, может быть, вы захотите изменить его при изменении размера диаграммы? Как вы заметили, вам также нужно изменить размер изображений.

Чтобы найти хорошее значение, вы можете использовать отладчик, чтобы увидеть, какие из них являются текущими в обоих случаях, и выбрать большее, а затем еще немного для безопасности.

В том же духе вы можете лучше контролировать формат, т. е. количество цифр в значениях меток по оси Y, например:

chart1.ChartAreas[0].AxisY.LabelStyle.Format = "0.00"; // some formatstring

Обновлять:

Чтобы использовать системный AutoScaling во время (после изменения размера, вы можете использовать этот обходной путь:

Сначала установите Auto и скопируйте полученный файл Elementposition. Затем используйте эти значения для создания нового под контролем:

int LeftEdge = yourValue;
chart1.ChartAreas[0].InnerPlotPosition.Auto = true;
ElementPosition EP = chart1.ChartAreas[0].InnerPlotPosition;
chart1.ChartAreas[0].InnerPlotPosition =  
                     new ElementPosition(LeftEdge, EP.Y, EP.Height, 100 - LeftEdge);
person TaW    schedule 24.10.2015
comment
Когда размер диаграммы изменяется, я также изменяю размер этого фона Bitmp. Размер диаграммы можно изменить только по вертикали. Ваш ответ устраняет некоторые проблемы, но как сделать автомасштабирование высоты с фиксированной позицией X? - person legier; 25.10.2015
comment
Можете ли вы объяснить это немного больше? - person TaW; 25.10.2015
comment
Я хочу сделать положение X и ширину этого графика постоянными. Но когда я изменяю размер формы, я бы хотел, чтобы сюжет был выше. Поэтому, когда я устанавливаю InnerPlotPosition.X с некоторым значением, его положение Y и высота перестают быть автоматическими. - person legier; 25.10.2015
comment
Ах! Смотрите мое обновление для обходного пути, который можно использовать с изменением размера! - person TaW; 25.10.2015