Browse Source

Add tooltip.show/hide API - #467 #509

pull/1616/head
Masayuki Tanaka 11 years ago
parent
commit
31cc5e4e88
  1. 1
      Gruntfile.coffee
  2. 79
      c3.js
  3. 8
      c3.min.js
  4. 6
      htdocs/index.html
  5. 38
      htdocs/samples/api_tooltip_show.html
  6. 35
      src/api.tooltip.js
  7. 7
      src/data.js
  8. 30
      src/interaction.js
  9. 3
      src/shape.bar.js
  10. 3
      src/shape.line.js

1
Gruntfile.coffee

@ -67,6 +67,7 @@ module.exports = (grunt) ->
'src/api.axis.js', 'src/api.axis.js',
'src/api.legend.js', 'src/api.legend.js',
'src/api.chart.js', 'src/api.chart.js',
'src/api.tooltip.js',
'src/c3.axis.js', 'src/c3.axis.js',
'src/tail.js' 'src/tail.js'
] ]

79
c3.js

@ -1379,6 +1379,11 @@
}); });
return xValues; return xValues;
}; };
c3_chart_internal_fn.getIndexByX = function (x) {
var $$ = this,
data = $$.filterByX($$.data.targets, x);
return data.length ? data[0].index : null;
};
c3_chart_internal_fn.getXValue = function (id, i) { c3_chart_internal_fn.getXValue = function (id, i) {
var $$ = this; var $$ = this;
return id in $$.data.xs && $$.data.xs[id] && isValue($$.data.xs[id][i]) ? $$.data.xs[id][i] : i; return id in $$.data.xs && $$.data.xs[id] && isValue($$.data.xs[id][i]) ? $$.data.xs[id][i] : i;
@ -1582,7 +1587,7 @@
} // TODO: accept name array for order } // TODO: accept name array for order
return targets; return targets;
}; };
c3_chart_internal_fn.filterSameX = function (targets, x) { c3_chart_internal_fn.filterByX = function (targets, x) {
return this.d3.merge(targets.map(function (t) { return t.values; })).filter(function (v) { return v.x - x === 0; }); return this.d3.merge(targets.map(function (t) { return t.values; })).filter(function (v) { return v.x - x === 0; });
}; };
c3_chart_internal_fn.filterRemoveNull = function (data) { c3_chart_internal_fn.filterRemoveNull = function (data) {
@ -2078,8 +2083,8 @@
selectedData = newData.concat(selectedData); // Add remained selectedData = newData.concat(selectedData); // Add remained
// Expand shapes for selection // Expand shapes for selection
if (config.point_focus_expand_enabled) { $$.expandCircles(index); } if (config.point_focus_expand_enabled) { $$.expandCircles(index, null, true); }
$$.expandBars(index); $$.expandBars(index, null, true);
// Call event handler // Call event handler
$$.main.selectAll('.' + CLASS.shape + '-' + index).each(function (d) { $$.main.selectAll('.' + CLASS.shape + '-' + index).each(function (d) {
@ -2092,7 +2097,7 @@
$$.hideXGridFocus(); $$.hideXGridFocus();
$$.hideTooltip(); $$.hideTooltip();
// Undo expanded shapes // Undo expanded shapes
$$.unexpandCircles(index); $$.unexpandCircles();
$$.unexpandBars(); $$.unexpandBars();
// Call event handler // Call event handler
$$.main.selectAll('.' + CLASS.shape + '-' + index).each(function (d) { $$.main.selectAll('.' + CLASS.shape + '-' + index).each(function (d) {
@ -2131,7 +2136,7 @@
$$.hideTooltip(); $$.hideTooltip();
if (!config.data_selection_grouped) { if (!config.data_selection_grouped) {
$$.unexpandCircles(index); $$.unexpandCircles(index);
$$.unexpandBars(); $$.unexpandBars(index);
} }
} }
}) })
@ -2150,8 +2155,8 @@
if (!config.tooltip_grouped) { if (!config.tooltip_grouped) {
$$.showTooltip([d], d3.mouse(this)); $$.showTooltip([d], d3.mouse(this));
$$.showXGridFocus([d]); $$.showXGridFocus([d]);
if (config.point_focus_expand_enabled) { $$.expandCircles(index, d.id); } if (config.point_focus_expand_enabled) { $$.expandCircles(index, d.id, true); }
$$.expandBars(index, d.id); $$.expandBars(index, d.id, true);
} }
}); });
}) })
@ -2204,7 +2209,7 @@
if ($$.isScatterType(closest)) { if ($$.isScatterType(closest)) {
sameXData = [closest]; sameXData = [closest];
} else { } else {
sameXData = $$.filterSameX(targetsToShow, closest.x); sameXData = $$.filterByX(targetsToShow, closest.x);
} }
// show tooltip when cursor is close to some point // show tooltip when cursor is close to some point
@ -2215,8 +2220,7 @@
// expand points // expand points
if (config.point_focus_expand_enabled) { if (config.point_focus_expand_enabled) {
$$.unexpandCircles(); $$.expandCircles(closest.index, closest.id, true);
$$.expandCircles(closest.index, closest.id);
} }
// Show xgrid focus line // Show xgrid focus line
@ -2261,6 +2265,19 @@
) )
.on("dblclick.zoom", null); .on("dblclick.zoom", null);
}; };
c3_chart_internal_fn.dispatchEvent = function (type, index, mouse) {
var $$ = this,
selector = '.' + CLASS.eventRect + (!$$.isMultipleX() ? '-' + index : ''),
eventRect = $$.main.select(selector).node(),
box = eventRect.getBoundingClientRect(),
x = box.left + (mouse ? mouse[0] : 0),
y = box.top + (mouse ? mouse[1] : 0),
event = document.createEvent("MouseEvents");
event.initMouseEvent(type, true, true, window, 0, x, y, x, y,
false, false, false, false, 0, null);
eventRect.dispatchEvent(event);
};
c3_chart_internal_fn.getCurrentWidth = function () { c3_chart_internal_fn.getCurrentWidth = function () {
var $$ = this, config = $$.config; var $$ = this, config = $$.config;
@ -2725,9 +2742,10 @@
var $$ = this; var $$ = this;
return (id ? $$.main.selectAll('.' + CLASS.circles + $$.getTargetSelectorSuffix(id)) : $$.main).selectAll('.' + CLASS.circle + (isValue(i) ? '-' + i : '')); return (id ? $$.main.selectAll('.' + CLASS.circles + $$.getTargetSelectorSuffix(id)) : $$.main).selectAll('.' + CLASS.circle + (isValue(i) ? '-' + i : ''));
}; };
c3_chart_internal_fn.expandCircles = function (i, id) { c3_chart_internal_fn.expandCircles = function (i, id, reset) {
var $$ = this, var $$ = this,
r = $$.pointExpandedR.bind($$); r = $$.pointExpandedR.bind($$);
if (reset) { $$.unexpandCircles(); }
$$.getCircles(i, id) $$.getCircles(i, id)
.classed(CLASS.EXPANDED, true) .classed(CLASS.EXPANDED, true)
.attr('r', r); .attr('r', r);
@ -2816,8 +2834,9 @@
var $$ = this; var $$ = this;
return $$.main.selectAll('.' + CLASS.bar + (isValue(i) ? '-' + i : '')); return $$.main.selectAll('.' + CLASS.bar + (isValue(i) ? '-' + i : ''));
}; };
c3_chart_internal_fn.expandBars = function (i) { c3_chart_internal_fn.expandBars = function (i, id, reset) {
var $$ = this; var $$ = this;
if (reset) { $$.unexpandBars(); }
$$.getBars(i).classed(CLASS.EXPANDED, true); $$.getBars(i).classed(CLASS.EXPANDED, true);
}; };
c3_chart_internal_fn.unexpandBars = function (i) { c3_chart_internal_fn.unexpandBars = function (i) {
@ -5936,6 +5955,42 @@
window.onresize = null; window.onresize = null;
}; };
c3_chart_fn.tooltip = function () {};
c3_chart_fn.tooltip.show = function (args) {
var $$ = this.internal, index, mouse;
// determine mouse position on the chart
if (args.mouse) {
mouse = args.mouse;
}
// determine focus data
if (args.data) {
if ($$.isMultipleX()) {
// if multiple xs, target point will be determined by mouse
mouse = [$$.x(args.data.x), $$.getYScale(args.data.id)(args.data.value)];
index = null;
} else {
// TODO: when tooltip_grouped = false
index = isValue(args.data.index) ? args.data.index : $$.getIndexByX(args.data.x);
}
}
else if (args.x) {
index = $$.getIndexByX(args.x);
}
else if (args.index) {
index = args.index;
}
// emulate mouse events to show
$$.dispatchEvent('mouseover', index, mouse);
$$.dispatchEvent('mousemove', index, mouse);
};
c3_chart_fn.tooltip.hide = function () {
// TODO: get target data by checking the state of focus
this.internal.dispatchEvent('mouseout', 0);
};
// Features: // Features:
// 1. category axis // 1. category axis
// 2. ceil values of translate/x/y to int for half pixel antialiasing // 2. ceil values of translate/x/y to int for half pixel antialiasing

