Skip to content

Commit

Permalink
[big number] various improvements (#2912)
Browse files Browse the repository at this point in the history
* [big number] various improvements

* dynamic number of X axis ticks based on width to prevent label overlap
* corrected overflow on the x axis
* improved tooltips (precise arrow and visible data point circle on hover)

* Fixing tooltips in heatmap viz
  • Loading branch information
mistercrunch committed Jun 8, 2017
1 parent 0e6f754 commit 24a2f5b
Show file tree
Hide file tree
Showing 7 changed files with 107 additions and 111 deletions.
2 changes: 1 addition & 1 deletion superset/assets/javascripts/modules/superset.js
Expand Up @@ -177,7 +177,7 @@ const px = function () {
$(selector + ' div.alert').remove();
},
width() {
return token.width();
return container.width();
},
height() {
let others = 0;
Expand Down
2 changes: 1 addition & 1 deletion superset/assets/package.json
Expand Up @@ -49,7 +49,7 @@
"d3-cloud": "^1.2.1",
"d3-sankey": "^0.4.1",
"d3-scale": "^1.0.3",
"d3-tip": "^0.7.1",
"d3-tip": "^0.6.7",
"datamaps": "^0.5.8",
"datatables-bootstrap3-plugin": "^0.5.0",
"datatables.net": "^1.10.13",
Expand Down
56 changes: 56 additions & 0 deletions superset/assets/stylesheets/d3tip.css
@@ -0,0 +1,56 @@
/* from d3-tip */
.d3-tip {
line-height: 1;
padding: 12px;
background: rgba(0, 0, 0, 0.8);
color: #fff;
border-radius: 2px;
pointer-events: none;
z-index: 1000;
}

/* Creates a small triangle extender for the tooltip */
.d3-tip:after {
box-sizing: border-box;
display: inline;
font-size: 10px;
width: 100%;
line-height: 1;
color: rgba(0, 0, 0, 0.8);
position: absolute;
pointer-events: none;
}

/* Northward tooltips */
.d3-tip.n:after {
content: "\25BC";
margin: -1px 0 0 0;
top: 100%;
left: 0;
text-align: center;
}

/* Eastward tooltips */
.d3-tip.e:after {
content: "\25C0";
margin: -4px 0 0 0;
top: 50%;
left: -8px;
}

/* Southward tooltips */
.d3-tip.s:after {
content: "\25B2";
margin: 0 0 1px 0;
top: -8px;
left: 0;
text-align: center;
}

/* Westward tooltips */
.d3-tip.w:after {
content: "\25B6";
margin: -4px 0 0 -1px;
top: 50%;
left: 100%;
}
10 changes: 1 addition & 9 deletions superset/assets/visualizations/big_number.css
Expand Up @@ -28,12 +28,4 @@
stroke: black;
stroke-width: 1;
}
.line-tooltip {
position: absolute;
text-align: left;
padding: 10px;
background: #ffffff;
border: 1px solid #ccc;
border-radius: 2px;
pointer-events: none;
}

58 changes: 31 additions & 27 deletions superset/assets/visualizations/big_number.js
@@ -1,7 +1,9 @@
import d3 from 'd3';
import d3tip from 'd3-tip';
import { formatDate } from '../javascripts/modules/dates';

require('./big_number.css');
import './big_number.css';
import '../stylesheets/d3tip.css';

function bigNumberVis(slice, payload) {
const div = d3.select(slice.selector);
Expand Down Expand Up @@ -39,9 +41,10 @@ function bigNumberVis(slice, payload) {
const dateExt = d3.extent(data, d => d[0]);
const valueExt = d3.extent(data, d => d[1]);

const margin = 20;
const scaleX = d3.time.scale.utc().domain(dateExt).range([margin, width - margin]);
const scaleY = d3.scale.linear().domain(valueExt).range([height - (margin), margin]);
const vMargin = 20;
const hMargin = 10;
const scaleX = d3.time.scale.utc().domain(dateExt).range([hMargin, width - hMargin]);
const scaleY = d3.scale.linear().domain(valueExt).range([height - (vMargin), vMargin]);
const colorRange = [d3.hsl(0, 1, 0.3), d3.hsl(120, 1, 0.3)];
const scaleColor = d3.scale
.linear().domain([-1, 1])
Expand Down Expand Up @@ -126,17 +129,18 @@ function bigNumberVis(slice, payload) {
const xAxis = d3.svg.axis()
.scale(scaleX)
.orient('bottom')
.ticks(4)
.ticks(Math.round(2 + (width / 150)))
.tickFormat(formatDate);
g.call(xAxis);
g.attr('transform', 'translate(0,' + (height - margin) + ')');
g.attr('transform', 'translate(0,' + (height - vMargin) + ')');

g = gAxis.append('g').attr('transform', 'translate(' + (width - margin) + ',0)');
g = gAxis.append('g').attr('transform', 'translate(' + (width - hMargin) + ',0)');
const yAxis = d3.svg.axis()
.scale(scaleY)
.orient('left')
.tickFormat(d3.format(fd.y_axis_format))
.tickValues(valueExt);

g.call(yAxis);
g.selectAll('text')
.style('text-anchor', 'end')
Expand All @@ -146,44 +150,44 @@ function bigNumberVis(slice, payload) {
g.selectAll('text')
.style('font-size', '10px');

// Define the div for the tooltip
const tooltipEl =
d3.select('body')
.append('div')
.attr('class', 'line-tooltip')
.attr('width', 200)
.attr('height', 200)
.style('opacity', 0);

const renderTooltip = (d) => {
const date = formatDate(d[0]);
const value = f(d[1]);
return `
<div>
<span style="float: left; margin-right: 20px;"><strong>${date}</strong></span>
<span style="float: right">${value}</span>
<span style="margin-right: 10px;">${date}: </span>
<strong>${value}</strong>
</div>
`;
};

const tip = d3tip()
.attr('class', 'd3-tip')
.direction('n')
.offset([-5, 0])
.html(renderTooltip);
svg.call(tip);

// Add the scatterplot and trigger the mouse events for the tooltips
svg
.selectAll('dot')
.data(data)
.enter()
.append('circle')
.attr('r', 10)
.attr('r', 3)
.attr('stroke-width', 15)
.attr('stroke', 'transparent')
.attr('stroke-location', 'outside')
.attr('cx', d => scaleX(d[0]))
.attr('cy', d => scaleY(d[1]))
.attr('fill-opacity', '0')
.on('mouseover', (d) => {
tooltipEl.html(renderTooltip(d))
.style('left', (d3.event.pageX) + 'px')
.style('top', (d3.event.pageY) + 'px');
tooltipEl.transition().duration(200).style('opacity', 0.9);
.attr('fill-opacity', 0)
.on('mouseover', function (d) {
d3.select(this).attr('fill-opacity', 1);
tip.show(d);
})
.on('mouseout', () => {
tooltipEl.transition().duration(500).style('opacity', 0);
.on('mouseout', function (d) {
d3.select(this).attr('fill-opacity', 0);
tip.hide(d);
});

div.on('mouseover', function () {
Expand Down
58 changes: 0 additions & 58 deletions superset/assets/visualizations/heatmap.css
Expand Up @@ -28,61 +28,3 @@
image-rendering: pixelated; /* Awesome future-browsers */
-ms-interpolation-mode: nearest-neighbor; /* IE */
}

/* from d3-tip */
.d3-tip {
line-height: 1;
font-weight: bold;
padding: 12px;
background: rgba(0, 0, 0, 0.8);
color: #fff;
border-radius: 2px;
pointer-events: none;
z-index: 1000;
}

/* Creates a small triangle extender for the tooltip */
.d3-tip:after {
box-sizing: border-box;
display: inline;
font-size: 10px;
width: 100%;
line-height: 1;
color: rgba(0, 0, 0, 0.8);
position: absolute;
pointer-events: none;
}

/* Northward tooltips */
.d3-tip.n:after {
content: "\25BC";
margin: -1px 0 0 0;
top: 100%;
left: 0;
text-align: center;
}

/* Eastward tooltips */
.d3-tip.e:after {
content: "\25C0";
margin: -4px 0 0 0;
top: 50%;
left: -8px;
}

/* Southward tooltips */
.d3-tip.s:after {
content: "\25B2";
margin: 0 0 1px 0;
top: -8px;
left: 0;
text-align: center;
}

/* Westward tooltips */
.d3-tip.w:after {
content: "\25B6";
margin: -4px 0 0 -1px;
top: 50%;
left: 100%;
}
32 changes: 17 additions & 15 deletions superset/assets/visualizations/heatmap.js
@@ -1,10 +1,11 @@
import d3 from 'd3';
import { colorScalerFactory } from '../javascripts/modules/colors';
import $ from 'jquery';
import d3tip from 'd3-tip';

const $ = require('jquery');
d3.tip = require('d3-tip');
import { colorScalerFactory } from '../javascripts/modules/colors';
import '../stylesheets/d3tip.css';
import './heatmap.css';

require('./heatmap.css');

// Inspired from http://bl.ocks.org/mbostock/3074470
// https://jsfiddle.net/cyril123/h0reyumq/
Expand Down Expand Up @@ -105,15 +106,7 @@ function heatmapVis(slice, payload) {
.style('top', headerHeight + 'px')
.style('position', 'absolute');

const rect = svg.append('g')
.attr('transform', 'translate(' + margin.left + ',' + margin.top + ')')
.append('rect')
.style('fill-opacity', 0)
.attr('stroke', 'black')
.attr('width', hmWidth)
.attr('height', hmHeight);

const tip = d3.tip()
const tip = d3tip()
.attr('class', 'd3-tip')
.offset(function () {
const k = d3.mouse(this);
Expand All @@ -140,6 +133,17 @@ function heatmapVis(slice, payload) {
return s;
});

const rect = svg.append('g')
.attr('transform', `translate(${margin.left}, ${margin.top})`)
.append('rect')
.attr('pointer-events', 'all')
.on('mousemove', tip.show)
.on('mouseout', tip.hide)
.style('fill-opacity', 0)
.attr('stroke', 'black')
.attr('width', hmWidth)
.attr('height', hmHeight);

rect.call(tip);

const xAxis = d3.svg.axis()
Expand Down Expand Up @@ -171,8 +175,6 @@ function heatmapVis(slice, payload) {
.attr('transform', 'translate(' + margin.left + ',' + margin.top + ')')
.call(yAxis);

rect.on('mousemove', tip.show);
rect.on('mouseout', tip.hide);

const context = canvas.node().getContext('2d');
context.imageSmoothingEnabled = false;
Expand Down

0 comments on commit 24a2f5b

Please sign in to comment.