Different ways of loading a d3js data

Different ways of loading a d3js data

Created By:Debasis Das (May 2016)

In this article we will discuss the different ways of loading a d3js data.

In the post we will load a d3 chart’s data from json, csv, tsv and from a local variable.

We will load a simple column chart with data sourced from different types.

d3js csv tsv json 2 d3js csv tsv json 1

Approach 1 – Loading D3 from CSV (Comma separated value)

http://www.knowstack.com/webtech/d3jsData/d3fromCsv.html

<!DOCTYPE html>
<meta charset="utf-8">
<head>
<link rel="stylesheet" type="text/css" href="css/barchart.css">
</head>
<body>
<script src="js/d3.v3.min.js"></script>
<script src="js/d3.tip.v0.6.3.js"></script>
<script>

var margin = {top: 40, right: 20, bottom: 30, left: 70},
    width = 460 - margin.left - margin.right,
    height = 500 - margin.top - margin.bottom;

var x = d3.scale.ordinal()
    .rangeRoundBands([0, width], .1);

var y = d3.scale.linear()
    .range([height, 0]);

var xAxis = d3.svg.axis()
    .scale(x)
    .orient("bottom");

var yAxis = d3.svg.axis()
    .scale(y)
    .orient("left")
    .ticks(10, "");

var tip = d3.tip()
  .attr('class', 'd3-tip')
  .offset([-10, 0])
  .html(function(d) {
    return "<strong>Salary:</strong> <span style='color:red'>" + d.Salary + "</span>";
  })
var svg = d3.select("body").append("svg")
    .attr("width", width + margin.left + margin.right)
    .attr("height", height + margin.top + margin.bottom)
  .append("g")
    .attr("transform", "translate(" + margin.left + "," + margin.top + ")");

svg.call(tip);

d3.csv("data/employeeSalary.csv", type, function(error, data) {
  if (error) throw error;

  x.domain(data.map(function(d) { return d.Employee; }));
  y.domain([0, d3.max(data, function(d) { return d.Salary; })]);

  svg.append("g")
      .attr("class", "x axis")
      .attr("transform", "translate(0," + height + ")")
      .call(xAxis);

  svg.append("g")
      .attr("class", "y axis")
      .call(yAxis)
    .append("text")
      .attr("transform", "rotate(-90)")
      .attr("y", -36)
      .attr("dy", ".71em")
      .style("text-anchor", "end")
      .text("Salary");

  svg.selectAll(".bar")
      .data(data)
    .enter().append("rect")
      .attr("class", "bar")
      .attr("x", function(d) { return x(d.Employee); })
      .attr("width", x.rangeBand())
      .attr("y", function(d) { return y(d.Salary); })
      .attr("height", function(d) { return height - y(d.Salary); })
      .on('mouseover', tip.show)
      .on('mouseout', tip.hide);
});

function type(d) {
  d.Salary = +d.Salary;
  return d;
}
</script>

Approach 2 – Loading D3 from TSV (Tab separated value)

http://www.knowstack.com/webtech/d3jsData/d3fromTsv.html

<!DOCTYPE html>
<meta charset="utf-8">
<head>
<link rel="stylesheet" type="text/css" href="css/barchart.css">
</head>
<body>
<script src="js/d3.v3.min.js"></script>
<script src="js/d3.tip.v0.6.3.js"></script>
<script>

var margin = {top: 40, right: 20, bottom: 30, left: 70},
    width = 460 - margin.left - margin.right,
    height = 500 - margin.top - margin.bottom;

var x = d3.scale.ordinal()
    .rangeRoundBands([0, width], .1);

var y = d3.scale.linear()
    .range([height, 0]);

var xAxis = d3.svg.axis()
    .scale(x)
    .orient("bottom");

var yAxis = d3.svg.axis()
    .scale(y)
    .orient("left")
    .ticks(10, "");

var tip = d3.tip()
  .attr('class', 'd3-tip')
  .offset([-10, 0])
  .html(function(d) {
    return "<strong>Salary:</strong> <span style='color:red'>" + d.Salary + "</span>";
  })
var svg = d3.select("body").append("svg")
    .attr("width", width + margin.left + margin.right)
    .attr("height", height + margin.top + margin.bottom)
  .append("g")
    .attr("transform", "translate(" + margin.left + "," + margin.top + ")");

svg.call(tip);

d3.tsv("data/employeeSalary.tsv", type, function(error, data) {
  if (error) throw error;

  x.domain(data.map(function(d) { return d.Employee; }));
  y.domain([0, d3.max(data, function(d) { return d.Salary; })]);

  svg.append("g")
      .attr("class", "x axis")
      .attr("transform", "translate(0," + height + ")")
      .call(xAxis);

  svg.append("g")
      .attr("class", "y axis")
      .call(yAxis)
    .append("text")
      .attr("transform", "rotate(-90)")
      .attr("y", -36)
      .attr("dy", ".71em")
      .style("text-anchor", "end")
      .text("Salary");

  svg.selectAll(".bar")
      .data(data)
    .enter().append("rect")
      .attr("class", "bar")
      .attr("x", function(d) { return x(d.Employee); })
      .attr("width", x.rangeBand())
      .attr("y", function(d) { return y(d.Salary); })
      .attr("height", function(d) { return height - y(d.Salary); })
      .on('mouseover', tip.show)
      .on('mouseout', tip.hide);
});

function type(d) {
  d.Salary = +d.Salary;
  return d;
}

</script>
<body>

</body>

Approach 3 – Loading D3 from JSON

http://www.knowstack.com/webtech/d3jsData/d3fromJson.html

<!DOCTYPE html>
<meta charset="utf-8">
<head>
<link rel="stylesheet" type="text/css" href="css/barchart.css">
</head>
<body>
<script src="js/d3.v3.min.js"></script>
<script src="js/d3.tip.v0.6.3.js"></script>
<script>

var margin = {top: 40, right: 20, bottom: 30, left: 70},
    width = 460 - margin.left - margin.right,
    height = 500 - margin.top - margin.bottom;

var x = d3.scale.ordinal()
    .rangeRoundBands([0, width], .1);

var y = d3.scale.linear()
    .range([height, 0]);

var xAxis = d3.svg.axis()
    .scale(x)
    .orient("bottom");

var yAxis = d3.svg.axis()
    .scale(y)
    .orient("left")
    .ticks(10, "");

var tip = d3.tip()
  .attr('class', 'd3-tip')
  .offset([-10, 0])
  .html(function(d) {
    return "<strong>Salary:</strong> <span style='color:red'>" + d.Salary + "</span>";
  })
