Adicionar

/** * impress.js * * impress.js is a presentation tool based on the power of CSS3 transforms and transitions * in modern browsers and inspired by the idea behind prezi.com. * * * Copyright 2011-2012 Bartek Szopka (@bartaz) * * Released under the MIT and GPL Licenses. * * ------------------------------------------------ * author: Bartek Szopka * version: 0.5.2 * url: http://bartaz.github.com/impress.js/ * source: http://github.com/bartaz/impress.js/ */ /*jshint bitwise:true, curly:true, eqeqeq:true, forin:true, latedef:true, newcap:true, noarg:true, noempty:true, undef:true, strict:true, browser:true */ // You are one of those who like to know how thing work inside? // Let me show you the cogs that make impress.js run... (function ( document, window ) { 'use strict'; // HELPER FUNCTIONS // `pfx` is a function that takes a standard CSS property name as a parameter // and returns it's prefixed version valid for current browser it runs in. // The code is heavily inspired by Modernizr http://www.modernizr.com/ var pfx = (function () { var style = document.createElement('dummy').style, prefixes = 'Webkit Moz O ms Khtml'.split(' '), memory = {}; return function ( prop ) { if ( typeof memory[ prop ] === "undefined" ) { var ucProp = prop.charAt(0).toUpperCase() + prop.substr(1), props = (prop + ' ' + prefixes.join(ucProp + ' ') + ucProp).split(' '); memory[ prop ] = null; for ( var i in props ) { if ( style[ props[i] ] !== undefined ) { memory[ prop ] = props[i]; break; } } } return memory[ prop ]; }; })(); // `arraify` takes an array-like object and turns it into real Array // to make all the Array.prototype goodness available. var arrayify = function ( a ) { return [].slice.call( a ); }; // `css` function applies the styles given in `props` object to the element // given as `el`. It runs all property names through `pfx` function to make // sure proper prefixed version of the property is used. var css = function ( el, props ) { var key, pkey; for ( key in props ) { if ( props.hasOwnProperty(key) ) { pkey = pfx(key); if ( pkey !== null ) { el.style[pkey] = props[key]; } } } return el; }; // `toNumber` takes a value given as `numeric` parameter and tries to turn // it into a number. If it is not possible it returns 0 (or other value // given as `fallback`). var toNumber = function (numeric, fallback) { return isNaN(numeric) ? (fallback || 0) : Number(numeric); }; // `byId` returns element with given `id` - you probably have guessed that ;) var byId = function ( id ) { return document.getElementById(id); }; // `$` returns first element for given CSS `selector` in the `context` of // the given element or whole document. var $ = function ( selector, context ) { context = context || document; return context.querySelector(selector); }; // `$$` return an array of elements for given CSS `selector` in the `context` of // the given element or whole document. var $$ = function ( selector, context ) { context = context || document; return arrayify( context.querySelectorAll(selector) ); }; // `triggerEvent` builds a custom DOM event with given `eventName` and `detail` data // and triggers it on element given as `el`. var triggerEvent = function (el, eventName, detail) { var event = document.createEvent("CustomEvent"); event.initCustomEvent(eventName, true, true, detail); el.dispatchEvent(event); }; // `translate` builds a translate transform string for given data. var translate = function ( t ) { return " translate3d(" + t.x + "px," + t.y + "px," + t.z + "px) "; }; // `rotate` builds a rotate transform string for given data. // By default the rotations are in X Y Z order that can be reverted by passing `true` // as second parameter. var rotate = function ( r, revert ) { var rX = " rotateX(" + r.x + "deg) ", rY = " rotateY(" + r.y + "deg) ", rZ = " rotateZ(" + r.z + "deg) "; return revert ? rZ+rY+rX : rX+rY+rZ; }; // `scale` builds a scale transform string for given data. var scale = function ( s ) { return " scale(" + s + ") "; }; // `perspective` builds a perspective transform string for given data. var perspective = function ( p ) { return " perspective(" + p + "px) "; }; // `getElementFromHash` returns an element located by id from hash part of // window location. var getElementFromHash = function () { // get id from url # by removing `#` or `#/` from the beginning, // so both "fallback" `#slide-id` and "enhanced" `#/slide-id` will work return byId( window.location.hash.replace(/^#\/?/,"") ); }; // `computeWindowScale` counts the scale factor between window size and size // defined for the presentation in the config. var computeWindowScale = function ( config ) { var hScale = window.innerHeight / config.height, wScale = window.innerWidth / config.width, scale = hScale > wScale ? wScale : hScale; if (config.maxScale && scale > config.maxScale) { scale = config.maxScale; } if (config.minScale && scale < config.minScale) { scale = config.minScale; } return scale; }; // CHECK SUPPORT var body = document.body; var ua = navigator.userAgent.toLowerCase(); var impressSupported = // browser should support CSS 3D transtorms ( pfx("perspective") !== null ) && // and `classList` and `dataset` APIs ( body.classList ) && ( body.dataset ) && // but some mobile devices need to be blacklisted, // because their CSS 3D support or hardware is not // good enough to run impress.js properly, sorry... ( ua.search(/(iphone)|(ipod)|(android)/) === -1 ); if (!impressSupported) { // we can't be sure that `classList` is supported body.className += " impress-not-supported "; } else { body.classList.remove("impress-not-supported"); body.classList.add("impress-supported"); } // GLOBALS AND DEFAULTS // Getting cross-browser transitionEnd event name. // It's hard to detect it, so we are using the list based on // https://developer.mozilla.org/en/CSS/CSS_transitions var transitionEnd = ({ 'transition' : 'transitionEnd', 'OTransition' : 'oTransitionEnd', 'msTransition' : 'MSTransitionEnd', // who knows how it will end up? 'MozTransition' : 'transitionend', 'WebkitTransition' : 'webkitTransitionEnd' })[pfx("transition")]; // This is were the root elements of all impress.js instances will be kept. // Yes, this means you can have more than one instance on a page, but I'm not // sure if it makes any sense in practice ;) var roots = {}; // some default config values. var defaults = { width: 1024, height: 768, maxScale: 1, minScale: 0, perspective: 1000, transitionDuration: 1000 }; // it's just an empty function ... and a useless comment. var empty = function () { return false; }; // IMPRESS.JS API // And that's where intresting things will start to happen. // It's the core `impress` function that returns the impress.js API // for a presentation based on the element with given id ('impress' // by default). var impress = window.impress = function ( rootId ) { // If impress.js is not supported by the browser return a dummy API // it may not be a perfect solution but we return early and avoid // running code that may use features not implemented in the browser. if (!impressSupported) { return { init: empty, goto: empty, prev: empty, next: empty }; } rootId = rootId || "impress"; // if given root is already initialized just return the API if (roots["impress-root-" + rootId]) { return roots["impress-root-" + rootId]; } // data of all presentation steps var stepsData = {}; // element of currently active step var activeStep = null; // current state (position, rotation and scale) of the presentation var currentState = null; // array of step elements var steps = null; // configuration options var config = null; // scale factor of the browser window var windowScale = null; // root presentation elements var root = byId( rootId ); var canvas = document.createElement("div"); var initialized = false; // STEP EVENTS // // There are currently two step events triggered by impress.js // `impress:stepenter` is triggered when the step is shown on the // screen (the transition from the previous one is finished) and // `impress:stepleave` is triggered when the step is left (the // transition to next step just starts). // reference to last entered step var lastEntered = null; // `onStepEnter` is called whenever the step element is entered // but the event is triggered only if the step is different than // last entered step. var onStepEnter = function (step) { if (lastEntered !== step) { triggerEvent(step, "impress:stepenter"); lastEntered = step; } }; // `onStepLeave` is called whenever the step element is left // but the event is triggered only if the step is the same as // last entered step. var onStepLeave = function (step) { if (lastEntered === step) { triggerEvent(step, "impress:stepleave"); lastEntered = null; } }; // To detect the moment when the transition to step element finished // we need to handle the transitionEnd event. // // It may not sound very hard but to makes things a little bit more // complicated there are two elements being animated separately: // `root` (used for scaling) and `canvas` for translate and rotations. // Transitions on them are triggered with different delays (to make // visually nice and 'natural' looking transitions), so we need to know // that both of them are finished. // // It sounds like a simple counter to two would be enough. Unfortunately // if there is no change in the transform value (for example scale doesn't // change between two steps) only one transition (and transitionEnd event) // will be triggered. // // So to properly detect when the transitions finished we need to keep // the `expectedTransitionTarget` (that can be one of `root` or `canvas`) // and only call `onStepEnter` then transition ended on the expected one. var expectedTransitionTarget = null; var onTransitionEnd = function (event) { if (event.target === expectedTransitionTarget) { onStepEnter(activeStep); } }; // `initStep` initializes given step element by reading data from its // data attributes and setting correct styles. var initStep = function ( el, idx ) { var data = el.dataset, step = { translate: { x: toNumber(data.x), y: toNumber(data.y), z: toNumber(data.z) }, rotate: { x: toNumber(data.rotateX), y: toNumber(data.rotateY), z: toNumber(data.rotateZ || data.rotate) }, scale: toNumber(data.scale, 1), el: el }; if ( !el.id ) { el.id = "step-" + (idx + 1); } stepsData["impress-" + el.id] = step; css(el, { position: "absolute", transform: "translate(-50%,-50%)" + translate(step.translate) + rotate(step.rotate) + scale(step.scale), transformStyle: "preserve-3d" }); }; // `init` API function that initializes (and runs) the presentation. var init = function () { if (initialized) { return; } // First we set up the viewport for mobile devices. // For some reason iPad goes nuts when it is not done properly. var meta = $("meta[name='viewport']") || document.createElement("meta"); meta.content = "width=device-width, minimum-scale=1, maximum-scale=1, user-scalable=no"; if (meta.parentNode !== document.head) { meta.name = 'viewport'; document.head.appendChild(meta); } // initialize configuration object var rootData = root.dataset; config = { width: toNumber( rootData.width, defaults.width ), height: toNumber( rootData.height, defaults.height ), maxScale: toNumber( rootData.maxScale, defaults.maxScale ), minScale: toNumber( rootData.minScale, defaults.minScale ), perspective: toNumber( rootData.perspective, defaults.perspective ), transitionDuration: toNumber( rootData.transitionDuration, defaults.transitionDuration ) }; windowScale = computeWindowScale( config ); // wrap steps with "canvas" element arrayify( root.childNodes ).forEach(function ( el ) { canvas.appendChild( el ); }); root.appendChild(canvas); // set initial styles document.documentElement.style.height = "100%"; css(body, { height: "100%", overflow: "hidden" }); var rootStyles = { position: "absolute", transformOrigin: "top left", transition: "all 0s ease-in-out", transformStyle: "preserve-3d" }; css(root, rootStyles); css(root, { top: "50%", left: "50%", transform: perspective( config.perspective/windowScale ) + scale( windowScale ) }); css(canvas, rootStyles); root.addEventListener(transitionEnd, onTransitionEnd, false); body.classList.remove("impress-disabled"); body.classList.add("impress-enabled"); // get and init steps steps = $$(".step", root); steps.forEach( initStep ); // set a default initial state of the canvas currentState = { translate: { x: 0, y: 0, z: 0 }, rotate: { x: 0, y: 0, z: 0 }, scale: 1 }; initialized = true; triggerEvent(root, "impress:init", { api: roots[ "impress-root-" + rootId ] }); }; // `getStep` is a helper function that returns a step element defined by parameter. // If a number is given, step with index given by the number is returned, if a string // is given step element with such id is returned, if DOM element is given it is returned // if it is a correct step element. var getStep = function ( step ) { if (typeof step === "number") { step = step < 0 ? steps[ steps.length + step] : steps[ step ]; } else if (typeof step === "string") { step = byId(step); } return (step && step.id && stepsData["impress-" + step.id]) ? step : null; }; // `goto` API function that moves to step given with `el` parameter (by index, id or element), // with a transition `duration` optionally given as second parameter. var goto = function ( el, duration ) { if ( !initialized || !(el = getStep(el)) ) { // presentation not initialized or given element is not a step return false; } // Sometimes it's possible to trigger focus on first link with some keyboard action. // Browser in such a case tries to scroll the page to make this element visible // (even that body overflow is set to hidden) and it breaks our careful positioning. // // So, as a lousy (and lazy) workaround we will make the page scroll back to the top // whenever slide is selected // // If you are reading this and know any better way to handle it, I'll be glad to hear about it! window.scrollTo(0, 0); var step = stepsData["impress-" + el.id]; if ( activeStep ) { activeStep.classList.remove("active"); body.classList.remove("impress-on-" + activeStep.id); } el.classList.add("active"); body.classList.add("impress-on-" + el.id); // compute target state of the canvas based on given step var target = { rotate: { x: -step.rotate.x, y: -step.rotate.y, z: -step.rotate.z }, translate: { x: -step.translate.x, y: -step.translate.y, z: -step.translate.z }, scale: 1 / step.scale }; // Check if the transition is zooming in or not. // // This information is used to alter the transition style: // when we are zooming in - we start with move and rotate transition // and the scaling is delayed, but when we are zooming out we start // with scaling down and move and rotation are delayed. var zoomin = target.scale >= currentState.scale; duration = toNumber(duration, config.transitionDuration); var delay = (duration / 2); // if the same step is re-selected, force computing window scaling, // because it is likely to be caused by window resize if (el === activeStep) { windowScale = computeWindowScale(config); } var targetScale = target.scale * windowScale; // Because one of the transition is delayed depending on zoom direction, // the last transition will happen on `root` or `canvas` element. // Here we store the expected transition event target, to be able to correctly // trigger `impress:stepenter` event. expectedTransitionTarget = target.scale > currentState.scale ? root : canvas; // trigger leave of currently active element (if it's not the same step again) if (activeStep && activeStep !== el) { onStepLeave(activeStep); } // alter transforms of `root` and `canvas` to trigger transitions css(root, { // to keep the perspective look similar for different scales // we need to 'scale' the perspective, too transform: perspective( config.perspective / targetScale ) + scale( targetScale ), transitionDuration: duration + "ms", transitionDelay: (zoomin ? delay : 0) + "ms" }); css(canvas, { transform: rotate(target.rotate, true) + translate(target.translate), transitionDuration: duration + "ms", transitionDelay: (zoomin ? 0 : delay) + "ms" }); // store current state currentState = target; activeStep = el; // manually trigger enter event if duration was set to 0 if (duration === 0) { onStepEnter(activeStep); } return el; }; // `prev` API function goes to previous step (in document order) var prev = function () { var prev = steps.indexOf( activeStep ) - 1; prev = prev >= 0 ? steps[ prev ] : steps[ steps.length-1 ]; return goto(prev); }; // `next` API function goes to next step (in document order) var next = function () { var next = steps.indexOf( activeStep ) + 1; next = next < steps.length ? steps[ next ] : steps[ 0 ]; return goto(next); }; // Adding some useful classes to step elements. // // All the steps that have not been shown yet are given `future` class. // When the step is entered the `future` class is removed and the `present` // class is given. When the step is left `present` class is replaced with // `past` class. // // So every step element is always in one of three possible states: // `future`, `present` and `past`. // // There classes can be used in CSS to style different types of steps. // For example the `present` class can be used to trigger some custom // animations when step is shown. root.addEventListener("impress:init", function(){ // STEP CLASSES steps.forEach(function (step) { step.classList.add("future"); }); root.addEventListener("impress:stepenter", function (event) { event.target.classList.remove("past"); event.target.classList.remove("future"); event.target.classList.add("present"); }, false); root.addEventListener("impress:stepleave", function (event) { event.target.classList.remove("present"); event.target.classList.add("past"); }, false); }, false); // Adding hash change support. root.addEventListener("impress:init", function(){ // last hash detected var lastHash = ""; // `#/step-id` is used instead of `#step-id` to prevent default browser // scrolling to element in hash. // // And it has to be set after animation finishes, because in Chrome it // makes transtion laggy. // BUG: http://code.google.com/p/chromium/issues/detail?id=62820 root.addEventListener("impress:stepenter", function (event) { window.location.hash = lastHash = "#/" + event.target.id; }, false); window.addEventListener("hashchange", function () { // When the step is entered hash in the location is updated // (just few lines above from here), so the hash change is // triggered and we would call `goto` again on the same element. // // To avoid this we store last entered hash and compare. if (window.location.hash !== lastHash) { goto( getElementFromHash() ); } }, false); // START // by selecting step defined in url or first step of the presentation goto(getElementFromHash() || steps[0], 0); }, false); body.classList.add("impress-disabled"); // store and return API for given impress.js root element return (roots[ "impress-root-" + rootId ] = { init: init, goto: goto, next: next, prev: prev }); }; // flag that can be used in JS to check if browser have passed the support test impress.supported = impressSupported; })(document, window); // NAVIGATION EVENTS // As you can see this part is separate from the impress.js core code. // It's because these navigation actions only need what impress.js provides with // its simple API. // // In future I think about moving it to make them optional, move to separate files // and treat more like a 'plugins'. (function ( document, window ) { 'use strict'; // throttling function calls, by Remy Sharp // http://remysharp.com/2010/07/21/throttling-function-calls/ var throttle = function (fn, delay) { var timer = null; return function () { var context = this, args = arguments; clearTimeout(timer); timer = setTimeout(function () { fn.apply(context, args); }, delay); }; }; // wait for impress.js to be initialized document.addEventListener("impress:init", function (event) { // Getting API from event data. // So you don't event need to know what is the id of the root element // or anything. `impress:init` event data gives you everything you // need to control the presentation that was just initialized. var api = event.detail.api; // KEYBOARD NAVIGATION HANDLERS // Prevent default keydown action when one of supported key is pressed. document.addEventListener("keydown", function ( event ) { if ( event.keyCode === 9 || ( event.keyCode >= 32 && event.keyCode <= 34 ) || (event.keyCode >= 37 && event.keyCode <= 40) ) { event.preventDefault(); } }, false); // Trigger impress action (next or prev) on keyup. // Supported keys are: // [space] - quite common in presentation software to move forward // [up] [right] / [down] [left] - again common and natural addition, // [pgdown] / [pgup] - often triggered by remote controllers, // [tab] - this one is quite controversial, but the reason it ended up on // this list is quite an interesting story... Remember that strange part // in the impress.js code where window is scrolled to 0,0 on every presentation // step, because sometimes browser scrolls viewport because of the focused element? // Well, the [tab] key by default navigates around focusable elements, so clicking // it very often caused scrolling to focused element and breaking impress.js // positioning. I didn't want to just prevent this default action, so I used [tab] // as another way to moving to next step... And yes, I know that for the sake of // consistency I should add [shift+tab] as opposite action... document.addEventListener("keyup", function ( event ) { if ( event.keyCode === 9 || ( event.keyCode >= 32 && event.keyCode <= 34 ) || (event.keyCode >= 37 && event.keyCode <= 40) ) { switch( event.keyCode ) { case 33: // pg up case 37: // left case 38: // up api.prev(); break; case 9: // tab case 32: // space case 34: // pg down case 39: // right case 40: // down api.next(); break; } event.preventDefault(); } }, false); // delegated handler for clicking on the links to presentation steps document.addEventListener("click", function ( event ) { // event delegation with "bubbling" // check if event target (or any of its parents is a link) var target = event.target; while ( (target.tagName !== "A") && (target !== document.documentElement) ) { target = target.parentNode; } if ( target.tagName === "A" ) { var href = target.getAttribute("href"); // if it's a link to presentation step, target this step if ( href && href[0] === '#' ) { target = document.getElementById( href.slice(1) ); } } if ( api.goto(target) ) { event.stopImmediatePropagation(); event.preventDefault(); } }, false); // delegated handler for clicking on step elements document.addEventListener("click", function ( event ) { var target = event.target; // find closest step element that is not active while ( !(target.classList.contains("step") && !target.classList.contains("active")) && (target !== document.documentElement) ) { target = target.parentNode; } if ( api.goto(target) ) { event.preventDefault(); } }, false); // touch handler to detect taps on the left and right side of the screen // based on awesome work of @hakimel: https://github.com/hakimel/reveal.js document.addEventListener("touchstart", function ( event ) { if (event.touches.length === 1) { var x = event.touches[0].clientX, width = window.innerWidth * 0.3, result = null; if ( x < width ) { result = api.prev(); } else if ( x > window.innerWidth - width ) { result = api.next(); } if (result) { event.preventDefault(); } } }, false); // rescale presentation when window is resized window.addEventListener("resize", throttle(function () { // force going to active step again, to trigger rescaling api.goto( document.querySelector(".active"), 500 ); }, 250), false); }, false); })(document, window); // THAT'S ALL FOLKS! // // Thanks for reading it all. // Or thanks for scrolling down and reading the last part. // // I've learnt a lot when building impress.js and I hope this code and comments // will help somebody learn at least some part of it.

El caso de Amazon.com

¿Como asegura el exito Amazon.com y logra ser una de las tiendas que mas vende en internet?

Realmente importa el tipo de empresa para aplicar BI?

Conoce algunos ejemplos de como grandes compañias han logrado superar problemas por medio del análisis de la información

Video Introductorio

Entiende mejor como trabaja BI por medio del ejemplo de las hormigas!

domingo, 31 de marzo de 2013

A implementar BI


Decidida la empresa por la implantación de un proyecto de BI, esto es superadas las fases de análisis previos sobre sus bondades y pertinencias, sobre sus posibilidades técnicas  y financieras es momento de iniciar  la estructuración del equipo técnico responsable de la estructuración y debido alistamiento para la producción y utilización permanente de la herramienta por parte de los interesados de la compañía. Por supuesto que la arquitectura de BI es del resorte de la unidad de T.I. pero la aplicación como tal es diseñada para la utilización de los usuarios del negocio. Recordemos que la base de datos es realmente una bodega (DWH) concepto que desborda la de la dimensión  del tamaño de almacenamiento de una  hoja electrónica. Por ello estamos hablando en términos de máquina una importante capacidad de almacenamiento para la base central, atendida por un grupo técnico básico liderado por el administrador de la base de datos relacional, acompañándolo se desempeñan un modelador de datos especialista en herramientas OLAP, un analista de sistemas del negocio y un desarrollador de aplicaciones de BI. En el mercado se encuentran una variedad de herramientas que realizan las tareas propias de los cubos OLAP y las sentencias SQL que operan sobre los datos almacenados. 


