From 09c77242fc923856425f0571558dcfbe911eaafd Mon Sep 17 00:00:00 2001 From: Maxime Beauchemin Date: Tue, 26 Jan 2016 23:17:58 -0800 Subject: [PATCH] Working without zoom --- panoramix/static/lib/d3.tip.css | 2 +- panoramix/static/widgets/viz_heatmap.css | 1 - panoramix/static/widgets/viz_heatmap.js | 151 ++++++++++------------- 3 files changed, 69 insertions(+), 85 deletions(-) diff --git a/panoramix/static/lib/d3.tip.css b/panoramix/static/lib/d3.tip.css index fc9a4ecdeacc..bb9a5451a99b 100644 --- a/panoramix/static/lib/d3.tip.css +++ b/panoramix/static/lib/d3.tip.css @@ -1,6 +1,6 @@ .d3-tip { line-height: 1; - font-weight: bold; + font-size: 12px; padding: 12px; background: rgba(0, 0, 0, 0.8); color: #fff; diff --git a/panoramix/static/widgets/viz_heatmap.css b/panoramix/static/widgets/viz_heatmap.css index 89629b5ce19a..8f09a346692a 100644 --- a/panoramix/static/widgets/viz_heatmap.css +++ b/panoramix/static/widgets/viz_heatmap.css @@ -10,7 +10,6 @@ } .heatmap svg { - cursor: move; } .heatmap canvas, .heatmap img { diff --git a/panoramix/static/widgets/viz_heatmap.js b/panoramix/static/widgets/viz_heatmap.js index 0d8faf71db23..ee06b636b853 100644 --- a/panoramix/static/widgets/viz_heatmap.js +++ b/panoramix/static/widgets/viz_heatmap.js @@ -1,21 +1,25 @@ // Inspired from http://bl.ocks.org/mbostock/3074470 // https://jsfiddle.net/cyril123/h0reyumq/ px.registerViz('heatmap', function(slice) { + var margins = {t:0, r:0, b:50, l:50}; function refresh() { var width = slice.width(); var height = slice.height(); + var hmWidth = width - (margins.l + margins.r) + var hmHeight = height - (margins.b + margins.t) d3.json(slice.jsonEndpoint(), function(error, payload) { var matrix = {}; if (error){ slice.error(error.responseText); return ''; } - var heatmap = payload.data; + var fd = payload.form_data; + var data = payload.data; function ordScale(k, rangeBands, reverse) { if (reverse === undefined) reverse = false; domain = {}; - $.each(heatmap, function(i, d){ + $.each(data, function(i, d){ domain[d[k]] = true; }); domain = Object.keys(domain).sort(); @@ -30,98 +34,106 @@ px.registerViz('heatmap', function(slice) { } var xScale = ordScale('x'); var yScale = ordScale('y', undefined, true); - var xRbScale = ordScale('x', [0, width]); - var yRbScale = ordScale('y', [height, 0]); + var xRbScale = ordScale('x', [0, hmWidth]); + var yRbScale = ordScale('y', [hmHeight, 0]); var X = 0, Y = 1; - var canvasDim = [width, height]; var heatmapDim = [xRbScale.domain().length, yRbScale.domain().length]; - ext = d3.extent(heatmap, function(d){return d.v;}); - var color = d3.scale.linear() - .domain(ext) - .range(["#fff", "#000"]); + ext = d3.extent(data, function(d){return d.v;}); + function colorScalerFactory(colors, data, accessor){ + var ext = d3.extent(data, accessor); + var points = []; + var chunkSize = (ext[1] - ext[0]) / colors.length; + $.each(colors, function(i, c){ + points.push(i * chunkSize) + }); + return d3.scale.linear().domain(points).range(colors); + } + var color = colorScalerFactory(['white', 'yellow', 'red', 'black'], data, function(d){return d.v}); + var scale = [ d3.scale.linear() .domain([0, heatmapDim[X]]) - .range([0, canvasDim[X]]), + .range([0, hmWidth]), d3.scale.linear() .domain([0, heatmapDim[Y]]) - .range([canvasDim[Y], 0]) + .range([0, hmHeight]) ]; - var container = d3.select(slice.selector); + var container = d3.select(slice.selector) + .style("left", "0px") + .style("position", "relative") + .style("top", "0px"); var canvas = container.append("canvas") .attr("width", heatmapDim[X]) .attr("height", heatmapDim[Y]) - .attr("image-rendering", "pixelated") - .style("width", canvasDim[X] + "px") - .style("height", canvasDim[Y] + "px") + .style("width", hmWidth + "px") + .style("height", hmHeight + "px") + .style("left", margins.l + "px") + .style("top", margins.t + "px") .style("position", "absolute"); var svg = container.append("svg") - .attr("width", canvasDim[X]) - .attr("height", canvasDim[Y]) - .style("position", "relative"); + .attr("width", width) + .attr("height", height) + .style("left", "0px") + .style("top", "0px") + .style("position", "absolute"); + + var rect = svg.append('g') + .attr("transform", "translate(" + margins.l + "," + margins.t + ")") + .append('rect') + .style('fill-opacity', 0) + .attr('stroke', 'black') + .attr("width", hmWidth) + .attr("height", hmHeight); var tip = d3.tip() .attr('class', 'd3-tip') .offset(function(){ var k = d3.mouse(this); - var x = k[0] - (width / 2); - return [k[1] - 15, x]; + var x = k[0] - (hmWidth/ 2); + return [k[1] - 20, x]; }) .html(function (d) { var k = d3.mouse(this); var m = Math.floor(scale[0].invert(k[0])); var n = Math.floor(scale[1].invert(k[1])); - var obj = matrix[m][n]; - if (obj !== undefined) { + if(m in matrix && n in matrix[m]) { + var obj = matrix[m][n]; var s = ""; - s += "
X: " + obj.x + "
" - s += "
Y: " + obj.y + "
" - s += "
V: " + obj.v + "
" + s += "
" + fd.all_columns_x + ": " + obj.x + "
" + s += "
" + fd.all_columns_y +": " + obj.y + "
" + s += "
" + fd.metric + ": " + obj.v + "
" return s; } }) - svg.call(tip); - - var zoom = d3.behavior.zoom() - .center(canvasDim.map( - function(v) {return v / 2})) - .scaleExtent([1, 10]) - .x(scale[X]) - .y(scale[Y]) - .on("zoom", zoomEvent); - - svg.append("rect") - .style("pointer-events", "all") - .attr("width", canvasDim[X]) - .attr("height", canvasDim[Y]) - .attr("id", "mycanvas") - .style("fill", "none") - .call(zoom); - - var axis = [ - d3.svg.axis() + rect.call(tip); + + xAxis = d3.svg.axis() .scale(xRbScale) - .orient("top"), - d3.svg.axis() + .orient("bottom"); + yAxis = d3.svg.axis() .scale(yRbScale) - .orient("right") - ]; + .orient("left"); - var axisElement = [ svg.append("g") .attr("class", "x axis") - .attr("transform", "translate(-1," + (canvasDim[Y]-1) + ")"), + .attr("transform", "translate(" + margins.l + "," + (margins.t + hmHeight) + ")") + .call(xAxis) + .selectAll("text") + .style("text-anchor", "end") + .attr("transform", "rotate(-45)") + .style("font-weight", "bold"); svg.append("g") .attr("class", "y axis") - ]; + .attr("transform", "translate(" + margins.l + ", 0)") + .call(yAxis); - svg.on('mousemove', tip.show); - svg.on('mouseout', tip.hide); + rect.on('mousemove', tip.show); + rect.on('mouseout', tip.hide); var context = canvas.node().getContext("2d"); context.imageSmoothingEnabled = false; @@ -129,14 +141,13 @@ px.registerViz('heatmap', function(slice) { var imageDim; var imageScale; createImageObj(); - drawAxes(); // Compute the pixel colors; scaled by CSS. function createImageObj() { imageObj = new Image(); image = context.createImageData(heatmapDim[0], heatmapDim[1]); var pixs = {}; - $.each(heatmap, function(i, d) { + $.each(data, function(i, d) { var c = d3.rgb(color(d.v)); var x = xScale(d.x); var y = yScale(d.y); @@ -162,36 +173,10 @@ px.registerViz('heatmap', function(slice) { } context.putImageData(image, 0, 0); imageObj.src = canvas.node().toDataURL(); - imageDim = [imageObj.width, imageObj.height]; - imageScale = imageDim.map( - function(v, i){return v / canvasDim[i]}); - } - - function drawAxes() { - console.log(scale[0].domain()); - axisElement[0].call(axis[0]); - axisElement[1].call(axis[1]); - } - - function zoomEvent() { - var s = d3.event.scale; - var n = imageDim.map( - function(v) {return v * s}); - var t = d3.event.translate.map(function(v, i) { - return Math.min( - 0, - Math.max(v, canvasDim[i] - n[i] / imageScale[i])); - }); - zoom.translate(t); - var it = t.map( - function(v, i) {return v * imageScale[i]}); - context.clearRect(0, 0, canvasDim[X], canvasDim[Y]); - context.drawImage(imageObj, it[X], it[Y], n[X], n[Y]); - drawAxes(); } + slice.done(); }); - slice.done(); } return { render: refresh,