var svg = d3.select("body").append("svg")
    .attr("width", width + margin.left + margin.right)
    .attr("height", height + margin.top + margin.bottom)
  .append("g")
    .attr("transform", "translate(" + margin.left + "," + margin.top + ")");

svg.call(tip);
d3.json("data/employeeSalary.json", function(error, data) {

  if (error) throw error;

  x.domain(data.map(function(d) { return d.Employee; }));
  y.domain([0, d3.max(data, function(d) { return d.Salary; })]);

  svg.append("g")
      .attr("class", "x axis")
      .attr("transform", "translate(0," + height + ")")
      .call(xAxis);

  svg.append("g")
      .attr("class", "y axis")
      .call(yAxis)
    .append("text")
      .attr("transform", "rotate(-90)")
      .attr("y", -36)
      .attr("dy", ".71em")
      .style("text-anchor", "end")
      .text("Salary");

  svg.selectAll(".bar")
      .data(data)
    .enter().append("rect")
      .attr("class", "bar")
      .attr("x", function(d) { return x(d.Employee); })
      .attr("width", x.rangeBand())
      .attr("y", function(d) { return y(d.Salary); })
      .attr("height", function(d) { return height - y(d.Salary); })
      .on('mouseover', tip.show)
      .on('mouseout', tip.hide);
});

function type(d) {
  d.Salary = +d.Salary;
  return d;
}

</script>

Approach 4 – Loading D3 from a local variable

http://www.knowstack.com/webtech/d3jsData/d3fromInlineData.html

<!DOCTYPE html>
<meta charset="utf-8">
<head>
<link rel="stylesheet" type="text/css" href="css/barchart.css">
</head>
<body>
<script src="js/d3.v3.min.js"></script>
<script src="js/d3.tip.v0.6.3.js"></script>
<script>

var margin = {top: 40, right: 20, bottom: 30, left: 70},
    width = 460 - margin.left - margin.right,
    height = 500 - margin.top - margin.bottom;

var data=[{"Employee":"John Doe","Salary":58},{"Employee":"Jane Doe","Salary":81},{"Employee":"Mary Jane","Salary":39},{"Employee":"Debasis Das","Salary":80},{"Employee":"Nishant Singh","Salary":99}];

var x = d3.scale.ordinal()
    .rangeRoundBands([0, width], .1);

var y = d3.scale.linear()
    .range([height, 0]);

var xAxis = d3.svg.axis()
    .scale(x)
    .orient("bottom");

var yAxis = d3.svg.axis()
    .scale(y)
    .orient("left")
    .ticks(10, "");

var tip = d3.tip()
  .attr('class', 'd3-tip')
  .offset([-10, 0])
  .html(function(d) {
    return "<strong>Salary:</strong> <span style='color:red'>" + d.Salary + "</span>";
  })
var svg = d3.select("body").append("svg")
    .attr("width", width + margin.left + margin.right)
    .attr("height", height + margin.top + margin.bottom)
  .append("g")
    .attr("transform", "translate(" + margin.left + "," + margin.top + ")");

svg.call(tip);



x.domain(data.map(function(d) { return d.Employee; }));
y.domain([0, d3.max(data, function(d) { return d.Salary; })]);

svg.append("g")
  .attr("class", "x axis")
  .attr("transform", "translate(0," + height + ")")
  .call(xAxis);

svg.append("g")
  .attr("class", "y axis")
  .call(yAxis)
.append("text")
  .attr("transform", "rotate(-90)")
  .attr("y", -36)
  .attr("dy", ".71em")
  .style("text-anchor", "end")
  .text("Salary");

svg.selectAll(".bar")
  .data(data)
.enter().append("rect")
  .attr("class", "bar")
  .attr("x", function(d) { return x(d.Employee); })
  .attr("width", x.rangeBand())
  .attr("y", function(d) { return y(d.Salary); })
  .attr("height", function(d) { return height - y(d.Salary); })
  .on('mouseover', tip.show)
  .on('mouseout', tip.hide);


function type(d) {
  d.Salary = +d.Salary;
  return d;
}

</script>

References & further read

https://d3js.org/
https://github.com/d3/d3/wiki/Gallery

Posted in CSS, d3js, HTML5, Web Technology Tagged with: , , , , ,

Swift CAEmitterCell CAEmitterLayer Sample Code

Swift CAEmitterCell Sample Code

Created By: Debasis Das (May 2016)

This post is inspired by the Objective C version of the Fire Demo Application from developer.apple.com and the flow is rewritten in Swift.

https://developer.apple.com/library/mac/samplecode/Fire/Introduction/Intro.html

The output of the program is as follows

Code

//  AppDelegate.swift
//  Swift_CAEmitterCell_Fire
//  Original Objective C Code https://developer.apple.com/library/mac/samplecode/Fire/Introduction/Intro.html
//  Created by Debasis Das on 28/05/16.
//  Copyright © 2016 Knowstack. All rights reserved.

import Cocoa

@NSApplicationMain
class AppDelegate: NSObject, NSApplicationDelegate {

    @IBOutlet weak var window: NSWindow!
    @IBOutlet weak var gasSlider:NSSlider!
    var rootLayer:CALayer = CALayer()
    var fireEmitterLayer:CAEmitterLayer = CAEmitterLayer()
    var smokeEmitterLayer:CAEmitterLayer = CAEmitterLayer()
    @IBOutlet weak var mainView:NSView!

    
    


    func applicationDidFinishLaunching(aNotification: NSNotification) {
        // Insert code here to initialize your application
    }

    func applicationWillTerminate(aNotification: NSNotification) {
        // Insert code here to tear down your application
    }

