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

Marker out of view #1046

Closed
blmyself opened this issue May 17, 2016 · 6 comments
Closed

Marker out of view #1046

blmyself opened this issue May 17, 2016 · 6 comments

Comments

@blmyself
Copy link

qq20160517-0
I try to adjust the marker offset property, but it is doesn't work.
The rotated xAxis label is also out of the view.
Anybody know how to fix it?

@liuxuan30
Copy link
Member

This is a legend more than a marker. Anyway, you should take a look at how marker rect is calculated.

@danielgindi
Copy link
Collaborator

It's a legend in a marker :-)

@danielgindi
Copy link
Collaborator

You are using the BalloonMarker from the demo, which had an oversight of not looking at offset. I will push a fix to this, but you will need to update your marker's code.

@blmyself
Copy link
Author

The rotated xAxis label is also out of the view?

@avityagi5
Copy link

It seems that it is still replicating.
The marker is clipping from left and right.

@shinurag
Copy link

shinurag commented Apr 11, 2017

I have made some changes for solving this issue, Please have a look

Add another draw method in ChartMarker.swift

public func draw(context context: CGContext, point: CGPoint, viewPortHandler: ChartViewPortHandler)
{
    let offset = self.offsetForDrawingAtPos(point)
    let size = self.size
    
    let rect = CGRect(x: point.x + offset.x, y: point.y + offset.y, width: size.width, height: size.height)
    
    UIGraphicsPushContext(context)
    image!.drawInRect(rect)
    UIGraphicsPopContext()
}

BalloonMarker.swift

public class BalloonMarker: ChartMarker
{
   public var color: UIColor?
   public var arrowSize = CGSize(width: 15, height: 11)
   public var font: UIFont?
   public var insets = UIEdgeInsets()
   public var minimumSize = CGSize()

private var labelns: NSString?
private var _labelSize: CGSize = CGSize()
private var _size: CGSize = CGSize()
private var _paragraphStyle: NSMutableParagraphStyle?
private var _drawAttributes = [String : AnyObject]()

public init(color: UIColor, font: UIFont, insets: UIEdgeInsets)
{
    super.init()
    
    self.color = color
    self.font = font
    self.insets = insets
    
    _paragraphStyle = NSParagraphStyle.defaultParagraphStyle().mutableCopy() as? NSMutableParagraphStyle
    _paragraphStyle?.alignment = .Center
}

public override var size: CGSize { return _size; }

public override func draw(context context: CGContext, point: CGPoint, viewPortHandler: ChartViewPortHandler)
{
    if (labelns == nil)
    {
        return
    }
    
    //var rect = CGRect(origin: point, size: _size)
    let offset = self.offsetForDrawingAtPos(point)
    var rect = CGRect(
                    origin: CGPoint(
                        x: point.x + offset.x,
                        y: point.y + offset.y),
                    size: _size)
    
    rect.origin.x -= _size.width / 2.0
    rect.origin.y -= _size.height
    
    let balloonEnd = rect.origin.x + rect.size.width
    var setArrowPosition = CGFloat(0.0)
    
    if balloonEnd > chartViewSize.width
    {
        rect.origin.x -= (balloonEnd - viewPortHandler.chartWidth)
        setArrowPosition = (balloonEnd - viewPortHandler.chartWidth)
    }
    else if rect.origin.x < 0
    {
        setArrowPosition = rect.origin.x
        rect.origin.x = 0
    }

    CGContextSaveGState(context)
    
    CGContextSetFillColorWithColor(context, (color?.CGColor)!)
    CGContextBeginPath(context)
    
    CGContextMoveToPoint(context,
        rect.origin.x,
        rect.origin.y)
    
    CGContextAddLineToPoint(context,
        rect.origin.x + rect.size.width,
        rect.origin.y)
    
    CGContextAddLineToPoint(context,
        rect.origin.x + rect.size.width,
        rect.origin.y + rect.size.height - arrowSize.height)
    
    CGContextAddLineToPoint(context,
        rect.origin.x + setArrowPosition + (rect.size.width + arrowSize.width) / 2.0,
        rect.origin.y + rect.size.height - arrowSize.height)
    
    CGContextAddLineToPoint(context,
        (rect.origin.x) + setArrowPosition + rect.size.width / 2.0,
        rect.origin.y + rect.size.height)
    
    CGContextAddLineToPoint(context,
        (rect.origin.x + setArrowPosition) + (rect.size.width - arrowSize.width) / 2.0,
        rect.origin.y + rect.size.height - arrowSize.height)
    
    CGContextAddLineToPoint(context,
        rect.origin.x,
        rect.origin.y + rect.size.height - arrowSize.height)
    
    CGContextAddLineToPoint(context,
        rect.origin.x,
        rect.origin.y)
    CGContextFillPath(context)
    
    rect.origin.y += self.insets.top
    rect.size.height -= self.insets.top + self.insets.bottom
    
    
    UIGraphicsPushContext(context)
    
    labelns?.drawInRect(rect, withAttributes: _drawAttributes)
    
    UIGraphicsPopContext()
    
    CGContextRestoreGState(context)
}

public override func refreshContent(entry entry: ChartDataEntry, highlight: ChartHighlight)
{
    let label = (entry.valueLabel.isEmpty) ? entry.value.description : entry.valueLabel
    labelns = label as NSString
    
    _drawAttributes.removeAll()
    _drawAttributes[NSFontAttributeName] = self.font
    _drawAttributes[NSParagraphStyleAttributeName] = _paragraphStyle
    
    _labelSize = labelns?.sizeWithAttributes(_drawAttributes) ?? CGSizeZero
    _size.width = _labelSize.width + self.insets.left + self.insets.right
    _size.height = _labelSize.height + self.insets.top + self.insets.bottom
    _size.width = max(minimumSize.width, _size.width)
    _size.height = max(minimumSize.height, _size.height)
}

ChartViewBase.swift

internal func drawMarkers(context context: CGContext)
    {
    // if there is no marker view or drawing marker is disabled
    if (marker === nil || !drawMarkers || !valuesToHighlight())
    {
        return
    }

    for (var i = 0, count = _indicesToHighlight.count; i < count; i++)
    {
        let highlight = _indicesToHighlight[i]
        let xIndex = highlight.xIndex

        if (xIndex <= Int(_deltaX) && xIndex <= Int(_deltaX * _animator.phaseX))
        {
            let e = _data.getEntryForHighlight(highlight)
            
            if (e === nil || e!.xIndex != highlight.xIndex)
            {
                continue
            }
            
            let pos = getMarkerPosition(entry: e!, highlight: highlight)

            // check bounds
            if (!_viewPortHandler.isInBounds(x: pos.x, y: pos.y))
            {
                continue
            }

            // callbacks to update the content
            marker!.refreshContent(entry: e!, highlight: highlight)

            let markerSize = marker!.size
            if (pos.y - markerSize.height <= 0.0)
            {
                let y = markerSize.height - pos.y
                marker!.draw(context: context, point: CGPoint(x: pos.x, y: pos.y + y), viewPortHandler: _viewPortHandler)
            }
            else
            {
                marker!.draw(context: context, point: pos, viewPortHandler: _viewPortHandler)
            }
        }
    }
}

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

5 participants