#winforms #powerpoint #winforms-interop
#winforms #powerpoint #winforms-interop
Вопрос:
Мы используем тип диаграммы взаимодействия PowerPoint для создания диаграммы областей, как показано на рисунке. Нам нужна «сломанная» ось y. Нам не нужен разрыв на самих столбцах — нам нужен разрыв только на оси y. Но не удается найти свойство или метод для достижения этой цели.
Это приложение winforms. Был бы очень признателен за некоторые указания…
Комментарии:
1. Вы можете попробовать записать макрос и посмотреть сгенерированный код VBA. Это часто приводит к желаемым API.
Ответ №1:
Случайно наткнулся на этот вопрос, и я позволил своему любопытству взять верх. Я понял, как это делается, с этого сайта.
Для этого пошагового руководства я использую пример данных с вышеуказанного сайта.
Шаг примерно такой:
- Назначьте значение cut для разделения данных. Разделите данные, используя значение сокращения (я использую значение сокращения 7,500,000 для примера)
Это разделение данных из примера (выше — оригинал, ниже — разделенные):
May June July
London 1,234,565 1,452,369 1,478,852
Paris 2,363,645 34,568,876 5,562,413
Madrid 32,645,254 3,211,654 5,857,421
Brussels 5,914,753 5,544,221 3,620,015
Lisbon 5,824,676 4,541,258 4,015,876
Munich 2,501,478 6,325,698 4,569,872
May June July Column4 Column5 Column6
London 1,234,565 1,452,369 1,478,852 0 0 0
Paris 2,363,645 7,500,000 5,562,413 0 34,568,876 0
Madrid 7,500,000 3,211,654 5,857,421 32,645,254 0 0
Brussels 5,914,753 5,544,221 3,620,015 0 0 0
Lisbon 5,824,676 4,541,258 4,015,876 0 0 0
Munich 2,501,478 6,325,698 4,569,872 0 0 0
- Назначьте
Column4
,Column5
, иColumn6
на вспомогательную ось.Dim c As Microsoft.Office.Interop.PowerPoint.Chart Dim sc As Microsoft.Office.Interop.PowerPoint.SeriesCollection = Nothing Dim sr As Microsoft.Office.Interop.PowerPoint.Series = Nothing sc = c.SeriesCollection For i = 4 To sc.Count sr = sc.SeriesCollection(i) sr.AxisGroup = Microsoft.Office.Interop.PowerPoint.XlAxisGroup.xlSecondary Next
- Измените масштаб основной и вспомогательной осей, чтобы они соответствовали, как если бы диаграмма была разделена. Я меняю масштаб основной оси с 0 на 1.6e7, а масштаб вторичной оси с -7.0e7 на 7.0e7. В то же время измените единицы отображения в миллионах и удалите все линии сетки.
Dim ax As Microsoft.Office.Interop.PowerPoint.Axes Dim axpri As Microsoft.Office.Interop.PowerPoint.Axis Dim axsec As Microsoft.Office.Interop.PowerPoint.Axis ax = c.Axes axpri = ax.Item(Microsoft.Office.Interop.PowerPoint.XlAxisType.xlValue, _ Microsoft.Office.Interop.PowerPoint.XlAxisGroup.xlPrimary) axsec = ax.Item(Microsoft.Office.Interop.PowerPoint.XlAxisType.xlValue, _ Microsoft.Office.Interop.PowerPoint.XlAxisGroup.xlSecondary) axpri.MinimumScale = 0 axpri.MaximumScale = 1.6e7 axpri.DisplayUnit = Microsoft.Office.Interop.PowerPoint.XlDisplayUnit.xlMillions axpri.HasMajorGridlines = False axpri.HasMinorGridlines = False axsec.MinimumScale = -7.0e7 axsec.MaximumScale = 7.0e7 axsec.DisplayUnit = Microsoft.Office.Interop.PowerPoint.XlDisplayUnit.xlMillions axsec.HasMajorGridlines = False axsec.HasMinorGridlines = False
- Измените формат номера первичной и вторичной осей, чтобы каждая ось отображала только свое собственное предполагаемое значение. Основная ось длиной более 8 метров отображаться не будет, а вспомогательная ось длиной менее 30 метров отображаться не будет.
axpri.TickLabels.NumberFormat = "[<=8]0;;;" axsec.TickLabels.NumberFormat = "[>=30]0;;;"
- Перекрасьте ряды на вторичной оси, чтобы они соответствовали рядам на основной оси.
Dim srPrev As Microsoft.Office.Interop.PowerPoint.Series = Nothing For i = 4 To sc.Count sr = sc.SeriesCollection(i) srPrev = sc.SeriesCollection(i - 3) sr.Format.Fill.ForeColor.RGB = srPrev.Format.Fill.ForeColor.RGB Next
- Удалите легенду для
Column4
,Column5
, иColumn6
для бесшовной легенды диаграммы.c.Legend.LegendEntries(4).Delete() c.Legend.LegendEntries(5).Delete() c.Legend.LegendEntries(6).Delete()
- [Необязательно] Добавьте аккуратный цветовой градиент для точек данных, которые превышают значения вырезания.
Dim p As Microsoft.Office.Interop.PowerPoint.Point = Nothing p = c.SeriesCollection("June").Points("Paris") p.Format.Fill.TwoColorGradient(Microsoft.Office.Core.MsoGradientStyle.msoGradientHorizontal, 1) p.Format.Fill.GradientAngle = 270 p.Format.Fill.GradientStops.Insert(p.Format.Fill.ForeColor.RGB, 0.8) p.Format.Fill.GradientStops.Insert(p.Format.Fill.BackColor.RGB, 0.97) p = c.SeriesCollection("May").Points("Madrid") p.Format.Fill.TwoColorGradient(Microsoft.Office.Core.MsoGradientStyle.msoGradientHorizontal, 1) p.Format.Fill.GradientAngle = 270 p.Format.Fill.GradientStops.Insert(p.Format.Fill.ForeColor.RGB, 0.8) p.Format.Fill.GradientStops.Insert(p.Format.Fill.BackColor.RGB, 0.97) p = c.SeriesCollection("Column5").Points("Paris") p.Format.Fill.TwoColorGradient(Microsoft.Office.Core.MsoGradientStyle.msoGradientHorizontal, 1) p.Format.Fill.GradientAngle = 90 p.Format.Fill.GradientStops.Insert(p.Format.Fill.ForeColor.RGB, 0.7) p.Format.Fill.GradientStops.Insert(p.Format.Fill.BackColor.RGB, 0.95) p = c.SeriesCollection("Column4").Points("Madrid") p.Format.Fill.TwoColorGradient(Microsoft.Office.Core.MsoGradientStyle.msoGradientHorizontal, 1) p.Format.Fill.GradientAngle = 90 p.Format.Fill.GradientStops.Insert(p.Format.Fill.ForeColor.RGB, 0.7) p.Format.Fill.GradientStops.Insert(p.Format.Fill.BackColor.RGB, 0.95)
- Вуаля! Тяжелая работа окупается, сломанная ось y в диаграмме PowerPoint.