    override func awakeFromNib() {
        self.rootLayer.bounds = self.mainView.bounds
        let color = CGColorCreateGenericRGB(0.0, 0.0, 0.0, 1.0)
        rootLayer.backgroundColor = color
        
        let fireImage = NSImage(named: "fire")
        let fireImg:CGImageRef = (fireImage?.CGImageForProposedRect(nil, context: nil, hints: nil))!
        
        let smokeImage = NSImage(named: "fire")
        let smokeImg:CGImageRef = (smokeImage?.CGImageForProposedRect(nil, context: nil, hints: nil))!
        
        
        //Create the fire emitter layer
        self.fireEmitterLayer = CAEmitterLayer()
        self.fireEmitterLayer.emitterPosition = CGPointMake(225, 50)
        self.fireEmitterLayer.emitterMode = kCAEmitterLayerOutline
        self.fireEmitterLayer.emitterShape = kCAEmitterLayerLine
        self.fireEmitterLayer.renderMode = kCAEmitterLayerAdditive
        self.fireEmitterLayer.emitterSize = CGSizeMake(0, 0)
        
        //Create the smoke emitter layer
        self.smokeEmitterLayer = CAEmitterLayer()
        self.smokeEmitterLayer.emitterPosition = CGPointMake(225, 50)
        self.smokeEmitterLayer.emitterMode = kCAEmitterLayerPoints
        
        //Create the fire emitter cell
        let fireCell = CAEmitterCell()
        fireCell.emissionLongitude = CGFloat(M_PI);
        fireCell.birthRate = 0;
        fireCell.velocity = 80;
        fireCell.velocityRange = 30;
        fireCell.emissionRange = 1.1;
        fireCell.yAcceleration = 200;
        fireCell.scaleSpeed = 0.3;
        let fireColor = CGColorCreateGenericRGB(0.8, 0.4, 0.2, 0.10)
        fireCell.color = fireColor;
        fireCell.contents = fireImg
        fireCell.name = "fire" //Name the cell so that it can be animated later using keypaths
        
        
        //Add the fire emitter cell to the fire emitter layer
        self.fireEmitterLayer.emitterCells = [fireCell]
        
        //Create the smoke emitter cell
        let smokeCell = CAEmitterCell()
        smokeCell.birthRate = 11
        smokeCell.emissionLongitude = CGFloat(M_PI / 2)
        smokeCell.lifetime = 0
        smokeCell.velocity = 40
        smokeCell.velocityRange = 20
        smokeCell.emissionRange = CGFloat(M_PI / 4)
        smokeCell.spin = 1
        smokeCell.spinRange = 6
        smokeCell.yAcceleration = 160
        smokeCell.contents = smokeImg
        let smokeColor = CGColorCreateGenericRGB(0.2, 0.2, 0.2, 0.10)
        smokeCell.color = smokeColor;
        smokeCell.scale = 0.1
        smokeCell.alphaSpeed = -0.12
        smokeCell.scaleSpeed = 0.7
        smokeCell.name = "smoke" //Name the cell so that it can be animated later using keypaths
        
        //Add the smoke emitter cell to the smoke emitter layer
        self.smokeEmitterLayer.emitterCells = [smokeCell]
        
        //Add the two emitter layers to the root layer
        rootLayer.addSublayer(self.smokeEmitterLayer)
        rootLayer.addSublayer(self.fireEmitterLayer)
        
        
        self.mainView.layer = rootLayer
        self.mainView.wantsLayer = true
        self.mainView.needsDisplay = true
        
        self.sliderChanged(self)

    }
    
    @IBAction func sliderChanged(sender:AnyObject){
        let gas:Float = Float((self.gasSlider.intValue)/100)
        let birthRt:NSNumber = gas * 1000
        let gasRange:NSNumber = gas * 0.35
        let gasNum:NSNumber = gas
        self.fireEmitterLayer.setValue(birthRt, forKeyPath: "emitterCells.fire.birthRate")
        self.fireEmitterLayer.setValue(gasNum, forKeyPath: "emitterCells.fire.lifetime")
        self.fireEmitterLayer.setValue(gasRange, forKeyPath: "emitterCells.fire.lifetimeRange")
        self.fireEmitterLayer.emitterSize = CGSizeMake(CGFloat(50 * gas), 0)
        
        let smokeNum:NSNumber = gas * 4
        self.smokeEmitterLayer.setValue(smokeNum, forKeyPath: "emitterCells.smoke.lifetime")
        let color = CGColorCreateGenericRGB(0.2, 0.2, 0.2, CGFloat(gas * 0.1))
        self.smokeEmitterLayer.setValue(color, forKeyPath: "emitterCells.smoke.color")

    }
}


Swift CAEmitterCell CAEmitterLayer 3

Swift CAEmitterCell CAEmitterLayer 3

Swift CAEmitterCell CAEmitterLayer 2

Swift CAEmitterCell CAEmitterLayer 2

Swift CAEmitterCell CAEmitterLayer 1

Swift CAEmitterCell CAEmitterLayer 1

The Code can be downloaded here Swift_CAEmitterCell_Fire

Posted in Swift Tagged with: , , ,

Swift NSSearchField NSTableView Sample Code

Swift NSSearchField NSTableView Sample Code

Created By:Debasis Das (May 2016)

In this post we will discuss the most lengthy way to implement a NSSearchField and tie the same to a NSTableView.

Earlier we have discussed two alternate ways to achieve the same functionality

Approach 1 http://www.knowstack.com/swift-nssearchfield-nstableview-with-bindings/ In this article we had achieved the same functionality using bindings. This approach is the simplest and least amount of coding is required. however things becomes tricky when columns are created dynamically

Approach 2: http://www.knowstack.com/swift-nssearchfield-nsarraycontroller-no-bindings/ In this article we have used an NSArrayController to hold the backup data prior to filtering.

In Approach 3 we will implement everything through code.

//  AppDelegate.swift
//  NSSearchField_NSTableView_Programatically
//  Created by Debasis Das on 27/05/16.
//  Copyright © 2016 Knowstack. All rights reserved.

import Cocoa

@NSApplicationMain
class AppDelegate: NSObject, NSApplicationDelegate, NSTableViewDelegate,NSTableViewDataSource {
//The app delegate is the table view delegate and datasource
    @IBOutlet weak var window: NSWindow!
    @IBOutlet weak var tableView: NSTableView!
    @IBOutlet weak var searchField:NSSearchField!

    var contacts:[Person] = [] //The contacts array
    var backUpContacts:[Person] = [] //The backup array to hold the original list
    
    func applicationDidFinishLaunching(aNotification: NSNotification) {
        // Insert code here to initialize your application
        self.tableView.setDataSource(self)
        self.tableView.setDelegate(self)
        
        for item in self.dataArray(){
            self.contacts.append(item as! Person)
        }
        self.backUpContacts = self.contacts //Creating a backup of the contacts. Ideally the backup list should be populated from the find method that fetches records from a database
        self.tableView.reloadData()
        
        self.createMenuForSearchField()
    }

