multiViewHuePlot = {
const selectedPoint = vl.selectPoint('selected_point')
.on('mouseover')
.nearest(true)
.clear('mouseout');
const sharedTransform = [
vl.calculate("hsl(datum.Color1).h").as('hue1'),
vl.calculate("hsl(datum.Color1).s").as('sat1'),
vl.calculate("hsl(datum.Color1).l").as('light1'),
vl.calculate("hsl(datum.Color1).h / 360.0").as('hue1_scaled'),];
const scatterWidth = Math.max(150, (width / 3) - 120), scatterHeight = 250;
const hueSatScatter = vl.markCircle()
.transform(sharedTransform)
.params(selectedPoint)
.encode(
vl.x().fieldQ('hue1').scale({domain: [0, 360]}).title('Hue'),
vl.y().fieldQ('sat1').title('Saturation'),
vl.size().fieldQ('light1'),
vl.color().fieldN('Color1').scale({range: vl.fieldN('Color1') }).legend(null),
vl.opacity().if(selectedPoint, vl.value(1)).value(0.1)
).width(scatterWidth).height(scatterHeight);
const hueSatText = vl.markText({align: 'right', dx: -12, dy: -4})
.transform(sharedTransform.concat(vl.filter(selectedPoint.empty(false))))
.encode(
vl.x().fieldQ('hue1').scale({domain: [0, 360]}),
vl.y().fieldQ('sat1'),
vl.text().fieldN('Team'),
);
const hueSatLayer = vl.layer(hueSatScatter, hueSatText);
const hueLightnessScatter = vl.markCircle()
.transform(sharedTransform)
.params(selectedPoint)
.encode(
vl.x().fieldQ('hue1').scale({domain: [0, 360]}).title('Hue'),
vl.y().fieldQ('light1').scale({domain: [0, 1]}).title('Lightness'),
vl.size().fieldQ('sat1'),
vl.color().fieldN('Color1').scale({range: vl.fieldN('Color1') }).legend(null),
vl.opacity().if(selectedPoint, vl.value(1)).value(0.1)
).width(scatterWidth).height(scatterHeight);
const hueLightnessText = vl.markText({align: 'right', dx: -8, dy: -2})
.transform(sharedTransform.concat(vl.filter(selectedPoint.empty(false))))
.encode(
vl.x().fieldQ('hue1').scale({domain: [0, 360]}),
vl.y().fieldQ('light1'),
vl.text().fieldN('Team'),
);
const hueLightnessLayer = vl.layer(hueLightnessScatter, hueLightnessText);
const satLightnessScatter = vl.markCircle()
.transform(sharedTransform)
.params(selectedPoint)
.encode(
vl.x().fieldQ('sat1').scale({domain: [0, 1]}).title('Saturation'),
vl.y().fieldQ('light1').scale({domain: [0, 1]}).title('Lightness'),
vl.size().fieldQ('hue1_scaled'),
vl.color().fieldN('Color1').scale({range: vl.fieldN('Color1') }).legend(null),
vl.opacity().if(selectedPoint, vl.value(1)).value(0.1)
).width(scatterWidth).height(scatterHeight);
const satLightnessText = vl.markText({align: 'right', dx: -8, dy: -2})
.transform(sharedTransform.concat(vl.filter(selectedPoint.empty(false))))
.encode(
vl.x().fieldQ('sat1').scale({domain: [0, 1]}),
vl.y().fieldQ('light1'),
vl.text().fieldN('Team'),
);
const satLightnessLayer = vl.layer(satLightnessScatter, satLightnessText);
const teamRectColors = vl.markRect()
.transform(sharedTransform)
.params(selectedPoint)
.encode(
vl.x().fieldN('Team')
.sort({field: 'hue1', order: 'descending'})
.axis({labelAngle: 320})
.title(null),
vl.color().fieldN('Color1')
.scale({range: vl.fieldN('Color1') })
.legend(null),
vl.opacity().if(selectedPoint, vl.value(1)).value(0.1)
).width(Math.max(600, scatterWidth * 3.5));
return vl.vconcat(vl.hconcat(hueSatLayer, hueLightnessLayer, satLightnessLayer), teamRectColors)
.data(nbaColors)
.resolve({scale: {color: 'independent'}});
}