'Chart.js 2.7.0 Grouped Horizontal Bar Chart, how to get tooltip to display data for one bar, not whole group?
Here is a Grouped Horizontal Bar Chart:
http://jsfiddle.net/jmpxgufu/185/
var ctx = document.getElementById("myChart").getContext("2d");
var chart = {
options: {
scales: {
yAxes: [{ barPercentage: 1.0 }],
},
tooltips: {
callbacks: {
label: function(tooltipItem, data) {
console.log(tooltipItem);
return data.datasets[tooltipItem.datasetIndex].label +': ' + data.datasets[tooltipItem.datasetIndex].data[tooltipItem.index].toLocaleString();
}
}
},
responsive: true,
maintainAspectRatio: false,
animation: {
onComplete: function(animation) {
}
}
},
type: 'horizontalBar',
data: {
labels: ['Topic1'],
datasets: [
{
label: 'Something',
borderColor: 'blue',
borderWidth: 1,
backgroundColor: Color('blue').alpha(0.5).rgbString(),
data: [40],
fill: false
},
{
label: 'Something else',
borderColor: 'orange',
borderWidth: 1,
backgroundColor: Color('orange').alpha(0.5).rgbString(),
data: [17],
fill: false
}
]
}};
var myLiveChart = new Chart(ctx, chart);
If you look at the chart, there are two bars (an orange and a blue) associated with the label 'Topic1'.
When I hover over just the orange bar it says:
Topic1
Something: 40
Something else: 17
When I hover over just the blue bar it says:
Topic1
Something: 40
Something else: 17
You will also notice that because there are two bars in the group, the function is executed twice, taking my string I am returning, and forming this "grouped" tooltip message (I put the console.log in there to show it is getting executed twice).
I only want the data for the bar I am hovering over.
When I hover over just the orange bar I want it to say:
Topic1
Something else: 17
When I hover over just the blue bar I want it to say:
Topic1
Something: 40
But, I haven't figured out how to determine which is the active bar (of the two).
What am I missing here?
Solution 1:[1]
tooltips: {
mode: 'nearest',
intersect: true
}
Solution 2:[2]
Here is a decent solution that requires just one GeometryReader.
For more information, check this article.
struct MyView: View {
@State private var offset: CGFloat?
var body: some View {
HStack {
Spacer()
Text("Some Text")
.anchorPreference(key: BoundsPreference.self, value: .bounds) { $0 }
Spacer(minLength: offset)
}
.backgroundPreferenceValue(BoundsPreference.self) { preferences in
GeometryReader { g in
preferences.map {
Color.clear.preference(key: OffsetPreference.self, value: offset(with: g.size.width - g[$0].width))
}
}
}
.onPreferenceChange(OffsetPreference.self) {
offset = $0
}
}
private func offset(with widthRemainder: CGFloat) -> CGFloat {
widthRemainder * (100.0 - X) / 100.0
}
}
private struct BoundsPreference: PreferenceKey {
typealias Value = Anchor<CGRect>?
static var defaultValue: Value = nil
static func reduce(value: inout Anchor<CGRect>?, nextValue: () -> Anchor<CGRect>?) {
value = nextValue()
}
}
private struct OffsetPreference: PreferenceKey {
typealias Value = CGFloat?
static var defaultValue: Value = nil
static func reduce(value: inout CGFloat?, nextValue: () -> CGFloat?) {
value = nextValue()
}
}
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | |
| Solution 2 |
