A New Page For Showing Interest In Sessions And Counts Up!

Come check out the new Sessions Interest Chart.  Using Sencha’s charting toolkit, we put together a new page that let’s you easily see all of this years sessions and mark which ones you are interested in attending.  Here is what my page looks like with the sessions I’m interested in.

 

image

There are several interesting features of this page that I’ve pointed to by arrows. 

1)    You can always quickly get to this page by press the hyperlink on the left top called “Sessions Interest Chart”

2)    Assuming you are logged in, you can tell what sessions you have expressed interest in by seeing the little green circle on the left of each session

3)    The columns are sortable by clicking on them (including the little column with the green circle of interest)

4)    If you are interested in going to a session, you can click the button next to the speakers picture to express that intent (you need to go to the normal sessions page to remove your interest if you change your mind)

 

This page really serve to very important purposes.  First, it let’s you easily navigate sessions and see what is coming to code camp (even by how many days since the session was submitted so you can see the new ones easily).  Second, it helps us know what you are interested in so we can allocate code camp resources appropriately and make sure we track important sessions.

For those wondering how we built this, we basically modified one of the samples from the Sencha Library (ExtJS 4.0).  The FormDashboard example.   It’s amazing how simple something like this is to put together.  If you want to see the details, we actually put the source Javascript code right in the page so simply view source will take you right there.

For those that want to see the code right away, I’ll paste it below.

<link rel="stylesheet" type="text/css" href="JSProd/resources/extjs/4/resources/css/ext-all.css" />

 <link rel="stylesheet" type="text/css" href="App_Themes/Gray2011/ext-app.css" />

 <script type="text/javascript" src="JSProd/resources/extjs/4/bootstrap.js"></script> 

 <script type="text/javascript" language="javascript">

     Ext.require([

         'Ext.form.*',

         'Ext.data.*',

         'Ext.chart.*',

         'Ext.grid.Panel',

         'Ext.layout.container.Column'

     ]);

 

 

     Ext.onReady(function () {

 

         Ext.define('Session', {

             extend: 'Ext.data.Model',

             fields: [

                 {name: 'Id', type: 'int'},

                 {name: 'Title', type: 'string'},

                 {name: 'Description', type: 'string'},

                 {name: 'InterestCountInt', type: 'int'},

                 {name: 'SessionPosted', type: 'string'},

                 {name: 'PresenterName', type: 'string'},

                 {name: 'PresenterURL', type: 'string'},

                 {name: 'SpeakerPictureUrl', type: 'string'},

                 {name: 'LoggedInUserInterested', type: 'bool'}

             ]

         });

 

         var rec = false,

             selectedStoreItem = false,

             loggedInUsername = '',

             selectItem = function(storeItem) {

                 selectedStoreItem = storeItem;

                 updateSessionDetailsPanel();

                 var sessionID = storeItem.get('Id'),

                     series = barChart.series.get(0),

                     i, items, l;

 

                 series.highlight = true;

                 series.unHighlightItem();

                 series.cleanHighlights();

 

                 for (i = 0, items = series.items, l = items.length; i < l; i++) {

                     if (sessionID == items[i].storeItem.get('Id')) {

                         series.highlightItem(items[i]);

                         break;

                     }

                 }

                 series.highlight = false;

             },

             greenDotImg = 'App_Themes/Gray2011/Images/green-dot.png',

             imInterestedRenderer = function (val) {

                 if (val) {

                     return '&nbsp;<img src="'+greenDotImg+'" />';

                 }

             },

             extInterestButtonHandler = function () {

                 this.disable();

                 var that = this;

                 // {"success":true,"msg":"ButtonName: Interested userName: elwhizard sessionId: 587 interestLevel: 2"}

                 var jsonData = {

                     success: true,

                     msg: 'ButtonName: Intersted userName:' + loggedInUsername + ' sessionId: ' + selectedStoreItem.data.Id + ' interestLevel: 2'

                 }

                 Ext.Ajax.request({

                     url: 'SessionInterest.ashx',

                     method: 'POST',

                     params: {

                         SessionId: selectedStoreItem.data.Id,

                         ButtonName: 'Interested',

                         UserName: loggedInUsername,

                         ChoiceNumber:1

                     },

                     success: function (response) {

                         that.destroy();

                         Ext.get('interestButton').update('&nbsp;<img src="'+greenDotImg+'" /> &nbsp; <b>You are interested in this session.</b>');

                         selectedStoreItem.set({LoggedInUserInterested: true});

                         // sync store

                         //sessionsStore.sync();

                     },

                     failure: function (response) {

                         Ext.Msg.alert('Error', 'There was an error updating your sessoin interest');

                         this.enable();

                     }

                 })

             },

             updateSessionDetailsPanel = function () {

                 if (!selectedStoreItem) return;

                 var sessionDetailsPanel = Ext.getCmp('sessionDetails'), interestButton = Ext.getCmp('extInterstButton');

                 var sessionDetailsHtml = '<h2 style="color: #AF1D00; font: bold 16px Cambria,Georgia,Arial,Verdana,Tahoma">' + selectedStoreItem.data.Title + '</h1>';

 

                 if (interestButton) interestButton.destroy();

 

                 var presenterUrl = selectedStoreItem.data.PresenterURL;

                 if (presenterUrl.search('http') === -1 && presenterUrl != '') {

                     presenterUrl = 'http://' + presenterUrl;

                 }

 

                 sessionDetailsHtml += '<br /><table width="100%"><tr><td width="50%"><img src="'+selectedStoreItem.data.SpeakerPictureUrl+'" /></td><td style="vertical-align:top">';

 

                 var createButton = false;

                 if (loggedInUsername == "") {

                     sessionDetailsHtml +=  '<b>Please login to show your session interests.</b>';

                 } else {

                     if (selectedStoreItem.data.LoggedInUserInterested) {

                         sessionDetailsHtml +=  '&nbsp;<img src="'+greenDotImg+'" /> &nbsp; <b>You are interested in this session.</b>';

                     } else {

                         createButton = true;

                         sessionDetailsHtml +=  '<span id="interestButton"></span>';

                     }

                 }

 

                 sessionDetailsHtml += '</td></tr></table>'

 

                 sessionDetailsHtml += '<br />' + selectedStoreItem.data.PresenterName +'<br /><a href="'+ presenterUrl+'" target="_blank">'+ presenterUrl+'</a>';

                 sessionDetailsHtml += '<br /><br /> ' + selectedStoreItem.data.Description;

                 sessionDetailsPanel.update(sessionDetailsHtml);

                 Ext.defer(sessionDetailsPanel.doLayout, 500, sessionDetailsPanel, []);

                 if (createButton) {

                     Ext.create('Ext.Button', {

                         text: 'Press Here To <br />Show Your Interest<br /> In This Session',

                         height: 60,

                         width: 120,

                         id: 'extInterstButton',

                         renderTo: Ext.get('interestButton'),

                         handler: extInterestButtonHandler

                     });

                 }

 

             },

             topSessionsStoreUpdater = function () {

                 var top25SessionsRecords = sessionsStore.getRange(0,24), top25SessionsArray = [];

                 for (var i = 0; i < top25SessionsRecords.length; i++) {

                     top25SessionsArray[top25SessionsArray.length] = [

                         top25SessionsRecords[i].data.Id,

                         top25SessionsRecords[i].data.Title,

                         top25SessionsRecords[i].data.Description,

                         top25SessionsRecords[i].data.InterestCountInt,

                         top25SessionsRecords[i].data.SessionPosted,

                         top25SessionsRecords[i].data.PresenterName,

                         top25SessionsRecords[i].data.PresenterURL,

                         top25SessionsRecords[i].data.SpeakerPictureUrl,

                         top25SessionsRecords[i].data.LoggedInUserInterested

                     ]

                 }

                 topSessionStore.loadData(top25SessionsArray);

             };

 

         var sessionsStore = new Ext.data.Store({

             model: 'Session',

             sorters: [

                 {

                     property : 'InterestCountInt',

                     direction: 'DESC'

                 }

             ],

             proxy: {

                 type: 'ajax',

                 url : 'GeneralHandlers/SessionsInterest.ashx',

                 limitParam: undefined,

                 reader: {

                     type: 'json',

                     root: 'rows'

                 }

             },

             autoLoad: {

                 params: {

                     limit: 1000

                 }

             },

             sortOnLoad: true,

             listeners: {

                 load: function (store, records, success) {

                     if (success) {

                         loggedInUsername = store.proxy.reader.jsonData.loggedInUsername;

                         topSessionsStoreUpdater();

                         sessionsGrid.getSelectionModel().select(0);

                         Ext.defer(selectItem, 1000, this, [sessionsStore.getAt(0)]);

                     } else {

                         Ext.Msg.alert('Error', 'Sorry, there was an error loading Silicon Valley Code Camp Sessions.');

                     }

                 }

             }

         });

 

         var topSessionStore = new Ext.data.Store({

             model: 'Session',

             proxy: {

                 type: 'memory',

                 data: [],

                 reader: {

                     type: 'array'

                 }

             }

         });

 

         var barChart = Ext.create('Ext.chart.Chart', {

             flex: 1,

             shadow: true,

             animate: true,

             store: topSessionStore,

             axes: [{

                 type: 'Numeric',

                 position: 'left',

                 fields: ['InterestCountInt'],

                 minimum: 0,

                 label: {

                     font: '9px Arial'

                 },

                 hidden: true

             }, {

                 type: 'Category',

                 position: 'bottom',

                 fields: ['Title'],

                 hidden: true,

                 label: {

                     font: '9px Arial'

                 }

             }],

             series: [{

                 type: 'column',

                 axis: 'left',

                 highlight: true,

                 style: {

                     fill: '#456d9f'

                 },

                 highlightCfg: {

                     fill: '#a2b5ca'

                 },

                 label: {

                     display: 'InterestCountInt',

                     field: 'InterestCountInt',

                     color: '#000',

                     orientation: 'vertical',

                     'text-anchor': 'middle'

                 },

                 listeners: {

                     'itemmouseup': function(item) {

                          var series = barChart.series.get(0),

                             index = Ext.Array.indexOf(series.items, item),

                             selectionModel = sessionsGrid.getSelectionModel();

 

                             selectedStoreItem = item.storeItem;

                             selectionModel.select(index);

                     }

                 },

                 xField: 'Title',

                 yField: ['InterestCountInt']

             }]

         });

 

         // Grid for sessoins

         var sessionsGrid = Ext.create('Ext.grid.Panel', {

             id: 'sessionsGrid',

             store: sessionsStore,

             title:'Sessions',

 

             columns: [

                 {

                     width: 20,

                     sortable: true,

                     dataIndex: 'LoggedInUserInterested',

                     renderer: imInterestedRenderer

                 },

                 {

                     text   : 'Interest',

                     width : 65,

                     cls: 'headerWrap',

                     sortable : true,

                     dataIndex: 'InterestCountInt'

                 },

                 {

                     text : 'Session Title',

                     flex: 1,

                     sortable : true,

                     dataIndex: 'Title'

                 },

                 {

                     text   : 'Days Up',

                     width: 60,

                     sortable : true,

                     dataIndex: 'SessionPosted'

                 },

                 {

                     text   : 'Speaker Name',

                     width: 130,

                     sortable : true,

                     dataIndex: 'PresenterName'

                 }

                 

             ],

 

             listeners: {

                 selectionchange: function(model, records) {

                     var json, name, i, l, items, series, fields;

                     if (records[0]) {

                         var rec = records[0];

                         selectItem(rec);

                     }

                 },

                 sortchange: topSessionsStoreUpdater

             }

         });

 

         var sessionsPanel = Ext.create('Ext.panel.Panel', {

             title: 'Sessions By Interest (Top 25 Session From Sortable Grid Are Charted)                       Green Dot Indicates Your Interest',

             renderTo: Ext.get('topChart'),

             frame: true,

             bodyPadding: 5,

             width: 870,

             height: 720,

 

             fieldDefaults: {

                 labelAlign: 'left',

                 msgTarget: 'side'

             },

 

             layout: {

                 type: 'vbox',

                 align: 'stretch'

             },

 

             items: [

                 {

                     height: 200,

                     layout: 'fit',

                     margin: '0 0 3 0',

                     items: [barChart]

                 },

                 {

                     flex: 3,

                     border: false,

                     bodyStyle: 'background-color: transparent',

                     layout: 'border',

                     items: [{

                         region: 'center',

                         border: false,

                         margin: '0 3 0 0',

                         autoHeight: true,

                         layout: 'fit',

                         items: [sessionsGrid]

                     }, {

                         region: 'east',

                         title: 'Session Details',

                         collapsible: true,

                         width: 300,

                         autoScroll: true,

                         layout: 'fit',

                         items: [{

                             id: 'sessionDetails',

                             bodyPadding: 10,

                             border: false,

                             autoScroll: true,

                             html: ''

                         }]

                 }]

             }]

         });

 

     });

 </script>

 <div class="mainHeading">Session Interest Chart</div>

 

v id="topChart"></div>

Tags: , , ,