“Business Intelligence Development Studio es un entorno de desarrollo basado en Microsoft Visual Studio 2008 que se emplea para crear y modificar soluciones de Business Intelligence. Con Business Intelligence Development Studio, se pueden crear proyectos de Analysis Services que contienen definiciones de objetos de Analysis Services (cubos, dimensiones, etc.), que se almacenan en archivos XML que contienen elementos ASSL (Analysis Services Scripting Language). Estos proyectos se incluyen en soluciones que a su vez pueden contener proyectos de otros componentes de SQL Server, incluidos SQL Server Integration Services y SQL Server Reporting Services. “ [1]

Los usuarios interesados en los productos finales deben aportar al grupo técnico anteriormente indicado las listas de requerimientos que pueden estar constituidas por formatos de cuadros  de salida de doble entrada que consolidan por diferentes criterios los datos que reposan en la bodega, la idea del trabajo es que los usuarios finales con pocas instrucciones puedan obtener la información que les es útil para su análisis del negocio. Como en todo proyecto no solamente es propio del desarrollo contemplar todos los aspectos referentes a la operatividad que le son inherentes sino también aquellos puntos que prácticas anteriores han destacado como errores  frecuentes. En las implantaciones de BI suelen presentarse los siguientes: TI construye el DWH sin considerar los requerimientos de los usuarios del negocio, se crean cubos complejos con muchas dimensiones que son difíciles de utilizar por los usuarios finales, no se atiende debidamente la confiabilidad y seguridad de los datos, existen más profesionales en la empresa implementando y soportando el BI que usuarios del negocio utilizándolo, construir un gigante que cubra todos los aspectos del negocio, se tarda mucho tiempo en proporcionar resultados de valor que hacen incomprensible de entender los costos monumentales de la inversión. Por ello como directriz de la solución se recomienda como directriz tener un objetivo claro lograble en no más de tres meses e implantar la utilización a un nivel de escala razonable dentro de la empresa. Seguramente las áreas comerciales o las que hagan sus veces serán las más interesadas de manera prioritaria.



