[big number] various improvements (#2912)

* [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
This commit is contained in:
Maxime Beauchemin 2017-06-08 08:50:30 -07:00 committed by GitHub
parent 0e6f754af9
commit 24a2f5b8f0
7 changed files with 107 additions and 111 deletions

View File

@ -177,7 +177,7 @@ const px = function () {
$(selector + ' div.alert').remove();
},
width() {
return token.width();
return container.width();
},
height() {
let others = 0;

View File

@ -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",

View File

@ -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%;
}

View File

@ -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;
}

View File

@ -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);
@ -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])
@ -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')
@ -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 () {

View File

@ -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%;
}

View File

@ -1,10 +1,11 @@
import d3 from 'd3';
import $ from 'jquery';
import d3tip from 'd3-tip';
import { colorScalerFactory } from '../javascripts/modules/colors';
import '../stylesheets/d3tip.css';
import './heatmap.css';
const $ = require('jquery');
d3.tip = require('d3-tip');
require('./heatmap.css');
// Inspired from http://bl.ocks.org/mbostock/3074470
// https://jsfiddle.net/cyril123/h0reyumq/
@ -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);
@ -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()
@ -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;