ios-charts Charts for Swift - purposely bleed/overflow chart bars - swift

I'm using a Bar Chart that I'm trying to make look like a design. The design's bars overflow a bit at the bottom and have a transparency gradient on them. I can't find any property that you can use for this and I guess I'll have to override somewhere. I've also tried to draw layers on top of the graph at the bars positions/bounds without success.
I tried overriding the BarChartRenderer and change the Y-positions, but since the graph is supposed to be "scrollable" by default it clips the bar.
I've already disabled the scrolling/moving/zooming functions because I don't need them:
doubleTapToZoomEnabled = false
highlightPerDragEnabled = false
highlightPerTapEnabled = false
clipValuesToContentEnabled = false

You can set the minimum axis value so that it set the bottom line correct try this code as
barChartView.leftAxis.axisMinimum = __Your minimum bar value__ i.e. 17000 //that is mention in your above graph

Solved it by drawing my own layers over the bars and then remove the old bars because of their anti-aliasing. This way it will be easier to implement the gradient too, and it works because you won't be able to move/scale the chart.
let bottomY = self.contentRect.maxY - leftAxis.gridLineWidth
for (_, bar) in self.barData!.dataSets.enumerated() {
let layer = CALayer(),
barBounds = self.getBarBounds(entry: bar.entryForIndex(0)! as! BarChartDataEntry),
// 30 extra height at bottom
frame = CGRect(x: barBounds.minX, y: barBounds.minY, width: barBounds.width, height: (bottomY - barBounds.minY) + 30)
// Set the new frame size, Z position and background
layer.frame = frame
layer.zPosition = 10
layer.backgroundColor = bar.color(atIndex: 0).cgColor
// Add the new bar layer and remove old bar
self.layer.addSublayer(layer)
bar.clear()
}

Related

Using Swift, how do I animate the .setPosition() method of an NSSplitView without visually stretching its contents?

I would like to animate the appearance of a NSSplitViewItem using .setPosition() using Swift, Cocoa and storyboards. My app allows a student to enter a natural deduction proof. When it is not correct, an 'advice view' appears on the right. When it is correct, this advice view will disappear.
The code I'm using is the below, where the first function makes the 'advice' appear, and the second makes it disappear:
func showAdviceView() {
// Our window
let windowSize = view.window?.frame.size.width
// A CGFloat proportion currently held as a constant
let adviceViewProportion = BKPrefConstants.adviceWindowSize
// Position is window size minus the proportion, since
// origin is top left
let newPosition = windowSize! - (windowSize! * adviceViewProportion)
NSAnimationContext.runAnimationGroup { context in
context.allowsImplicitAnimation = true
context.duration = 0.75
splitView.animator().setPosition(newPosition, ofDividerAt: 1)
}
}
func hideAdviceView() {
let windowSize = view.window?.frame.size.width
let newPosition = windowSize!
NSAnimationContext.runAnimationGroup{ context in
context.allowsImplicitAnimation = true
context.duration = 0.75
splitView.animator().setPosition(newPosition, ofDividerAt: 1)
}
}
My problem is that the animation action itself is causing the text in the views to stretch, as you can see in this example: Current behaviour
What I really want is the text itself to maintain all proportions and slide gracefully in the same manner that we see when the user themselves moves the separator: Ideal behaviour (but to be achieved programmatically, not manually)
Thus far in my troubleshooting process, I've tried to animate this outside of NSAnimationContext; played with concurrent drawing and autoresizing of subviews in XCode; and looked generally into Cocoa's animation system (though much of what I've read doesn't seem to have direct application here, but I might well be misunderstanding it). I suspect what's going on is that the .animator() proxy object allows only alpha changes and stretches---redrawing so that text alignment is honoured during the animation might be too non-standard. My feeling is that I need to 'trick' the app into treating the animation as though it's being performed by the user, but I'm not sure how to go about that.
Any tips greatly appreciated...
Cheers

UIprogressview bar using multiple colors based on progress and condition

