diff --git a/src/charts/bubbleChart.ts b/src/charts/bubbleChart.ts
index 18c7adf9fe66c613f38f5fb2d213e69ef3bec428..194f83861f9f6043dd64876c3d6fdeb4db1703b3 100644
--- a/src/charts/bubbleChart.ts
+++ b/src/charts/bubbleChart.ts
@@ -3,7 +3,10 @@ import {HierarchyNode, NumberValue, ScaleLinear, ScaleOrdinal, ScaleSequential}
 import {ChartConfig, ChartConfigParam} from "@/charts/chart.ts";
 import SearchableChart from "@/charts/SearchableChart.ts";
 import {debounce} from "@/utils.ts";
+// @ts-ignore
 import Legend from "@/charts/utils/legendColor.js";
+// @ts-ignore
+import legendCircle from "@/charts/utils/legendCircle.js";
 
 export type BubbleChartConfig = ChartConfig & {
     groupAccessor: (d: any) => string | null,
@@ -29,6 +32,7 @@ export default class BubbleChart extends SearchableChart {
     sizeScale: ScaleLinear<any, number> | null = null
     groupLabels: any | null = null
     groupsWithLabels: any[] = []
+    defaultSizeAccessor = (_: any) => 5
 
     constructor(data: any[], _config: BubbleChartConfigParam) {
         super(data, _config as ChartConfigParam)
@@ -51,7 +55,7 @@ export default class BubbleChart extends SearchableChart {
             margin: _config.margin || {top: 10, bottom: 30, right: 10, left: 30},
             tooltipPadding: _config.tooltipPadding || 30,
             groupAccessor: _config.groupAccessor || (() => null),
-            sizeAccessor: _config.sizeAccessor || (() => 5),
+            sizeAccessor: _config.sizeAccessor || this.defaultSizeAccessor,
             colorAccessor: _config.colorAccessor || (() => null),
             idAccessor: _config.idAccessor || (() => null),
             zoomExtent: _config.zoomExtent || [0.5, 20],
@@ -66,7 +70,7 @@ export default class BubbleChart extends SearchableChart {
             <svg id="${this.chartId}"></svg>
         `;
         vis.config.parentElement.innerHTML += `
-            <div id="tooltip"></div>
+            <div id="tooltip" class="tooltip"></div>
         `;
         vis.config.parentElement.innerHTML += `
             <div id="color-legend"></div>
@@ -121,6 +125,7 @@ export default class BubbleChart extends SearchableChart {
                     .attr("transform", (d: any) => `translate(${d.x},${d.y})`),
                 (exit: any) => exit.remove()
             )
+        node.selectAll('text').remove()
 
         node.selectAll('circle')
             .data((d: any) => [d])
@@ -128,6 +133,18 @@ export default class BubbleChart extends SearchableChart {
             .duration(1000)
             .attr('fill', (d: any) => vis.getFillForNode(d))
             .attr('r', (d: any) => d.r)
+
+        /*setTimeout(() => {
+            node
+                .filter((d: any) => d.r > 25)
+                .append('text')
+                .text((d: any) => vis.config.sizeAccessor(d.data))
+                .attr('text-anchor', 'middle')
+                .attr('opacity', '0')
+                .transition()
+                .duration(100)
+                .attr('opacity', '1')
+        }, 1000)*/
     }
 
     renderVis(): void {
@@ -203,16 +220,18 @@ export default class BubbleChart extends SearchableChart {
             .attr('group', true)
             .attr("transform", (d: any) => `translate(${d.x},${d.y})`)
             .on('mouseover', (event: Event) => {
+                const target = event.target as HTMLElement
                 // hide label
-                d3.select(event.target.closest('g'))
+                d3.select(target.closest('g'))
                     .selectAll("*")
                     .transition()
                     .duration(100)
                     .attr('opacity', 0)
             })
             .on('mouseleave', (event: Event) => {
+                const target = event.target as HTMLElement
                 // show label
-                d3.select(event.target.closest('g'))
+                d3.select(target.closest('g'))
                     .selectAll("*")
                     .transition()
                     .duration(100)
@@ -230,9 +249,9 @@ export default class BubbleChart extends SearchableChart {
             .filter((d: any) => d.data[0])
             .data((d: any) => [d])
             .join(
-                enter => enter.append("rect"),
-                update => update,
-                exit => exit.remove()
+                (enter: any) => enter.append("rect"),
+                (update: any) => update,
+                (exit: any) => exit.remove()
             )
             .attr('fill', 'white')
             .attr('stroke', '#333')
@@ -244,17 +263,19 @@ export default class BubbleChart extends SearchableChart {
             .selectAll('text')
             .data((d: any) => [d])
             .join(
-                enter => enter.append("text"),
-                update => update,
-                exit => exit.remove()
+                (enter: any) => enter.append("text"),
+                (update: any) => update,
+                (exit: any) => exit.remove()
             )
             .attr('text-anchor', 'middle')
             .attr('alignment-baseline', 'middle')
             .attr('font-size', 12 / this.zoomLevel)
             .attr('fill', 'black')
-            .text(d => d.data[0])
+            .text((d: any) => d.data[0])
             .call((selection: any) => selection.each(
                 function (d: any) {
+                    // I can't get TS to type annotate 'this' correctly here
+                    // @ts-ignore
                     d.bbox = this.getBBox()
                 }
             ))
@@ -387,6 +408,9 @@ export default class BubbleChart extends SearchableChart {
 
     zoomToPoint(dataPoint: any) {
         if (dataPoint) {
+            if (typeof dataPoint === 'string') {
+                dataPoint = this.packRoot?.leaves().find((d: any) => this.config.idAccessor(d.data) === dataPoint)
+            }
             if (this.highlightedNode) {
                 this.getNode(this.highlightedNode.data)
                     .transition()
diff --git a/src/charts/radarChart.ts b/src/charts/radarChart.ts
index 499182234fd2460f034cf4ab3369e646bc7f87d9..c8c6e74d36d0d4774960d818767f6189b299b63d 100644
--- a/src/charts/radarChart.ts
+++ b/src/charts/radarChart.ts
@@ -61,7 +61,7 @@ export default class RadarChart extends Chart {
             <svg id="${this.chartId}"></svg>
         `;
         vis.config.parentElement.innerHTML += `
-            <div id="tooltip"></div>
+            <div id="tooltip-radar-chart" class="tooltip"></div>
         `;
 
         const svg = d3.select(`#${this.chartId}`)
@@ -92,14 +92,18 @@ export default class RadarChart extends Chart {
         this.drawData();
     }
 
-    private getPreparedData(): { data: RadarChartSelection, axesValues: { label: string, value: number }[] }[] {
+    private getPreparedData(): {
+        data: RadarChartSelection,
+        axesValues: { label: string, r: number, value: number }[]
+    }[] {
         return this.config.selectedData.map(
             (d: any) => ({
                 data: d,
                 axesValues: this.axes.map(axis => (
                     {
                         label: axis.label,
-                        value: axis.scale(d[axis.key])
+                        r: axis.scale(d[axis.key]),
+                        value: d[axis.key],
                     }
                 ))
             })
@@ -131,6 +135,7 @@ export default class RadarChart extends Chart {
             .attr('class', 'axis')
 
         axes.append("path")
+            .attr("pointer-events", "none")
             .attr("d", (_: any, index: number) => d3.lineRadial()
                 ([[0, 0], [Math.PI * 2 * index / vis.axes.length, this.axisLength]])
             )
@@ -162,10 +167,11 @@ export default class RadarChart extends Chart {
                 (enter: any) => {
                     const data = enter.append("g")
                         .attr("class", "data")
+
                     data
                         .append("path")
                         .attr("d", (d: any) => {
-                            const data = d.axesValues.map((d: any) => d.value)
+                            const data = d.axesValues.map((d: any) => d.r)
                             return d3.lineRadial()
                                 .angle((_, index) => Math.PI * 2 / this.axes.length * index)
                                 .radius((value) => value || 0)
@@ -195,17 +201,29 @@ export default class RadarChart extends Chart {
                         .attr("class", "dataPoint")
                         .attr("r", 5)
                         .attr("cx", (data: {
-                            label: string,
-                            value: number
-                        }, index: number) => Math.sin(2 * Math.PI * (index / this.axes.length)) * data.value)
+                            r: number,
+                        }, index: number) => Math.sin(2 * Math.PI * (index / this.axes.length)) * data.r)
                         .attr("cy", (data: {
-                            label: string,
-                            value: number
-                        }, index: number) => -Math.cos(2 * Math.PI * (index / this.axes.length)) * data.value)
+                            r: number,
+                        }, index: number) => -Math.cos(2 * Math.PI * (index / this.axes.length)) * data.r)
                         .attr('fill', (d: any) => d.data._color)
+                        .on('mouseover', (_: Event, d: any) => {
+                            const element = d3.select('#tooltip-radar-chart')
+                                .style('display', 'block')
+                            if (!this.config.renderTooltip) return
+                            this.config.renderTooltip(d, element)
+                        })
+                        .on('mousemove', (event: any) => {
+                            d3.select('#tooltip-radar-chart')
+                                .style('left', (event.layerX + this.config.tooltipPadding) + 'px')
+                                .style('top', (event.layerY + this.config.tooltipPadding) + 'px')
+                        })
+                        .on('mouseleave', (_: Event) => {
+                            d3.select('#tooltip-radar-chart').style('display', 'none');
+                        })
                 },
-                update => update,
-                exit => exit.remove()
+                (update: any) => update,
+                (exit: any) => exit.remove()
             )
 
 
diff --git a/src/charts/utils/legendCircle.js b/src/charts/utils/legendCircle.js
deleted file mode 100644
index 179ea2484fa84786cfacb92c2c1fe7fea749ff9b..0000000000000000000000000000000000000000
--- a/src/charts/utils/legendCircle.js
+++ /dev/null
@@ -1,69 +0,0 @@
-// Circle legend, made by Harry Stevens
-// https://observablehq.com/@harrystevens/circle-legend
-
-export default function legendCircle(context){
-    let scale,
-        tickValues,
-        tickFormat = d => d,
-        tickSize = 5;
-
-    function legend(context){
-        let g = context.select("g");
-        if (!g._groups[0][0]){
-            g = context.append("g");
-        }
-        g.attr("transform", `translate(${[1, 1]})`);
-
-        const ticks = tickValues || scale.ticks();
-
-        const max = ticks[ticks.length - 1];
-
-        g.selectAll("circle")
-            .data(ticks.slice().reverse())
-            .enter().append("circle")
-            .attr("fill", "none")
-            .attr("stroke", "currentColor")
-            .attr("cx", scale(max))
-            .attr("cy", scale)
-            .attr("r", scale);
-
-        g.selectAll("line")
-            .data(ticks)
-            .enter().append("line")
-            .attr("stroke", "currentColor")
-            .attr("stroke-dasharray", "4, 2")
-            .attr("x1", scale(max))
-            .attr("x2", tickSize + scale(max) * 2)
-            .attr("y1", d => scale(d) * 2)
-            .attr("y2", d => scale(d) * 2);
-
-        g.selectAll("text")
-            .data(ticks)
-            .enter().append("text")
-            .attr("font-family", "'Helvetica Neue', sans-serif")
-            .attr("font-size", 11)
-            .attr("dx", 3)
-            .attr("dy", 4)
-            .attr("x", tickSize + scale(max) * 2)
-            .attr("y", d => scale(d) * 2)
-            .text(tickFormat);
-    }
-
-    legend.tickSize = function(_){
-        return arguments.length ? (tickSize = +_, legend) : tickSize;
-    }
-
-    legend.scale = function(_){
-        return arguments.length ? (scale = _, legend) : scale;
-    }
-
-    legend.tickFormat = function(_){
-        return arguments.length ? (tickFormat = _, legend) : tickFormat;
-    }
-
-    legend.tickValues = function(_){
-        return arguments.length ? (tickValues = _, legend) : tickValues;
-    }
-
-    return legend;
-}
\ No newline at end of file
diff --git a/src/main.ts b/src/main.ts
index 480ab06733e2d29669fc1f7a58761f71879c8227..89098df075dba371f3c01ce9d8b37d07e8cbf3f0 100644
--- a/src/main.ts
+++ b/src/main.ts
@@ -147,6 +147,15 @@ function updateSelectedNodes(node: Player) {
             margin: {top: 20, right: 20, bottom: 20, left: 20},
             axisCircles: 2,
             idAccessor: (d: any) => d.player,
+            renderTooltip: (dataPoint: any, tooltip: d3.Selection<d3.BaseType, unknown, HTMLElement, any>) => {
+                bubbleChart?.zoomToPoint(dataPoint.data.player)
+                tooltip.html(`
+                <h4>${dataPoint.data['player']}</h4>
+                <table>
+                    <tr><th>${dataPoint['label']}</th><td>${dataPoint['value']}</td></tr>
+                </table>
+            `)
+            },
             attributes: [
                 {
                     key: 'Performance _ G+A',
diff --git a/src/styles/index.scss b/src/styles/index.scss
index 0254b58452d19f6a760451c4709fd4c4743ac122..f529d95e958be468f8396c23259d30d333079bd7 100644
--- a/src/styles/index.scss
+++ b/src/styles/index.scss
@@ -43,7 +43,7 @@ h1 {
   font-size: 11px;
 }
 
-#tooltip {
+.tooltip {
   position: absolute;
   display: none;
   background: white;