mirror of
https://github.com/apache/superset.git
synced 2024-09-12 00:29:39 -04:00
[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:
parent
0e6f754af9
commit
24a2f5b8f0
@ -177,7 +177,7 @@ const px = function () {
|
||||
$(selector + ' div.alert').remove();
|
||||
},
|
||||
width() {
|
||||
return token.width();
|
||||
return container.width();
|
||||
},
|
||||
height() {
|
||||
let others = 0;
|
||||
|
@ -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",
|
||||
|
56
superset/assets/stylesheets/d3tip.css
Normal file
56
superset/assets/stylesheets/d3tip.css
Normal 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%;
|
||||
}
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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 () {
|
||||
|
@ -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%;
|
||||
}
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user