domingo, 24 de marzo de 2013

Hora de implementar, pero antes...


En las anteriores publicaciones hemos dado la idea de las funciones y los beneficios que puede brindar BI mediante ejemplos de la vida real de compañías que han agregado valor a esta solución y han visto los frutos en un tiempo determinado luego de implementado. Luego de eso vimos algunas de las herramientas que usa BI para así dar una idea de la composición de este y de las muchas funcionalidades que contiene. Es tiempo entonces de ingresar a la implementación de la solución, la etapa crucial y que marca un antes y un después en la organización y el funcionamiento de las compañías que se aventuran en este proyecto, pero antes de involucrarnos directamente en la implementación de BI, existen una serie de puntos que hay que tener en cuenta antes de hacer todo este proceso, nombraremos algunos de los puntos a modo de interrogantes para dar un mejor lineamiento de lo que en realidad usted necesita, los puntos son nombrados a continuación:


1.    ¿Realmente lo que necesito lo solucionará un BI?: este punto es base y debe ser tenido en cuenta antes que cualquier otro, ya que un mal planteamiento de este puede llevar a consecuencia catastróficas. Para resolverlo, hay que tener muy claro y definido tanto nuestro problema como las funciones y beneficios que brinda BI, si su compañía presenta antecedentes en malas decisiones debido a problemas en entender la información proporcionada en reportes e informes, puede ser esto una alerta de lo que necesita en efecto es BI.

