Skip to content
Snippets Groups Projects
Commit 9c06b45e authored by jonschi's avatar jonschi
Browse files

color scheme using hsv colors with hue

parent 7f35521c
No related branches found
No related tags found
No related merge requests found
......@@ -21,6 +21,18 @@ const tooltipString = ref("");
const cameraTargetPosition = new THREE.Vector3(370, 370, -15);
const cameraInitialPosition = new THREE.Vector3(1000, 500, 2000);
const regionMeshData = {};
// structure of this variable:
// ATT2: [
// {
// mesh: mesh1,
// shape: [{x,y}, {x,y}, ...],
// },
// {
// mesh: mesh2,
// shape: [{x,y}, {x,y}, ...],
// },
// ],
// };
const offset = 700; // for the globes offset to the right, TODO: change based on window width
let rootObject = new THREE.Object3D(); // root object for the extruded elements
......@@ -95,8 +107,6 @@ mapMaterial.wrapT = THREE.RepeatWrapping;
let material = new THREE.MeshPhongMaterial({
map: mapMaterial,
color: 0xb0c8e8,
// opacity: 0.1,
// transparent: true,
});
let mesh = new THREE.Mesh(geometry, material);
mesh.layers.set(worldLayer);
......@@ -194,18 +204,6 @@ function createRegions() {
})
});
// desired output = {
// ATT2: [
// {
// mesh: mesh1,
// shape: [{x,y}, {x,y}, ...],
// },
// {
// mesh: mesh2,
// shape: [{x,y}, {x,y}, ...],
// },
// ],
// };
regionMeshData[regionNutsCode] = output;
});
}
......@@ -214,7 +212,7 @@ function updateRegions(animationTime) {
for (const nuts in regionMeshData) {
regionMeshData[nuts].forEach(({mesh, shape}) => {
const covidDataWeek = props.covidData[props.selectedDate.toJSON()][nuts];
const color = visualization.colorByIncidence(covidDataWeek.incidence);
const color = new THREE.Color(visualization.colorByIncidence(covidDataWeek.incidence));
const extrusion = visualization.extrusion(covidDataWeek.incidence)
const shapeGeometry = createShapeGeometry(shape, extrusion);
......@@ -329,7 +327,7 @@ onMounted(async () => {
intersectedObject.currentHex =
intersectedObject.material.color.getHex();
// set a new color for closest object
intersectedObject.material.color.setHex(0x00cc00);
intersectedObject.material.color.setHex(0x6dc1fd);
// update text, if it has a "name" field. This will contain the nuts code of the intersected region
const name = intersects[0].object.name;
......
......@@ -10,6 +10,7 @@ import "vue-datepicker-next/index.css";
import BarChart from "./BarChart.vue";
import { getFlagUrl } from "../helpers/flags.js";
import VCenter from "./VCenter.vue"
import visualization from "../helpers/visualization.js";
const chartDisplayWeeks = ref(5);
const casesChartDivide = ref(false);
......@@ -86,15 +87,18 @@ const chartDataIncidence = computed({
const { accessors, labels } = extractAccessorsAndLabels();
const data = accessors.map((date) => {
const data = [];
const colors = [];
accessors.forEach((date) => {
let element = props.covidData[date][props.selectedNutsCode];
return parseFloat(element.incidence);
data.push(parseFloat(element.incidence));
colors.push(visualization.colorByIncidence(element.incidence))
});
// return labels and data
return {
labels,
datasets: [{ data, backgroundColor: "#660000" }],
datasets: [{ data, backgroundColor: colors }],
};
},
});
......@@ -109,18 +113,18 @@ const chartDataNewCases = computed({
const { accessors, labels } = extractAccessorsAndLabels();
const data = accessors.map((date) => {
const data = [];
const colors = [];
accessors.forEach((date) => {
let element = props.covidData[date][props.selectedNutsCode];
if (casesChartDivide.value) {
return parseFloat(element.count) / parseFloat(element.population);
} else {
return parseFloat(element.count);
}
let proportion = parseFloat(element.count) / parseFloat(element.population)
data.push(casesChartDivide.value ? proportion : parseFloat(element.count));
colors.push(visualization.colorByProportion(proportion))
});
return {
labels,
datasets: [{ data, backgroundColor: "#006600" }],
datasets: [{ data, backgroundColor: colors }],
};
},
});
......
import { Color } from "three";
const mediumIncidence = 2500;
const maxIncidence = 10000;
const mediumProportion = 0.03;
const maxProportion = 0.1;
const mediumValue = 0.7;
const bestHue = 138;
const insulation = 0.8;
const extrusion = function (incidence) {
incidence = parseFloat(incidence)
return incidence / 500
return incidence / mediumIncidence * 5
}
function HSVtoRGB(h, s, v) {
let r, g, b, i, f, p, q, t;
i = Math.floor(h * 6);
f = h * 6 - i;
p = v * (1 - s);
q = v * (1 - f * s);
t = v * (1 - (1 - f) * s);
switch (i % 6) {
case 0: r = v, g = t, b = p; break;
case 1: r = q, g = v, b = p; break;
case 2: r = p, g = v, b = t; break;
case 3: r = p, g = q, b = v; break;
case 4: r = t, g = p, b = v; break;
case 5: r = v, g = p, b = q; break;
}
return {
r: Math.round(r * 255),
g: Math.round(g * 255),
b: Math.round(b * 255)
};
}
function componentToHex(c) {
var hex = c.toString(16);
return hex.length == 1 ? "0" + hex : hex;
}
function rgbToHex({r, g, b}) {
const color = "#" + componentToHex(r) + componentToHex(g) + componentToHex(b);
return color.toUpperCase();
}
// black and white scheme for now
const colorByIncidence = function (incidence) {
incidence = parseFloat(incidence)
if (incidence > maxIncidence) incidence = maxIncidence
let value = (255 - Math.round((incidence / maxIncidence) * 255))
.toString(16)
.padStart(2, "0");
return new Color(`#${value}${value}${value}`);
let rgb;
if (incidence <= mediumIncidence) {
const hue = ((1 - (incidence / mediumIncidence)) * bestHue) / 360
rgb = HSVtoRGB(hue, insulation, mediumValue)
} else {
if (incidence >= maxIncidence) incidence = maxIncidence;
incidence -= mediumIncidence;
const value = 1 - ((incidence / (maxIncidence - mediumIncidence)) * insulation);
rgb = HSVtoRGB(0, insulation, value);
}
return rgbToHex(rgb);
}
const colorByProportion = function (proportion) {
let rgb;
if (proportion <= mediumProportion) {
const hue = ((1 - (proportion / mediumProportion)) * bestHue) / 360
rgb = HSVtoRGB(hue, insulation, mediumValue)
}
else {
const value = 1 - ((proportion / (maxProportion - mediumProportion)) * insulation);
rgb = HSVtoRGB(0, insulation, value);
}
return rgbToHex(rgb);
}
export default {
extrusion,
colorByIncidence,
colorByProportion,
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment