spaceMin and spaceMax in swift Charts not working - swift

I am using charts for linechart and I am trying to add space on the left and right sides of the line.
let xAxis = chtChart.xAxis
xAxis.spaceMax = 0.5
xAxis.spaceMin = 0.5
but space does not add and also chart does not plot at all.
Full xAxis setup is here:
let xAxis = chtChart.xAxis
xAxis.spaceMax = 0.5
xAxis.spaceMin = 0.5
xAxis.labelPosition = .bottom
xAxis.gridLineDashPhase = 0
xAxis.axisLineWidth = CGFloat(2)
xAxis.avoidFirstLastClippingEnabled = true
xAxis.gridColor = UIColor(red: 0.76, green: 0.76, blue: 0.76, alpha: 1.0)
xAxis.gridLineDashLengths = [5, 5]
xAxis.axisLineColor = #colorLiteral(red: 1, green: 0, blue: 0.2392156863, alpha: 1)
xAxis.axisMinimum = 0
xAxis.granularity = 1
xAxis.labelCount = 12
xAxis.valueFormatter = self
xAxis.labelFont = .OpenInter(.regular, size: 10)
xAxis.labelTextColor = UIColor(red: 0.49, green: 0.49, blue: 0.49, alpha: 1.00)
chtChart.animate(xAxisDuration: 3.0, yAxisDuration: 3.0)
what am I missing here?
graph shown in image is plot after removing xAxis.spaceMax = 0.5 ,xAxis.spaceMin = 0.5

Related

How to make an animation shadowOffset in Swift?

I wrote the code but I can not understand why it does not work...
func animate(vc: UIView) {
vc.layer.shadowColor = #colorLiteral(red: 0.9254902005, green: 0.2352941185, blue: 0.1019607857, alpha: 1)
vc.layer.shadowRadius = 5
vc.layer.shadowOffset = CGSize(width: 0, height: 0)
let animationX = CABasicAnimation()
animationX.keyPath = "shadowOffset"
animationX.fromValue = vc.layer.shadowOffset
animationX.toValue = CGSize(width: 10, height: 10)
animationX.duration = 1
vc.layer.add(animationX, forKey: animationX.keyPath)
}
#IBAction func buttonTapped(_ sender: UIButton) {
animate(vc: sender)
}
Does anyone know how this works?
Couple of things missing
shadowPath
shadowOpacity
vc.layer.masksToBounds = false
vc.layer.shadowColor = #colorLiteral(red: 0.9254902005, green: 0.2352941185, blue: 0.1019607857, alpha: 1)
vc.layer.shadowRadius = 5
vc.layer.shadowOffset = CGSize(width: 0, height: 0)
vc.layer.shadowPath = UIBezierPath(rect: vc.bounds).cgPath
vc.layer.shadowOpacity = 1.0
let animationX = CABasicAnimation()
animationX.keyPath = "shadowOffset"
animationX.fromValue = vc.layer.shadowOffset
animationX.toValue = CGSize(width: 10, height: 10)
animationX.duration = 1
vc.layer.add(animationX, forKey: animationX.keyPath)
By default shadowOpacity is 0.
Final O/P
EDIT:
If you want shadow to persist in its position even after animation specify
fillMode
isRemovedOnCompletion
final code will look like
func animate(vc: UIView) {
vc.layer.masksToBounds = false
vc.layer.shadowColor = #colorLiteral(red: 0.9254902005, green: 0.2352941185, blue: 0.1019607857, alpha: 1)
vc.layer.shadowRadius = 5
vc.layer.shadowOffset = CGSize(width: 0, height: 0)
vc.layer.shadowPath = UIBezierPath(rect: vc.bounds).cgPath
vc.layer.shadowOpacity = 1.0
let animationX = CABasicAnimation()
animationX.keyPath = "shadowOffset"
animationX.fromValue = vc.layer.shadowOffset
animationX.toValue = CGSize(width: 10, height: 10)
animationX.duration = 1
animationX.fillMode = .forwards
animationX.isRemovedOnCompletion = false
vc.layer.add(animationX, forKey: animationX.keyPath)
}
Final O/P looks like:

Can i use 'for' loop on this?

I'm wondering if i may use 'for' loop for this code. Please forgive me, I know that is kind of a lame question, but I'm new to swift. Hope that you can help me here, guys!
Thanks a lot everyone!
Code:
override func viewDidLoad() {
super.viewDidLoad()
// Background color
let kolorTla = UIColor(red: 0/255.0, green: 66/255.0, blue: 132/255.0, alpha: 1.0)
view.backgroundColor = kolorTla
// Icons border
ramka.layer.borderColor = UIColor(red: 255, green: 255, blue: 255, alpha: 1.0).cgColor
ramka.layer.cornerRadius = 5.0
ramka.layer.borderWidth = 3
// Image
skill1.image = UIImage(named: "english")
// Image border
skill1.layer.borderColor = UIColor(red: 255, green: 255, blue: 255, alpha: 1.0).cgColor
skill1.layer.cornerRadius = 5.0
skill1.layer.borderWidth = 3
skill1.contentMode = .scaleAspectFit
// Image
skill2.image = UIImage(named: "literature")
// Image border
skill2.layer.borderColor = UIColor(red: 255, green: 255, blue: 255, alpha: 1.0).cgColor
skill2.layer.cornerRadius = 5.0
skill2.layer.borderWidth = 3
skill2.contentMode = .scaleAspectFit
// Image
skill3.image = UIImage(named: "idea1")
// Image border
skill3.layer.borderColor = UIColor(red: 255, green: 255, blue: 255, alpha: 1.0).cgColor
skill3.layer.cornerRadius = 5.0
skill3.layer.borderWidth = 3
skill3.contentMode = .scaleAspectFit
You can to some extent. You would just need to define an array of your items and loop over them. Not sure if it saves you much code wise but does make it a little more understandable.
override func viewDidLoad() {
super.viewDidLoad()
// Background color
let kolorTla = UIColor(red: 0/255.0, green: 66/255.0, blue: 132/255.0, alpha: 1.0)
view.backgroundColor = kolorTla
// Icons border
ramka.layer.borderColor = UIColor(red: 255, green: 255, blue: 255, alpha: 1.0).cgColor
ramka.layer.cornerRadius = 5.0
ramka.layer.borderWidth = 3
// Set Image
skill1.image = UIImage(named: "english")
skill2.image = UIImage(named: "literature")
skill3.image = UIImage(named: "idea1")
// Set Image border
for skill in [skill1, skill2, skill3] {
skill.layer.borderColor = UIColor(red: 255, green: 255, blue: 255, alpha: 1.0).cgColor
skill.layer.cornerRadius = 5.0
skill.layer.borderWidth = 3
skill.contentMode = .scaleAspectFit
}
}
Better approach at least in my opinion would be to create a simple function to handle this instead.
override func viewDidLoad() {
super.viewDidLoad()
// Background color
let kolorTla = UIColor(red: 0/255.0, green: 66/255.0, blue: 132/255.0, alpha: 1.0)
view.backgroundColor = kolorTla
// Icons border
ramka.layer.borderColor = UIColor(red: 255, green: 255, blue: 255, alpha: 1.0).cgColor
ramka.layer.cornerRadius = 5.0
ramka.layer.borderWidth = 3
// Set Images
setupImageView(imageView: skill1, imageName: "english")
setupImageView(imageView: skill2, imageName: "literature")
setupImageView(imageView: skill3, imageName: "idea1")
}
func setupImageView(imageView: UIImageView, imageName: String) {
// Set Image
imageView.image = UIImage(named: imageName)
// Set Image border
imageView.layer.borderColor = UIColor(red: 255, green: 255, blue: 255, alpha: 1.0).cgColor
imageView.layer.cornerRadius = 5.0
imageView.layer.borderWidth = 3
imageView.contentMode = .scaleAspectFit
}
While you're not able to use a for loop to modify the variable names and loop through them, you could put your skill instances in an array and loop through them that way.
...
skill1.image = UIImage(named: "english")
skill2.image = UIImage(named: "literature")
skill3.image = UIImage(named: "idea1")
let skills = [skill1, skill2, skill3]
for skill in skills {
skill.layer.borderColor = UIColor(red: 255, green: 255, blue: 255, alpha: 1.0).cgColor
skill.layer.cornerRadius = 5.0
skill.layer.borderWidth = 3
skill.contentMode = .scaleAspectFit
}
Yes, you can. Place skill1,skill2, and skill3 in an array and iterate over it like this:
var objectArray = [skill1,skill2,skill3]
for object in objectArray
{
object.layer = ....
}
You could just extend your ImageView
extension UIImageView {
func addCustomLayer() { // add arguments to function if you wish to change the value assigned
self.layer.borderColor = UIColor(red: 255, green: 255, blue: 255, alpha: 1.0).cgColor
self.layer.cornerRadius = 5.0
self.layer.borderWidth = 3
self.contentMode = .scaleAspectFit
}
}
}
Then you call that method on each UIImageView
for each in [skill1, skill2, skill3] {
each.addCustomLayer()
}

Cannot change color of SCNCone - Scenekit

I have an 'attach node' that has 2 child nodes that are Blender models. I have added a third node to this attach node that is a SCNCone. For some reason, I can't change the color of the cone node, only the transparency. I can't seem to see anything wrong with the code, but during runtime the cone is always a black color no matter what color I set it to.
let coneGeo = SCNCone(topRadius: 0.1, bottomRadius: 0.7, height: 4)
let coneMaterial = SCNMaterial()
coneMaterial.diffuse.contents = UIColor(red: 255.0/255.0, green: 108.0/255.0, blue: 91.0/255.0, alpha: 0.2)
coneGeo.materials = [coneMaterial]
let coneNode = SCNNode(geometry: coneGeo)
coneNode.position = SCNVector3(0, -1.5, 0)
coneNode.name = "coneNode"
AttachNode.addChildNode(coneNode)
Replace coneMaterial.diffuse.contents = UIColor(red: 255.0/255.0, green: 108.0/255.0, blue: 91.0/255.0, alpha: 0.2) with coneGeo.geometry?.firstMaterial?.diffuse.contents.diffuse.contents = UIColor(red: 255.0/255.0, green: 108.0/255.0, blue: 91.0/255.0, alpha: 0.2). Instead of changing the cone's material color without geometry, you have to access it's material color through it's geometry parameter.
coneGeo.materials = [coneMaterial]
This will also work. I tested your code by adding the cone node to an empty scene.
I just get a black screen.
But if I change the alpha value to say 0.5, this is what I get.
The code.
override func viewDidLoad()
{
super.viewDidLoad()
// create a new scene
let scene = SCNScene()
let coneGeo = SCNCone(topRadius: 0.1, bottomRadius: 0.7, height: 4)
let coneMaterial = SCNMaterial()
coneMaterial.diffuse.contents = UIColor(red: 255.0 / 255.0,
green: 108.0 / 255.0,
blue: 91.0 / 255.0, alpha: 0.5)
coneGeo.materials = [coneMaterial]
let coneNode = SCNNode(geometry
: coneGeo)
coneNode.position = SCNVector3(0, -1.5, 0)
coneNode.name = "coneNode"
scene.rootNode.addChildNode(coneNode)
// retrieve the SCNView
let scnView = self.view as! SCNView
// set the scene to the view
scnView.scene = scene
// allows the user to manipulate the camera
scnView.allowsCameraControl = true
// show statistics such as fps and timing information
scnView.showsStatistics = true
// configure the view
scnView.backgroundColor = UIColor.black
}
So I would say, check your alpha value in UIColor(red: 255.0/255.0, green: 108.0/255.0, blue: 91.0/255.0, alpha: 0.2)

Matching node.fillColor (SKShapeNode)

I have 25 circles on screen each with a random colour that has been generated from the declared colours and each names 'CIRCLE_1', 'CIRCLE_2' etc.
When matching the node.fillColor with the pre-defined colours, only the Yellow returns a value. Everything else remains at 0.
Can't see what I'm doing wrong/missing.
let SDRed = SKColor(red: 255/255, green: 61/255, blue: 61/255, alpha: 1.0)
let SDBlue = SKColor(red: 0/255, green: 175/255, blue: 255/255, alpha: 1.0)
let SDYellow = SKColor(red: 255/255, green: 255/255, blue: 0/255, alpha: 1.0)
let SDOrange = SKColor(red: 255/255, green: 128/255, blue: 0/255, alpha: 1.0)
let SDPink = SKColor(red: 255/255, green: 105/255, blue: 180/255, alpha: 1.0)
let SDGreen = SKColor(red: 144/255, green: 238/255, blue: 144/255, alpha: 1.0)
let SDDodgerBlue = SKColor(red: 30/255, green: 144/255, blue: 255/255, alpha: 1.0)
func checkAllColoursAvailable() -> Bool {
var yellow = 0
var blue = 0
var pink = 0
var green = 0
var red = 0
var orange = 0
enumerateChildNodes(withName: "CIRCLE_*", using:
{ (node, stop) -> Void in
print((node as! SKShapeNode).name!)
let col: SKColor = (node as! SKShapeNode).fillColor
if col == SDYellow {
yellow = yellow + 1
} else if col == SDGreen {
green = green + 1
} else if col == SDDodgerBlue {
blue = blue + 1
} else if col == SDOrange {
orange = orange + 1
} else if col == SDRed {
red = red + 1
} else if col == SDPink {
pink = pink + 1
}
})
if yellow >= 1 && blue >= 1 && green >= 1 && orange >= 1 && red >= 1 && pink >= 1 {
return true
} else {
return false
}
}

Does the legend limit the number of titles?