    func createMenuForSearchField(){
        let menu = NSMenu()
        menu.title = "Menu"
        
        let allMenuItem = NSMenuItem()
        allMenuItem.title = "All"
        allMenuItem.target = self
        allMenuItem.action = #selector(AppDelegate.changeSearchFieldItem(_:))
        
        let fNameMenuItem = NSMenuItem()
        fNameMenuItem.title = "First Name"
        fNameMenuItem.target = self
        fNameMenuItem.action = #selector(AppDelegate.changeSearchFieldItem(_:))
        
        let lNameMenuItem = NSMenuItem()
        lNameMenuItem.title = "Last Name"
        lNameMenuItem.target = self
        lNameMenuItem.action = #selector(AppDelegate.changeSearchFieldItem(_:))

        
        menu.addItem(allMenuItem)
        menu.addItem(fNameMenuItem)
        menu.addItem(lNameMenuItem)
        
        self.searchField.searchMenuTemplate = menu
        self.changeSearchFieldItem(allMenuItem)

    }
    
    func changeSearchFieldItem(sender:AnyObject){
    //Based on the Menu item selection in the search field the placeholder string is set
        (self.searchField.cell as? NSSearchFieldCell)?.placeholderString = sender.title
        
    }
    
    func numberOfRowsInTableView(tableView: NSTableView) -> Int {
        return self.contacts.count
    }
    
    func tableView(tableView: NSTableView, objectValueForTableColumn tableColumn: NSTableColumn?, row: Int) -> AnyObject? {
        let identifier = tableColumn?.identifier
        let str = self.contacts[row].valueForKey(identifier!)
        return str
    }
    
    func tableView(tableView: NSTableView, setObjectValue object: AnyObject?, forTableColumn tableColumn: NSTableColumn?, row: Int) {
        self.contacts[row].setValue(object, forKey: (tableColumn?.identifier)!)
    }
    
    func dataArray()->NSMutableArray{
        let arr = NSMutableArray()
        arr.addObject(Person.createPerson("Debasis", lName: "Das"))
        arr.addObject(Person.createPerson("John", lName: "Doe"))
        arr.addObject(Person.createPerson("Jane", lName: "Doe"))
        return arr
    }

    func applicationWillTerminate(aNotification: NSNotification) {
        // Insert code here to tear down your application
    }

    override func controlTextDidChange(obj: NSNotification) {
        if obj.object === self.searchField{
            
            let searchString = self.searchField.stringValue
            var predicate:NSPredicate = NSPredicate()
            if searchString.isEmpty{
                self.contacts = self.backUpContacts
            }
            else{
                if (self.searchField.cell as? NSSearchFieldCell)?.placeholderString == "All"{
                    predicate = NSPredicate(format: "firstName contains %@ OR lastName contains %@ ",searchString,searchString)
                }
                else if (self.searchField.cell as? NSSearchFieldCell)?.placeholderString == "First Name"{
                predicate = NSPredicate(format: "firstName contains %@",searchString)
                }
                else if (self.searchField.cell as? NSSearchFieldCell)?.placeholderString == "Last Name"{
                    predicate = NSPredicate(format: "lastName contains %@",searchString)
                }
                self.contacts = (self.backUpContacts as NSArray).filteredArrayUsingPredicate(predicate) as! [Person]
            }
            self.tableView.reloadData()
        }
    }


}

class Person:NSObject{
    var firstName:String = ""
    var lastName:String = ""
    
    class func createPerson(fName:String, lName:String)->Person{
        let person = Person()
        person.firstName = fName
        person.lastName = lName
        return person
        
    }
}

Swift NSSearchField NSTableView Sample Code 2

Swift NSSearchField NSTableView Sample Code 1

 

You can download the sample code from NSSearchField_NSTableView_Programatically

Posted in Swift Tagged with: , ,

Swift NSSearchField NSArrayController No Bindings

Swift NSSearchField NSArrayController No Bindings

Created By:Debasis Das (May 2016)

In this post we will create a simple cocoa application to filter the data in a NSTableView using a NSSearchField without using Bindings

The NSArrayController will maintain the backup data in the form of its content and the NSArrayController->arrangedObjects will return the filtered contents.

//  AppDelegate.swift
//  NSSearchField_ArrayController_NoBindings
//  Created by Debasis Das on 26/05/16.
//  Copyright © 2016 Knowstack. All rights reserved.

import Cocoa

@NSApplicationMain
//App Delegate will be the delegate and datasource for the table view
class AppDelegate: NSObject, NSApplicationDelegate,NSTableViewDelegate,NSTableViewDataSource,NSSearchFieldDelegate {

    @IBOutlet weak var window: NSWindow!
    @IBOutlet weak var tableView:NSTableView!
    @IBOutlet weak var searchField:NSSearchField!
   
    var contacts:[Person] = [] //Create an empty Array to hold the person records
    var personArrayController:NSArrayController = NSArrayController()
    
    func applicationDidFinishLaunching(aNotification: NSNotification) {
        self.tableView.setDelegate(self)
        self.tableView.setDataSource(self)
        self.searchField.delegate = self
        
        for item in self.dataArray(){
            self.contacts.append(item as! Person) //Adding person objects to the contacts property
        }

        self.personArrayController.content = contacts //Setting the contents of the array controller as the recently created contacts. 
//Alternatively the array controllers content must be updated from the data fetched from db
        self.tableView.reloadData()

    }

   
    
    override func controlTextDidChange(obj: NSNotification) {
        var searchString = ""
        searchString = ((obj.object as? NSSearchField)?.stringValue)!
        let predicate = NSPredicate(format: "firstName contains %@ OR lastName contains %@ ",searchString,searchString)
        
        if searchString != ""{
            self.personArrayController.filterPredicate = predicate
        }
        else{
            self.personArrayController.filterPredicate = nil
        }
        
        self.tableView.reloadData()
    }

//Table View Delegate and datasource methods
    func numberOfRowsInTableView(tableView: NSTableView) -> Int {
        return self.personArrayController.arrangedObjects.count
    }

    func tableView(tableView: NSTableView, objectValueForTableColumn tableColumn: NSTableColumn?, row: Int) -> AnyObject? {
        if let tColIdentifier = tableColumn?.identifier{
            let str = self.personArrayController.arrangedObjects[row].valueForKey(tColIdentifier)
            return str
        }
        else{
            return ""
        }
        
    }

    func applicationWillTerminate(aNotification: NSNotification) {
        // Insert code here to tear down your application
    }

    func dataArray()->NSMutableArray{
        let arr = NSMutableArray()
        arr.addObject(Person.createPerson("Debasis", lName: "aabb"))
        arr.addObject(Person.createPerson("John", lName: "ccdd"))
        arr.addObject(Person.createPerson("Jane", lName: "eeff"))
        return arr
    }

}


class Person:NSObject{
    var firstName:String = ""
    var lastName:String = ""
    
    class func createPerson(fName:String, lName:String)->Person{
        let person = Person()
        person.firstName = fName
        person.lastName = lName
        return person
        
    }
}