8
c3.min.js vendored

File diff suppressed because one or more lines are too long

6
htdocs/index.html

@ -434,6 +434,12 @@
Update data color Update data color
</a> </a>
</div> </div>
<div class="col-md-4">
<h3>Tooltip</h3>
<a href="./samples/api_tooltip_show.html">
Show tooltip programmatically
</a>
</div>
</div> </div>
</div> </div>
</div> </div>

38
htdocs/samples/api_tooltip_show.html

@ -0,0 +1,38 @@
<html>
<head>
<link rel="stylesheet" type="text/css" href="/css/c3.css">
</head>
<body>
<div id="chart"></div>
<script src="http://d3js.org/d3.v3.min.js" charset="utf-8"></script>
<script src="/js/c3.js"></script>
<script>
var chart = c3.generate({
data: {
columns: [
['data1', 30, 200, 100, 400, 150, 250],
['data2', 50, 20, 10, 40, 15, 25]
],
}
});
setTimeout(function () {
chart.tooltip.show({ x: 1 });
}, 1000);
setTimeout(function () {
chart.tooltip.show({ index: 3 });
}, 2000);
setTimeout(function () {
chart.tooltip.show({ data: {x: 2} });
}, 3000);
setTimeout(function () {
chart.tooltip.hide();
}, 4000);
</script>
</body>
</html>

35
src/api.tooltip.js

@ -0,0 +1,35 @@
c3_chart_fn.tooltip = function () {};
c3_chart_fn.tooltip.show = function (args) {
var $$ = this.internal, index, mouse;
// determine mouse position on the chart
if (args.mouse) {
mouse = args.mouse;
}
// determine focus data
if (args.data) {
if ($$.isMultipleX()) {
// if multiple xs, target point will be determined by mouse
mouse = [$$.x(args.data.x), $$.getYScale(args.data.id)(args.data.value)];
index = null;
} else {
// TODO: when tooltip_grouped = false
index = isValue(args.data.index) ? args.data.index : $$.getIndexByX(args.data.x);
}
}
else if (args.x) {
index = $$.getIndexByX(args.x);
}
else if (args.index) {
index = args.index;
}
// emulate mouse events to show
$$.dispatchEvent('mouseover', index, mouse);
$$.dispatchEvent('mousemove', index, mouse);
};
c3_chart_fn.tooltip.hide = function () {
// TODO: get target data by checking the state of focus
this.internal.dispatchEvent('mouseout', 0);
};

7
src/data.js

@ -19,6 +19,11 @@ c3_chart_internal_fn.getXValuesOfXKey = function (key, targets) {
}); });
return xValues; return xValues;
}; };
c3_chart_internal_fn.getIndexByX = function (x) {
var $$ = this,
data = $$.filterByX($$.data.targets, x);
return data.length ? data[0].index : null;
};
c3_chart_internal_fn.getXValue = function (id, i) { c3_chart_internal_fn.getXValue = function (id, i) {
var $$ = this; var $$ = this;
return id in $$.data.xs && $$.data.xs[id] && isValue($$.data.xs[id][i]) ? $$.data.xs[id][i] : i; return id in $$.data.xs && $$.data.xs[id] && isValue($$.data.xs[id][i]) ? $$.data.xs[id][i] : i;
@ -222,7 +227,7 @@ c3_chart_internal_fn.orderTargets = function (targets) {
} // TODO: accept name array for order } // TODO: accept name array for order
return targets; return targets;
}; };
c3_chart_internal_fn.filterSameX = function (targets, x) { c3_chart_internal_fn.filterByX = function (targets, x) {
return this.d3.merge(targets.map(function (t) { return t.values; })).filter(function (v) { return v.x - x === 0; }); return this.d3.merge(targets.map(function (t) { return t.values; })).filter(function (v) { return v.x - x === 0; });
}; };
c3_chart_internal_fn.filterRemoveNull = function (data) { c3_chart_internal_fn.filterRemoveNull = function (data) {

30
src/interaction.js

@ -116,8 +116,8 @@ c3_chart_internal_fn.generateEventRectsForSingleX = function (eventRectEnter) {
selectedData = newData.concat(selectedData); // Add remained selectedData = newData.concat(selectedData); // Add remained
// Expand shapes for selection // Expand shapes for selection
if (config.point_focus_expand_enabled) { $$.expandCircles(index); } if (config.point_focus_expand_enabled) { $$.expandCircles(index, null, true); }
$$.expandBars(index); $$.expandBars(index, null, true);
// Call event handler // Call event handler
$$.main.selectAll('.' + CLASS.shape + '-' + index).each(function (d) { $$.main.selectAll('.' + CLASS.shape + '-' + index).each(function (d) {
@ -130,7 +130,7 @@ c3_chart_internal_fn.generateEventRectsForSingleX = function (eventRectEnter) {
$$.hideXGridFocus(); $$.hideXGridFocus();
$$.hideTooltip(); $$.hideTooltip();
// Undo expanded shapes // Undo expanded shapes
$$.unexpandCircles(index); $$.unexpandCircles();
$$.unexpandBars(); $$.unexpandBars();
// Call event handler // Call event handler
$$.main.selectAll('.' + CLASS.shape + '-' + index).each(function (d) { $$.main.selectAll('.' + CLASS.shape + '-' + index).each(function (d) {
@ -169,7 +169,7 @@ c3_chart_internal_fn.generateEventRectsForSingleX = function (eventRectEnter) {
$$.hideTooltip(); $$.hideTooltip();
if (!config.data_selection_grouped) { if (!config.data_selection_grouped) {
$$.unexpandCircles(index); $$.unexpandCircles(index);
$$.unexpandBars(); $$.unexpandBars(index);
} }
} }
}) })
@ -188,8 +188,8 @@ c3_chart_internal_fn.generateEventRectsForSingleX = function (eventRectEnter) {
if (!config.tooltip_grouped) { if (!config.tooltip_grouped) {
$$.showTooltip([d], d3.mouse(this)); $$.showTooltip([d], d3.mouse(this));
$$.showXGridFocus([d]); $$.showXGridFocus([d]);
if (config.point_focus_expand_enabled) { $$.expandCircles(index, d.id); } if (config.point_focus_expand_enabled) { $$.expandCircles(index, d.id, true); }
$$.expandBars(index, d.id); $$.expandBars(index, d.id, true);
} }
}); });
}) })
@ -242,7 +242,7 @@ c3_chart_internal_fn.generateEventRectsForMultipleXs = function (eventRectEnter)
if ($$.isScatterType(closest)) { if ($$.isScatterType(closest)) {
sameXData = [closest]; sameXData = [closest];
} else { } else {
sameXData = $$.filterSameX(targetsToShow, closest.x); sameXData = $$.filterByX(targetsToShow, closest.x);
} }
// show tooltip when cursor is close to some point // show tooltip when cursor is close to some point
@ -253,8 +253,7 @@ c3_chart_internal_fn.generateEventRectsForMultipleXs = function (eventRectEnter)
// expand points // expand points
if (config.point_focus_expand_enabled) { if (config.point_focus_expand_enabled) {
$$.unexpandCircles(); $$.expandCircles(closest.index, closest.id, true);
$$.expandCircles(closest.index, closest.id);
} }
// Show xgrid focus line // Show xgrid focus line
@ -299,3 +298,16 @@ c3_chart_internal_fn.generateEventRectsForMultipleXs = function (eventRectEnter)
) )
.on("dblclick.zoom", null); .on("dblclick.zoom", null);
}; };
c3_chart_internal_fn.dispatchEvent = function (type, index, mouse) {
var $$ = this,
selector = '.' + CLASS.eventRect + (!$$.isMultipleX() ? '-' + index : ''),
eventRect = $$.main.select(selector).node(),
box = eventRect.getBoundingClientRect(),
x = box.left + (mouse ? mouse[0] : 0),
y = box.top + (mouse ? mouse[1] : 0),
event = document.createEvent("MouseEvents");
event.initMouseEvent(type, true, true, window, 0, x, y, x, y,
false, false, false, false, 0, null);
eventRect.dispatchEvent(event);
};

3
src/shape.bar.js

@ -55,8 +55,9 @@ c3_chart_internal_fn.getBars = function (i) {
var $$ = this; var $$ = this;
return $$.main.selectAll('.' + CLASS.bar + (isValue(i) ? '-' + i : '')); return $$.main.selectAll('.' + CLASS.bar + (isValue(i) ? '-' + i : ''));
}; };
c3_chart_internal_fn.expandBars = function (i) { c3_chart_internal_fn.expandBars = function (i, id, reset) {
var $$ = this; var $$ = this;
if (reset) { $$.unexpandBars(); }
$$.getBars(i).classed(CLASS.EXPANDED, true); $$.getBars(i).classed(CLASS.EXPANDED, true);
}; };
c3_chart_internal_fn.unexpandBars = function (i) { c3_chart_internal_fn.unexpandBars = function (i) {

3
src/shape.line.js

@ -305,9 +305,10 @@ c3_chart_internal_fn.getCircles = function (i, id) {
var $$ = this; var $$ = this;
return (id ? $$.main.selectAll('.' + CLASS.circles + $$.getTargetSelectorSuffix(id)) : $$.main).selectAll('.' + CLASS.circle + (isValue(i) ? '-' + i : '')); return (id ? $$.main.selectAll('.' + CLASS.circles + $$.getTargetSelectorSuffix(id)) : $$.main).selectAll('.' + CLASS.circle + (isValue(i) ? '-' + i : ''));
}; };
c3_chart_internal_fn.expandCircles = function (i, id) { c3_chart_internal_fn.expandCircles = function (i, id, reset) {
var $$ = this, var $$ = this,
r = $$.pointExpandedR.bind($$); r = $$.pointExpandedR.bind($$);
if (reset) { $$.unexpandCircles(); }
$$.getCircles(i, id) $$.getCircles(i, id)
.classed(CLASS.EXPANDED, true) .classed(CLASS.EXPANDED, true)
.attr('r', r); .attr('r', r);

Loading…
Cancel
Save