2.    ¿Qué limitaciones hay dentro de mi empresa?: como hemos visto en las últimas publicaciones, BI se soporta de una serie de herramientas las varían tanto de su funcionalidad como de los componentes que estas necesitan para trabajar con normalidad, es necesario conocer muy bien los recursos que dispone la compañía y los que tiene en el momento tales como sus utilidades, sus aplicaciones y su infraestructura (tanto de equipos como de red) para así conocer muy bien las limitantes que existen y que un determinado BI pueda soportar para así evitar futuros gastos no deseados como la compra de equipos y aplicaciones para que la herramienta funcione con normalidad.

3.    ¿Mi personal está enterado del cambio?: BI como cualquier solución de software implica que habrán cambios en la compañía, algunos de esos cambios implica en el “¿cómo se hacen las cosas” en algunas funciones, es necesario comunicar a tiempo que se tiene pensado implementar una solución que puede cambiar muchas de las cosas y forma de trabajar en la actualidad. Este punto es uno de los más constantes en toda la etapa de implementación ya que se tendrá un constante contacto con el personal en temas como pueden ser la capacitación para usar la herramienta, las metas que se tienen propuestas para probar la inversión realizada, entre otros.

4.    ¿Tengo algún conocimiento del mercado en cuestión?: el mercado de BI es muy amplio y se tienen infinidad de opciones en el tipo de servicios ofrecidos a los clientes, esto puede ser un riesgo potencial ya que muchos de esos proveedores pueden tomar provecho de eso y persuadir a los clientes de que su solución es la más adecuada cuando esta no lo puede ser tanto y ser el inicio de un dolor de cabeza incuso mayor al que se tiene. La solución a esto, es investigar y hacer un trabajo de campo en las soluciones que brindan los proveedores ya sea por referencias o la misma experiencia adquirida, para así no “tragar entero de los proveedores” y hacer más fácil el proceso de selección.