On build and Run
NSSearchField NSTableView NSArrayController No Bindings 1

 

On entering a search query

NSSearchField NSTableView NSArrayController No Bindings 2

Note: The Searches are case sensitive

The working code can be downloaded here NSSearchField_ArrayController_NoBindings

Posted in Cocoa, Swift Tagged with: , ,

Swift NSSearchField NSTableView With Bindings

Swift NSSearchField NSTableView With Bindings

Created By: Debasis Das (may 2016)

In this post we are going to create a simple cocoa application having a NSSearchField and bind the same to a NSTableView Array Controller

Step 1 : Create a new Cocoa Application from the xcode new project templates

NSSearchField NSTableView With Bindings 1

Step 2: Create a new project

NSSearchField NSTableView With Bindings 2

Step 3: Add a NSSearchField and a NSTableView to the window.

The NSTableView instance will be a cell based table view having 2 table columns (First Name, Last Name with identifiers firstName and lastName for the columns)

NSSearchField NSTableView With Bindings 3

Step 4: Create a Person Class that will represent each record in the table view

class Person:NSObject{
    var firstName:String = ""
    var lastName:String = ""
    
    class func createPerson(fName:String, lName:String)->Person{
        let person = Person()
        person.firstName = fName
        person.lastName = lName
        return person
        
    }
}

Step 5: Add a dataArray function in the App Delegate which returns an array of Person Objects

    func dataArray()->NSMutableArray{
        let arr = NSMutableArray()
        arr.addObject(Person.createPerson("Debasis", lName: "Das"))
        arr.addObject(Person.createPerson("John", lName: "ccdd"))
        arr.addObject(Person.createPerson("Jane", lName: "eeff"))
        return arr
    }

Step 5: Add a NSArrayController instance to the xib and bind the contentArray to dataArray function of the App Controller/ Delegate

NSSearchField NSTableView With Bindings 10

 

Step 6: After binding the NSArrayController to the dataArray function, bind the table columns to the ArrayController->arrangedObjects ->keyPaths

NSSearchField NSTableView With Bindings 5

Step 7: Bind the NSSearchField for the search predicate with the Array Controller with controller key as filterPredicate and Predicate Format as “self.firstName contains[cd] $value OR self.lastName contains[cd] $value”

 

NSSearchField NSTableView With Bindings 9

Step 8: Build and Run

 

 

NSSearchField NSTableView With Bindings 6

 

Step 9: Type in different search values in the search field and see the NSSearchField working along with the NSTableView to render only filtered records/Persons

NSSearchField NSTableView With Bindings 8 NSSearchField NSTableView With Bindings 7

You can download the working project here NSSearchField_NSTableView_WithBindings

 

 

Posted in Cocoa, Swift Tagged with: , ,

HTML CSS Horizontal Timeline

HTML CSS Horizontal Timeline

Created By: Debasis Das (May 2016)

For Demo

Indian Prime Minister Horizontal Time line

 

Indian Prime Minister Horizontal Time line 5 Indian Prime Minister Horizontal Time line 4 Indian Prime Minister Horizontal Time line 3 Indian Prime Minister Horizontal Time line 2 Indian Prime Minister Horizontal Time line 1

Posted in CSS, HTML5, Web Technology Tagged with: , , ,

Swift Fractal Tree

Swift Fractal Tree

Created By : Debasis Das (May 2016)

Swift Fractal Tree 1

Swift Fractal Tree 1

Swift Fractal Tree 2

Swift Fractal Tree 2

Swift Fractal Tree 3

Swift Fractal Tree 3

Swift Fractal Tree 4

Swift Fractal Tree 4

Swift Fractal Tree 5

Swift Fractal Tree 5

Swift Fractal Tree 6

Swift Fractal Tree 6

Swift Fractal Tree 7

Swift Fractal Tree 7

Swift Fractal Tree 8

Swift Fractal Tree 8

Swift Fractal Tree 9

Swift Fractal Tree 9

Swift Fractal Tree 10

Swift Fractal Tree 10

Swift Fractal Tree 11

Swift Fractal Tree 11

Swift Fractal Tree 12

Swift Fractal Tree 12

Source Code



//  Swift Fractal Tree
//  Created by Debasis Das on 15/05/16.
//  Copyright © 2016 Knowstack. All rights reserved.

import Cocoa
import Foundation

class Tree: NSView {

    let PI = 3.14156
    var leftAngle:Double = 10
    var rightAngle:Double = 10
    var treeDepth:Float = 10
    var backgroundColor:NSColor = NSColor.whiteColor()
    var leafColor:NSColor = NSColor(calibratedRed: 0, green: 30, blue: 0, alpha: 1.0)
    var trunkColor:NSColor = NSColor.darkGrayColor()
    
    @IBAction func changeDepth(sender:AnyObject){
        self.treeDepth = Float(sender.intValue)
        Swift.print(self.treeDepth)
        self.needsDisplay = true
    }
    
    @IBAction func changeLeftAngle(sender:AnyObject){
        self.leftAngle = sender.doubleValue
        self.needsDisplay = true
    }
    
    @IBAction func changeRightAngle(sender:AnyObject){
        self.rightAngle = sender.doubleValue
        self.needsDisplay = true
    }
    
    @IBAction func changeBackgroundColor(sender:AnyObject){
        self.backgroundColor = ((sender as? NSColorWell)?.color)!
        self.needsDisplay = true
    }
    
    @IBAction func changeLeafColor(sender:AnyObject){
        self.leafColor = ((sender as? NSColorWell)?.color)!
        self.needsDisplay = true
    }
    @IBAction func changeTrunkColor(sender:AnyObject){
        self.trunkColor = ((sender as? NSColorWell)?.color)!
        self.needsDisplay = true
    }
    
    override func drawRect(dirtyRect: NSRect) {
        super.drawRect(dirtyRect)
        self.backgroundColor.setFill()
        NSRectFill(dirtyRect)
        self.drawBranch(Float(self.frame.size.width/2), y1: 100.0, angle: 90.0, depth: self.treeDepth)
    }
    
