Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Distance between chart legend and the horizontal bar chart is to big in case of rotated labels #2138

Closed
SvenMuc opened this issue Feb 4, 2017 · 7 comments

Comments

@SvenMuc
Copy link
Contributor

SvenMuc commented Feb 4, 2017

I rechecked the issue with Charts 3.0.1. The behavior is the same. See images below.

chart.xAxis.labelRotationAngle       = -90.0           // rotate label
chart.xAxis.centerAxisLabelsEnabled  = true

bildschirmfoto 2017-02-04 um 22 16 43

chart.xAxis.centerAxisLabelsEnabled  = true

bildschirmfoto 2017-02-04 um 22 19 45

See also my old issue #1360

@SvenMuc
Copy link
Contributor Author

SvenMuc commented Feb 19, 2017

I tried to investigate the HorizontalBarChartView.calculateOffsets() function. The offset results depend strongly on xAxis label rotation. The calculateOffset() is called 4 times. As you can see, the offsetBottom parameter strongly depends on the xAxis.labelRotationAngle. It increases with a higher rotation angle.

For me it looks like a bug in the calculateLegendOffsetsfunction (see debugging results below). I'll investigate this topics this evening.

chart.xAxis.labelRotationAngle = 0.0

calculateLegendOffsets: offsetTop: 0.0   offsetRight: 0.0  offsetBottom: 29.93359375  offsetLeft: 0.0
Before Extra Offset: offsetTop: 0.0   offsetRight: 0.0  offsetBottom: 41.8671875  offsetLeft: 70.0
After Extra Offset:  offsetTop: 0.0   offsetRight: 0.0  offsetBottom: 41.8671875  offsetLeft: 70.0
restrainViewPort:    offsetTop: 10.0   offsetRight: 10.0  offsetBottom: 41.8671875  offsetLeft: 70.0

chart.xAxis.labelRotationAngle = -45.0

calculateLegendOffsets: offsetTop: 0.0   offsetRight: 0.0  offsetBottom: 63.93359375  offsetLeft: 0.0
Before Extra Offset: offsetTop: 0.0   offsetRight: 0.0  offsetBottom: 75.8671875  offsetLeft: 63.0
After Extra Offset:  offsetTop: 0.0   offsetRight: 0.0  offsetBottom: 75.8671875  offsetLeft: 63.0
restrainViewPort:    offsetTop: 10.0   offsetRight: 10.0  offsetBottom: 75.8671875  offsetLeft: 63.0

chart.xAxis.labelRotationAngle = -90.0

calculateLegendOffsets: offsetTop: 0.0   offsetRight: 0.0  offsetBottom: 69.93359375  offsetLeft: 0.0
Before Extra Offset: offsetTop: 0.0   offsetRight: 0.0  offsetBottom: 81.8671875  offsetLeft: 29.0
After Extra Offset:  offsetTop: 0.0   offsetRight: 0.0  offsetBottom: 81.8671875  offsetLeft: 29.0
restrainViewPort:    offsetTop: 10.0   offsetRight: 10.0  offsetBottom: 81.8671875  offsetLeft: 29.0

@SvenMuc
Copy link
Contributor Author

SvenMuc commented Feb 19, 2017

I think the root cause can be found in the function calculateLegendOffsetsin BarLineChartViewBase. The switch case .bottom calculates the offsetBottom value by adding the xAxis_labelRotatedHeightwhich in case of an horizontal bar chart the left axis. The correct distance can be calculated by using the label height of the right axis (rightAxis.getRequiredHeightSpace()).

Is there a way to find out if we have a horizontal or vertical chart?

What's the difference between _legend.orientationand _legend.verticalAlignment in the switch cases?