Si las interrogantes expuestas anteriormente están muy alineadas con lo que usted requiere y además de que la solución propuesta se encuentra muy asociada a que usted ya tiene, ha dado usted entonces un paso muy grande para iniciar la implementación de un BI en su compañía, con lo que esperamos que esta herramienta le de muchos beneficios y su empresa tenga la prosperidad que usted desea tener.

Autor: John Cortés 

domingo, 17 de marzo de 2013

Cuentas con la información, Ahora ¿Cómo representarla?

Para concluir el tema de herramientas necesarias para BI, vamos a mencionar una, que si bien no esta relacionada directamente con la solución, tiene una importancia al final del proceso de éste, si integramos cada uno de los ingredientes mencionados de momento,nos encontramos con el problema de representar los resultados y llevarlos a la mesa directiva. Llevar a cabo esta labor implica preguntarnos cosas como: Un formato estándar, medios de publicación, velocidad de respuesta, que grado de interacción con la información y que tan clara ser ésta? Esto puede llegar a ser complejo. Pues bien, Navegando por el mar de información que encontramos en internet, existen herramientas con este fin que ayudarán al responsable en ejecutar la solución de BI, ya que solo se enfocará en la calidad de la información, diseñando formatos y plantillas, que podrán ser integrados en la solución BI sin ningún grado de complejidad como un módulo presentación de informes para los usuarios finales.




  