    func drawBranch(x1:Float, y1:Float, angle:Double,depth:Float){
        var branchArmLength = depth
        if depth > 0 && depth < 3{             branchArmLength = depth * 0.7         }         else if depth > 3 && depth < 7{
            branchArmLength = depth * 0.7
        }
        else{
            branchArmLength = depth*0.7
        }
        if depth != 0{
            let x2 = x1 + (Float(cos(angle * PI/180)) * depth * branchArmLength)
            let y2 = y1 + (Float(sin(angle * PI/180)) * depth * branchArmLength)
            drawLine(depth, fromPoint: NSMakePoint(CGFloat(x1), CGFloat(y1)), toPoint: NSMakePoint(CGFloat(x2), CGFloat(y2)))
            drawBranch(x2, y1: y2, angle: angle - self.leftAngle, depth: depth-1)
            drawBranch(x2, y1: y2, angle: angle + self.rightAngle, depth: depth-1)
        }
    }
    
    func drawLine(lineWidth:Float, fromPoint:NSPoint, toPoint:NSPoint){
        let path = NSBezierPath()
        if (lineWidth < 5){
            self.leafColor.set()
            path.lineWidth = 1.0//CGFloat(lineWidth*0.2)
        }
        else{
            self.trunkColor.set()
            path.lineWidth = 2.0//CGFloat(lineWidth*0.5)
        }
        path.moveToPoint(fromPoint)
        path.lineToPoint(toPoint)
        path.stroke()
    }
}

The Source Code can be downloaded hereSwiftTree

Posted in algorithms, Swift Tagged with: , , , ,

HTML5 Canvas Fractal Tree

HTML5 Canvas Fractal Tree

Created By:Debasis Das (may 2016)

HTML5 Fractal Tree 1

HTML5 Fractal Tree 1

HTML5 Fractal Tree

HTML5 Fractal Tree

HTMl canvas fractal tree

HTMl canvas fractal tree

HTMl canvas fractal tree

HTMl canvas fractal tree

Source code

<html>
<head>
<script type="text/javascript">
	function draw(){
	  var canvas = document.getElementById('canvas');
	  var context = canvas.getContext('2d');
	  context.beginPath();
	  context.rect(0,0,1500,1000);
	  context.fillStyle = "white";
	  context.fill();
	  drawTree(context);
	}
	
	function drawTree(context){
		branch(context, 100, 900, -90, 5);
		branch(context, 200, 900, -90, 8);
		branch(context, 300, 900, -90, 4);
		branch(context, 350, 900, -90, 7);
		branch(context, 500, 900, -90, 10);
		branch(context, 900, 900, -90, 11);
		branch(context, 1200, 900, -90, 13);
	}
	function branch(context, x1, y1, angle, depth){
		var branchArmLength = random(0, 20);
		if (depth != 0){
			var x2 = x1 + (Math.cos(angle*(Math.PI/180.0)) * depth * branchArmLength);
			var y2 = y1 + (Math.sin(angle*(Math.PI/180.0)) * depth * branchArmLength);
			
			line(context, x1, y1, x2, y2, depth);
			branch(context, x2, y2, angle - random(15,20), depth - 1);
			branch(context, x2, y2, angle + random(15,20), depth - 1);
		}
		else{
		
		var x2 = x1 + (Math.cos(angle*(Math.PI/180.0)) * depth * branchArmLength);
		var y2 = y1 + (Math.sin(angle*(Math.PI/180.0)) * depth * branchArmLength);
		context.fillStyle = 'rgb(0,200,0)';
		context.arc(x2, y2, random(0,10), 0, 2 * Math.PI, false);
		context.fill();
		}
	}
	function line(context, x1, y1, x2, y2, thickness){
		context.strokeStyle = "black"		
		context.lineWidth = thickness * 1.5;
		context.beginPath();
		context.moveTo(x1,y1);
		context.lineTo(x2, y2);
		context.closePath();
		context.stroke();
	}
	function random(min, max){
		return min + Math.floor(Math.random()*(max+1-min));
	}
	 
</script>

<style type="text/css">
  canvas { border: 1px solid black; }
</style>

</head>

<body>
  <canvas id="canvas" width="1500" height="1000"></canvas>
  <script type="text/javascript">
  draw();
  </script>
</body>

</html>

More randomness :

function branch(context, x1, y1, angle, depth){
		var branchArmLength = random(0, 20);
                var leafColorArray = ['rgb(204,255,204)','rgb(0,153,0)','rgb(255,255,102)'];
                var randomLeafColor = leafColorArray[random(0,leafColorArray.length-1)];
		if (depth != 0){
			var x2 = x1 + (Math.cos(angle*(Math.PI/180.0)) * depth * branchArmLength);
			var y2 = y1 + (Math.sin(angle*(Math.PI/180.0)) * depth * branchArmLength);
			
			line(context, x1, y1, x2, y2, depth);
			branch(context, x2, y2, angle - random(15,20), depth - 1);
			branch(context, x2, y2, angle + random(15,20), depth - 1);
		}
		else{
		
		var x2 = x1 + (Math.cos(angle*(Math.PI/180.0)) * depth * branchArmLength);
		var y2 = y1 + (Math.sin(angle*(Math.PI/180.0)) * depth * branchArmLength);
                context.fillStyle = randomLeafColor;
		context.arc(x2, y2, random(0,10), 0, 2 * Math.PI, false);
		context.fill();
		}
	}
More Randomness

More Randomness

References

https://en.wikipedia.org/wiki/Fractal_tree_index
http://natureofcode.com/book/chapter-8-fractals/
https://processing.org/tutorials/transform2d/

Posted in algorithms, HTML5 Tagged with: ,

React+Datamaps => Choropleth region map

This post will walk through on how to create a Datamap React component using the Datamap npm module and then use that component to have a region based world map choropleth.

Here we go:

Create a JSX component which encapsulates a Datamaps instance ( var map = new Datamaps() ) and we will use that map instance to update/clear/create the maps behaviour based on the data being passed to the React component.

First install datamaps


npm install datamaps --save-dev

Lets write the function which will create the map in a given dom target:


	drawMap = () =&rt; {
        var map = new Datamaps(Object.assign({}, { // create the instance here
            ...this.props
        }, {
            element: this.refs.container,
            projection: 'mercator',
            responsive: true
        }));

        this.map = map; assign this instance to the react class.
    }

