diff --git a/panels/parallelcoordinates/module.js b/panels/parallelcoordinates/module.js index 1ad21cf57cd252..ee4fc8bc2f0226 100644 --- a/panels/parallelcoordinates/module.js +++ b/panels/parallelcoordinates/module.js @@ -241,7 +241,16 @@ angular.module('kibana.parallelcoordinates', []) //.fade class hides the "inactive" lines, helps speed up rendering significantly directive.foregroundLines.classed("fade", function(d) { return !actives.every(function(p, i) { - var inside = extents[i][0] <= d[p] && d[p] <= extents[i][1]; + + var pointValue; + + if (directive.ordinals[p] === true) { + pointValue = directive.y[p](d[p]); + } else { + pointValue = d[p]; + } + + var inside = extents[i][0] <= pointValue && pointValue <= extents[i][1]; return inside; }); }); @@ -305,32 +314,53 @@ angular.module('kibana.parallelcoordinates', []) directive.y = {}; directive.line = d3.svg.line().interpolate('cardinal'); - directive.axis = d3.svg.axis().orient("left"); + directive.axis = d3.svg.axis().orient("left").ticks(5); + directive.ordinals = {}; + scope.panel.fields.forEach(function(d) { + var firstField = scope.data[0][d]; - var colorExtent = d3.extent(scope.data, function(p) { return +p[scope.panel.fields[0]]; }); + if (_.isString(firstField)) { + if (isValidDate(new Date(firstField))) { - directive.colors = d3.scale.linear() - .domain([colorExtent[0],colorExtent[1]]) - .range(["#4580FF", "#FF9245"]); + //convert date timestamps to actual dates + _.map(scope.data, function(v) { + v[d] = new Date(v[d]); + }); + var extents = d3.extent(scope.data, function(p) { return p[d]; }); - scope.panel.fields.forEach(function(d) { + directive.y[d] = d3.time.scale() + .domain([extents[0],extents[1]]) + .range([directive.h, 0]); + + } else { + directive.ordinals[d] = true; - //If it is a string, setup an ordinal scale. - //Otherwise, use a linear scale for numbers - if (_.isString(scope.data[0][d])) { + var value = function(v) { return v[d]; }; + var values = _.map(_.uniq(scope.data, value),value); - var value = function(v) { return v[d]; }; - var values = _.map(_.uniq(scope.data, value),value); + directive.y[d] = d3.scale.ordinal() + .domain(values) + .rangePoints([directive.h, 0]); - directive.y[d] = d3.scale.ordinal() - .domain(values) - .rangeBands([directive.h, 0]); - } else if (_.isNumber(scope.data[0][d])) { + } + + } else if (_.isNumber(firstField)) { directive.y[d] = d3.scale.linear() .domain(d3.extent(scope.data, function(p) { return +p[d]; })) .range([directive.h, 0]); + + } else if (_.isDate(firstField)) { + //this section is only used after timestamps have been parsed into actual date objects... + //avoids reparsing + + var extents = d3.extent(scope.data, function(p) { return p[d]; }); + + directive.y[d] = d3.time.scale() + .domain([extents[0],extents[1]]) + .range([directive.h, 0]); + } directive.y[d].brush = d3.svg.brush() @@ -338,6 +368,8 @@ angular.module('kibana.parallelcoordinates', []) .on("brush", brush); }); + //setup the colors for the lines + setColors(); //pull out the actively selected columns for rendering the axis/lines var activeData = _.map(scope.data, function(d) { @@ -439,6 +471,43 @@ angular.module('kibana.parallelcoordinates', []) } + function setColors() { + + var firstPanelField = scope.data[0][scope.panel.fields[0]]; + var extents = d3.extent(scope.data, function(p) { return p[scope.panel.fields[0]]; }); + + if (_.isString(firstPanelField)) { + + var value = function(v) { return v[firstPanelField]; }; + var values = _.map(_.uniq(scope.data, value),value); + + values = scope.data; + directive.colors = d3.scale.ordinal() + .domain(values) + .range(d3.range(values.length).map(d3.scale.linear() + .domain([0, values.length - 1]) + .range(["red", "blue"]) + .interpolate(d3.interpolateLab))); + + } else if (_.isNumber(firstPanelField)) { + directive.colors = d3.scale.linear() + .domain([extents[0],extents[1]]) + .range(["#4580FF", "#FF9245"]); + + } else if (_.isDate(firstPanelField)) { + directive.colors = d3.time.scale() + .domain([extents[0],extents[1]]) + .range(["#4580FF", "#FF9245"]); + } + + } + + function isValidDate(d) { + if ( Object.prototype.toString.call(d) !== "[object Date]" ) + return false; + return !isNaN(d.getTime()); + } + } }; }); \ No newline at end of file