Hoy mencionaremos una aplicación de estas multiplataforma.  La herramienta iReport es un constructor / diseñador de informes visual, poderoso, intuitivo y fácil de usar para JasperReports escrito en Java. Este instrumento permite que los usuarios corrijan visualmente informes complejos con cartas, imágenes, subinformes, algunas de sus bondades




- Crear un diseño de informe en blanco.
- Definir una conexión de base de datos  o data warehouse.
- Definir una consulta a la base de datos.
- Arrastre los campos a la banda de detalle.
- Mejorar el diseño.
- Apoyo para datos relativos.
- HTML5 gráficos.
- XML / Un soporte de SASS.
- Las tablas anidadas.

 



Referencias: 

domingo, 10 de marzo de 2013

Almacena, Organiza y Analiza la información


Un concepto en boga desde hace varias décadas hoy es de verdad más cierto que nunca, y por supuesto es una realidad nada virtual pero sí definitivamente digital y dice así: “Quien tiene la información tiene el poder”. Con intención o sin ella, solo como consecuencia del devenir normal de las organizaciones, la información que se genera por las operaciones empresariales, los registros de tantas y tantas transacciones al interior de la compañía, y por supuesto, en relación con los clientes generan tal cumulo de datos que bien conservados y almacenados debidamente constituyen verdaderas bodegas de información que en inglés son designadas como “Data Wharehouse”, término que en español lo podemos leer como bodegas de datos o almacén de datos. Por ejemplo, el tráfico de larga distancia que se transporta por un operador de telecomunicaciones, puede ser almacenado en tiempo o en valores monetarios y de acuerdo a la información descriptiva, posible, indicada en los registros de las conferencias telefónicas puede saberse el destino de la llamada, el día, la hora de la comunicación, hechos estos que debidamente analizados puede conducir a plantear comportamientos específicos a nivel de mercadeo del producto larga distancia. Se puede extraer “el jugo” e identificar horarios, o días, o destinos de bajo  uso de la red y mediante promociones incentivar la utilización deservicio.


Imagen 1:
Uso de Data Wharehouse

Es interesante como el Data Wharehouse permite organizar información almacenada de manera estructurada y a su vez analizarla, mediante herramientas como los cubos OLAP (On Line Analitical Processing), ya mencionados en una publicación anterior.  Estos cubos geométricamente los podemos interpretar como un sólido en un espacio de k-dimensiones en el cual cada característica del registro de datos es una dimensión, el cubo que sea definido se refiere a los datos pertinentes almacenados en la Bodega de Datos y analiza de manera ordenada construyendo los debidos resúmenes de información con sentido para el usuario de acuerdo a las definiciones establecidas para el cubo OLAP.



Imagen 2:
Integración Data Wharehouse-OLAP

Una vez más concluimos como la información es una herramienta esencial para el éxito de una compañía y como menciona Bill Gates, una las personas más hábiles de los negocios: “Ganar o perder dependerá de cómo captemos, gestionemos y utilicemos la información”.  

Referencias:



domingo, 3 de marzo de 2013

El futuro como herramienta


Continuando con las herramientas de BI, hoy resaltaremos una de las herramientas de tipo analítico, la cual nos permite realizar proyecciones a futuro en base a los datos históricos recolectados, esta herramienta es conocida como “Forecasting”.

Imagen 1:
Proyección de ventas mensuales (gráfico)

Forecasting realiza gráficos y presenta datos de estimación de un producto o recurso en particular, para ello forecasting toma los datos obtenidos del producto o recurso a estimar y realiza un patrón (serie) de acuerdo al orden cronológico en el que se presentaron esos datos (no confundir con el tiempo en que los datos fueron ingresados al sistema), agregando eventualidades o fenómenos que hayan incidido directa o indirectamente durante un intervalo de tiempo que se encuentre incluido a los datos recolectados.

Una utilidad de Forecasting puede ser la estimación de la producción adecuada para cubrir la demanda en un periodo específico del año.  Para dar una mejor ilustración del uso de Forecasting, mostraremos un ejemplo real de un Forecasting de una empresa de Telecomunicaciones.

 Imagen 2:
Forecasting de una compañía de Telecomunicaciones

La siguiente imagen muestra la proyección del flujo de caja tomado en los años 2008 y 2009 en una empresa de telecomunicaciones, vemos que el flujo viene apoyado de factores que alteran el curso del flujo como los son los impuestos, y demás descuentos aplicados. Vemos que en los primeros años se tiene un alto porcentaje de acierto, dando a entender que las cifras que se presenten en esos años sean muy similares a las que proyecta el Forecasting, en el trascurso del tiempo la probabilidad de acierto tiende a reducir y los valores presentados no cambian prácticamente, dando así la tendencia a la imprecisión a proyecciones ya muy lejanas. 

Referencias:
>http://www.pwc.com/gx/en/communications/telecom-industry-accounting-group/valuing-deferred-tax-assets.jhtml.
>http://www.franciscomojica.com/articulos/adalfut.pdf.