Browse Source

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

pull/1616/head
Masayuki Tanaka 10 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.legend.js',
'src/api.chart.js',
'src/api.tooltip.js',
'src/c3.axis.js',
'src/tail.js'
]

79
c3.js

@ -1379,6 +1379,11 @@
});
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) {
var $$ = this;
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
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; });
};
c3_chart_internal_fn.filterRemoveNull = function (data) {
@ -2078,8 +2083,8 @@
selectedData = newData.concat(selectedData); // Add remained
// Expand shapes for selection
if (config.point_focus_expand_enabled) { $$.expandCircles(index); }
$$.expandBars(index);
if (config.point_focus_expand_enabled) { $$.expandCircles(index, null, true); }
$$.expandBars(index, null, true);
// Call event handler
$$.main.selectAll('.' + CLASS.shape + '-' + index).each(function (d) {
@ -2092,7 +2097,7 @@
$$.hideXGridFocus();
$$.hideTooltip();
// Undo expanded shapes
$$.unexpandCircles(index);
$$.unexpandCircles();
$$.unexpandBars();
// Call event handler
$$.main.selectAll('.' + CLASS.shape + '-' + index).each(function (d) {
@ -2131,7 +2136,7 @@
$$.hideTooltip();
if (!config.data_selection_grouped) {
$$.unexpandCircles(index);
$$.unexpandBars();
$$.unexpandBars(index);
}
}
})
@ -2150,8 +2155,8 @@
if (!config.tooltip_grouped) {
$$.showTooltip([d], d3.mouse(this));
$$.showXGridFocus([d]);
if (config.point_focus_expand_enabled) { $$.expandCircles(index, d.id); }
$$.expandBars(index, d.id);
if (config.point_focus_expand_enabled) { $$.expandCircles(index, d.id, true); }
$$.expandBars(index, d.id, true);
}
});
})
@ -2204,7 +2209,7 @@
if ($$.isScatterType(closest)) {
sameXData = [closest];
} else {
sameXData = $$.filterSameX(targetsToShow, closest.x);
sameXData = $$.filterByX(targetsToShow, closest.x);
}
// show tooltip when cursor is close to some point
@ -2215,8 +2220,7 @@
// expand points
if (config.point_focus_expand_enabled) {
$$.unexpandCircles();
$$.expandCircles(closest.index, closest.id);
$$.expandCircles(closest.index, closest.id, true);
}
// Show xgrid focus line
@ -2261,6 +2265,19 @@
)
.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 () {
var $$ = this, config = $$.config;
@ -2725,9 +2742,10 @@
var $$ = this;
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,
r = $$.pointExpandedR.bind($$);
if (reset) { $$.unexpandCircles(); }
$$.getCircles(i, id)
.classed(CLASS.EXPANDED, true)
.attr('r', r);
@ -2816,8 +2834,9 @@
var $$ = this;
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;
if (reset) { $$.unexpandBars(); }
$$.getBars(i).classed(CLASS.EXPANDED, true);
};
c3_chart_internal_fn.unexpandBars = function (i) {
@ -5936,6 +5955,42 @@
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:
// 1. category axis
// 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
</a>
</div>
<div class="col-md-4">
<h3>Tooltip</h3>
<a href="./samples/api_tooltip_show.html">
Show tooltip programmatically
</a>
</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;
};
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) {
var $$ = this;
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
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; });
};
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
// Expand shapes for selection
if (config.point_focus_expand_enabled) { $$.expandCircles(index); }
$$.expandBars(index);
if (config.point_focus_expand_enabled) { $$.expandCircles(index, null, true); }
$$.expandBars(index, null, true);
// Call event handler
$$.main.selectAll('.' + CLASS.shape + '-' + index).each(function (d) {
@ -130,7 +130,7 @@ c3_chart_internal_fn.generateEventRectsForSingleX = function (eventRectEnter) {
$$.hideXGridFocus();
$$.hideTooltip();
// Undo expanded shapes
$$.unexpandCircles(index);
$$.unexpandCircles();
$$.unexpandBars();
// Call event handler
$$.main.selectAll('.' + CLASS.shape + '-' + index).each(function (d) {
@ -169,7 +169,7 @@ c3_chart_internal_fn.generateEventRectsForSingleX = function (eventRectEnter) {
$$.hideTooltip();
if (!config.data_selection_grouped) {
$$.unexpandCircles(index);
$$.unexpandBars();
$$.unexpandBars(index);
}
}
})
@ -188,8 +188,8 @@ c3_chart_internal_fn.generateEventRectsForSingleX = function (eventRectEnter) {
if (!config.tooltip_grouped) {
$$.showTooltip([d], d3.mouse(this));
$$.showXGridFocus([d]);
if (config.point_focus_expand_enabled) { $$.expandCircles(index, d.id); }
$$.expandBars(index, d.id);
if (config.point_focus_expand_enabled) { $$.expandCircles(index, d.id, true); }
$$.expandBars(index, d.id, true);
}
});
})
@ -242,7 +242,7 @@ c3_chart_internal_fn.generateEventRectsForMultipleXs = function (eventRectEnter)
if ($$.isScatterType(closest)) {
sameXData = [closest];
} else {
sameXData = $$.filterSameX(targetsToShow, closest.x);
sameXData = $$.filterByX(targetsToShow, closest.x);
}
// show tooltip when cursor is close to some point
@ -253,8 +253,7 @@ c3_chart_internal_fn.generateEventRectsForMultipleXs = function (eventRectEnter)
// expand points
if (config.point_focus_expand_enabled) {
$$.unexpandCircles();
$$.expandCircles(closest.index, closest.id);
$$.expandCircles(closest.index, closest.id, true);
}
// Show xgrid focus line
@ -299,3 +298,16 @@ c3_chart_internal_fn.generateEventRectsForMultipleXs = function (eventRectEnter)
)
.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;
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;
if (reset) { $$.unexpandBars(); }
$$.getBars(i).classed(CLASS.EXPANDED, true);
};
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;
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,
r = $$.pointExpandedR.bind($$);
if (reset) { $$.unexpandCircles(); }
$$.getCircles(i, id)
.classed(CLASS.EXPANDED, true)
.attr('r', r);

Loading…
Cancel
Save