The lets write a React component around this, and we will invoke this function in the componentDidMount and the ComponentDidUpdate life cycle events.


	import React, {PropTypes} from 'react';
	import Datamaps from 'datamaps/dist/datamaps.world.hires.min.js';

	export default class Datamap extends React.Component {

		//defining our expected props which will be directly passed on to the datamaps instance
		static propTypes = {
			arc: React.PropTypes.array,
			arcOptions: React.PropTypes.object,
			bubbleOptions: React.PropTypes.object,
			bubbles: React.PropTypes.array,
			graticule: React.PropTypes.bool,
			labels: React.PropTypes.bool
		};

		constructor(props) {
			super(props);
			window.addEventListener('resize', this.resize);
		}

		resize = () =&rt; {
			if (this.map) {
				this.map.resize();
			}
		}
	
		//this will create the map when the component mounts
		componentDidMount() {
			this.drawMap();
		}

		//this will remove the map from the dom when the react component is unmounted
		componentWillReceiveProps() {
			this.clear();
		}

		//this will update the map with the latest props
		componentDidUpdate() {
			this.drawMap();
		}

		componentWillUnmount() {
			this.clear();
			window.removeEventListener('resize', this.resize);
		}

		clear = () =&rt; {
			const container = this.refs.container;

			for (const child of Array.from(container.childNodes)) {
				container.removeChild(child);
			}
		}

		drawMap = () =&rt; {
			var map = new Datamaps(Object.assign({}, {
				...this.props
			}, {
				element: this.refs.container, // this is the place where the react dom and the Datamaps dom will be wired
				projection: 'mercator', // this is hardcoded here as we want the projection to be constant
				responsive: true
			}));

			this.map = map;
		}

		render() {
			const style = {
				position: 'relative',
				width: '80%',
				height: '60%'
			};

			return <div ref="container" style={style}&rt;</div&rt;;
		}

	}

Now that our Datamaps React component is ready, ets write a container JSX file (MapView.jsx):

This will call invoke our Datamaps react component and will also pass the props into this.
We will add some filters as well to this component which will change the state of the Datamaps by changing the props values.

Here is the render function:


	render() {
        return (
            <div className="App"&rt;
                <div className="App-options"&rt;
                    <RadioGroup name="fruit" selectedValue={this.state.selectedRegion} onChange={this.update}&rt;
                        {Radio =&rt; (
                            <div&rt;
                                <Radio value="AMR"/&rt;AMR
                                <Radio value="APAC"/&rt;APAC
                                <Radio value="EMEA"/&rt;EMEA
                                <Radio value="ALL"/&rt;ALL

                            </div&rt;
                        )}
                    </RadioGroup&rt;

                </div&rt;
                <div className="App-map"&rt;
                    <Datamap {...this.state}/&rt;
                </div&rt;
            </div&rt;
        );
    }

Here is the function which changes the props(in this case state which is passed as the props to Datamaps) based on the filter selection:

	
	update = (region) =&rt; {
		//some data manipulation object to filter the data based on region param
        this.setState(Object.assign({}, {
            data: regionData,
            selectedRegion:region
        }, window.example));
    }

And finally lets add the constructor to this class which will add some initial data to the state so that on page load, the map loads with a unfiltered data set.


	constructor(props) {
        super(props);
        var dataset = {};
        /* 
        logic to populate the dataset, please note that this should be in the following format:
        dataset[iso] = {
                numberOfThings: <numeric value&rt;,
                fillColor: <some rgb color&rt;,
                region: <region&rt;
        };
        
        Please check the final code in the github account to get the full picture.
        */
        this.state = {
            scope: 'world',
            selectedRegion:'ALL',
            allData: dataset,
            data: dataset,
            fills: {
                defaultFill: '#ddd'
            },
            geographyConfig: {  // this one is the xact same config which is you will see in the Datamaps config, you can add any confi option required for the Datamaps instance depending on your requirement.
                borderColor: '#888',
                borderWidth: .5,
                highlightBorderWidth: .5,
                highlightBorderColor: 'black',
                highlightFillColor: function(geo) {
                    return geo['fillColor'] || '#ddd';
                },
                popupTemplate: function(geo, data) {
                    //some custom popup html fragment
                }
            }
        };

    }

The final result here:

Screen Shot 2016-05-10 at 4.19.37 PM Screen Shot 2016-05-10 at 4.19.33 PM Screen Shot 2016-05-10 at 4.19.30 PM Screen Shot 2016-05-10 at 4.19.26 PM

Full code:

https://github.com/nishantnisonko/react-datamaps

 

References:

http://datamaps.github.io

https://github.com/btmills/react-datamaps

 

 

Posted in Generic

Custom Model in Objective C

Custom Model in Objective C

Created By: Debasis Das (17-Apr-2016)

Today we will create a Custom Model in Objective C where attributes can be added from within a loop. The model will support formatters and will have convenience method to create different types of attributes.

Normally a subclass of NSDictionary or a subclass of NSObject should suffice with the only exception that though we can programatically add keys to a dictionary, the keys are unsorted and if the desired behavior is to get all the attributes in the order in which they were added, it poses a challenge.

//  KSModel.h
//  DemoObjcKSModel
//  Created by Debasis Das on 17/04/16.
//  Copyright © 2016 Knowstack. All rights reserved.

#import <Foundation/Foundation.h>

@interface KSModel : NSObject

-(void)createAttributes; //This is the method that subclasses needs to override to add attributes to themselves
-(NSArray *)allKeys; //Returns an array of keys present in the model

-(void)addStringAttribute:(NSString *)attributeName;
-(void)addIntegerAttribute:(NSString *)attributeName;
-(void)addFloatAttribute:(NSString *)attributeName withFormatter:(NSNumberFormatter *)numberFormatter;
-(void)addDateAttribute:(NSString *)attributeName withFormatter:(NSDateFormatter *)dateFormatter;

-(NSMutableArray *)allAttributesWithValues; //Returns the entire model with keys, values and formatters
-(NSMutableDictionary *)findAttributeByName:(NSString *)attributeName;
-(NSString *)attributeAsString:(NSString *)attributeName;
-(int)attributeAsInt:(NSString *)attributeName;
-(float)attributeAsFloat:(NSString *)attributeName;

-(id )valueForAttributeName:(NSString *)attributeName;
-(void)setValue:(id)value forAttributeName:(NSString *)attributeName;

@end
//  KSModel.m
//  DemoObjcKSModel
//  Created by Debasis Das on 17/04/16.
//  Copyright © 2016 Knowstack. All rights reserved.

#import "KSModel.h"

@interface KSModel(){
    NSMutableArray *attributes;
}

@end

@implementation KSModel
- (instancetype)init
{
    self = [super init];
    if (self) {
        attributes = [[NSMutableArray alloc] init];
        [self createAttributes];
    }
    
    return self;
}

-(void)createAttributes{
    NSLog(@"%s",__func__);
}


-(void)addStringAttribute:(NSString *)attributeName{
    NSMutableDictionary *dict = [NSMutableDictionary dictionaryWithObjectsAndKeys:attributeName,@"key",
                                 @"",@"value",
                                 nil];
    [attributes addObject:dict];
}