I am using iso-charts to try and draw a pie chart in an iOS app.
No matter what I try, I can't seem to get the full number of titles to draw in the legend.
I have my data set up as:
ages = ["18-", "25-", "35-", "45-", "55-", "65-", "75+"]
agePercentages = [10.0, 20.0, 30.0, 5.0, 10.0, 45.0, 120.0]
My code to setup the pieChart as:
func setPieDefaults(myPieChart: PieChartView) -> PieChartView {
myPieChart.frame = CGRectMake(0, 0, UIScreen.mainScreen().bounds.size.width, UIScreen.mainScreen().bounds.size.width*0.5)
myPieChart.usePercentValuesEnabled = true
myPieChart.holeTransparent = true
myPieChart.holeColor = UIColor.darkPurpleColor()
myPieChart.backgroundColor = UIColor.darkPurpleColor()
myPieChart.rotationAngle = 0.0
myPieChart.rotationEnabled = true
myPieChart.centerTextFont = UIFont(name: "HelveticaNeue-Bold", size:20)!
myPieChart.descriptionText = ""
myPieChart.centerText = "%"
myPieChart.centerTextColor = UIColor.whiteColor()
myPieChart.drawHoleEnabled = true
myPieChart.noDataText = "Loading Data ..."
let legend = myPieChart.legend
legend.font = UIFont(name: "Arial", size: 11)!
legend.textColor = UIColor.whiteColor()
legend.position = .RightOfChart
legend.form = .Circle
return myPieChart
}
And ..
func setChart(dataPoints: [String], values: [Double], myPieView: PieChartView) {
var dataEntries: [ChartDataEntry] = []
for i in 0..<dataPoints.count {
let dataEntry = ChartDataEntry(value: values[i], xIndex: i)
dataEntries.append(dataEntry)
}
var colors = [UIColor]()
switch myPieView {
case genderPieChartView:
colors = [UIColor.blueColor(), UIColor.pinkColor()]
default:
colors = ChartColorTemplates.colorful()
}
let pieChartDataSet = PieChartDataSet(yVals: dataEntries, label: nil)
pieChartDataSet.sliceSpace = 3.0
pieChartDataSet.colors = colors
let pieChartData = PieChartData(xVals: dataPoints, dataSet: pieChartDataSet)
myPieView.animate(xAxisDuration: 2, yAxisDuration: 2)
let pFormatter = NSNumberFormatter()
pFormatter.numberStyle = .PercentStyle
pFormatter.maximumFractionDigits = 0
pFormatter.percentSymbol = ""
pFormatter.multiplier = 1
pieChartData.setValueFormatter(pFormatter)
pieChartData.setValueFont(UIFont(name: "HelveticaNeue-Bold", size: 11)!)
pieChartData.setValueTextColor(UIColor.whiteColor())
myPieView.data = pieChartData
myPieView.drawSliceTextEnabled = false
}
But it won't print any more than 5 of the labels. It's returning the pie-slices perfectly. But not the labels in the legend.
Am I doing something wrong? Thanks in advance for letting me know.
Solved.
In reading the framework docs for the Android version a little better:
The number of entries the automatically generated legend contains
depends on the number of different colors (across all DataSet objects)
as well as on the DataSet labels. The labels of the Legend depend on
the labels set for the used DataSet objects in the chart. If no labels
for the DataSet objects have been specified, the chart will
automatically generate them. If multiple colors are used for one
DataSet, those colors are grouped and only described by one label.
I realised I needed to increase the number of colours in the ChartColorTemplate.colorful() definition to match the number of labels I was trying to use. The current example code comes with only 5 colours defined.
public class func colorful () -> [UIColor]
{
return [
UIColor(red: 193/255.0, green: 37/255.0, blue: 82/255.0, alpha: 1.0),
UIColor(red: 255/255.0, green: 102/255.0, blue: 0/255.0, alpha: 1.0),
UIColor(red: 245/255.0, green: 199/255.0, blue: 0/255.0, alpha: 1.0),
UIColor(red: 106/255.0, green: 150/255.0, blue: 31/255.0, alpha: 1.0),
UIColor(red: 179/255.0, green: 100/255.0, blue: 53/255.0, alpha: 1.0),
UIColor(red: 200/255.0, green: 100/255.0, blue: 53/255.0, alpha: 1.0), // added colour
UIColor(red: 150/255.0, green: 150/255.0, blue: 70/255.0, alpha: 1.0), // added colour
UIColor(red: 84/255.0, green: 78/255.0, blue: 53/255.0, alpha: 1.0), // added colour
]
}
If you have the same problem, then define a lot more colours to meet the needs of the maximum number of labels needed. This will also solve a problem if you try and word-wrap the legend (which I was also facing).