     let xConnector: Connector
     let yConnector: Connector
     
+    let gridLineView: GridLineView
+    let functionLayer: CAShapeLayer
+    let selectedPointLayer: CAShapeLayer
+    
     init(xConnector: Connector, yConnector: Connector) {
         self.xConnector = xConnector
         self.yConnector = yConnector
         
+        gridLineView = GridLineView(frame: CGRect.zero)
+        functionLayer = CAShapeLayer()
+        selectedPointLayer = CAShapeLayer()
+        
         super.init(frame: CGRect.zero)
+        
+        self.addSubview(gridLineView)
+        gridLineView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
+        
+        functionLayer.strokeColor = GraphToy.yColor.cgColor
+        functionLayer.fillColor = nil
+        functionLayer.lineCap = "round"
+        functionLayer.lineWidth = 4
+        self.layer.addSublayer(functionLayer)
+        
+        selectedPointLayer.fillColor = GraphToy.xColor.cgColor
+        self.layer.addSublayer(selectedPointLayer)
+        
+        self.clipsToBounds = true
     }
     
     required init(coder aDecoder: NSCoder) {

        
        stroke(path: minorAxisPaths, width: minorAxisWidth, color: minorAxisColor)
        stroke(path: majorAxisPaths, width: majorAxisWidth, color: majorAxisColor)
        
        // Draw the function line
        if let functionLine = self.functionLine {
            context.saveGState()
            
            context.concatenate(graphingToDrawing)
            context.addPath(functionLine)
            
            context.setLineWidth(functionLineWidth * scale)
            context.setLineCap(.round)
            context.setStrokeColor(functionLineColor)
            context.strokePath()
            
            context.restoreGState()
        }
        
        // Draw the dot for the current X and Y values
        if let selectedX = selectedX, let selectedY = selectedY {
            let drawingPoint = CGPoint(x: selectedX, y: selectedY).applying(graphingToDrawing)

            let clampedY = drawingPoint.y.clamp(lower: self.bounds.minY, upper: self.bounds.maxY)
            
            let ellipseRect = CGRect(x: drawingPoint.x, y: clampedY, width: 0, height: 0).insetBy(dx: -selectedPointRadius, dy: -selectedPointRadius)
            
            context.addEllipse(in: ellipseRect)
            context.setFillColor(GraphToy.xColor.cgColor)
            context.fillPath()
        }
    }
    
    
    var functionLine: CGMutablePath? = nil
    func update(currentStates: [Connector: ConnectorState], resolver: InputResolver) {
        
        let drawingToGraphing = transformFromDrawingToGraphing()
        var lastPoint: CGPoint?
        let functionLine = CGMutablePath()
        self.functionLine = nil
        
        // For each X in our bounds, figure out the Y and add the resulting graphPoint to the line
        let xVariable = "x"
        let resolvedContext = resolver([self.xConnector: 5], [self.xConnector: xVariable])
        guard let yExpression = resolvedContext.connectorValues[self.yConnector]?.Expression else {
            return
        }
        
        for drawingX in 0...Int(self.bounds.size.width) {
            let graphX = CGPoint(x: drawingX, y: 0).applying(drawingToGraphing).x
            
            var graphYNumber: NSNumber?
            graphYNumber = try? resolvedContext.mathEvaluator.evaluateExpression(yExpression, withSubstitutions:
                [ xVariable : constantExpression(number: Double(graphX)) ])
            
            guard let graphY = graphYNumber as? Double, graphY.isFinite else {
                lastPoint = nil
                continue
            }

            let newPoint = CGPoint(x: graphX, y: CGFloat(graphY))
            if lastPoint == nil {
                functionLine.move(to: newPoint)
            } else {
                functionLine.addLine(to: newPoint)
            }
            lastPoint = newPoint
        }
        self.functionLine = functionLine
        self.setNeedsDisplay()
    }
    
    func valuesForTap(at point: CGPoint) -> [Connector: Double] {
        let poinInside = point - self.frame.origin
        let graphPoint = poinInside.applying(transformFromDrawingToGraphing())
        
        return [xConnector: Double(graphPoint.x)]
    }
    
    func contains(_ point: CGPoint) -> Bool {
        return self.frame.contains(point)
    }
}

        let drawingToGraphing = transformFromDrawingToGraphing()
        let graphingToDrawing = drawingToGraphing.inverted()
        
        let topLeft = CGPoint.zero.applying(drawingToGraphing)
        let maxX = self.bounds.maxX
        let maxY = self.bounds.maxY