-(void)addIntegerAttribute:(NSString *)attributeName{
    NSMutableDictionary *dict = [NSMutableDictionary dictionaryWithObjectsAndKeys:attributeName,@"key",
                                 [NSNull null],@"value",
                                 nil];
        [attributes addObject:dict];
}

-(void)addFloatAttribute:(NSString *)attributeName withFormatter:(NSNumberFormatter *)numberFormatter{
    NSMutableDictionary *dict = [NSMutableDictionary dictionaryWithObjectsAndKeys:attributeName,@"key",
                                 numberFormatter,@"formatter",
                                 [NSNull null],@"value",
                                 nil];
    [attributes addObject:dict];
}

-(void)addDateAttribute:(NSString *)attributeName withFormatter:(NSDateFormatter *)dateFormatter{
    NSMutableDictionary *dict = [NSMutableDictionary dictionaryWithObjectsAndKeys:attributeName,@"key",
                                 [NSDate date],@"value",
                                 dateFormatter,@"formatter",
                                 nil];
    [attributes addObject:dict];
}

-(NSArray *)allKeys{
    NSMutableArray *keyArray = [NSMutableArray new];
    for (NSDictionary *dict in attributes){
        [keyArray addObject:[dict objectForKey:@"key"]];
    }
    return [NSArray arrayWithArray:keyArray];
}

-(NSMutableArray *)allAttributesWithValues{
    return attributes;
}

-(NSMutableDictionary *)findAttributeByName:(NSString *)attributeName{
    for (NSMutableDictionary *dict in attributes){
        if ([attributeName isEqualToString:[dict objectForKey:@"key"]]){
            return dict;
        }
    }
    return nil;
}

-(NSString *)attributeAsString:(NSString *)attributeName{
    NSMutableDictionary *dict = [self findAttributeByName:attributeName];
    if ([dict objectForKey:@"formatter"] == nil){
        return [NSString stringWithFormat:@"%@",[dict objectForKey:@"value"]];
    }
    else{
        if ([[dict objectForKey:@"formatter"] isKindOfClass:[NSDateFormatter class]]){
            return [[dict objectForKey:@"formatter"] stringFromDate:[dict objectForKey:@"value"]];
        }
    }
    return [NSString stringWithFormat:@"%@",[dict objectForKey:@"value"]];
}

-(int)attributeAsInt:(NSString *)attributeName{
    return [[[self findAttributeByName:attributeName] objectForKey:@"value"] intValue];
}

-(float)attributeAsFloat:(NSString *)attributeName{
    NSMutableDictionary *dict = [self findAttributeByName:attributeName];
    if ([dict objectForKey:@"formatter"] == nil){
        return [[[self findAttributeByName:attributeName] objectForKey:@"value"] floatValue];
    }
    else{
        if ([[dict objectForKey:@"formatter"] isKindOfClass:[NSNumberFormatter class]]){
            return [[[dict objectForKey:@"formatter"] stringFromNumber:[dict objectForKey:@"value"]] floatValue];
        }
    }
    return [[[self findAttributeByName:attributeName] objectForKey:@"value"] floatValue];
}


-(id )valueForAttributeName:(NSString *)attributeName{
    return [[self findAttributeByName:attributeName] objectForKey:@"value"];
}

-(void)setValue:(id)value forAttributeName:(NSString *)attributeName{
    [[self findAttributeByName:attributeName] setObject:value forKey:@"value"];
}
@end

Sample Model

@interface Department : KSModel

@end

@implementation Department


-(void)createAttributes{
    [self addStringAttribute:@"firstName"];
    [self addStringAttribute:@"lastName"];
    [self addIntegerAttribute:@"age"];
    [self addFloatAttribute:@"salary" withFormatter:[self numberFormatter]];
    [self addFloatAttribute:@"experience" withFormatter:nil];
    for (int i =0; i<2; i++){
        [self addStringAttribute:[NSString stringWithFormat:@"Account%d",i]];
    }
    [self addDateAttribute:@"openingDate" withFormatter:[self mediumStyleDateFormatter]];
    [self addDateAttribute:@"closingDate" withFormatter:nil];
    [self addDateAttribute:@"meetingDate" withFormatter:[self longStyleDateFormatter]];
    
}

-(NSNumberFormatter *)numberFormatter{
    NSNumberFormatter *formatter = [[NSNumberFormatter alloc] init];
    [formatter setMinimumFractionDigits:(unsigned int)0];
    [formatter setMaximumFractionDigits:(unsigned int)2];
    return formatter;
    
}
//Test with 2 Date Formatters
-(NSDateFormatter *)mediumStyleDateFormatter{
    NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
    [dateFormatter setDateStyle:NSDateFormatterMediumStyle];
    return dateFormatter;
}

-(NSDateFormatter *)longStyleDateFormatter{
    NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
    [dateFormatter setDateStyle:NSDateFormatterLongStyle];
    return dateFormatter;
}
@end

Test Code

    Department *dept = [[Department alloc] init];
    NSLog(@"All Keys are as follows %@",[dept allKeys]);
/*
All Keys are as follows (
    firstName,
    lastName,
    age,
    salary,
    experience,
    Account0,
    Account1,
    openingDate,
    closingDate,
    meetingDate
)
*/
    NSLog(@"First Name BEFORE = %@",[dept attributeAsString:@"firstName"]); //First Name BEFORE = 
    [dept setValue:@"Debasis" forAttributeName:@"firstName"];
    NSLog(@"First Name AFTER = %@",[dept attributeAsString:@"firstName"]); // First Name AFTER = Debasis
    
    NSLog(@"SALARY BEFORE = %2.2f",[dept attributeAsFloat:@"salary"]); //SALARY BEFORE = 0.00
    [dept setValue:@20.6589876 forAttributeName:@"salary"];
    NSLog(@"SALARY AFTER = %2.2f",[dept attributeAsFloat:@"salary"]); //SALARY AFTER = 20.66
    
    [dept setValue:@12.3 forAttributeName:@"experience"];
    
    NSLog(@"Opening Date BEFORE = %@",[dept attributeAsString:@"openingDate"]); //Opening Date BEFORE = 17-Apr-2016
    NSDate *date = [NSDate dateWithTimeIntervalSinceNow:12345678];
    [dept setValue:date forAttributeName:@"openingDate"];
    NSLog(@"Opening Date AFTER = %@",[dept attributeAsString:@"openingDate"]); //Opening Date AFTER = 07-Sep-2016

You can download the source code hereDemoObjcKSModel

Posted in Cocoa, Objective C

Hit Counter provided by technology news