I am currently working on a quiz based iOS application. I wanted to add a progress bar that changed colors based on if the question was answered correctly or incorrectly. Based on if it was answered correctly or incorrectly, I want only that interval to change to green/red, not the whole bar. I have 50 intervals for the progress bar. Everything I have tried has resulted in the whole bar changing color instead of just the interval. I am pretty new to iOS development still and am struggling to figure this out.
let progress = Progress(totalUnitCount: 50)
challengeProgressBar.progress = 0.0
progress.completedUnitCount = 0
for i in 0..<index {
progress.completedUnitCount += 1
challengeProgressBar.setProgress(Float(self.progress.fractionCompleted), animated: true)
if (selectedAnswer[i] == Answers[i]){
challengeProgressBar.progressTintColor = UIColor.green
} else {
challengeProgressBar.progressTintColor = UIColor.red
}
}
The result I get is the very last color the loop produced. The whole bar is either red or green.
With UIProgressView you can change color only for for filled part of view and color for not filled part.
You need to create custom progress bar by inheriting UIView/UIControl. That way you can achieve needed for you result.

Added subview is positioned slightly off - how can I get it back into place?

UPDATE: Solved! While the contentMode for pianoNoteDisplayed and piano_background were indeed the same, apparently this wasn't true for the added subviews. I simply added the line subview.contentMode = superview.contentMode to the function vdmzz suggested, and now everything looks right on all 4 screen sizes.
There are two image views: one called "piano_background" holds a background image (a piano keyboard) and the other will be used to display highlighted notes. The second is constrained to the first:
(the width constraint is probably unnecessary, because the leading and trailing constraints are already set, right?)
To display multiple highlighted keys, I am programmatically adding subviews to the piano_note view and activating the NSLayoutConstraints to get it into place (otherwise it shows up way out of position) like so:
pianoNoteDisplayed.image = nil
if !notesAlreadyAttempted.contains(currentUserAnswer) {
let wrongNoteImageName = "large_\(currentUserAnswer)_wrong"
let wrongNoteImage = UIImage(named: wrongNoteImageName)
let wrongNoteImageView = UIImageView(image: wrongNoteImage!)
wrongNoteImageView.translatesAutoresizingMaskIntoConstraints = false
pianoNoteDisplayed.addSubview(wrongNoteImageView)
NSLayoutConstraint.activate([
wrongNoteImageView.widthAnchor.constraint(equalToConstant: pianoNoteDisplayed!.frame.width),
wrongNoteImageView.heightAnchor.constraint(equalToConstant: pianoNoteDisplayed!.frame.height)
])
}
notesAlreadyAttempted.append(currentUserAnswer)
}
The issue is that the subview is displayed slightly off, and I can't seem to figure out why:
(as you can see, the highlight looks slightly compressed vertically.. the top lands correctly, but the bottom doesn't reach far enough by about 5px)
I have tried centering and constraining the subview in multiple ways, using suggestions from about 5 different answers on stack, and a few other articles I found. The images I am using (the piano background and the overlaying note highlight subview) are identical sizes. I have tried adding more or fewer constraints in the interface builder, and I have tried adding subviews to the original piano_background view instead of the second pianoNoteDisplayed view - same result. Using the pianoNoteDisplayed view itself to display the highlighted note works fine by the way:
And these are displayed using the usual .image method:
pianoNoteDisplayed.image = UIImage(named: "large_\(currentCorrectAnswer)_right")
Any suggestions for how to troubleshoot the issue further?
First of all, as far as I understood pianoNoteDisplayed doesn't need to be an UIImageView.
Secondly, if you align piano_background and pianoNoteDisplayed by top, leading, trailing and bottom edges, one will be exactly on top of other. Or you could set them equal height, width and center positions.
The problem with your current set of constraints is that piano_background's Y position is determined by Safe Area and therefore might defer from pianoNoteDisplayed's Y position.
Try using this function:
func addSameSize(subview: UIView, onTopOf superview: UIView) {
superview.addSubview(subview)
subview.translatesAutoresizingMaskIntoConstraints = false
subview.centerXAnchor.constraint(equalTo: superview.centerXAnchor).isActive = true
subview.centerYAnchor.constraint(equalTo: superview.centerYAnchor).isActive = true
subview.widthAnchor.constraint(equalTo: superview.widthAnchor).isActive = true
subview.heightAnchor.constraint(equalTo: superview.heightAnchor).isActive = true
subview.contentMode = superview.contentMode
}
E.g.
addSameSize(subview: wrongNoteImageView, onTopOf: pianoNoteDisplayed)
It will add your image views exactly aligned on top of pianoNoteDisplayed view

unable to set background color on iTextSharp signature appearance

Does anyone have any ideas on how to set the background color on the PdfSignatureAppearance rectangle in iTextSharp? I create the PdfSignatureAppearance object and can set its positioning on the page, but the rectangle only has a transparent background. I'm trying to apply a color (any really).
I've tried creating a new iTextSharp.text.Rectangle then setting the rect.BackgroundColor = new BaseColor(System.Drawing.Color.Yellow); That doesn't work. I saw someone else trying to something similar by applying the styles to the layer2 of the signature appearance object. I've tried these with no luck.
PdfTemplate sigAppLayer2 = appearance.GetLayer(2);
sigAppLayer2.SetRGBColorFill(255, 0, 0);
sigAppLayer2.SetGrayFill(2);
sigAppLayer2.BoundingBox.BackgroundColor = new BaseColor(System.Drawing.Color.Yellow);
Anytime I try one of the above styling changes to the layer2 the visible signature disappears on the PDF. If I try applying it to layer 0 or layer 1 then nothing happens. I'm assuming then I'm touching the correct layer (2).
Any ideas? The goal is to just get a background on the signature box vs having it be transparent.
See comment below. I tried this as well setting against layer 2 and layer 0. Both result in a red box, but the signature text is missing.
PdfTemplate sigAppLayer2 = appearance.GetLayer(2);
Rectangle rect = sigAppLayer2.BoundingBox;
PdfTemplate sigAppLayer0 = appearance.GetLayer(0);
sigAppLayer0.SetRGBColorFill(255, 0, 0);
sigAppLayer0.Rectangle(rect.Left, rect.Bottom, rect.Width, rect.Height);
sigAppLayer0.Fill();
You need to draw the rectangle and fill that rectangle with the fill color.
From memory (untested), you need something like this:
PdfTemplate sigAppLayer2 = appearance.GetLayer(2);
Rectangle rect = sigAppLayer2.BoundingBox;
sigAppLayer2.SetRGBColorFill(255, 0, 0);
sigAppLayer2.Rectangle(rect.Left, rect.Bottom, rect.Width, rect.Height);
sigAppLayer2.Fill();
This is the way:
PdfTemplate sigAppLayer2 = appearance.GetLayer(2);
Rectangle rect = sigAppLayer2.BoundingBox;
sigAppLayer2.SetRGBColorFill(255, 0, 0);
sigAppLayer2.Rectangle(rect.Left, rect.Bottom, rect.Width, rect.Height);
sigAppLayer2.Fill();
sigAppLayer2.ResetRGBColorFill();// <--------- you needs this
sigAppLayer2.BeginText() ...etc

Raphael-GWT: fill image of a shape (Rect) appears offset. How to resolve this?

I'm wondering about the behavior of {Shape}.attr("fill","url({image.path})").
when applying a fill image to a shape:
public class AppMapCanvas extends Raphael {
public AppMapCanvas(int width, int height) {
super(width, height);
this.hCenter = width / 2;
this.vCenter = height / 2;
...
Rect rect = this.new Rect(hCenter, vCenter, 144, 40, 4);
rect.attr("fill", "url('../images/app-module-1-bg.png')"); // <--
...
}
}
The background image seem to teal accross the canvas behind the shape, thus gets weird positioning (an illustration snapshot is enclosed - i marked the original image borders in red).
This seem to resolve itself in the presence of an animation along a path (a mere path.M(0,0) is sufficiant).
How can i position the fill-image properly in the first place?
The proper way to do this from what I can understand would be to use an SVG pattern declaration to specify the portion and position of the image you would want to use. Then you would use that pattern to fill the rectangle element. Unfortunately, the Raphael javascript library doesn't have support for patterns... so there's no direct way to use an image to fill a rectangle.