BarLineChartViewBase.calculateLegendOffsets()

          case .horizontal:
                
                print("calculateLegendOffsets->horizontal")
                
                switch _legend.verticalAlignment
                {
                case .top:
                    offsetTop += min(_legend.neededHeight, _viewPortHandler.chartHeight * _legend.maxSizePercent) + _legend.yOffset
                    if xAxis.isEnabled && xAxis.isDrawLabelsEnabled
                    {
                        offsetTop += xAxis.labelRotatedHeight
                        print("calculateLegendOffsets(horizontal,top): offsetTop: \(xAxis.labelRotatedHeight)")
                    }
                    
                case .bottom:
                    offsetBottom += min(_legend.neededHeight, _viewPortHandler.chartHeight * _legend.maxSizePercent) + _legend.yOffset
                    if xAxis.isEnabled && xAxis.isDrawLabelsEnabled
                    {
                        offsetBottom += xAxis.labelRotatedHeight
                        print("calculateLegendOffsets(horizontal,bottom): offsetBottom: \(xAxis.labelRotatedHeight)")
                    }

@SvenMuc
Copy link
Contributor Author

SvenMuc commented Feb 19, 2017

One possible solution can be the following (case .bottom:):

if rightAxis.isEnabled && rightAxis.isDrawLabelsEnabled
{
    offsetBottom += rightAxis.getRequiredHeightSpace()
}

By this modification I get the correct offset values for a horizontal chart.

calculateLegendOffsets: offsetTop: 0.0   offsetRight: 0.0  offsetBottom: 29.8671875  offsetLeft: 0.0
Before Extra Offset:    offsetTop: 0.0   offsetRight: 0.0  offsetBottom: 41.80078125  offsetLeft: 29.0
After Extra Offset:     offsetTop: 0.0   offsetRight: 0.0  offsetBottom: 41.80078125  offsetLeft: 29.0
restrainViewPort:       offsetTop: 10.0   offsetRight: 10.0  offsetBottom: 41.80078125  offsetLeft: 29.0

But how do I detect the horizontal chart view in BarLineChartViewBase.calculateLegendOffsets()?

Interim solution:

              case .bottom:
                    offsetBottom += min(_legend.neededHeight, _viewPortHandler.chartHeight * _legend.maxSizePercent) + _legend.yOffset

                    if _xAxisRenderer.isKind(of: XAxisRendererHorizontalBarChart.self) {
                        if rightAxis.isEnabled && rightAxis.isDrawLabelsEnabled
                        {
                            offsetBottom += rightAxis.getRequiredHeightSpace()
                            print("calculateLegendOffsets(horizintal,bottom): offsetBottom: \(rightAxis.getRequiredHeightSpace())")
                        }
                    } else {
                        if xAxis.isEnabled && xAxis.isDrawLabelsEnabled
                        {
                            offsetBottom += xAxis.labelRotatedHeight
                            print("calculateLegendOffsets(horizintal,bottom): offsetBottom: \(xAxis.labelRotatedHeight)")
                        }
                    }

@SvenMuc SvenMuc changed the title Distance between chart legend and the chart is to big in case of rotated labels Distance between chart legend and the horizontal bar chart is to big in case of rotated labels Feb 19, 2017
@liuxuan30
Copy link
Member

Thanks @SvenMuc ! Seems you did a lot of work. Mind to file a PR to fix?

@SvenMuc
Copy link
Contributor Author

SvenMuc commented Mar 1, 2017

I can do so. But I don't like my solution (see above) very much. Is there a better way to identify whether the xAxis is really the xAxis or the rightAxis @liuxuan30 ?

@liuxuan30
Copy link
Member

I saw some code like let didUserDrag = (self is HorizontalBarChartView) to know whether it's horizontal or vertical bar chart.
Also, not sure why you ask 'better way' to identify xAxis is really the xAxis or the rightAxis. Just using the Class.self can know which class it is. But I wonder this seems not an answer to your question.

@SvenMuc
Copy link
Contributor Author

SvenMuc commented Mar 2, 2017

Filed pull request #2214

@jjatie jjatie closed this as completed in b0022f8 Jan 21, 2018
FreddyZeng added a commit to FreddyZeng/Charts that referenced this issue Jan 25, 2018
* 'master' of https://github.com/danielgindi/Charts:
  Fixed a duplicated assignment compared with obj-c code. (ChartsOrg#3179)
  Updated README for 3.0.5 (ChartsOrg#3183)
  Added custom text alignment for noData
  Fixes the distance issue between the legend and the horizontal bar chart (Fixes ChartsOrg#2138) (ChartsOrg#2214)
  call setNeedsDisplay() here to trigger render noDataText (ChartsOrg#3198)
kzyryanov pushed a commit to fishbrain/Charts that referenced this issue Feb 20, 2018
…art (Fixes ChartsOrg#2138) (ChartsOrg#2214)

* Fixes the distance issue between the legend and the horizontal bar chart (Fixes ChartsOrg#2138)

Override the function calculateLegendOffsets in HorizontalBarChartView
in order to select the correct axis for distance calculation. In case
of horizontal chart the x-axis is described the the rightAxis (bottom)
or the leftAxis(top).

* Added guard for _legend status
FreddyZeng added a commit to FreddyZeng/Charts that referenced this issue Mar 14, 2018
* master: (55 commits)
  Refactors -[tableView:cellForRowAtIndexPath:] (ChartsOrg#3326)
  fix ChartsOrg#3311. Need one more key for iOS 11 camera roll saving
  revert a mistake, fix ChartsOrg#3299
  add pie chart unit tests (ChartsOrg#3297)
  ChartsOrg#3287: align Objc and Swift demos balloon marker
  update changelog
  Min and Max reset when clearing ChartDataSet (Fixes ChartsOrg#3260)
  Restored old performance (ChartsOrg#3216)
  Support other bundle than main MarkerView.viewFromXib() (ChartsOrg#3215)
  For ChartsOrg#2840. add dataIndex parameter in `highlightValue()` calls (ChartsOrg#2852)
  Balloon Marker indicates position of data (ChartsOrg#3181)
  bump Info.plist version
  Fixed a duplicated assignment compared with obj-c code. (ChartsOrg#3179)
  Updated README for 3.0.5 (ChartsOrg#3183)
  BubbleChart uses correct colour for index now.
  Added custom text alignment for noData
  Fixes the distance issue between the legend and the horizontal bar chart (Fixes ChartsOrg#2138) (ChartsOrg#2214)
  call setNeedsDisplay() here to trigger render noDataText (ChartsOrg#3198)
  添加定制TY的Mark
  添加修改过的Mark到工程中
  ...

# Conflicts:
#	ICXCharts.podspec
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants