Skip to content
Snippets Groups Projects
Commit dbe46408 authored by Leander's avatar Leander
Browse files

feat: prop selection

parent fe3dff1a
No related branches found
No related tags found
No related merge requests found
......@@ -20,7 +20,7 @@
<div id="bubble-chart-wrapper">
</div>
<div class="bubble-chart-settings">
<div class="chart-settings bubble-chart-settings">
<div class="size-by">
<label for="group-by-setting">Größe nach:</label>
......@@ -58,6 +58,7 @@
<div id="radar-chart-wrapper">
</div>
<div class="radar-chart-settings chart-settings"></div>
</div>
</div>
<script type="module" src="/src/main.ts"></script>
......
import * as d3 from "d3";
import {ScaleLinear} from "d3";
import Chart, {ChartConfig, ChartConfigParam} from "@/charts/chart.ts";
import {BubbleChartConfigParam} from "@/charts/bubbleChart.ts";
export type RadarChartConfig = ChartConfig & {
selectedData: RadarChartSelection[],
......@@ -10,7 +11,7 @@ export type RadarChartConfig = ChartConfig & {
attributes: { key: string, label: string }[] | [],
}
export type RadarChartConfigParam = ChartConfigParam & Partial<RadarChartConfig>
export type RadarChartConfigParam = Partial<ChartConfigParam> & Partial<RadarChartConfig>
type RadarChartSelection = {
_color: string | null | undefined,
......@@ -71,13 +72,18 @@ export default class RadarChart extends Chart {
vis.chart = svg.append('g')
for (const attribute of vis.config.attributes) {
const domain: [number, number] = [0, (d3.max(vis.data, (d: any) => d[attribute.key] as number) as number)]
vis.updateAxes()
}
updateAxes() {
this.axes = []
for (const attribute of this.config.attributes) {
const domain: [number, number] = [0, (d3.max(this.data, (d: any) => d[attribute.key] as number) as number)]
const scale = d3.scaleLinear(
domain,
[0, vis.axisLength],
[0, this.axisLength],
)
vis.axes.push({
this.axes.push({
scale,
domain,
label: attribute.label,
......@@ -92,6 +98,18 @@ export default class RadarChart extends Chart {
this.drawData();
}
updateSelectedAttribute(attributes: { key: string, label: string }[]): void {
this.config.attributes = attributes
this.updateAxes()
// force a redraw. Due to the idAccessor, the data would not be rerendered otherwise
const copy = this.config.selectedData
this.config.selectedData = []
this.renderVis()
this.config.selectedData = copy
this.drawData()
}
private getPreparedData(): {
data: RadarChartSelection,
axesValues: { label: string, r: number, value: number }[]
......@@ -124,12 +142,23 @@ export default class RadarChart extends Chart {
renderVis(): void {
let vis: RadarChart = this;
const axisGrid = vis.chart.append("g")
vis.drawAxes()
vis.drawData();
}
private drawAxes() {
let axisGrid = this.chart.selectAll(".axisWrapper")
if (axisGrid.empty()) {
axisGrid = this.chart.append("g")
.attr("class", "axisWrapper")
.attr('transform', `translate(${vis.chartCenter},${vis.chartCenter})`)
.attr('transform', `translate(${this.chartCenter},${this.chartCenter})`)
}
axisGrid.selectAll('*').remove()
const axes = axisGrid.selectAll('.axis')
.data(vis.axes)
.data(this.axes)
.enter()
.append('g')
.attr('class', 'axis')
......@@ -137,18 +166,16 @@ export default class RadarChart extends Chart {
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]])
([[0, 0], [Math.PI * 2 * index / this.axes.length, this.axisLength]])
)
axes.append('text')
.attr("x", (_: any, index: number) => Math.sin(2 * Math.PI * (index / vis.axes.length)) * (this.axisLength + 10))
.attr("y", (_: any, index: number) => -Math.cos(2 * Math.PI * (index / vis.axes.length)) * (this.axisLength + 10))
.attr("x", (_: any, index: number) => Math.sin(2 * Math.PI * (index / this.axes.length)) * (this.axisLength + 10))
.attr("y", (_: any, index: number) => -Math.cos(2 * Math.PI * (index / this.axes.length)) * (this.axisLength + 10))
.attr('text-anchor', 'middle')
.attr('alignment-baseline', 'middle')
.attr('font-size', 12)
.attr('fill', 'black')
.text((d: any) => d.label)
this.drawData();
}
private drawData() {
......
......@@ -61,6 +61,34 @@ sizeBySetting.oninput = (event) => {
}
const selectedNodes: (Player & { _color: string})[] = []
const radarChartSettings = document.querySelector('.radar-chart-settings') as HTMLDivElement
const radarChartAttributes = [
{
key: 'Performance _ G+A',
label: numericColumns['Performance _ G+A']
},
{
key: 'Expected_0 _ npxG+xAG',
label: numericColumns['Expected_0 _ npxG+xAG']
},
{
key: 'PrgP',
label: numericColumns['PrgP']
},
{
key: 'Total _ Cmp%',
label: numericColumns['Total _ Cmp%']
},
{
key: 'Tkl+Int',
label: numericColumns['Tkl+Int']
},
{
key: 'Touches _ Touches',
label: numericColumns['Touches _ Touches']
},
]
dsv(';', 'data/output.csv').then(data => {
parsedData = data.map((d: any) => {
for (const column of Object.keys(numericColumns)) {
......@@ -156,34 +184,34 @@ function updateSelectedNodes(node: Player) {
</table>
`)
},
attributes: [
{
key: 'Performance _ G+A',
label: numericColumns['Performance _ G+A']
},
{
key: 'Expected_0 _ npxG+xAG',
label: numericColumns['Expected_0 _ npxG+xAG']
},
{
key: 'PrgP',
label: numericColumns['PrgP']
},
{
key: 'Total _ Cmp%',
label: numericColumns['Total _ Cmp%']
},
{
key: 'Tkl+Int',
label: numericColumns['Tkl+Int']
},
{
key: 'Touches _ Touches',
label: numericColumns['Touches _ Touches']
},
]
attributes: radarChartAttributes,
})
radarChart.renderVis()
// add attribute settings
for (const index in radarChartAttributes) {
const input = document.createElement('select')
for (const column of Object.keys(numericColumns)) {
const option = document.createElement('option')
option.value = column
option.text = numericColumns[column as keyof typeof numericColumns]
input.appendChild(option)
}
input.value = radarChartAttributes[index].key
input.oninput = (event) => {
const value = (event.target as any)?.value
radarChartAttributes[index] = {
key: value,
label: numericColumns[value as keyof typeof numericColumns]
}
radarChart?.updateSelectedAttribute(radarChartAttributes)
}
radarChartSettings.appendChild(input)
}
} else {
radarChart.updateVis(selectedNodes)
}
......
......@@ -85,17 +85,9 @@ h1 {
}
.bubble-chart-settings {
position: absolute;
top: 100%;
right: 0;
display: flex;
padding: 2rem;
border-radius: 0.5rem;
flex-direction: column;
align-items: flex-end;
justify-content: flex-end;
gap: 1rem;
@include glass;
> div {
align-items: center;
......@@ -117,6 +109,21 @@ h1 {
margin: 0 4rem 4rem;
}
}
.chart-settings {
position: absolute;
top: 100%;
right: 0;
display: flex;
padding: 2rem;
border-radius: 0.5rem;
flex-direction: column;
@include glass;
&:empty {
display: none;
}
}
}
button {
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment